1 /*******************************************************************************
2 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
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
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.
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
21 ********************************************************************************/
22 /*****************************************************************************/
25 * The file implementing SCSI/ATA Translation (SAT).
26 * The routines in this file are independent from HW LL API.
29 /*****************************************************************************/
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 #include <dev/pms/config.h>
34 #include <dev/pms/freebsd/driver/common/osenv.h>
35 #include <dev/pms/freebsd/driver/common/ostypes.h>
36 #include <dev/pms/freebsd/driver/common/osdebug.h>
40 #include <dev/pms/RefTisa/sallsdk/api/sa.h>
41 #include <dev/pms/RefTisa/sallsdk/api/saapi.h>
42 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
44 #include <dev/pms/RefTisa/tisa/api/titypes.h>
45 #include <dev/pms/RefTisa/tisa/api/ostiapi.h>
46 #include <dev/pms/RefTisa/tisa/api/tiapi.h>
47 #include <dev/pms/RefTisa/tisa/api/tiglobal.h>
50 #include <dev/pms/RefTisa/sat/api/sm.h>
51 #include <dev/pms/RefTisa/sat/api/smapi.h>
52 #include <dev/pms/RefTisa/sat/api/tdsmapi.h>
56 #include <dev/pms/RefTisa/discovery/api/dm.h>
57 #include <dev/pms/RefTisa/discovery/api/dmapi.h>
58 #include <dev/pms/RefTisa/discovery/api/tddmapi.h>
61 #include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h>
62 #include <dev/pms/freebsd/driver/common/osstring.h>
63 #include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h>
65 #ifdef INITIATOR_DRIVER
66 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h>
67 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h>
68 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h>
72 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h>
73 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h>
74 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h>
77 #include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h>
78 #include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h>
80 #include <dev/pms/RefTisa/tisa/sassata/sata/host/sat.h>
81 #include <dev/pms/RefTisa/tisa/sassata/sata/host/satproto.h>
83 /*****************************************************************************
86 * This routine is called to initiate a new SCSI request to SATL.
88 * \param tiRoot: Pointer to TISA initiator driver/port instance.
89 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
90 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
91 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
92 * \param satIOContext_t: Pointer to the SAT IO Context
96 * \e tiSuccess: I/O request successfully initiated.
97 * \e tiBusy: No resources available, try again later.
98 * \e tiIONoDevice: Invalid device handle.
99 * \e tiError: Other errors that prevent the I/O request to be started.
102 *****************************************************************************/
103 GLOBAL bit32 satIOStart(
105 tiIORequest_t *tiIORequest,
106 tiDeviceHandle_t *tiDeviceHandle,
107 tiScsiInitiatorRequest_t *tiScsiRequest,
108 satIOContext_t *satIOContext
112 bit32 retVal = tiSuccess;
113 satDeviceData_t *pSatDevData;
114 scsiRspSense_t *pSense;
115 tiIniScsiCmnd_t *scsiCmnd;
117 satInternalIo_t *pSatIntIo;
118 #ifdef TD_DEBUG_ENABLE
119 tdsaDeviceData_t *oneDeviceData;
122 pSense = satIOContext->pSense;
123 pSatDevData = satIOContext->pSatDevData;
124 scsiCmnd = &tiScsiRequest->scsiCmnd;
125 pLun = &scsiCmnd->lun;
128 * Reject all other LUN other than LUN 0.
130 if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
131 pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) &&
132 (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY)
135 TI_DBG1(("satIOStart: *** REJECT *** LUN not zero, cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
136 scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
137 satSetSensePayload( pSense,
138 SCSI_SNSKEY_ILLEGAL_REQUEST,
140 SCSI_SNSCODE_LOGICAL_NOT_SUPPORTED,
143 ostiInitiatorIOCompleted( tiRoot,
146 SCSI_STAT_CHECK_CONDITION,
147 satIOContext->pTiSenseData,
148 satIOContext->interruptContext );
153 TI_DBG6(("satIOStart: satPendingIO %d satNCQMaxIO %d\n",pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
155 /* this may happen after tiCOMReset until OS sends inquiry */
156 if (pSatDevData->IDDeviceValid == agFALSE && (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY))
158 #ifdef TD_DEBUG_ENABLE
159 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
161 TI_DBG1(("satIOStart: invalid identify device data did %d\n", oneDeviceData->id));
162 retVal = tiIONoDevice;
166 * Check if we need to return BUSY, i.e. recovery in progress
168 if (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY)
170 #ifdef TD_DEBUG_ENABLE
171 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
173 TI_DBG1(("satIOStart: IN RECOVERY STATE cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
174 scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
175 TI_DBG1(("satIOStart: IN RECOVERY STATE did %d\n", oneDeviceData->id));
177 TI_DBG1(("satIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
178 TI_DBG1(("satIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
184 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
186 if (scsiCmnd->cdb[0] == SCSIOPC_REPORT_LUN)
188 return satReportLun(tiRoot, tiIORequest, tiDeviceHandle, tiScsiRequest, satIOContext);
192 return satPacket(tiRoot, tiIORequest, tiDeviceHandle, tiScsiRequest, satIOContext);
195 else /* pSatDevData->satDeviceType != SATA_ATAPI_DEVICE */
198 switch(scsiCmnd->cdb[0])
201 retVal = satRead6( tiRoot,
208 case SCSIOPC_READ_10:
209 retVal = satRead10( tiRoot,
216 case SCSIOPC_READ_12:
217 TI_DBG5(("satIOStart: SCSIOPC_READ_12\n"));
218 retVal = satRead12( tiRoot,
225 case SCSIOPC_READ_16:
226 retVal = satRead16( tiRoot,
233 case SCSIOPC_WRITE_6:
234 retVal = satWrite6( tiRoot,
241 case SCSIOPC_WRITE_10:
242 retVal = satWrite10( tiRoot,
249 case SCSIOPC_WRITE_12:
250 TI_DBG5(("satIOStart: SCSIOPC_WRITE_12 \n"));
251 retVal = satWrite12( tiRoot,
259 case SCSIOPC_WRITE_16:
260 TI_DBG5(("satIOStart: SCSIOPC_WRITE_16\n"));
261 retVal = satWrite16( tiRoot,
269 case SCSIOPC_VERIFY_10:
270 retVal = satVerify10( tiRoot,
277 case SCSIOPC_VERIFY_12:
278 TI_DBG5(("satIOStart: SCSIOPC_VERIFY_12\n"));
279 retVal = satVerify12( tiRoot,
286 case SCSIOPC_VERIFY_16:
287 TI_DBG5(("satIOStart: SCSIOPC_VERIFY_16\n"));
288 retVal = satVerify16( tiRoot,
295 case SCSIOPC_TEST_UNIT_READY:
296 retVal = satTestUnitReady( tiRoot,
303 case SCSIOPC_INQUIRY:
304 retVal = satInquiry( tiRoot,
311 case SCSIOPC_REQUEST_SENSE:
312 retVal = satRequestSense( tiRoot,
319 case SCSIOPC_MODE_SENSE_6:
320 retVal = satModeSense6( tiRoot,
327 case SCSIOPC_MODE_SENSE_10:
328 retVal = satModeSense10( tiRoot,
336 case SCSIOPC_READ_CAPACITY_10:
337 retVal = satReadCapacity10( tiRoot,
344 case SCSIOPC_READ_CAPACITY_16:
345 retVal = satReadCapacity16( tiRoot,
352 case SCSIOPC_REPORT_LUN:
353 retVal = satReportLun( tiRoot,
360 case SCSIOPC_FORMAT_UNIT:
361 TI_DBG5(("satIOStart: SCSIOPC_FORMAT_UNIT\n"));
362 retVal = satFormatUnit( tiRoot,
368 case SCSIOPC_SEND_DIAGNOSTIC: /* Table 28, p40 */
369 TI_DBG5(("satIOStart: SCSIOPC_SEND_DIAGNOSTIC\n"));
370 retVal = satSendDiagnostic( tiRoot,
377 case SCSIOPC_START_STOP_UNIT:
378 TI_DBG5(("satIOStart: SCSIOPC_START_STOP_UNIT\n"));
379 retVal = satStartStopUnit( tiRoot,
386 case SCSIOPC_WRITE_SAME_10: /* sector and LBA; SAT p64 case 3 accessing payload and very
388 TI_DBG5(("satIOStart: SCSIOPC_WRITE_SAME_10\n"));
389 retVal = satWriteSame10( tiRoot,
396 case SCSIOPC_WRITE_SAME_16: /* no support due to transfer length(sector count) */
397 TI_DBG5(("satIOStart: SCSIOPC_WRITE_SAME_16\n"));
398 retVal = satWriteSame16( tiRoot,
405 case SCSIOPC_LOG_SENSE: /* SCT and log parameter(informational exceptions) */
406 TI_DBG5(("satIOStart: SCSIOPC_LOG_SENSE\n"));
407 retVal = satLogSense( tiRoot,
414 case SCSIOPC_MODE_SELECT_6: /*mode layout and AlloLen check */
415 TI_DBG5(("satIOStart: SCSIOPC_MODE_SELECT_6\n"));
416 retVal = satModeSelect6( tiRoot,
423 case SCSIOPC_MODE_SELECT_10: /* mode layout and AlloLen check and sharing CB with satModeSelect6*/
424 TI_DBG5(("satIOStart: SCSIOPC_MODE_SELECT_10\n"));
425 retVal = satModeSelect10( tiRoot,
432 case SCSIOPC_SYNCHRONIZE_CACHE_10: /* on error what to return, sharing CB with
433 satSynchronizeCache16 */
434 TI_DBG5(("satIOStart: SCSIOPC_SYNCHRONIZE_CACHE_10\n"));
435 retVal = satSynchronizeCache10( tiRoot,
442 case SCSIOPC_SYNCHRONIZE_CACHE_16:/* on error what to return, sharing CB with
443 satSynchronizeCache16 */
445 TI_DBG5(("satIOStart: SCSIOPC_SYNCHRONIZE_CACHE_16\n"));
446 retVal = satSynchronizeCache16( tiRoot,
453 case SCSIOPC_WRITE_AND_VERIFY_10: /* single write and multiple writes */
454 TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_10\n"));
455 retVal = satWriteAndVerify10( tiRoot,
462 case SCSIOPC_WRITE_AND_VERIFY_12:
463 TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_12\n"));
464 retVal = satWriteAndVerify12( tiRoot,
471 case SCSIOPC_WRITE_AND_VERIFY_16:
472 TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_16\n"));
473 retVal = satWriteAndVerify16( tiRoot,
481 case SCSIOPC_READ_MEDIA_SERIAL_NUMBER:
482 TI_DBG5(("satIOStart: SCSIOPC_READ_MEDIA_SERIAL_NUMBER\n"));
483 retVal = satReadMediaSerialNumber( tiRoot,
491 case SCSIOPC_READ_BUFFER:
492 TI_DBG5(("satIOStart: SCSIOPC_READ_BUFFER\n"));
493 retVal = satReadBuffer( tiRoot,
501 case SCSIOPC_WRITE_BUFFER:
502 TI_DBG5(("satIOStart: SCSIOPC_WRITE_BUFFER\n"));
503 retVal = satWriteBuffer( tiRoot,
511 case SCSIOPC_REASSIGN_BLOCKS:
512 TI_DBG5(("satIOStart: SCSIOPC_REASSIGN_BLOCKS\n"));
513 retVal = satReassignBlocks( tiRoot,
522 /* Not implemented SCSI cmd, set up error response */
523 TI_DBG1(("satIOStart: unsupported SCSI cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
524 scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
526 satSetSensePayload( pSense,
527 SCSI_SNSKEY_ILLEGAL_REQUEST,
529 SCSI_SNSCODE_INVALID_COMMAND,
532 ostiInitiatorIOCompleted( tiRoot,
535 SCSI_STAT_CHECK_CONDITION,
536 satIOContext->pTiSenseData,
537 satIOContext->interruptContext );
544 if (retVal == tiBusy)
546 #ifdef TD_DEBUG_ENABLE
547 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
549 TI_DBG1(("satIOStart: BUSY did %d\n", oneDeviceData->id));
550 TI_DBG3(("satIOStart: LL is busy or target queue is full\n"));
551 TI_DBG3(("satIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
552 TI_DBG3(("satIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
553 pSatIntIo = satIOContext->satIntIoContext;
555 /* interal structure free */
556 satFreeIntIoResource( tiRoot,
566 /*****************************************************************************/
567 /*! \brief Setup up the SCSI Sense response.
569 * This function is used to setup up the Sense Data payload for
570 * CHECK CONDITION status.
572 * \param pSense: Pointer to the scsiRspSense_t sense data structure.
573 * \param SnsKey: SCSI Sense Key.
574 * \param SnsInfo: SCSI Sense Info.
575 * \param SnsCode: SCSI Sense Code.
579 /*****************************************************************************/
580 void satSetSensePayload( scsiRspSense_t *pSense,
584 satIOContext_t *satIOContext
587 /* for fixed format sense data, SPC-4, p37 */
591 TI_DBG5(("satSetSensePayload: start\n"));
593 senseLength = sizeof(scsiRspSense_t);
595 /* zero out the data area */
596 for (i=0;i< senseLength;i++)
598 ((bit8*)pSense)[i] = 0;
602 * SCSI Sense Data part of response data
604 pSense->snsRespCode = 0x70; /* 0xC0 == vendor specific */
605 /* 0x70 == standard current error */
606 pSense->senseKey = SnsKey;
608 * Put sense info in scsi order format
610 pSense->info[0] = (bit8)((SnsInfo >> 24) & 0xff);
611 pSense->info[1] = (bit8)((SnsInfo >> 16) & 0xff);
612 pSense->info[2] = (bit8)((SnsInfo >> 8) & 0xff);
613 pSense->info[3] = (bit8)((SnsInfo) & 0xff);
614 pSense->addSenseLen = 11; /* fixed size of sense data = 18 */
615 pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF);
616 pSense->senseQual = (bit8)(SnsCode & 0xFF);
618 * Set pointer in scsi status
623 * set illegal request sense key specific error in cdb, no bit pointer
625 case SCSI_SNSKEY_ILLEGAL_REQUEST:
626 pSense->skeySpecific[0] = 0xC8;
632 /* setting sense data length */
633 if (satIOContext != agNULL)
635 satIOContext->pTiSenseData->senseLen = 18;
639 TI_DBG1(("satSetSensePayload: satIOContext is NULL\n"));
643 /*****************************************************************************/
644 /*! \brief Setup up the SCSI Sense response.
646 * This function is used to setup up the Sense Data payload for
647 * CHECK CONDITION status.
649 * \param pSense: Pointer to the scsiRspSense_t sense data structure.
650 * \param SnsKey: SCSI Sense Key.
651 * \param SnsInfo: SCSI Sense Info.
652 * \param SnsCode: SCSI Sense Code.
656 /*****************************************************************************/
658 void satSetDeferredSensePayload( scsiRspSense_t *pSense,
662 satIOContext_t *satIOContext
665 /* for fixed format sense data, SPC-4, p37 */
669 senseLength = sizeof(scsiRspSense_t);
671 /* zero out the data area */
672 for (i=0;i< senseLength;i++)
674 ((bit8*)pSense)[i] = 0;
678 * SCSI Sense Data part of response data
680 pSense->snsRespCode = 0x71; /* 0xC0 == vendor specific */
681 /* 0x70 == standard current error */
682 pSense->senseKey = SnsKey;
684 * Put sense info in scsi order format
686 pSense->info[0] = (bit8)((SnsInfo >> 24) & 0xff);
687 pSense->info[1] = (bit8)((SnsInfo >> 16) & 0xff);
688 pSense->info[2] = (bit8)((SnsInfo >> 8) & 0xff);
689 pSense->info[3] = (bit8)((SnsInfo) & 0xff);
690 pSense->addSenseLen = 11; /* fixed size of sense data = 18 */
691 pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF);
692 pSense->senseQual = (bit8)(SnsCode & 0xFF);
694 * Set pointer in scsi status
699 * set illegal request sense key specific error in cdb, no bit pointer
701 case SCSI_SNSKEY_ILLEGAL_REQUEST:
702 pSense->skeySpecific[0] = 0xC8;
709 /* setting sense data length */
710 if (satIOContext != agNULL)
712 satIOContext->pTiSenseData->senseLen = 18;
716 TI_DBG1(("satSetDeferredSensePayload: satIOContext is NULL\n"));
720 /*****************************************************************************/
721 /*! \brief SAT implementation for ATAPI Packet Command.
723 * SAT implementation for ATAPI Packet and send FIS request to LL layer.
725 * \param tiRoot: Pointer to TISA initiator driver/port instance.
726 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
727 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
728 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
729 * \param satIOContext_t: Pointer to the SAT IO Context
731 * \return If command is started successfully
732 * - \e tiSuccess: I/O request successfully initiated.
733 * - \e tiBusy: No resources available, try again later.
734 * - \e tiIONoDevice: Invalid device handle.
735 * - \e tiError: Other errors.
737 /*****************************************************************************/
738 GLOBAL bit32 satPacket(
740 tiIORequest_t *tiIORequest,
741 tiDeviceHandle_t *tiDeviceHandle,
742 tiScsiInitiatorRequest_t *tiScsiRequest,
743 satIOContext_t *satIOContext)
746 bit32 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
747 satDeviceData_t *pSatDevData;
748 tiIniScsiCmnd_t *scsiCmnd;
749 agsaFisRegHostToDevice_t *fis;
751 pSatDevData = satIOContext->pSatDevData;
752 scsiCmnd = &tiScsiRequest->scsiCmnd;
753 fis = satIOContext->pFis;
755 TI_DBG3(("satPacket: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
756 scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
757 scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
758 scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
760 fis->h.fisType = 0x27; /* Reg host to device */
761 fis->h.c_pmPort = 0x80; /* C Bit is set 1*/
762 fis->h.command = SAT_PACKET; /* 0xA0 */
763 if (pSatDevData->satDMADIRSupport) /* DMADIR enabled*/
765 fis->h.features = (tiScsiRequest->dataDirection == tiDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */
769 fis->h.features = 0; /* FIS reserve */
771 /* Byte count low and byte count high */
772 if ( scsiCmnd->expDataLength > 0xFFFF )
774 fis->d.lbaMid = 0xFF; /* FIS LBA (7 :0 ) */
775 fis->d.lbaHigh = 0xFF; /* FIS LBA (15:8 ) */
779 fis->d.lbaMid = (bit8)scsiCmnd->expDataLength; /* FIS LBA (7 :0 ) */
780 fis->d.lbaHigh = (bit8)(scsiCmnd->expDataLength>>8); /* FIS LBA (15:8 ) */
783 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
784 fis->d.device = 0; /* FIS LBA (27:24) and FIS LBA mode */
785 fis->d.lbaLowExp = 0;
786 fis->d.lbaMidExp = 0;
787 fis->d.lbaHighExp = 0;
788 fis->d.featuresExp = 0;
789 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
790 fis->d.sectorCountExp = 0;
791 fis->d.reserved4 = 0;
792 fis->d.control = 0; /* FIS HOB bit clear */
793 fis->d.reserved5 = 0;
795 satIOContext->ATACmd = SAT_PACKET;
797 if (tiScsiRequest->dataDirection == tiDirectionIn)
799 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
803 agRequestType = AGSA_SATA_PROTOCOL_H2D_PKT;
806 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
808 /*DMA transfer mode*/
809 fis->h.features |= 0x01;
813 /*PIO transfer mode*/
814 fis->h.features |= 0x0;
817 satIOContext->satCompleteCB = &satPacketCB;
820 * Prepare SGL and send FIS to LL layer.
822 satIOContext->reqType = agRequestType; /* Save it */
824 status = sataLLIOStart( tiRoot,
830 TI_DBG5(("satPacket: return\n"));
834 /*****************************************************************************/
835 /*! \brief SAT implementation for satSetFeatures.
837 * This function creates SetFeatures fis and sends the request to LL layer
839 * \param tiRoot: Pointer to TISA initiator driver/port instance.
840 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
841 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
842 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
843 * \param satIOContext_t: Pointer to the SAT IO Context
845 * \return If command is started successfully
846 * - \e tiSuccess: I/O request successfully initiated.
847 * - \e tiBusy: No resources available, try again later.
848 * - \e tiIONoDevice: Invalid device handle.
849 * - \e tiError: Other errors.
851 /*****************************************************************************/
852 GLOBAL bit32 satSetFeatures(
854 tiIORequest_t *tiIORequest,
855 tiDeviceHandle_t *tiDeviceHandle,
856 tiScsiInitiatorRequest_t *tiScsiRequest,
857 satIOContext_t *satIOContext,
863 agsaFisRegHostToDevice_t *fis;
865 fis = satIOContext->pFis;
866 TI_DBG3(("satSetFeatures: start\n"));
869 * Send the Set Features command.
871 fis->h.fisType = 0x27; /* Reg host to device */
872 fis->h.c_pmPort = 0x80; /* C Bit is set */
873 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
874 fis->h.features = 0x03; /* set transfer mode */
879 fis->d.lbaLowExp = 0;
880 fis->d.lbaMidExp = 0;
881 fis->d.lbaHighExp = 0;
882 fis->d.featuresExp = 0;
883 fis->d.sectorCountExp = 0;
884 fis->d.reserved4 = 0;
885 fis->d.control = 0; /* FIS HOB bit clear */
886 fis->d.reserved5 = 0;
888 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
890 /* Initialize CB for SATA completion.
894 fis->d.sectorCount = 0x45;
895 /*satIOContext->satCompleteCB = &satSetFeaturesDMACB;*/
899 fis->d.sectorCount = 0x0C;
900 /*satIOContext->satCompleteCB = &satSetFeaturesPIOCB;*/
902 satIOContext->satCompleteCB = &satSetFeaturesCB;
905 * Prepare SGL and send FIS to LL layer.
907 satIOContext->reqType = agRequestType; /* Save it */
909 status = sataLLIOStart( tiRoot,
915 TI_DBG5(("satSetFeatures: return\n"));
919 /*****************************************************************************/
920 /*! \brief SAT implementation for SCSI REQUEST SENSE to ATAPI device.
922 * SAT implementation for SCSI REQUEST SENSE.
924 * \param tiRoot: Pointer to TISA initiator driver/port instance.
925 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
926 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
927 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
928 * \param satIOContext_t: Pointer to the SAT IO Context
930 * \return If command is started successfully
931 * - \e tiSuccess: I/O request successfully initiated.
932 * - \e tiBusy: No resources available, try again later.
933 * - \e tiIONoDevice: Invalid device handle.
934 * - \e tiError: Other errors.
936 /*****************************************************************************/
937 GLOBAL bit32 satRequestSenseForATAPI(
939 tiIORequest_t *tiIORequest,
940 tiDeviceHandle_t *tiDeviceHandle,
941 tiScsiInitiatorRequest_t *tiScsiRequest,
942 satIOContext_t *satIOContext)
945 bit32 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
946 satDeviceData_t *pSatDevData;
947 tiIniScsiCmnd_t *scsiCmnd;
948 agsaFisRegHostToDevice_t *fis;
950 pSatDevData = satIOContext->pSatDevData;
951 scsiCmnd = &tiScsiRequest->scsiCmnd;
952 fis = satIOContext->pFis;
954 scsiCmnd->cdb[0] = SCSIOPC_REQUEST_SENSE;
955 scsiCmnd->cdb[1] = 0;
956 scsiCmnd->cdb[2] = 0;
957 scsiCmnd->cdb[3] = 0;
958 scsiCmnd->cdb[4] = SENSE_DATA_LENGTH;
959 scsiCmnd->cdb[5] = 0;
960 TI_DBG3(("satRequestSenseForATAPI: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
961 scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
962 scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
963 scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
965 fis->h.fisType = 0x27; /* Reg host to device */
966 fis->h.c_pmPort = 0x80; /* C Bit is set 1*/
967 fis->h.command = SAT_PACKET; /* 0xA0 */
968 if (pSatDevData->satDMADIRSupport) /* DMADIR enabled*/
970 fis->h.features = (tiScsiRequest->dataDirection == tiDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */
974 fis->h.features = 0; /* FIS reserve */
977 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
978 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
979 fis->d.lbaHigh = 0x20; /* FIS LBA (23:16) */
980 fis->d.device = 0; /* FIS LBA (27:24) and FIS LBA mode */
981 fis->d.lbaLowExp = 0;
982 fis->d.lbaMidExp = 0;
983 fis->d.lbaHighExp = 0;
984 fis->d.featuresExp = 0;
985 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
986 fis->d.sectorCountExp = 0;
987 fis->d.reserved4 = 0;
988 fis->d.control = 0; /* FIS HOB bit clear */
989 fis->d.reserved5 = (bit32)(scsiCmnd->cdb[0]|(scsiCmnd->cdb[1]<<8)|(scsiCmnd->cdb[2]<<16)|(scsiCmnd->cdb[3]<<24));
991 satIOContext->ATACmd = SAT_PACKET;
993 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
995 //if (pSatDevData->sat48BitSupport == agTRUE)
997 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
999 fis->h.features |= 0x01;
1003 fis->h.features |= 0x0;
1007 satIOContext->satCompleteCB = &satRequestSenseForATAPICB;
1010 * Prepare SGL and send FIS to LL layer.
1012 satIOContext->reqType = agRequestType; /* Save it */
1014 status = sataLLIOStart( tiRoot,
1020 TI_DBG5(("satRequestSenseForATAPI: return\n"));
1023 /*****************************************************************************/
1024 /*! \brief SAT implementation for satDeviceReset.
1026 * This function creates DEVICE RESET fis and sends the request to LL layer
1028 * \param tiRoot: Pointer to TISA initiator driver/port instance.
1029 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
1030 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
1031 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
1032 * \param satIOContext_t: Pointer to the SAT IO Context
1034 * \return If command is started successfully
1035 * - \e tiSuccess: I/O request successfully initiated.
1036 * - \e tiBusy: No resources available, try again later.
1037 * - \e tiIONoDevice: Invalid device handle.
1038 * - \e tiError: Other errors.
1040 /*****************************************************************************/
1041 GLOBAL bit32 satDeviceReset(
1043 tiIORequest_t *tiIORequest,
1044 tiDeviceHandle_t *tiDeviceHandle,
1045 tiScsiInitiatorRequest_t *tiScsiRequest,
1046 satIOContext_t *satIOContext
1050 bit32 agRequestType;
1051 agsaFisRegHostToDevice_t *fis;
1053 fis = satIOContext->pFis;
1055 TI_DBG3(("satDeviceReset: start\n"));
1058 * Send the Execute Device Diagnostic command.
1060 fis->h.fisType = 0x27; /* Reg host to device */
1061 fis->h.c_pmPort = 0x80; /* C Bit is set */
1062 fis->h.command = SAT_DEVICE_RESET; /* 0x90 */
1063 fis->h.features = 0;
1068 fis->d.lbaLowExp = 0;
1069 fis->d.lbaMidExp = 0;
1070 fis->d.lbaHighExp = 0;
1071 fis->d.featuresExp = 0;
1072 fis->d.sectorCount = 0;
1073 fis->d.sectorCountExp = 0;
1074 fis->d.reserved4 = 0;
1075 fis->d.control = 0; /* FIS HOB bit clear */
1076 fis->d.reserved5 = 0;
1078 agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET;
1080 /* Initialize CB for SATA completion.
1082 satIOContext->satCompleteCB = &satDeviceResetCB;
1085 * Prepare SGL and send FIS to LL layer.
1087 satIOContext->reqType = agRequestType; /* Save it */
1089 status = sataLLIOStart( tiRoot,
1095 TI_DBG3(("satDeviceReset: return\n"));
1100 /*****************************************************************************/
1101 /*! \brief SAT implementation for saExecuteDeviceDiagnostic.
1103 * This function creates Execute Device Diagnostic fis and sends the request to LL layer
1105 * \param tiRoot: Pointer to TISA initiator driver/port instance.
1106 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
1107 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
1108 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
1109 * \param satIOContext_t: Pointer to the SAT IO Context
1111 * \return If command is started successfully
1112 * - \e tiSuccess: I/O request successfully initiated.
1113 * - \e tiBusy: No resources available, try again later.
1114 * - \e tiIONoDevice: Invalid device handle.
1115 * - \e tiError: Other errors.
1117 /*****************************************************************************/
1118 GLOBAL bit32 satExecuteDeviceDiagnostic(
1120 tiIORequest_t *tiIORequest,
1121 tiDeviceHandle_t *tiDeviceHandle,
1122 tiScsiInitiatorRequest_t *tiScsiRequest,
1123 satIOContext_t *satIOContext
1127 bit32 agRequestType;
1128 agsaFisRegHostToDevice_t *fis;
1130 fis = satIOContext->pFis;
1132 TI_DBG3(("satExecuteDeviceDiagnostic: start\n"));
1135 * Send the Execute Device Diagnostic command.
1137 fis->h.fisType = 0x27; /* Reg host to device */
1138 fis->h.c_pmPort = 0x80; /* C Bit is set */
1139 fis->h.command = SAT_EXECUTE_DEVICE_DIAGNOSTIC; /* 0x90 */
1140 fis->h.features = 0;
1145 fis->d.lbaLowExp = 0;
1146 fis->d.lbaMidExp = 0;
1147 fis->d.lbaHighExp = 0;
1148 fis->d.featuresExp = 0;
1149 fis->d.sectorCount = 0;
1150 fis->d.sectorCountExp = 0;
1151 fis->d.reserved4 = 0;
1152 fis->d.control = 0; /* FIS HOB bit clear */
1153 fis->d.reserved5 = 0;
1155 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
1157 /* Initialize CB for SATA completion.
1159 satIOContext->satCompleteCB = &satExecuteDeviceDiagnosticCB;
1162 * Prepare SGL and send FIS to LL layer.
1164 satIOContext->reqType = agRequestType; /* Save it */
1166 status = sataLLIOStart( tiRoot,
1172 TI_DBG5(("satExecuteDeviceDiagnostic: return\n"));
1178 /*****************************************************************************/
1179 /*! \brief SAT implementation for SCSI READ10.
1181 * SAT implementation for SCSI READ10 and send FIS request to LL layer.
1183 * \param tiRoot: Pointer to TISA initiator driver/port instance.
1184 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
1185 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
1186 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
1187 * \param satIOContext_t: Pointer to the SAT IO Context
1189 * \return If command is started successfully
1190 * - \e tiSuccess: I/O request successfully initiated.
1191 * - \e tiBusy: No resources available, try again later.
1192 * - \e tiIONoDevice: Invalid device handle.
1193 * - \e tiError: Other errors.
1195 /*****************************************************************************/
1196 GLOBAL bit32 satRead10(
1198 tiIORequest_t *tiIORequest,
1199 tiDeviceHandle_t *tiDeviceHandle,
1200 tiScsiInitiatorRequest_t *tiScsiRequest,
1201 satIOContext_t *satIOContext)
1205 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1206 satDeviceData_t *pSatDevData;
1207 scsiRspSense_t *pSense;
1208 tiIniScsiCmnd_t *scsiCmnd;
1209 agsaFisRegHostToDevice_t *fis;
1215 bit32 rangeChk = agFALSE; /* lba and tl range check */
1217 pSense = satIOContext->pSense;
1218 pSatDevData = satIOContext->pSatDevData;
1219 scsiCmnd = &tiScsiRequest->scsiCmnd;
1220 fis = satIOContext->pFis;
1222 TI_DBG5(("satRead10: start\n"));
1223 TI_DBG5(("satRead10: pSatDevData=%p\n", pSatDevData));
1224 // tdhexdump("satRead10", (bit8 *)scsiCmnd->cdb, 10);
1226 /* checking FUA_NV */
1227 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
1229 satSetSensePayload( pSense,
1230 SCSI_SNSKEY_ILLEGAL_REQUEST,
1232 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1235 ostiInitiatorIOCompleted( tiRoot,
1238 SCSI_STAT_CHECK_CONDITION,
1239 satIOContext->pTiSenseData,
1240 satIOContext->interruptContext );
1242 TI_DBG1(("satRead10: return FUA_NV\n"));
1247 /* checking CONTROL */
1248 /* NACA == 1 or LINK == 1*/
1249 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
1251 satSetSensePayload( pSense,
1252 SCSI_SNSKEY_ILLEGAL_REQUEST,
1254 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1257 ostiInitiatorIOCompleted( tiRoot,
1260 SCSI_STAT_CHECK_CONDITION,
1261 satIOContext->pTiSenseData,
1262 satIOContext->interruptContext );
1264 TI_DBG1(("satRead10: return control\n"));
1268 osti_memset(LBA, 0, sizeof(LBA));
1269 osti_memset(TL, 0, sizeof(TL));
1271 /* do not use memcpy due to indexing in LBA and TL */
1272 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
1273 LBA[1] = scsiCmnd->cdb[3];
1274 LBA[2] = scsiCmnd->cdb[4];
1275 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
1279 TL[2] = scsiCmnd->cdb[7]; /* MSB */
1280 TL[3] = scsiCmnd->cdb[8]; /* LSB */
1282 rangeChk = satAddNComparebit32(LBA, TL);
1284 /* cbd10; computing LBA and transfer length */
1285 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
1286 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
1287 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
1290 TI_DBG5(("satRead10: lba %d functioned lba %d\n", lba, satComputeCDB10LBA(satIOContext)));
1291 TI_DBG5(("satRead10: lba 0x%x functioned lba 0x%x\n", lba, satComputeCDB10LBA(satIOContext)));
1292 TI_DBG5(("satRead10: tl %d functioned tl %d\n", tl, satComputeCDB10TL(satIOContext)));
1294 /* Table 34, 9.1, p 46 */
1296 note: As of 2/10/2006, no support for DMA QUEUED
1300 Table 34, 9.1, p 46, b
1301 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
1302 return check condition
1305 if (pSatDevData->satNCQ != agTRUE &&
1306 pSatDevData->sat48BitSupport != agTRUE
1309 if (lba > SAT_TR_LBA_LIMIT - 1)
1311 TI_DBG1(("satRead10: return LBA out of range, not EXT\n"));
1312 satSetSensePayload( pSense,
1313 SCSI_SNSKEY_ILLEGAL_REQUEST,
1315 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
1318 ostiInitiatorIOCompleted( tiRoot,
1321 SCSI_STAT_CHECK_CONDITION,
1322 satIOContext->pTiSenseData,
1323 satIOContext->interruptContext );
1329 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
1331 TI_DBG1(("satRead10: return LBA+TL out of range, not EXT\n"));
1332 satSetSensePayload( pSense,
1333 SCSI_SNSKEY_ILLEGAL_REQUEST,
1335 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
1338 ostiInitiatorIOCompleted( tiRoot,
1341 SCSI_STAT_CHECK_CONDITION,
1342 satIOContext->pTiSenseData,
1343 satIOContext->interruptContext );
1350 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
1352 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
1356 /* in case that we can't fit the transfer length,
1357 we need to make it fit by sending multiple ATA cmnds */
1358 TI_DBG5(("satRead10: case 2\n"));
1361 fis->h.fisType = 0x27; /* Reg host to device */
1362 fis->h.c_pmPort = 0x80; /* C Bit is set */
1363 fis->h.command = SAT_READ_DMA; /* 0xC8 */
1364 fis->h.features = 0; /* FIS reserve */
1365 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
1366 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
1367 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
1369 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
1370 fis->d.lbaLowExp = 0;
1371 fis->d.lbaMidExp = 0;
1372 fis->d.lbaHighExp = 0;
1373 fis->d.featuresExp = 0;
1374 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
1375 fis->d.sectorCountExp = 0;
1376 fis->d.reserved4 = 0;
1377 fis->d.control = 0; /* FIS HOB bit clear */
1378 fis->d.reserved5 = 0;
1381 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1382 satIOContext->ATACmd = SAT_READ_DMA;
1387 /* READ MULTIPLE or READ SECTOR(S) */
1388 /* READ SECTORS for easier implemetation */
1389 /* in case that we can't fit the transfer length,
1390 we need to make it fit by sending multiple ATA cmnds */
1391 TI_DBG5(("satRead10: case 1\n"));
1393 fis->h.fisType = 0x27; /* Reg host to device */
1394 fis->h.c_pmPort = 0x80; /* C Bit is set */
1395 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
1396 fis->h.features = 0; /* FIS reserve */
1397 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
1398 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
1399 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
1401 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
1402 fis->d.lbaLowExp = 0;
1403 fis->d.lbaMidExp = 0;
1404 fis->d.lbaHighExp = 0;
1405 fis->d.featuresExp = 0;
1406 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
1407 fis->d.sectorCountExp = 0;
1408 fis->d.reserved4 = 0;
1409 fis->d.control = 0; /* FIS HOB bit clear */
1410 fis->d.reserved5 = 0;
1413 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1414 satIOContext->ATACmd = SAT_READ_SECTORS;
1419 if (pSatDevData->sat48BitSupport == agTRUE)
1421 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
1425 TI_DBG5(("satRead10: case 3\n"));
1426 fis->h.fisType = 0x27; /* Reg host to device */
1428 fis->h.c_pmPort = 0x80; /* C Bit is set */
1429 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */
1430 fis->h.features = 0; /* FIS reserve */
1431 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
1432 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
1433 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
1434 fis->d.device = 0x40; /* FIS LBA mode set */
1435 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
1436 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
1437 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
1438 fis->d.featuresExp = 0; /* FIS reserve */
1439 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
1440 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
1441 fis->d.reserved4 = 0;
1442 fis->d.control = 0; /* FIS HOB bit clear */
1443 fis->d.reserved5 = 0;
1445 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1446 satIOContext->ATACmd = SAT_READ_DMA_EXT;
1452 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
1453 /* READ SECTORS EXT for easier implemetation */
1454 TI_DBG5(("satRead10: case 4\n"));
1455 fis->h.fisType = 0x27; /* Reg host to device */
1456 fis->h.c_pmPort = 0x80; /* C Bit is set */
1459 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
1462 /* for now, no support for FUA */
1463 satSetSensePayload( pSense,
1464 SCSI_SNSKEY_ILLEGAL_REQUEST,
1466 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1469 ostiInitiatorIOCompleted( tiRoot,
1472 SCSI_STAT_CHECK_CONDITION,
1473 satIOContext->pTiSenseData,
1474 satIOContext->interruptContext );
1478 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
1480 fis->h.features = 0; /* FIS reserve */
1481 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
1482 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
1483 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
1484 fis->d.device = 0x40; /* FIS LBA mode set */
1485 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
1486 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
1487 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
1488 fis->d.featuresExp = 0; /* FIS reserve */
1489 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
1490 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
1491 fis->d.reserved4 = 0;
1492 fis->d.control = 0; /* FIS HOB bit clear */
1493 fis->d.reserved5 = 0;
1495 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1496 satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
1501 if (pSatDevData->satNCQ == agTRUE)
1503 /* READ FPDMA QUEUED */
1504 if (pSatDevData->sat48BitSupport != agTRUE)
1506 TI_DBG5(("satRead10: case 5 !!! error NCQ but 28 bit address support \n"));
1507 satSetSensePayload( pSense,
1508 SCSI_SNSKEY_ILLEGAL_REQUEST,
1510 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1513 ostiInitiatorIOCompleted( tiRoot,
1516 SCSI_STAT_CHECK_CONDITION,
1517 satIOContext->pTiSenseData,
1518 satIOContext->interruptContext );
1522 TI_DBG6(("satRead10: case 5\n"));
1524 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
1526 fis->h.fisType = 0x27; /* Reg host to device */
1527 fis->h.c_pmPort = 0x80; /* C Bit is set */
1528 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */
1529 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
1530 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
1531 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
1532 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
1535 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
1536 fis->d.device = 0xC0; /* FIS FUA set */
1538 fis->d.device = 0x40; /* FIS FUA clear */
1540 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
1541 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
1542 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
1543 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
1544 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
1545 fis->d.sectorCountExp = 0;
1546 fis->d.reserved4 = 0;
1547 fis->d.control = 0; /* FIS HOB bit clear */
1548 fis->d.reserved5 = 0;
1550 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
1551 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
1555 // tdhexdump("satRead10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
1557 /* saves the current LBA and orginal TL */
1558 satIOContext->currentLBA = lba;
1559 satIOContext->OrgTL = tl;
1562 computing number of loop and remainder for tl
1563 0xFF in case not ext
1566 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
1568 LoopNum = satComputeLoopNum(tl, 0xFF);
1570 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
1572 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
1573 LoopNum = satComputeLoopNum(tl, 0xFFFF);
1577 /* SAT_READ_FPDMA_QUEUED */
1578 LoopNum = satComputeLoopNum(tl, 0xFFFF);
1581 satIOContext->LoopNum = LoopNum;
1583 /* Initialize CB for SATA completion.
1587 TI_DBG5(("satRead10: NON CHAINED data\n"));
1588 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
1592 TI_DBG1(("satRead10: CHAINED data\n"));
1594 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
1596 fis->d.sectorCount = 0xFF;
1598 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
1600 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
1601 fis->d.sectorCount = 0xFF;
1602 fis->d.sectorCountExp = 0xFF;
1606 /* SAT_READ_FPDMA_QUEUED */
1607 fis->h.features = 0xFF;
1608 fis->d.featuresExp = 0xFF;
1612 satIOContext->satCompleteCB = &satChainedDataIOCB;
1617 * Prepare SGL and send FIS to LL layer.
1619 satIOContext->reqType = agRequestType; /* Save it */
1621 status = sataLLIOStart( tiRoot,
1627 TI_DBG5(("satRead10: return\n"));
1633 /*****************************************************************************/
1634 /*! \brief SAT implementation for SCSI satRead_1.
1636 * SAT implementation for SCSI satRead_1
1637 * Sub function of satRead10
1639 * \param tiRoot: Pointer to TISA initiator driver/port instance.
1640 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
1641 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
1642 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
1643 * \param satIOContext_t: Pointer to the SAT IO Context
1645 * \return If command is started successfully
1646 * - \e tiSuccess: I/O request successfully initiated.
1647 * - \e tiBusy: No resources available, try again later.
1648 * - \e tiIONoDevice: Invalid device handle.
1649 * - \e tiError: Other errors.
1651 /*****************************************************************************/
1653 * as a part of loop for read10
1655 GLOBAL bit32 satRead_1(
1657 tiIORequest_t *tiIORequest,
1658 tiDeviceHandle_t *tiDeviceHandle,
1659 tiScsiInitiatorRequest_t *tiScsiRequest,
1660 satIOContext_t *satIOContext)
1663 Assumption: error check on lba and tl has been done in satRead*()
1667 satIOContext_t *satOrgIOContext = agNULL;
1668 tiIniScsiCmnd_t *scsiCmnd;
1669 agsaFisRegHostToDevice_t *fis;
1670 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1672 bit32 DenomTL = 0xFF;
1673 bit32 Remainder = 0;
1674 bit8 LBA[4]; /* 0 MSB, 3 LSB */
1676 TI_DBG2(("satRead_1: start\n"));
1678 fis = satIOContext->pFis;
1679 satOrgIOContext = satIOContext->satOrgIOContext;
1680 scsiCmnd = satOrgIOContext->pScsiCmnd;
1682 osti_memset(LBA,0, sizeof(LBA));
1684 switch (satOrgIOContext->ATACmd)
1689 case SAT_READ_SECTORS:
1692 case SAT_READ_DMA_EXT:
1695 case SAT_READ_SECTORS_EXT:
1698 case SAT_READ_FPDMA_QUEUED:
1702 TI_DBG1(("satRead_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
1707 Remainder = satOrgIOContext->OrgTL % DenomTL;
1708 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
1709 lba = satOrgIOContext->currentLBA;
1711 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3));
1712 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
1713 LBA[2] = (bit8)((lba & 0xF0) >> 8);
1714 LBA[3] = (bit8)(lba & 0xF);
1717 switch (satOrgIOContext->ATACmd)
1720 fis->h.fisType = 0x27; /* Reg host to device */
1721 fis->h.c_pmPort = 0x80; /* C Bit is set */
1722 fis->h.command = SAT_READ_DMA; /* 0xC8 */
1723 fis->h.features = 0; /* FIS reserve */
1724 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
1725 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
1726 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
1728 (bit8)((0x4 << 4) | (LBA[0] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
1729 fis->d.lbaLowExp = 0;
1730 fis->d.lbaMidExp = 0;
1731 fis->d.lbaHighExp = 0;
1732 fis->d.featuresExp = 0;
1734 if (satOrgIOContext->LoopNum == 1)
1737 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
1741 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
1744 fis->d.sectorCountExp = 0;
1745 fis->d.reserved4 = 0;
1746 fis->d.control = 0; /* FIS HOB bit clear */
1747 fis->d.reserved5 = 0;
1749 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1752 case SAT_READ_SECTORS:
1753 fis->h.fisType = 0x27; /* Reg host to device */
1754 fis->h.c_pmPort = 0x80; /* C Bit is set */
1755 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
1756 fis->h.features = 0; /* FIS reserve */
1757 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
1758 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
1759 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
1761 (bit8)((0x4 << 4) | (LBA[0] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
1762 fis->d.lbaLowExp = 0;
1763 fis->d.lbaMidExp = 0;
1764 fis->d.lbaHighExp = 0;
1765 fis->d.featuresExp = 0;
1766 if (satOrgIOContext->LoopNum == 1)
1769 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
1773 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
1775 fis->d.sectorCountExp = 0;
1776 fis->d.reserved4 = 0;
1777 fis->d.control = 0; /* FIS HOB bit clear */
1778 fis->d.reserved5 = 0;
1780 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1783 case SAT_READ_DMA_EXT:
1784 fis->h.fisType = 0x27; /* Reg host to device */
1785 fis->h.c_pmPort = 0x80; /* C Bit is set */
1786 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */
1787 fis->h.features = 0; /* FIS reserve */
1788 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
1789 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
1790 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
1791 fis->d.device = 0x40; /* FIS LBA mode set */
1792 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
1793 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
1794 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
1795 fis->d.featuresExp = 0; /* FIS reserve */
1796 if (satOrgIOContext->LoopNum == 1)
1799 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
1800 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
1805 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
1806 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
1808 fis->d.reserved4 = 0;
1809 fis->d.control = 0; /* FIS HOB bit clear */
1810 fis->d.reserved5 = 0;
1812 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1815 case SAT_READ_SECTORS_EXT:
1816 fis->h.fisType = 0x27; /* Reg host to device */
1817 fis->h.c_pmPort = 0x80; /* C Bit is set */
1818 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
1819 fis->h.features = 0; /* FIS reserve */
1820 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
1821 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
1822 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
1823 fis->d.device = 0x40; /* FIS LBA mode set */
1824 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
1825 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
1826 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
1827 fis->d.featuresExp = 0; /* FIS reserve */
1828 if (satOrgIOContext->LoopNum == 1)
1831 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
1832 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
1836 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
1837 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
1839 fis->d.reserved4 = 0;
1840 fis->d.control = 0; /* FIS HOB bit clear */
1841 fis->d.reserved5 = 0;
1843 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1845 case SAT_READ_FPDMA_QUEUED:
1846 fis->h.fisType = 0x27; /* Reg host to device */
1847 fis->h.c_pmPort = 0x80; /* C Bit is set */
1848 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */
1849 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
1850 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
1851 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
1854 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
1855 fis->d.device = 0xC0; /* FIS FUA set */
1857 fis->d.device = 0x40; /* FIS FUA clear */
1859 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
1860 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
1861 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
1862 if (satOrgIOContext->LoopNum == 1)
1865 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
1866 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
1870 fis->h.features = 0xFF; /* FIS sector count (7:0) */
1871 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */
1873 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
1874 fis->d.sectorCountExp = 0;
1875 fis->d.reserved4 = 0;
1876 fis->d.control = 0; /* FIS HOB bit clear */
1877 fis->d.reserved5 = 0;
1879 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
1882 TI_DBG1(("satRead_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
1887 /* Initialize CB for SATA completion.
1890 satIOContext->satCompleteCB = &satChainedDataIOCB;
1894 * Prepare SGL and send FIS to LL layer.
1896 satIOContext->reqType = agRequestType; /* Save it */
1898 status = sataLLIOStart( tiRoot,
1904 TI_DBG5(("satRead_1: return\n"));
1907 /*****************************************************************************/
1908 /*! \brief SAT implementation for SCSI READ12.
1910 * SAT implementation for SCSI READ12 and send FIS request to LL layer.
1912 * \param tiRoot: Pointer to TISA initiator driver/port instance.
1913 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
1914 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
1915 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
1916 * \param satIOContext_t: Pointer to the SAT IO Context
1918 * \return If command is started successfully
1919 * - \e tiSuccess: I/O request successfully initiated.
1920 * - \e tiBusy: No resources available, try again later.
1921 * - \e tiIONoDevice: Invalid device handle.
1922 * - \e tiError: Other errors.
1924 /*****************************************************************************/
1925 GLOBAL bit32 satRead12(
1927 tiIORequest_t *tiIORequest,
1928 tiDeviceHandle_t *tiDeviceHandle,
1929 tiScsiInitiatorRequest_t *tiScsiRequest,
1930 satIOContext_t *satIOContext)
1933 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1934 satDeviceData_t *pSatDevData;
1935 scsiRspSense_t *pSense;
1936 tiIniScsiCmnd_t *scsiCmnd;
1937 agsaFisRegHostToDevice_t *fis;
1943 bit32 rangeChk = agFALSE; /* lba and tl range check */
1945 pSense = satIOContext->pSense;
1946 pSatDevData = satIOContext->pSatDevData;
1947 scsiCmnd = &tiScsiRequest->scsiCmnd;
1948 fis = satIOContext->pFis;
1950 TI_DBG5(("satRead12: start\n"));
1952 /* checking FUA_NV */
1953 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
1955 satSetSensePayload( pSense,
1956 SCSI_SNSKEY_ILLEGAL_REQUEST,
1958 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1961 ostiInitiatorIOCompleted( tiRoot,
1964 SCSI_STAT_CHECK_CONDITION,
1965 satIOContext->pTiSenseData,
1966 satIOContext->interruptContext );
1968 TI_DBG1(("satRead12: return FUA_NV\n"));
1973 /* checking CONTROL */
1974 /* NACA == 1 or LINK == 1*/
1975 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
1977 satSetSensePayload( pSense,
1978 SCSI_SNSKEY_ILLEGAL_REQUEST,
1980 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1983 ostiInitiatorIOCompleted( tiRoot,
1986 SCSI_STAT_CHECK_CONDITION,
1987 satIOContext->pTiSenseData,
1988 satIOContext->interruptContext );
1990 TI_DBG2(("satRead12: return control\n"));
1994 osti_memset(LBA, 0, sizeof(LBA));
1995 osti_memset(TL, 0, sizeof(TL));
1997 /* do not use memcpy due to indexing in LBA and TL */
1998 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
1999 LBA[1] = scsiCmnd->cdb[3];
2000 LBA[2] = scsiCmnd->cdb[4];
2001 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
2003 TL[0] = scsiCmnd->cdb[6]; /* MSB */
2004 TL[1] = scsiCmnd->cdb[7];
2005 TL[2] = scsiCmnd->cdb[8];
2006 TL[3] = scsiCmnd->cdb[9]; /* LSB */
2008 rangeChk = satAddNComparebit32(LBA, TL);
2010 lba = satComputeCDB12LBA(satIOContext);
2011 tl = satComputeCDB12TL(satIOContext);
2013 /* Table 34, 9.1, p 46 */
2015 note: As of 2/10/2006, no support for DMA QUEUED
2019 Table 34, 9.1, p 46, b
2020 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
2021 return check condition
2023 if (pSatDevData->satNCQ != agTRUE &&
2024 pSatDevData->sat48BitSupport != agTRUE
2027 if (lba > SAT_TR_LBA_LIMIT - 1)
2029 TI_DBG1(("satRead12: return LBA out of range, not EXT\n"));
2030 satSetSensePayload( pSense,
2031 SCSI_SNSKEY_ILLEGAL_REQUEST,
2033 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2036 ostiInitiatorIOCompleted( tiRoot,
2039 SCSI_STAT_CHECK_CONDITION,
2040 satIOContext->pTiSenseData,
2041 satIOContext->interruptContext );
2045 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
2047 TI_DBG1(("satRead12: return LBA+TL out of range, not EXT\n"));
2048 satSetSensePayload( pSense,
2049 SCSI_SNSKEY_ILLEGAL_REQUEST,
2051 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2054 ostiInitiatorIOCompleted( tiRoot,
2057 SCSI_STAT_CHECK_CONDITION,
2058 satIOContext->pTiSenseData,
2059 satIOContext->interruptContext );
2066 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
2068 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2072 /* in case that we can't fit the transfer length,
2073 we need to make it fit by sending multiple ATA cmnds */
2074 TI_DBG5(("satRead12: case 2\n"));
2077 fis->h.fisType = 0x27; /* Reg host to device */
2078 fis->h.c_pmPort = 0x80; /* C Bit is set */
2079 fis->h.command = SAT_READ_DMA; /* 0xC8 */
2080 fis->h.features = 0; /* FIS reserve */
2081 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
2082 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
2083 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
2085 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
2086 fis->d.lbaLowExp = 0;
2087 fis->d.lbaMidExp = 0;
2088 fis->d.lbaHighExp = 0;
2089 fis->d.featuresExp = 0;
2090 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
2091 fis->d.sectorCountExp = 0;
2092 fis->d.reserved4 = 0;
2093 fis->d.control = 0; /* FIS HOB bit clear */
2094 fis->d.reserved5 = 0;
2097 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2098 satIOContext->ATACmd = SAT_READ_DMA;
2103 /* READ MULTIPLE or READ SECTOR(S) */
2104 /* READ SECTORS for easier implemetation */
2105 /* can't fit the transfer length but need to make it fit by sending multiple*/
2106 TI_DBG5(("satRead12: case 1\n"));
2108 fis->h.fisType = 0x27; /* Reg host to device */
2109 fis->h.c_pmPort = 0x80; /* C Bit is set */
2110 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
2111 fis->h.features = 0; /* FIS reserve */
2112 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
2113 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
2114 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
2116 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
2117 fis->d.lbaLowExp = 0;
2118 fis->d.lbaMidExp = 0;
2119 fis->d.lbaHighExp = 0;
2120 fis->d.featuresExp = 0;
2121 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
2122 fis->d.sectorCountExp = 0;
2123 fis->d.reserved4 = 0;
2124 fis->d.control = 0; /* FIS HOB bit clear */
2125 fis->d.reserved5 = 0;
2128 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2129 satIOContext->ATACmd = SAT_READ_SECTORS;
2134 if (pSatDevData->sat48BitSupport == agTRUE)
2136 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2140 TI_DBG5(("satRead12: case 3\n"));
2141 fis->h.fisType = 0x27; /* Reg host to device */
2143 fis->h.c_pmPort = 0x80; /* C Bit is set */
2144 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */
2145 fis->h.features = 0; /* FIS reserve */
2146 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
2147 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
2148 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
2149 fis->d.device = 0x40; /* FIS LBA mode set */
2150 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
2151 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
2152 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
2153 fis->d.featuresExp = 0; /* FIS reserve */
2154 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
2155 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
2156 fis->d.reserved4 = 0;
2157 fis->d.control = 0; /* FIS HOB bit clear */
2158 fis->d.reserved5 = 0;
2160 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2161 satIOContext->ATACmd = SAT_READ_DMA_EXT;
2167 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
2168 /* READ SECTORS EXT for easier implemetation */
2169 TI_DBG5(("satRead12: case 4\n"));
2170 fis->h.fisType = 0x27; /* Reg host to device */
2171 fis->h.c_pmPort = 0x80; /* C Bit is set */
2174 if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
2176 /* for now, no support for FUA */
2177 satSetSensePayload( pSense,
2178 SCSI_SNSKEY_ILLEGAL_REQUEST,
2180 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2183 ostiInitiatorIOCompleted( tiRoot,
2186 SCSI_STAT_CHECK_CONDITION,
2187 satIOContext->pTiSenseData,
2188 satIOContext->interruptContext );
2192 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
2194 fis->h.features = 0; /* FIS reserve */
2195 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
2196 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
2197 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
2198 fis->d.device = 0x40; /* FIS LBA mode set */
2199 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
2200 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
2201 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
2202 fis->d.featuresExp = 0; /* FIS reserve */
2203 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
2204 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
2205 fis->d.reserved4 = 0;
2206 fis->d.control = 0; /* FIS HOB bit clear */
2207 fis->d.reserved5 = 0;
2209 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2210 satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
2215 if (pSatDevData->satNCQ == agTRUE)
2217 /* READ FPDMA QUEUED */
2218 if (pSatDevData->sat48BitSupport != agTRUE)
2220 TI_DBG5(("satRead12: case 5 !!! error NCQ but 28 bit address support \n"));
2221 satSetSensePayload( pSense,
2222 SCSI_SNSKEY_ILLEGAL_REQUEST,
2224 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2227 ostiInitiatorIOCompleted( tiRoot,
2230 SCSI_STAT_CHECK_CONDITION,
2231 satIOContext->pTiSenseData,
2232 satIOContext->interruptContext );
2236 TI_DBG6(("satRead12: case 5\n"));
2238 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
2240 fis->h.fisType = 0x27; /* Reg host to device */
2241 fis->h.c_pmPort = 0x80; /* C Bit is set */
2242 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */
2243 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
2244 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
2245 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
2246 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
2249 if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
2250 fis->d.device = 0xC0; /* FIS FUA set */
2252 fis->d.device = 0x40; /* FIS FUA clear */
2254 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
2255 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
2256 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
2257 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
2258 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
2259 fis->d.sectorCountExp = 0;
2260 fis->d.reserved4 = 0;
2261 fis->d.control = 0; /* FIS HOB bit clear */
2262 fis->d.reserved5 = 0;
2264 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
2265 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
2268 /* saves the current LBA and orginal TL */
2269 satIOContext->currentLBA = lba;
2270 satIOContext->OrgTL = tl;
2273 computing number of loop and remainder for tl
2274 0xFF in case not ext
2277 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2279 LoopNum = satComputeLoopNum(tl, 0xFF);
2281 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2283 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2284 LoopNum = satComputeLoopNum(tl, 0xFFFF);
2288 /* SAT_READ_FPDMA_QUEUEDK */
2289 LoopNum = satComputeLoopNum(tl, 0xFFFF);
2292 satIOContext->LoopNum = LoopNum;
2296 TI_DBG5(("satRead12: NON CHAINED data\n"));
2297 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
2301 TI_DBG1(("satRead12: CHAINED data\n"));
2303 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2305 fis->d.sectorCount = 0xFF;
2307 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2309 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2310 fis->d.sectorCount = 0xFF;
2311 fis->d.sectorCountExp = 0xFF;
2315 /* SAT_READ_FPDMA_QUEUED */
2316 fis->h.features = 0xFF;
2317 fis->d.featuresExp = 0xFF;
2321 satIOContext->satCompleteCB = &satChainedDataIOCB;
2325 * Prepare SGL and send FIS to LL layer.
2327 satIOContext->reqType = agRequestType; /* Save it */
2329 status = sataLLIOStart( tiRoot,
2335 TI_DBG5(("satRead12: return\n"));
2338 /*****************************************************************************/
2339 /*! \brief SAT implementation for SCSI READ16.
2341 * SAT implementation for SCSI READ16 and send FIS request to LL layer.
2343 * \param tiRoot: Pointer to TISA initiator driver/port instance.
2344 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
2345 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
2346 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
2347 * \param satIOContext_t: Pointer to the SAT IO Context
2349 * \return If command is started successfully
2350 * - \e tiSuccess: I/O request successfully initiated.
2351 * - \e tiBusy: No resources available, try again later.
2352 * - \e tiIONoDevice: Invalid device handle.
2353 * - \e tiError: Other errors.
2355 /*****************************************************************************/
2356 GLOBAL bit32 satRead16(
2358 tiIORequest_t *tiIORequest,
2359 tiDeviceHandle_t *tiDeviceHandle,
2360 tiScsiInitiatorRequest_t *tiScsiRequest,
2361 satIOContext_t *satIOContext)
2364 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2365 satDeviceData_t *pSatDevData;
2366 scsiRspSense_t *pSense;
2367 tiIniScsiCmnd_t *scsiCmnd;
2368 agsaFisRegHostToDevice_t *fis;
2374 bit32 rangeChk = agFALSE; /* lba and tl range check */
2375 bit32 limitChk = agFALSE; /* lba and tl range check */
2377 pSense = satIOContext->pSense;
2378 pSatDevData = satIOContext->pSatDevData;
2379 scsiCmnd = &tiScsiRequest->scsiCmnd;
2380 fis = satIOContext->pFis;
2382 TI_DBG5(("satRead16: start\n"));
2384 /* checking FUA_NV */
2385 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
2387 satSetSensePayload( pSense,
2388 SCSI_SNSKEY_ILLEGAL_REQUEST,
2390 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2393 ostiInitiatorIOCompleted( tiRoot,
2396 SCSI_STAT_CHECK_CONDITION,
2397 satIOContext->pTiSenseData,
2398 satIOContext->interruptContext );
2400 TI_DBG1(("satRead16: return FUA_NV\n"));
2405 /* checking CONTROL */
2406 /* NACA == 1 or LINK == 1*/
2407 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
2409 satSetSensePayload( pSense,
2410 SCSI_SNSKEY_ILLEGAL_REQUEST,
2412 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2415 ostiInitiatorIOCompleted( tiRoot,
2418 SCSI_STAT_CHECK_CONDITION,
2419 satIOContext->pTiSenseData,
2420 satIOContext->interruptContext );
2422 TI_DBG1(("satRead16: return control\n"));
2427 osti_memset(LBA, 0, sizeof(LBA));
2428 osti_memset(TL, 0, sizeof(TL));
2431 /* do not use memcpy due to indexing in LBA and TL */
2432 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
2433 LBA[1] = scsiCmnd->cdb[3];
2434 LBA[2] = scsiCmnd->cdb[4];
2435 LBA[3] = scsiCmnd->cdb[5];
2436 LBA[4] = scsiCmnd->cdb[6];
2437 LBA[5] = scsiCmnd->cdb[7];
2438 LBA[6] = scsiCmnd->cdb[8];
2439 LBA[7] = scsiCmnd->cdb[9]; /* LSB */
2445 TL[4] = scsiCmnd->cdb[10]; /* MSB */
2446 TL[5] = scsiCmnd->cdb[11];
2447 TL[6] = scsiCmnd->cdb[12];
2448 TL[7] = scsiCmnd->cdb[13]; /* LSB */
2450 rangeChk = satAddNComparebit64(LBA, TL);
2452 limitChk = satCompareLBALimitbit(LBA);
2454 lba = satComputeCDB16LBA(satIOContext);
2455 tl = satComputeCDB16TL(satIOContext);
2458 /* Table 34, 9.1, p 46 */
2460 note: As of 2/10/2006, no support for DMA QUEUED
2464 Table 34, 9.1, p 46, b
2465 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
2466 return check condition
2468 if (pSatDevData->satNCQ != agTRUE &&
2469 pSatDevData->sat48BitSupport != agTRUE
2474 TI_DBG1(("satRead16: return LBA out of range, not EXT\n"));
2475 satSetSensePayload( pSense,
2476 SCSI_SNSKEY_ILLEGAL_REQUEST,
2478 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2481 ostiInitiatorIOCompleted( tiRoot,
2484 SCSI_STAT_CHECK_CONDITION,
2485 satIOContext->pTiSenseData,
2486 satIOContext->interruptContext );
2490 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
2492 TI_DBG1(("satRead16: return LBA+TL out of range, not EXT\n"));
2493 satSetSensePayload( pSense,
2494 SCSI_SNSKEY_ILLEGAL_REQUEST,
2496 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2499 ostiInitiatorIOCompleted( tiRoot,
2502 SCSI_STAT_CHECK_CONDITION,
2503 satIOContext->pTiSenseData,
2504 satIOContext->interruptContext );
2511 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
2513 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2517 /* in case that we can't fit the transfer length,
2518 we need to make it fit by sending multiple ATA cmnds */
2519 TI_DBG5(("satRead16: case 2\n"));
2522 fis->h.fisType = 0x27; /* Reg host to device */
2523 fis->h.c_pmPort = 0x80; /* C Bit is set */
2524 fis->h.command = SAT_READ_DMA; /* 0xC8 */
2525 fis->h.features = 0; /* FIS reserve */
2526 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
2527 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
2528 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
2530 (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
2531 fis->d.lbaLowExp = 0;
2532 fis->d.lbaMidExp = 0;
2533 fis->d.lbaHighExp = 0;
2534 fis->d.featuresExp = 0;
2535 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
2536 fis->d.sectorCountExp = 0;
2537 fis->d.reserved4 = 0;
2538 fis->d.control = 0; /* FIS HOB bit clear */
2539 fis->d.reserved5 = 0;
2542 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2543 satIOContext->ATACmd = SAT_READ_DMA;
2548 /* READ MULTIPLE or READ SECTOR(S) */
2549 /* READ SECTORS for easier implemetation */
2550 /* can't fit the transfer length but need to make it fit by sending multiple*/
2551 TI_DBG5(("satRead16: case 1\n"));
2553 fis->h.fisType = 0x27; /* Reg host to device */
2554 fis->h.c_pmPort = 0x80; /* C Bit is set */
2555 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
2556 fis->h.features = 0; /* FIS reserve */
2557 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
2558 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
2559 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
2561 (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
2562 fis->d.lbaLowExp = 0;
2563 fis->d.lbaMidExp = 0;
2564 fis->d.lbaHighExp = 0;
2565 fis->d.featuresExp = 0;
2566 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
2567 fis->d.sectorCountExp = 0;
2568 fis->d.reserved4 = 0;
2569 fis->d.control = 0; /* FIS HOB bit clear */
2570 fis->d.reserved5 = 0;
2573 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2574 satIOContext->ATACmd = SAT_READ_SECTORS;
2579 if (pSatDevData->sat48BitSupport == agTRUE)
2581 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2585 TI_DBG5(("satRead16: case 3\n"));
2586 fis->h.fisType = 0x27; /* Reg host to device */
2588 fis->h.c_pmPort = 0x80; /* C Bit is set */
2589 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */
2590 fis->h.features = 0; /* FIS reserve */
2591 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
2592 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
2593 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
2594 fis->d.device = 0x40; /* FIS LBA mode set */
2595 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
2596 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
2597 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
2598 fis->d.featuresExp = 0; /* FIS reserve */
2599 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
2600 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
2601 fis->d.reserved4 = 0;
2602 fis->d.control = 0; /* FIS HOB bit clear */
2603 fis->d.reserved5 = 0;
2605 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2606 satIOContext->ATACmd = SAT_READ_DMA_EXT;
2612 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
2613 /* READ SECTORS EXT for easier implemetation */
2614 TI_DBG5(("satRead16: case 4\n"));
2615 fis->h.fisType = 0x27; /* Reg host to device */
2616 fis->h.c_pmPort = 0x80; /* C Bit is set */
2619 if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
2622 /* for now, no support for FUA */
2623 satSetSensePayload( pSense,
2624 SCSI_SNSKEY_ILLEGAL_REQUEST,
2626 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2629 ostiInitiatorIOCompleted( tiRoot,
2632 SCSI_STAT_CHECK_CONDITION,
2633 satIOContext->pTiSenseData,
2634 satIOContext->interruptContext );
2638 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
2640 fis->h.features = 0; /* FIS reserve */
2641 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
2642 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
2643 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
2644 fis->d.device = 0x40; /* FIS LBA mode set */
2645 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
2646 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
2647 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
2648 fis->d.featuresExp = 0; /* FIS reserve */
2649 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
2650 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
2651 fis->d.reserved4 = 0;
2652 fis->d.control = 0; /* FIS HOB bit clear */
2653 fis->d.reserved5 = 0;
2655 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2656 satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
2662 if (pSatDevData->satNCQ == agTRUE)
2664 /* READ FPDMA QUEUED */
2665 if (pSatDevData->sat48BitSupport != agTRUE)
2667 TI_DBG5(("satRead16: case 5 !!! error NCQ but 28 bit address support \n"));
2668 satSetSensePayload( pSense,
2669 SCSI_SNSKEY_ILLEGAL_REQUEST,
2671 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2674 ostiInitiatorIOCompleted( tiRoot,
2677 SCSI_STAT_CHECK_CONDITION,
2678 satIOContext->pTiSenseData,
2679 satIOContext->interruptContext );
2683 TI_DBG6(("satRead16: case 5\n"));
2685 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
2687 fis->h.fisType = 0x27; /* Reg host to device */
2688 fis->h.c_pmPort = 0x80; /* C Bit is set */
2689 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */
2690 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
2691 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
2692 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
2693 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
2696 if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
2697 fis->d.device = 0xC0; /* FIS FUA set */
2699 fis->d.device = 0x40; /* FIS FUA clear */
2701 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
2702 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
2703 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
2704 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
2705 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
2706 fis->d.sectorCountExp = 0;
2707 fis->d.reserved4 = 0;
2708 fis->d.control = 0; /* FIS HOB bit clear */
2709 fis->d.reserved5 = 0;
2711 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
2712 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
2715 /* saves the current LBA and orginal TL */
2716 satIOContext->currentLBA = lba;
2717 satIOContext->OrgTL = tl;
2720 computing number of loop and remainder for tl
2721 0xFF in case not ext
2724 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2726 LoopNum = satComputeLoopNum(tl, 0xFF);
2728 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2730 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2731 LoopNum = satComputeLoopNum(tl, 0xFFFF);
2735 /* SAT_READ_FPDMA_QUEUEDK */
2736 LoopNum = satComputeLoopNum(tl, 0xFFFF);
2738 satIOContext->LoopNum = LoopNum;
2742 TI_DBG5(("satRead16: NON CHAINED data\n"));
2743 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
2747 TI_DBG1(("satRead16: CHAINED data\n"));
2749 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2751 fis->d.sectorCount = 0xFF;
2753 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2755 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2756 fis->d.sectorCount = 0xFF;
2757 fis->d.sectorCountExp = 0xFF;
2761 /* SAT_READ_FPDMA_QUEUED */
2762 fis->h.features = 0xFF;
2763 fis->d.featuresExp = 0xFF;
2767 satIOContext->satCompleteCB = &satChainedDataIOCB;
2771 * Prepare SGL and send FIS to LL layer.
2773 satIOContext->reqType = agRequestType; /* Save it */
2775 status = sataLLIOStart( tiRoot,
2781 TI_DBG5(("satRead16: return\n"));
2786 /*****************************************************************************/
2787 /*! \brief SAT implementation for SCSI READ6.
2789 * SAT implementation for SCSI READ6 and send FIS request to LL layer.
2791 * \param tiRoot: Pointer to TISA initiator driver/port instance.
2792 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
2793 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
2794 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
2795 * \param satIOContext_t: Pointer to the SAT IO Context
2797 * \return If command is started successfully
2798 * - \e tiSuccess: I/O request successfully initiated.
2799 * - \e tiBusy: No resources available, try again later.
2800 * - \e tiIONoDevice: Invalid device handle.
2801 * - \e tiError: Other errors.
2803 /*****************************************************************************/
2804 GLOBAL bit32 satRead6(
2806 tiIORequest_t *tiIORequest,
2807 tiDeviceHandle_t *tiDeviceHandle,
2808 tiScsiInitiatorRequest_t *tiScsiRequest,
2809 satIOContext_t *satIOContext)
2813 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2814 satDeviceData_t *pSatDevData;
2815 scsiRspSense_t *pSense;
2816 tiIniScsiCmnd_t *scsiCmnd;
2817 agsaFisRegHostToDevice_t *fis;
2821 pSense = satIOContext->pSense;
2822 pSatDevData = satIOContext->pSatDevData;
2823 scsiCmnd = &tiScsiRequest->scsiCmnd;
2824 fis = satIOContext->pFis;
2827 TI_DBG5(("satRead6: start\n"));
2829 /* no FUA checking since read6 */
2832 /* checking CONTROL */
2833 /* NACA == 1 or LINK == 1*/
2834 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
2836 satSetSensePayload( pSense,
2837 SCSI_SNSKEY_ILLEGAL_REQUEST,
2839 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2842 ostiInitiatorIOCompleted( tiRoot,
2845 SCSI_STAT_CHECK_CONDITION,
2846 satIOContext->pTiSenseData,
2847 satIOContext->interruptContext );
2849 TI_DBG2(("satRead6: return control\n"));
2853 /* cbd6; computing LBA and transfer length */
2854 lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
2855 + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
2856 tl = scsiCmnd->cdb[4];
2859 /* Table 34, 9.1, p 46 */
2861 note: As of 2/10/2006, no support for DMA QUEUED
2865 Table 34, 9.1, p 46, b
2866 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
2867 return check condition
2869 if (pSatDevData->satNCQ != agTRUE &&
2870 pSatDevData->sat48BitSupport != agTRUE
2873 if (lba > SAT_TR_LBA_LIMIT - 1)
2875 satSetSensePayload( pSense,
2876 SCSI_SNSKEY_ILLEGAL_REQUEST,
2878 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2881 ostiInitiatorIOCompleted( tiRoot,
2884 SCSI_STAT_CHECK_CONDITION,
2885 satIOContext->pTiSenseData,
2886 satIOContext->interruptContext );
2888 TI_DBG1(("satRead6: return LBA out of range\n"));
2894 if (lba + tl <= SAT_TR_LBA_LIMIT)
2896 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2900 TI_DBG5(("satRead6: case 2\n"));
2903 fis->h.fisType = 0x27; /* Reg host to device */
2904 fis->h.c_pmPort = 0x80; /* C Bit is set */
2905 fis->h.command = SAT_READ_DMA; /* 0xC8 */
2906 fis->h.features = 0; /* FIS reserve */
2907 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
2908 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
2909 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
2910 fis->d.device = 0x40; /* FIS LBA mode */
2911 fis->d.lbaLowExp = 0;
2912 fis->d.lbaMidExp = 0;
2913 fis->d.lbaHighExp = 0;
2914 fis->d.featuresExp = 0;
2918 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */
2922 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
2924 fis->d.sectorCountExp = 0;
2925 fis->d.reserved4 = 0;
2926 fis->d.control = 0; /* FIS HOB bit clear */
2927 fis->d.reserved5 = 0;
2929 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2934 /* READ SECTORS for easier implemetation */
2935 TI_DBG5(("satRead6: case 1\n"));
2937 fis->h.fisType = 0x27; /* Reg host to device */
2938 fis->h.c_pmPort = 0x80; /* C Bit is set */
2939 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
2940 fis->h.features = 0; /* FIS reserve */
2941 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
2942 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
2943 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
2944 fis->d.device = 0x40; /* FIS LBA mode */
2945 fis->d.lbaLowExp = 0;
2946 fis->d.lbaMidExp = 0;
2947 fis->d.lbaHighExp = 0;
2948 fis->d.featuresExp = 0;
2952 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */
2956 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
2958 fis->d.sectorCountExp = 0;
2959 fis->d.reserved4 = 0;
2960 fis->d.control = 0; /* FIS HOB bit clear */
2961 fis->d.reserved5 = 0;
2963 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2969 if (pSatDevData->sat48BitSupport == agTRUE)
2971 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2974 /* READ DMA EXT only */
2975 TI_DBG5(("satRead6: case 3\n"));
2976 fis->h.fisType = 0x27; /* Reg host to device */
2977 fis->h.c_pmPort = 0x80; /* C Bit is set */
2978 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */
2979 fis->h.features = 0; /* FIS reserve */
2980 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
2981 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
2982 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
2983 fis->d.device = 0x40; /* FIS LBA mode set */
2984 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
2985 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
2986 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
2987 fis->d.featuresExp = 0; /* FIS reserve */
2990 /* sector count is 256, 0x100*/
2991 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
2992 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */
2996 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
2997 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
2999 fis->d.reserved4 = 0;
3000 fis->d.control = 0; /* FIS HOB bit clear */
3001 fis->d.reserved5 = 0;
3003 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
3008 /* READ SECTORS EXT for easier implemetation */
3009 TI_DBG5(("satRead6: case 4\n"));
3011 fis->h.fisType = 0x27; /* Reg host to device */
3012 fis->h.c_pmPort = 0x80; /* C Bit is set */
3013 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
3014 fis->h.features = 0; /* FIS reserve */
3015 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
3016 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
3017 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
3018 fis->d.device = 0x40; /* FIS LBA mode set */
3019 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
3020 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
3021 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
3022 fis->d.featuresExp = 0; /* FIS reserve */
3025 /* sector count is 256, 0x100*/
3026 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
3027 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */
3031 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
3032 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
3034 fis->d.reserved4 = 0;
3035 fis->d.control = 0; /* FIS HOB bit clear */
3036 fis->d.reserved5 = 0;
3038 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
3043 if (pSatDevData->satNCQ == agTRUE)
3045 /* READ FPDMA QUEUED */
3046 if (pSatDevData->sat48BitSupport != agTRUE)
3049 TI_DBG5(("satRead6: case 5 !!! error NCQ but 28 bit address support \n"));
3050 satSetSensePayload( pSense,
3051 SCSI_SNSKEY_ILLEGAL_REQUEST,
3053 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3056 ostiInitiatorIOCompleted( tiRoot,
3059 SCSI_STAT_CHECK_CONDITION,
3060 satIOContext->pTiSenseData,
3061 satIOContext->interruptContext );
3064 TI_DBG5(("satRead6: case 5\n"));
3066 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
3068 fis->h.fisType = 0x27; /* Reg host to device */
3069 fis->h.c_pmPort = 0x80; /* C Bit is set */
3070 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */
3071 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
3072 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
3073 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
3074 fis->d.device = 0x40; /* FIS FUA clear */
3075 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
3076 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
3077 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
3080 /* sector count is 256, 0x100*/
3081 fis->h.features = 0; /* FIS sector count (7:0) */
3082 fis->d.featuresExp = 0x01; /* FIS sector count (15:8) */
3086 fis->h.features = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
3087 fis->d.featuresExp = 0; /* FIS sector count (15:8) */
3089 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
3090 fis->d.sectorCountExp = 0;
3091 fis->d.reserved4 = 0;
3092 fis->d.control = 0; /* FIS HOB bit clear */
3093 fis->d.reserved5 = 0;
3095 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
3098 /* Initialize CB for SATA completion.
3100 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
3103 * Prepare SGL and send FIS to LL layer.
3105 satIOContext->reqType = agRequestType; /* Save it */
3107 status = sataLLIOStart( tiRoot,
3116 /*****************************************************************************/
3117 /*! \brief SAT implementation for SCSI WRITE16.
3119 * SAT implementation for SCSI WRITE16 and send FIS request to LL layer.
3121 * \param tiRoot: Pointer to TISA initiator driver/port instance.
3122 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
3123 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
3124 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
3125 * \param satIOContext_t: Pointer to the SAT IO Context
3127 * \return If command is started successfully
3128 * - \e tiSuccess: I/O request successfully initiated.
3129 * - \e tiBusy: No resources available, try again later.
3130 * - \e tiIONoDevice: Invalid device handle.
3131 * - \e tiError: Other errors.
3133 /*****************************************************************************/
3134 GLOBAL bit32 satWrite16(
3136 tiIORequest_t *tiIORequest,
3137 tiDeviceHandle_t *tiDeviceHandle,
3138 tiScsiInitiatorRequest_t *tiScsiRequest,
3139 satIOContext_t *satIOContext)
3142 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3143 satDeviceData_t *pSatDevData;
3144 scsiRspSense_t *pSense;
3145 tiIniScsiCmnd_t *scsiCmnd;
3146 agsaFisRegHostToDevice_t *fis;
3152 bit32 rangeChk = agFALSE; /* lba and tl range check */
3153 bit32 limitChk = agFALSE; /* lba and tl range check */
3155 pSense = satIOContext->pSense;
3156 pSatDevData = satIOContext->pSatDevData;
3157 scsiCmnd = &tiScsiRequest->scsiCmnd;
3158 fis = satIOContext->pFis;
3160 TI_DBG5(("satWrite16: start\n"));
3162 /* checking FUA_NV */
3163 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
3165 satSetSensePayload( pSense,
3166 SCSI_SNSKEY_ILLEGAL_REQUEST,
3168 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3171 ostiInitiatorIOCompleted( tiRoot,
3174 SCSI_STAT_CHECK_CONDITION,
3175 satIOContext->pTiSenseData,
3176 satIOContext->interruptContext );
3178 TI_DBG1(("satWrite16: return FUA_NV\n"));
3183 /* checking CONTROL */
3184 /* NACA == 1 or LINK == 1*/
3185 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
3187 satSetSensePayload( pSense,
3188 SCSI_SNSKEY_ILLEGAL_REQUEST,
3190 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3193 ostiInitiatorIOCompleted( tiRoot,
3196 SCSI_STAT_CHECK_CONDITION,
3197 satIOContext->pTiSenseData,
3198 satIOContext->interruptContext );
3200 TI_DBG1(("satWrite16: return control\n"));
3205 osti_memset(LBA, 0, sizeof(LBA));
3206 osti_memset(TL, 0, sizeof(TL));
3209 /* do not use memcpy due to indexing in LBA and TL */
3210 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
3211 LBA[1] = scsiCmnd->cdb[3];
3212 LBA[2] = scsiCmnd->cdb[4];
3213 LBA[3] = scsiCmnd->cdb[5];
3214 LBA[4] = scsiCmnd->cdb[6];
3215 LBA[5] = scsiCmnd->cdb[7];
3216 LBA[6] = scsiCmnd->cdb[8];
3217 LBA[7] = scsiCmnd->cdb[9]; /* LSB */
3223 TL[4] = scsiCmnd->cdb[10]; /* MSB */
3224 TL[5] = scsiCmnd->cdb[11];
3225 TL[6] = scsiCmnd->cdb[12];
3226 TL[7] = scsiCmnd->cdb[13]; /* LSB */
3228 rangeChk = satAddNComparebit64(LBA, TL);
3230 limitChk = satCompareLBALimitbit(LBA);
3232 lba = satComputeCDB16LBA(satIOContext);
3233 tl = satComputeCDB16TL(satIOContext);
3237 /* Table 34, 9.1, p 46 */
3239 note: As of 2/10/2006, no support for DMA QUEUED
3243 Table 34, 9.1, p 46, b
3244 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
3245 return check condition
3247 if (pSatDevData->satNCQ != agTRUE &&
3248 pSatDevData->sat48BitSupport != agTRUE
3253 TI_DBG1(("satWrite16: return LBA out of range, not EXT\n"));
3254 satSetSensePayload( pSense,
3255 SCSI_SNSKEY_ILLEGAL_REQUEST,
3257 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3260 ostiInitiatorIOCompleted( tiRoot,
3263 SCSI_STAT_CHECK_CONDITION,
3264 satIOContext->pTiSenseData,
3265 satIOContext->interruptContext );
3269 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
3271 TI_DBG1(("satWrite16: return LBA+TL out of range, not EXT\n"));
3272 satSetSensePayload( pSense,
3273 SCSI_SNSKEY_ILLEGAL_REQUEST,
3275 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3278 ostiInitiatorIOCompleted( tiRoot,
3281 SCSI_STAT_CHECK_CONDITION,
3282 satIOContext->pTiSenseData,
3283 satIOContext->interruptContext );
3290 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
3292 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3296 /* In case that we can't fit the transfer length, we loop */
3297 TI_DBG5(("satWrite16: case 2\n"));
3298 fis->h.fisType = 0x27; /* Reg host to device */
3299 fis->h.c_pmPort = 0x80; /* C bit is set */
3300 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
3301 fis->h.features = 0; /* FIS reserve */
3302 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
3303 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
3304 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
3306 /* FIS LBA mode set LBA (27:24) */
3307 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
3309 fis->d.lbaLowExp = 0;
3310 fis->d.lbaMidExp = 0;
3311 fis->d.lbaHighExp = 0;
3312 fis->d.featuresExp = 0;
3313 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
3314 fis->d.sectorCountExp = 0;
3315 fis->d.reserved4 = 0;
3316 fis->d.control = 0; /* FIS HOB bit clear */
3317 fis->d.reserved5 = 0;
3319 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3320 satIOContext->ATACmd = SAT_WRITE_DMA;
3325 /* WRITE MULTIPLE or WRITE SECTOR(S) */
3326 /* WRITE SECTORS for easier implemetation */
3327 /* In case that we can't fit the transfer length, we loop */
3328 TI_DBG5(("satWrite16: case 1\n"));
3329 fis->h.fisType = 0x27; /* Reg host to device */
3330 fis->h.c_pmPort = 0x80; /* C bit is set */
3331 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
3332 fis->h.features = 0; /* FIS reserve */
3333 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
3334 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
3335 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
3337 /* FIS LBA mode set LBA (27:24) */
3338 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
3340 fis->d.lbaLowExp = 0;
3341 fis->d.lbaMidExp = 0;
3342 fis->d.lbaHighExp = 0;
3343 fis->d.featuresExp = 0;
3344 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
3345 fis->d.sectorCountExp = 0;
3346 fis->d.reserved4 = 0;
3347 fis->d.control = 0; /* FIS HOB bit clear */
3348 fis->d.reserved5 = 0;
3350 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3351 satIOContext->ATACmd = SAT_WRITE_SECTORS;
3356 if (pSatDevData->sat48BitSupport == agTRUE)
3358 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3361 /* WRITE DMA EXT or WRITE DMA FUA EXT */
3362 TI_DBG5(("satWrite16: case 3\n"));
3363 fis->h.fisType = 0x27; /* Reg host to device */
3364 fis->h.c_pmPort = 0x80; /* C Bit is set */
3366 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
3367 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
3369 fis->h.features = 0; /* FIS reserve */
3370 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
3371 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
3372 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
3373 fis->d.device = 0x40; /* FIS LBA mode set */
3374 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
3375 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
3376 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
3377 fis->d.featuresExp = 0; /* FIS reserve */
3378 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
3379 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
3380 fis->d.reserved4 = 0;
3381 fis->d.control = 0; /* FIS HOB bit clear */
3382 fis->d.reserved5 = 0;
3384 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3385 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
3390 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
3391 /* WRITE SECTORS EXT for easier implemetation */
3392 TI_DBG5(("satWrite16: case 4\n"));
3393 fis->h.fisType = 0x27; /* Reg host to device */
3394 fis->h.c_pmPort = 0x80; /* C Bit is set */
3395 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
3397 fis->h.features = 0; /* FIS reserve */
3398 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
3399 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
3400 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
3401 fis->d.device = 0x40; /* FIS LBA mode set */
3402 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
3403 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
3404 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
3405 fis->d.featuresExp = 0; /* FIS reserve */
3406 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
3407 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
3408 fis->d.reserved4 = 0;
3409 fis->d.control = 0; /* FIS HOB bit clear */
3410 fis->d.reserved5 = 0;
3412 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3413 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
3418 if (pSatDevData->satNCQ == agTRUE)
3420 /* WRITE FPDMA QUEUED */
3421 if (pSatDevData->sat48BitSupport != agTRUE)
3423 TI_DBG5(("satWrite16: case 5 !!! error NCQ but 28 bit address support \n"));
3424 satSetSensePayload( pSense,
3425 SCSI_SNSKEY_ILLEGAL_REQUEST,
3427 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3430 ostiInitiatorIOCompleted( tiRoot,
3433 SCSI_STAT_CHECK_CONDITION,
3434 satIOContext->pTiSenseData,
3435 satIOContext->interruptContext );
3438 TI_DBG6(("satWrite16: case 5\n"));
3440 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
3442 fis->h.fisType = 0x27; /* Reg host to device */
3443 fis->h.c_pmPort = 0x80; /* C Bit is set */
3444 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
3445 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
3446 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
3447 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
3448 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
3451 if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
3452 fis->d.device = 0xC0; /* FIS FUA set */
3454 fis->d.device = 0x40; /* FIS FUA clear */
3456 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
3457 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
3458 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
3459 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
3460 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
3461 fis->d.sectorCountExp = 0;
3462 fis->d.reserved4 = 0;
3463 fis->d.control = 0; /* FIS HOB bit clear */
3464 fis->d.reserved5 = 0;
3466 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
3467 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
3470 satIOContext->currentLBA = lba;
3471 satIOContext->OrgTL = tl;
3474 computing number of loop and remainder for tl
3475 0xFF in case not ext
3478 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3480 LoopNum = satComputeLoopNum(tl, 0xFF);
3482 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3483 fis->h.command == SAT_WRITE_DMA_EXT ||
3484 fis->h.command == SAT_WRITE_DMA_FUA_EXT
3487 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
3488 LoopNum = satComputeLoopNum(tl, 0xFFFF);
3492 /* SAT_WRITE_FPDMA_QUEUEDK */
3493 LoopNum = satComputeLoopNum(tl, 0xFFFF);
3496 satIOContext->LoopNum = LoopNum;
3501 TI_DBG5(("satWrite16: NON CHAINED data\n"));
3502 /* Initialize CB for SATA completion.
3504 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
3508 TI_DBG1(("satWrite16: CHAINED data\n"));
3510 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3512 fis->d.sectorCount = 0xFF;
3514 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3515 fis->h.command == SAT_WRITE_DMA_EXT ||
3516 fis->h.command == SAT_WRITE_DMA_FUA_EXT
3519 fis->d.sectorCount = 0xFF;
3520 fis->d.sectorCountExp = 0xFF;
3524 /* SAT_WRITE_FPDMA_QUEUED */
3525 fis->h.features = 0xFF;
3526 fis->d.featuresExp = 0xFF;
3529 /* Initialize CB for SATA completion.
3531 satIOContext->satCompleteCB = &satChainedDataIOCB;
3536 * Prepare SGL and send FIS to LL layer.
3538 satIOContext->reqType = agRequestType; /* Save it */
3540 status = sataLLIOStart( tiRoot,
3548 /*****************************************************************************/
3549 /*! \brief SAT implementation for SCSI WRITE12.
3551 * SAT implementation for SCSI WRITE12 and send FIS request to LL layer.
3553 * \param tiRoot: Pointer to TISA initiator driver/port instance.
3554 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
3555 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
3556 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
3557 * \param satIOContext_t: Pointer to the SAT IO Context
3559 * \return If command is started successfully
3560 * - \e tiSuccess: I/O request successfully initiated.
3561 * - \e tiBusy: No resources available, try again later.
3562 * - \e tiIONoDevice: Invalid device handle.
3563 * - \e tiError: Other errors.
3565 /*****************************************************************************/
3566 GLOBAL bit32 satWrite12(
3568 tiIORequest_t *tiIORequest,
3569 tiDeviceHandle_t *tiDeviceHandle,
3570 tiScsiInitiatorRequest_t *tiScsiRequest,
3571 satIOContext_t *satIOContext)
3574 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3575 satDeviceData_t *pSatDevData;
3576 scsiRspSense_t *pSense;
3577 tiIniScsiCmnd_t *scsiCmnd;
3578 agsaFisRegHostToDevice_t *fis;
3584 bit32 rangeChk = agFALSE; /* lba and tl range check */
3586 pSense = satIOContext->pSense;
3587 pSatDevData = satIOContext->pSatDevData;
3588 scsiCmnd = &tiScsiRequest->scsiCmnd;
3589 fis = satIOContext->pFis;
3591 TI_DBG5(("satWrite12: start\n"));
3593 /* checking FUA_NV */
3594 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
3596 satSetSensePayload( pSense,
3597 SCSI_SNSKEY_ILLEGAL_REQUEST,
3599 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3602 ostiInitiatorIOCompleted( tiRoot,
3605 SCSI_STAT_CHECK_CONDITION,
3606 satIOContext->pTiSenseData,
3607 satIOContext->interruptContext );
3609 TI_DBG1(("satWrite12: return FUA_NV\n"));
3615 /* checking CONTROL */
3616 /* NACA == 1 or LINK == 1*/
3617 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
3619 satSetSensePayload( pSense,
3620 SCSI_SNSKEY_ILLEGAL_REQUEST,
3622 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3625 ostiInitiatorIOCompleted( tiRoot,
3628 SCSI_STAT_CHECK_CONDITION,
3629 satIOContext->pTiSenseData,
3630 satIOContext->interruptContext );
3632 TI_DBG1(("satWrite12: return control\n"));
3637 osti_memset(LBA, 0, sizeof(LBA));
3638 osti_memset(TL, 0, sizeof(TL));
3640 /* do not use memcpy due to indexing in LBA and TL */
3641 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
3642 LBA[1] = scsiCmnd->cdb[3];
3643 LBA[2] = scsiCmnd->cdb[4];
3644 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
3646 TL[0] = scsiCmnd->cdb[6]; /* MSB */
3647 TL[1] = scsiCmnd->cdb[7];
3648 TL[2] = scsiCmnd->cdb[8];
3649 TL[3] = scsiCmnd->cdb[9]; /* LSB */
3651 rangeChk = satAddNComparebit32(LBA, TL);
3653 lba = satComputeCDB12LBA(satIOContext);
3654 tl = satComputeCDB12TL(satIOContext);
3657 /* Table 34, 9.1, p 46 */
3659 note: As of 2/10/2006, no support for DMA QUEUED
3663 Table 34, 9.1, p 46, b
3664 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
3665 return check condition
3667 if (pSatDevData->satNCQ != agTRUE &&
3668 pSatDevData->sat48BitSupport != agTRUE
3671 if (lba > SAT_TR_LBA_LIMIT - 1)
3673 satSetSensePayload( pSense,
3674 SCSI_SNSKEY_ILLEGAL_REQUEST,
3676 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3679 ostiInitiatorIOCompleted( tiRoot,
3682 SCSI_STAT_CHECK_CONDITION,
3683 satIOContext->pTiSenseData,
3684 satIOContext->interruptContext );
3686 TI_DBG1(("satWrite12: return LBA out of range, not EXT\n"));
3690 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
3692 TI_DBG1(("satWrite12: return LBA+TL out of range, not EXT\n"));
3693 satSetSensePayload( pSense,
3694 SCSI_SNSKEY_ILLEGAL_REQUEST,
3696 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3699 ostiInitiatorIOCompleted( tiRoot,
3702 SCSI_STAT_CHECK_CONDITION,
3703 satIOContext->pTiSenseData,
3704 satIOContext->interruptContext );
3712 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
3714 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3718 /* In case that we can't fit the transfer length, we loop */
3719 TI_DBG5(("satWrite12: case 2\n"));
3720 fis->h.fisType = 0x27; /* Reg host to device */
3721 fis->h.c_pmPort = 0x80; /* C bit is set */
3722 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
3723 fis->h.features = 0; /* FIS reserve */
3724 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
3725 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
3726 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
3728 /* FIS LBA mode set LBA (27:24) */
3729 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
3731 fis->d.lbaLowExp = 0;
3732 fis->d.lbaMidExp = 0;
3733 fis->d.lbaHighExp = 0;
3734 fis->d.featuresExp = 0;
3735 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
3736 fis->d.sectorCountExp = 0;
3737 fis->d.reserved4 = 0;
3738 fis->d.control = 0; /* FIS HOB bit clear */
3739 fis->d.reserved5 = 0;
3741 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3742 satIOContext->ATACmd = SAT_WRITE_DMA;
3747 /* WRITE MULTIPLE or WRITE SECTOR(S) */
3748 /* WRITE SECTORS for easier implemetation */
3749 /* In case that we can't fit the transfer length, we loop */
3750 TI_DBG5(("satWrite12: case 1\n"));
3751 fis->h.fisType = 0x27; /* Reg host to device */
3752 fis->h.c_pmPort = 0x80; /* C bit is set */
3753 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
3754 fis->h.features = 0; /* FIS reserve */
3755 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
3756 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
3757 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
3759 /* FIS LBA mode set LBA (27:24) */
3760 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
3762 fis->d.lbaLowExp = 0;
3763 fis->d.lbaMidExp = 0;
3764 fis->d.lbaHighExp = 0;
3765 fis->d.featuresExp = 0;
3766 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
3767 fis->d.sectorCountExp = 0;
3768 fis->d.reserved4 = 0;
3769 fis->d.control = 0; /* FIS HOB bit clear */
3770 fis->d.reserved5 = 0;
3772 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3773 satIOContext->ATACmd = SAT_WRITE_SECTORS;
3778 if (pSatDevData->sat48BitSupport == agTRUE)
3780 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3783 /* WRITE DMA EXT or WRITE DMA FUA EXT */
3784 TI_DBG5(("satWrite12: case 3\n"));
3785 fis->h.fisType = 0x27; /* Reg host to device */
3786 fis->h.c_pmPort = 0x80; /* C Bit is set */
3788 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
3789 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
3791 fis->h.features = 0; /* FIS reserve */
3792 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
3793 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
3794 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
3795 fis->d.device = 0x40; /* FIS LBA mode set */
3796 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
3797 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
3798 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
3799 fis->d.featuresExp = 0; /* FIS reserve */
3800 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
3801 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
3802 fis->d.reserved4 = 0;
3803 fis->d.control = 0; /* FIS HOB bit clear */
3804 fis->d.reserved5 = 0;
3806 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3807 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
3812 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
3813 /* WRITE SECTORS EXT for easier implemetation */
3814 TI_DBG5(("satWrite12: case 4\n"));
3815 fis->h.fisType = 0x27; /* Reg host to device */
3816 fis->h.c_pmPort = 0x80; /* C Bit is set */
3817 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
3819 fis->h.features = 0; /* FIS reserve */
3820 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
3821 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
3822 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
3823 fis->d.device = 0x40; /* FIS LBA mode set */
3824 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
3825 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
3826 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
3827 fis->d.featuresExp = 0; /* FIS reserve */
3828 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
3829 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
3830 fis->d.reserved4 = 0;
3831 fis->d.control = 0; /* FIS HOB bit clear */
3832 fis->d.reserved5 = 0;
3834 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3835 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
3840 if (pSatDevData->satNCQ == agTRUE)
3842 /* WRITE FPDMA QUEUED */
3843 if (pSatDevData->sat48BitSupport != agTRUE)
3845 TI_DBG5(("satWrite12: case 5 !!! error NCQ but 28 bit address support \n"));
3846 satSetSensePayload( pSense,
3847 SCSI_SNSKEY_ILLEGAL_REQUEST,
3849 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3852 ostiInitiatorIOCompleted( tiRoot,
3855 SCSI_STAT_CHECK_CONDITION,
3856 satIOContext->pTiSenseData,
3857 satIOContext->interruptContext );
3860 TI_DBG6(("satWrite12: case 5\n"));
3862 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
3864 fis->h.fisType = 0x27; /* Reg host to device */
3865 fis->h.c_pmPort = 0x80; /* C Bit is set */
3866 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
3867 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
3868 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
3869 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
3870 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
3873 if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
3874 fis->d.device = 0xC0; /* FIS FUA set */
3876 fis->d.device = 0x40; /* FIS FUA clear */
3878 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
3879 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
3880 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
3881 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
3882 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
3883 fis->d.sectorCountExp = 0;
3884 fis->d.reserved4 = 0;
3885 fis->d.control = 0; /* FIS HOB bit clear */
3886 fis->d.reserved5 = 0;
3888 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
3889 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
3892 satIOContext->currentLBA = lba;
3893 satIOContext->OrgTL = tl;
3896 computing number of loop and remainder for tl
3897 0xFF in case not ext
3900 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3902 LoopNum = satComputeLoopNum(tl, 0xFF);
3904 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3905 fis->h.command == SAT_WRITE_DMA_EXT ||
3906 fis->h.command == SAT_WRITE_DMA_FUA_EXT
3909 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
3910 LoopNum = satComputeLoopNum(tl, 0xFFFF);
3914 /* SAT_WRITE_FPDMA_QUEUEDK */
3915 LoopNum = satComputeLoopNum(tl, 0xFFFF);
3918 satIOContext->LoopNum = LoopNum;
3923 TI_DBG5(("satWrite12: NON CHAINED data\n"));
3924 /* Initialize CB for SATA completion.
3926 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
3930 TI_DBG1(("satWrite12: CHAINED data\n"));
3932 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3934 fis->d.sectorCount = 0xFF;
3936 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3937 fis->h.command == SAT_WRITE_DMA_EXT ||
3938 fis->h.command == SAT_WRITE_DMA_FUA_EXT
3941 fis->d.sectorCount = 0xFF;
3942 fis->d.sectorCountExp = 0xFF;
3946 /* SAT_WRITE_FPDMA_QUEUED */
3947 fis->h.features = 0xFF;
3948 fis->d.featuresExp = 0xFF;
3951 /* Initialize CB for SATA completion.
3953 satIOContext->satCompleteCB = &satChainedDataIOCB;
3958 * Prepare SGL and send FIS to LL layer.
3960 satIOContext->reqType = agRequestType; /* Save it */
3962 status = sataLLIOStart( tiRoot,
3970 /*****************************************************************************/
3971 /*! \brief SAT implementation for SCSI WRITE10.
3973 * SAT implementation for SCSI WRITE10 and send FIS request to LL layer.
3975 * \param tiRoot: Pointer to TISA initiator driver/port instance.
3976 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
3977 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
3978 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
3979 * \param satIOContext_t: Pointer to the SAT IO Context
3981 * \return If command is started successfully
3982 * - \e tiSuccess: I/O request successfully initiated.
3983 * - \e tiBusy: No resources available, try again later.
3984 * - \e tiIONoDevice: Invalid device handle.
3985 * - \e tiError: Other errors.
3987 /*****************************************************************************/
3988 GLOBAL bit32 satWrite10(
3990 tiIORequest_t *tiIORequest,
3991 tiDeviceHandle_t *tiDeviceHandle,
3992 tiScsiInitiatorRequest_t *tiScsiRequest,
3993 satIOContext_t *satIOContext)
3997 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3998 satDeviceData_t *pSatDevData;
3999 scsiRspSense_t *pSense;
4000 tiIniScsiCmnd_t *scsiCmnd;
4001 agsaFisRegHostToDevice_t *fis;
4007 bit32 rangeChk = agFALSE; /* lba and tl range check */
4009 pSense = satIOContext->pSense;
4010 pSatDevData = satIOContext->pSatDevData;
4011 scsiCmnd = &tiScsiRequest->scsiCmnd;
4012 fis = satIOContext->pFis;
4014 TI_DBG5(("satWrite10: start\n"));
4016 /* checking FUA_NV */
4017 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
4019 satSetSensePayload( pSense,
4020 SCSI_SNSKEY_ILLEGAL_REQUEST,
4022 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4025 ostiInitiatorIOCompleted( tiRoot,
4028 SCSI_STAT_CHECK_CONDITION,
4029 satIOContext->pTiSenseData,
4030 satIOContext->interruptContext );
4032 TI_DBG1(("satWrite10: return FUA_NV\n"));
4037 /* checking CONTROL */
4038 /* NACA == 1 or LINK == 1*/
4039 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
4041 satSetSensePayload( pSense,
4042 SCSI_SNSKEY_ILLEGAL_REQUEST,
4044 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4047 ostiInitiatorIOCompleted( tiRoot,
4050 SCSI_STAT_CHECK_CONDITION,
4051 satIOContext->pTiSenseData,
4052 satIOContext->interruptContext );
4054 TI_DBG1(("satWrite10: return control\n"));
4058 osti_memset(LBA, 0, sizeof(LBA));
4059 osti_memset(TL, 0, sizeof(TL));
4061 /* do not use memcpy due to indexing in LBA and TL */
4062 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
4063 LBA[1] = scsiCmnd->cdb[3];
4064 LBA[2] = scsiCmnd->cdb[4];
4065 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
4069 TL[2] = scsiCmnd->cdb[7]; /* MSB */
4070 TL[3] = scsiCmnd->cdb[8]; /* LSB */
4072 rangeChk = satAddNComparebit32(LBA, TL);
4075 /* cbd10; computing LBA and transfer length */
4076 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
4077 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
4078 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
4080 TI_DBG5(("satWrite10: lba %d functioned lba %d\n", lba, satComputeCDB10LBA(satIOContext)));
4081 TI_DBG5(("satWrite10: tl %d functioned tl %d\n", tl, satComputeCDB10TL(satIOContext)));
4083 /* Table 34, 9.1, p 46 */
4085 note: As of 2/10/2006, no support for DMA QUEUED
4089 Table 34, 9.1, p 46, b
4090 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
4091 return check condition
4093 if (pSatDevData->satNCQ != agTRUE &&
4094 pSatDevData->sat48BitSupport != agTRUE
4097 if (lba > SAT_TR_LBA_LIMIT - 1)
4099 satSetSensePayload( pSense,
4100 SCSI_SNSKEY_ILLEGAL_REQUEST,
4102 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4105 ostiInitiatorIOCompleted( tiRoot,
4108 SCSI_STAT_CHECK_CONDITION,
4109 satIOContext->pTiSenseData,
4110 satIOContext->interruptContext );
4112 TI_DBG1(("satWrite10: return LBA out of range, not EXT\n"));
4113 TI_DBG1(("satWrite10: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
4114 scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
4115 TI_DBG1(("satWrite10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
4119 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
4121 TI_DBG1(("satWrite10: return LBA+TL out of range, not EXT\n"));
4122 satSetSensePayload( pSense,
4123 SCSI_SNSKEY_ILLEGAL_REQUEST,
4125 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4128 ostiInitiatorIOCompleted( tiRoot,
4131 SCSI_STAT_CHECK_CONDITION,
4132 satIOContext->pTiSenseData,
4133 satIOContext->interruptContext );
4142 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
4144 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4148 /* can't fit the transfer length */
4149 TI_DBG5(("satWrite10: case 2\n"));
4150 fis->h.fisType = 0x27; /* Reg host to device */
4151 fis->h.c_pmPort = 0x80; /* C bit is set */
4152 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
4153 fis->h.features = 0; /* FIS reserve */
4154 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
4155 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
4156 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
4158 /* FIS LBA mode set LBA (27:24) */
4159 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
4161 fis->d.lbaLowExp = 0;
4162 fis->d.lbaMidExp = 0;
4163 fis->d.lbaHighExp = 0;
4164 fis->d.featuresExp = 0;
4165 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
4166 fis->d.sectorCountExp = 0;
4167 fis->d.reserved4 = 0;
4168 fis->d.control = 0; /* FIS HOB bit clear */
4169 fis->d.reserved5 = 0;
4171 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4172 satIOContext->ATACmd = SAT_WRITE_DMA;
4177 /* WRITE MULTIPLE or WRITE SECTOR(S) */
4178 /* WRITE SECTORS for easier implemetation */
4179 /* can't fit the transfer length */
4180 TI_DBG5(("satWrite10: case 1\n"));
4181 fis->h.fisType = 0x27; /* Reg host to device */
4182 fis->h.c_pmPort = 0x80; /* C bit is set */
4183 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
4184 fis->h.features = 0; /* FIS reserve */
4185 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
4186 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
4187 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
4189 /* FIS LBA mode set LBA (27:24) */
4190 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
4192 fis->d.lbaLowExp = 0;
4193 fis->d.lbaMidExp = 0;
4194 fis->d.lbaHighExp = 0;
4195 fis->d.featuresExp = 0;
4196 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
4197 fis->d.sectorCountExp = 0;
4198 fis->d.reserved4 = 0;
4199 fis->d.control = 0; /* FIS HOB bit clear */
4200 fis->d.reserved5 = 0;
4202 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4203 satIOContext->ATACmd = SAT_WRITE_SECTORS;
4207 if (pSatDevData->sat48BitSupport == agTRUE)
4209 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4212 /* WRITE DMA EXT or WRITE DMA FUA EXT */
4213 TI_DBG5(("satWrite10: case 3\n"));
4214 fis->h.fisType = 0x27; /* Reg host to device */
4215 fis->h.c_pmPort = 0x80; /* C Bit is set */
4217 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
4218 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
4219 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
4221 fis->h.features = 0; /* FIS reserve */
4222 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
4223 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
4224 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
4225 fis->d.device = 0x40; /* FIS LBA mode set */
4226 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
4227 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4228 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4229 fis->d.featuresExp = 0; /* FIS reserve */
4230 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
4231 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
4232 fis->d.reserved4 = 0;
4233 fis->d.control = 0; /* FIS HOB bit clear */
4234 fis->d.reserved5 = 0;
4236 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4241 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
4242 /* WRITE SECTORS EXT for easier implemetation */
4243 TI_DBG5(("satWrite10: case 4\n"));
4244 fis->h.fisType = 0x27; /* Reg host to device */
4245 fis->h.c_pmPort = 0x80; /* C Bit is set */
4246 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
4248 fis->h.features = 0; /* FIS reserve */
4249 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
4250 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
4251 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
4252 fis->d.device = 0x40; /* FIS LBA mode set */
4253 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
4254 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4255 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4256 fis->d.featuresExp = 0; /* FIS reserve */
4257 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
4258 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
4259 fis->d.reserved4 = 0;
4260 fis->d.control = 0; /* FIS HOB bit clear */
4261 fis->d.reserved5 = 0;
4263 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4264 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
4268 if (pSatDevData->satNCQ == agTRUE)
4270 /* WRITE FPDMA QUEUED */
4271 if (pSatDevData->sat48BitSupport != agTRUE)
4273 TI_DBG5(("satWrite10: case 5 !!! error NCQ but 28 bit address support \n"));
4274 satSetSensePayload( pSense,
4275 SCSI_SNSKEY_ILLEGAL_REQUEST,
4277 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4280 ostiInitiatorIOCompleted( tiRoot,
4283 SCSI_STAT_CHECK_CONDITION,
4284 satIOContext->pTiSenseData,
4285 satIOContext->interruptContext );
4288 TI_DBG6(("satWrite10: case 5\n"));
4290 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
4292 fis->h.fisType = 0x27; /* Reg host to device */
4293 fis->h.c_pmPort = 0x80; /* C Bit is set */
4294 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
4295 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
4296 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
4297 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
4298 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
4301 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
4302 fis->d.device = 0xC0; /* FIS FUA set */
4304 fis->d.device = 0x40; /* FIS FUA clear */
4306 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
4307 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4308 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4309 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
4310 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
4311 fis->d.sectorCountExp = 0;
4312 fis->d.reserved4 = 0;
4313 fis->d.control = 0; /* FIS HOB bit clear */
4314 fis->d.reserved5 = 0;
4316 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
4317 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
4320 // tdhexdump("satWrite10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
4322 satIOContext->currentLBA = lba;
4323 satIOContext->OrgTL = tl;
4326 computing number of loop and remainder for tl
4327 0xFF in case not ext
4330 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
4332 LoopNum = satComputeLoopNum(tl, 0xFF);
4334 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
4335 fis->h.command == SAT_WRITE_DMA_EXT ||
4336 fis->h.command == SAT_WRITE_DMA_FUA_EXT
4339 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
4340 LoopNum = satComputeLoopNum(tl, 0xFFFF);
4344 /* SAT_WRITE_FPDMA_QUEUEDK */
4345 LoopNum = satComputeLoopNum(tl, 0xFFFF);
4348 satIOContext->LoopNum = LoopNum;
4353 TI_DBG5(("satWrite10: NON CHAINED data\n"));
4354 /* Initialize CB for SATA completion.
4356 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
4360 TI_DBG1(("satWrite10: CHAINED data\n"));
4362 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
4364 fis->d.sectorCount = 0xFF;
4366 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
4367 fis->h.command == SAT_WRITE_DMA_EXT ||
4368 fis->h.command == SAT_WRITE_DMA_FUA_EXT
4371 fis->d.sectorCount = 0xFF;
4372 fis->d.sectorCountExp = 0xFF;
4376 /* SAT_WRITE_FPDMA_QUEUED */
4377 fis->h.features = 0xFF;
4378 fis->d.featuresExp = 0xFF;
4381 /* Initialize CB for SATA completion.
4383 satIOContext->satCompleteCB = &satChainedDataIOCB;
4388 * Prepare SGL and send FIS to LL layer.
4390 satIOContext->reqType = agRequestType; /* Save it */
4392 status = sataLLIOStart( tiRoot,
4400 /*****************************************************************************/
4401 /*! \brief SAT implementation for SCSI satWrite_1.
4403 * SAT implementation for SCSI WRITE10 and send FIS request to LL layer.
4404 * This is used when WRITE10 is divided into multiple ATA commands
4406 * \param tiRoot: Pointer to TISA initiator driver/port instance.
4407 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
4408 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
4409 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
4410 * \param satIOContext_t: Pointer to the SAT IO Context
4412 * \return If command is started successfully
4413 * - \e tiSuccess: I/O request successfully initiated.
4414 * - \e tiBusy: No resources available, try again later.
4415 * - \e tiIONoDevice: Invalid device handle.
4416 * - \e tiError: Other errors.
4418 /*****************************************************************************/
4419 GLOBAL bit32 satWrite_1(
4421 tiIORequest_t *tiIORequest,
4422 tiDeviceHandle_t *tiDeviceHandle,
4423 tiScsiInitiatorRequest_t *tiScsiRequest,
4424 satIOContext_t *satIOContext)
4427 Assumption: error check on lba and tl has been done in satWrite*()
4431 satIOContext_t *satOrgIOContext = agNULL;
4432 tiIniScsiCmnd_t *scsiCmnd;
4433 agsaFisRegHostToDevice_t *fis;
4434 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4436 bit32 DenomTL = 0xFF;
4437 bit32 Remainder = 0;
4438 bit8 LBA[4]; /* 0 MSB, 3 LSB */
4440 TI_DBG2(("satWrite_1: start\n"));
4442 fis = satIOContext->pFis;
4443 satOrgIOContext = satIOContext->satOrgIOContext;
4444 scsiCmnd = satOrgIOContext->pScsiCmnd;
4446 osti_memset(LBA,0, sizeof(LBA));
4448 switch (satOrgIOContext->ATACmd)
4453 case SAT_WRITE_SECTORS:
4456 case SAT_WRITE_DMA_EXT:
4459 case SAT_WRITE_DMA_FUA_EXT:
4462 case SAT_WRITE_SECTORS_EXT:
4465 case SAT_WRITE_FPDMA_QUEUED:
4469 TI_DBG1(("satWrite_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
4474 Remainder = satOrgIOContext->OrgTL % DenomTL;
4475 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
4476 lba = satOrgIOContext->currentLBA;
4478 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
4479 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
4480 LBA[2] = (bit8)((lba & 0xF0) >> 8);
4481 LBA[3] = (bit8)(lba & 0xF); /* LSB */
4483 switch (satOrgIOContext->ATACmd)
4486 fis->h.fisType = 0x27; /* Reg host to device */
4487 fis->h.c_pmPort = 0x80; /* C bit is set */
4488 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
4489 fis->h.features = 0; /* FIS reserve */
4490 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
4491 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
4492 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
4494 /* FIS LBA mode set LBA (27:24) */
4495 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
4497 fis->d.lbaLowExp = 0;
4498 fis->d.lbaMidExp = 0;
4499 fis->d.lbaHighExp = 0;
4500 fis->d.featuresExp = 0;
4501 if (satOrgIOContext->LoopNum == 1)
4504 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
4508 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
4510 fis->d.sectorCountExp = 0;
4511 fis->d.reserved4 = 0;
4512 fis->d.control = 0; /* FIS HOB bit clear */
4513 fis->d.reserved5 = 0;
4515 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4518 case SAT_WRITE_SECTORS:
4519 fis->h.fisType = 0x27; /* Reg host to device */
4520 fis->h.c_pmPort = 0x80; /* C bit is set */
4521 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
4522 fis->h.features = 0; /* FIS reserve */
4523 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
4524 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
4525 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
4527 /* FIS LBA mode set LBA (27:24) */
4528 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
4530 fis->d.lbaLowExp = 0;
4531 fis->d.lbaMidExp = 0;
4532 fis->d.lbaHighExp = 0;
4533 fis->d.featuresExp = 0;
4534 if (satOrgIOContext->LoopNum == 1)
4537 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
4541 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
4543 fis->d.sectorCountExp = 0;
4544 fis->d.reserved4 = 0;
4545 fis->d.control = 0; /* FIS HOB bit clear */
4546 fis->d.reserved5 = 0;
4548 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4551 case SAT_WRITE_DMA_EXT:
4552 fis->h.fisType = 0x27; /* Reg host to device */
4553 fis->h.c_pmPort = 0x80; /* C Bit is set */
4554 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x3D */
4555 fis->h.features = 0; /* FIS reserve */
4556 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
4557 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
4558 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
4559 fis->d.device = 0x40; /* FIS LBA mode set */
4560 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
4561 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4562 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4563 fis->d.featuresExp = 0; /* FIS reserve */
4564 if (satOrgIOContext->LoopNum == 1)
4567 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
4568 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
4572 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
4573 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
4575 fis->d.reserved4 = 0;
4576 fis->d.control = 0; /* FIS HOB bit clear */
4577 fis->d.reserved5 = 0;
4579 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4582 case SAT_WRITE_SECTORS_EXT:
4583 fis->h.fisType = 0x27; /* Reg host to device */
4584 fis->h.c_pmPort = 0x80; /* C Bit is set */
4585 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
4587 fis->h.features = 0; /* FIS reserve */
4588 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
4589 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
4590 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
4591 fis->d.device = 0x40; /* FIS LBA mode set */
4592 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
4593 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4594 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4595 fis->d.featuresExp = 0; /* FIS reserve */
4596 if (satOrgIOContext->LoopNum == 1)
4599 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
4600 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
4604 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
4605 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
4607 fis->d.reserved4 = 0;
4608 fis->d.control = 0; /* FIS HOB bit clear */
4609 fis->d.reserved5 = 0;
4611 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4614 case SAT_WRITE_FPDMA_QUEUED:
4615 fis->h.fisType = 0x27; /* Reg host to device */
4616 fis->h.c_pmPort = 0x80; /* C Bit is set */
4617 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
4618 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
4619 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
4620 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
4623 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
4624 fis->d.device = 0xC0; /* FIS FUA set */
4626 fis->d.device = 0x40; /* FIS FUA clear */
4628 fis->d.lbaLowExp = LBA[0];; /* FIS LBA (31:24) */
4629 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4630 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4631 if (satOrgIOContext->LoopNum == 1)
4634 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
4635 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
4639 fis->h.features = 0xFF; /* FIS sector count (7:0) */
4640 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */
4642 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
4643 fis->d.sectorCountExp = 0;
4644 fis->d.reserved4 = 0;
4645 fis->d.control = 0; /* FIS HOB bit clear */
4646 fis->d.reserved5 = 0;
4648 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
4652 TI_DBG1(("satWrite_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
4657 /* Initialize CB for SATA completion.
4660 satIOContext->satCompleteCB = &satChainedDataIOCB;
4664 * Prepare SGL and send FIS to LL layer.
4666 satIOContext->reqType = agRequestType; /* Save it */
4668 status = sataLLIOStart( tiRoot,
4674 TI_DBG5(("satWrite_1: return\n"));
4678 /*****************************************************************************/
4679 /*! \brief SAT implementation for SCSI WRITE6.
4681 * SAT implementation for SCSI WRITE6 and send FIS request to LL layer.
4683 * \param tiRoot: Pointer to TISA initiator driver/port instance.
4684 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
4685 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
4686 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
4687 * \param satIOContext_t: Pointer to the SAT IO Context
4689 * \return If command is started successfully
4690 * - \e tiSuccess: I/O request successfully initiated.
4691 * - \e tiBusy: No resources available, try again later.
4692 * - \e tiIONoDevice: Invalid device handle.
4693 * - \e tiError: Other errors.
4695 /*****************************************************************************/
4696 GLOBAL bit32 satWrite6(
4698 tiIORequest_t *tiIORequest,
4699 tiDeviceHandle_t *tiDeviceHandle,
4700 tiScsiInitiatorRequest_t *tiScsiRequest,
4701 satIOContext_t *satIOContext)
4705 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4706 satDeviceData_t *pSatDevData;
4707 scsiRspSense_t *pSense;
4708 tiIniScsiCmnd_t *scsiCmnd;
4709 agsaFisRegHostToDevice_t *fis;
4713 pSense = satIOContext->pSense;
4714 pSatDevData = satIOContext->pSatDevData;
4715 scsiCmnd = &tiScsiRequest->scsiCmnd;
4716 fis = satIOContext->pFis;
4718 TI_DBG5(("satWrite6: start\n"));
4720 /* checking CONTROL */
4721 /* NACA == 1 or LINK == 1*/
4722 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
4724 satSetSensePayload( pSense,
4725 SCSI_SNSKEY_ILLEGAL_REQUEST,
4727 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4730 ostiInitiatorIOCompleted( tiRoot,
4733 SCSI_STAT_CHECK_CONDITION,
4734 satIOContext->pTiSenseData,
4735 satIOContext->interruptContext );
4737 TI_DBG1(("satWrite6: return control\n"));
4742 /* cbd6; computing LBA and transfer length */
4743 lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
4744 + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
4745 tl = scsiCmnd->cdb[4];
4748 /* Table 34, 9.1, p 46 */
4750 note: As of 2/10/2006, no support for DMA QUEUED
4754 Table 34, 9.1, p 46, b
4755 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
4756 return check condition
4758 if (pSatDevData->satNCQ != agTRUE &&
4759 pSatDevData->sat48BitSupport != agTRUE
4762 if (lba > SAT_TR_LBA_LIMIT - 1)
4764 satSetSensePayload( pSense,
4765 SCSI_SNSKEY_ILLEGAL_REQUEST,
4767 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4770 ostiInitiatorIOCompleted( tiRoot,
4773 SCSI_STAT_CHECK_CONDITION,
4774 satIOContext->pTiSenseData,
4775 satIOContext->interruptContext );
4777 TI_DBG1(("satWrite6: return LBA out of range\n"));
4783 if (lba + tl <= SAT_TR_LBA_LIMIT)
4785 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4789 TI_DBG5(("satWrite6: case 2\n"));
4792 fis->h.fisType = 0x27; /* Reg host to device */
4793 fis->h.c_pmPort = 0x80; /* C Bit is set */
4794 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
4795 fis->h.features = 0; /* FIS reserve */
4796 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
4797 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
4798 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
4799 fis->d.device = 0x40; /* FIS LBA mode */
4800 fis->d.lbaLowExp = 0;
4801 fis->d.lbaMidExp = 0;
4802 fis->d.lbaHighExp = 0;
4803 fis->d.featuresExp = 0;
4807 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */
4811 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
4813 fis->d.sectorCountExp = 0;
4814 fis->d.reserved4 = 0;
4815 fis->d.control = 0; /* FIS HOB bit clear */
4816 fis->d.reserved5 = 0;
4818 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4823 /* WRITE SECTORS for easier implemetation */
4824 TI_DBG5(("satWrite6: case 1\n"));
4826 fis->h.fisType = 0x27; /* Reg host to device */
4827 fis->h.c_pmPort = 0x80; /* C Bit is set */
4828 fis->h.command = SAT_WRITE_SECTORS; /* 0xCA */
4829 fis->h.features = 0; /* FIS reserve */
4830 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
4831 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
4832 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
4833 fis->d.device = 0x40; /* FIS LBA mode */
4834 fis->d.lbaLowExp = 0;
4835 fis->d.lbaMidExp = 0;
4836 fis->d.lbaHighExp = 0;
4837 fis->d.featuresExp = 0;
4841 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */
4845 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
4847 fis->d.sectorCountExp = 0;
4848 fis->d.reserved4 = 0;
4849 fis->d.control = 0; /* FIS HOB bit clear */
4850 fis->d.reserved5 = 0;
4852 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4858 if (pSatDevData->sat48BitSupport == agTRUE)
4860 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4863 /* WRITE DMA EXT only */
4864 TI_DBG5(("satWrite6: case 3\n"));
4865 fis->h.fisType = 0x27; /* Reg host to device */
4866 fis->h.c_pmPort = 0x80; /* C Bit is set */
4867 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
4868 fis->h.features = 0; /* FIS reserve */
4869 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
4870 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
4871 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
4872 fis->d.device = 0x40; /* FIS LBA mode set */
4873 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
4874 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4875 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4876 fis->d.featuresExp = 0; /* FIS reserve */
4879 /* sector count is 256, 0x100*/
4880 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
4881 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */
4885 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
4886 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
4888 fis->d.reserved4 = 0;
4889 fis->d.control = 0; /* FIS HOB bit clear */
4890 fis->d.reserved5 = 0;
4892 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4897 /* WRITE SECTORS EXT for easier implemetation */
4898 TI_DBG5(("satWrite6: case 4\n"));
4900 fis->h.fisType = 0x27; /* Reg host to device */
4901 fis->h.c_pmPort = 0x80; /* C Bit is set */
4902 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
4903 fis->h.features = 0; /* FIS reserve */
4904 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
4905 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
4906 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
4907 fis->d.device = 0x40; /* FIS LBA mode set */
4908 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
4909 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4910 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4911 fis->d.featuresExp = 0; /* FIS reserve */
4914 /* sector count is 256, 0x100*/
4915 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
4916 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */
4920 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
4921 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
4923 fis->d.reserved4 = 0;
4924 fis->d.control = 0; /* FIS HOB bit clear */
4925 fis->d.reserved5 = 0;
4927 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4932 if (pSatDevData->satNCQ == agTRUE)
4934 /* WRITE FPDMA QUEUED */
4935 if (pSatDevData->sat48BitSupport != agTRUE)
4938 TI_DBG5(("satWrite6: case 5 !!! error NCQ but 28 bit address support \n"));
4939 satSetSensePayload( pSense,
4940 SCSI_SNSKEY_ILLEGAL_REQUEST,
4942 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4945 ostiInitiatorIOCompleted( tiRoot,
4948 SCSI_STAT_CHECK_CONDITION,
4949 satIOContext->pTiSenseData,
4950 satIOContext->interruptContext );
4953 TI_DBG5(("satWrite6: case 5\n"));
4955 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
4957 fis->h.fisType = 0x27; /* Reg host to device */
4958 fis->h.c_pmPort = 0x80; /* C Bit is set */
4959 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
4960 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
4961 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
4962 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
4963 fis->d.device = 0x40; /* FIS FUA clear */
4964 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
4965 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4966 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4969 /* sector count is 256, 0x100*/
4970 fis->h.features = 0; /* FIS sector count (7:0) */
4971 fis->d.featuresExp = 0x01; /* FIS sector count (15:8) */
4975 fis->h.features = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
4976 fis->d.featuresExp = 0; /* FIS sector count (15:8) */
4978 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
4979 fis->d.sectorCountExp = 0;
4980 fis->d.reserved4 = 0;
4981 fis->d.control = 0; /* FIS HOB bit clear */
4982 fis->d.reserved5 = 0;
4984 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
4987 /* Initialize CB for SATA completion.
4989 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
4992 * Prepare SGL and send FIS to LL layer.
4994 satIOContext->reqType = agRequestType; /* Save it */
4996 status = sataLLIOStart( tiRoot,
5005 /*****************************************************************************/
5006 /*! \brief SAT implementation for SCSI TEST UNIT READY.
5008 * SAT implementation for SCSI TUR and send FIS request to LL layer.
5010 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5011 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5012 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5013 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5014 * \param satIOContext_t: Pointer to the SAT IO Context
5016 * \return If command is started successfully
5017 * - \e tiSuccess: I/O request successfully initiated.
5018 * - \e tiBusy: No resources available, try again later.
5019 * - \e tiIONoDevice: Invalid device handle.
5020 * - \e tiError: Other errors.
5022 /*****************************************************************************/
5023 GLOBAL bit32 satTestUnitReady(
5025 tiIORequest_t *tiIORequest,
5026 tiDeviceHandle_t *tiDeviceHandle,
5027 tiScsiInitiatorRequest_t *tiScsiRequest,
5028 satIOContext_t *satIOContext)
5032 bit32 agRequestType;
5033 satDeviceData_t *pSatDevData;
5034 scsiRspSense_t *pSense;
5035 tiIniScsiCmnd_t *scsiCmnd;
5036 agsaFisRegHostToDevice_t *fis;
5038 pSense = satIOContext->pSense;
5039 pSatDevData = satIOContext->pSatDevData;
5040 scsiCmnd = &tiScsiRequest->scsiCmnd;
5041 fis = satIOContext->pFis;
5043 TI_DBG6(("satTestUnitReady: entry tiDeviceHandle=%p tiIORequest=%p\n",
5044 tiDeviceHandle, tiIORequest));
5046 /* checking CONTROL */
5047 /* NACA == 1 or LINK == 1*/
5048 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
5050 satSetSensePayload( pSense,
5051 SCSI_SNSKEY_ILLEGAL_REQUEST,
5053 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5056 ostiInitiatorIOCompleted( tiRoot,
5059 SCSI_STAT_CHECK_CONDITION,
5060 satIOContext->pTiSenseData,
5061 satIOContext->interruptContext );
5063 TI_DBG1(("satTestUnitReady: return control\n"));
5067 /* SAT revision 8, 8.11.2, p42*/
5068 if (pSatDevData->satStopState == agTRUE)
5070 satSetSensePayload( pSense,
5071 SCSI_SNSKEY_NOT_READY,
5073 SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED,
5076 ostiInitiatorIOCompleted( tiRoot,
5079 SCSI_STAT_CHECK_CONDITION,
5080 satIOContext->pTiSenseData,
5081 satIOContext->interruptContext );
5082 TI_DBG1(("satTestUnitReady: stop state\n"));
5087 * Check if format is in progress
5090 if (pSatDevData->satDriveState == SAT_DEV_STATE_FORMAT_IN_PROGRESS)
5092 TI_DBG1(("satTestUnitReady() FORMAT_IN_PROGRESS tiDeviceHandle=%p tiIORequest=%p\n",
5093 tiDeviceHandle, tiIORequest));
5095 satSetSensePayload( pSense,
5096 SCSI_SNSKEY_NOT_READY,
5098 SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_FORMAT_IN_PROGRESS,
5101 ostiInitiatorIOCompleted( tiRoot,
5104 SCSI_STAT_CHECK_CONDITION,
5105 satIOContext->pTiSenseData,
5106 satIOContext->interruptContext );
5107 TI_DBG1(("satTestUnitReady: format in progress\n"));
5112 check previously issued ATA command
5114 if (pSatDevData->satPendingIO != 0)
5116 if (pSatDevData->satDeviceFaultState == agTRUE)
5118 satSetSensePayload( pSense,
5119 SCSI_SNSKEY_HARDWARE_ERROR,
5121 SCSI_SNSCODE_LOGICAL_UNIT_FAILURE,
5124 ostiInitiatorIOCompleted( tiRoot,
5127 SCSI_STAT_CHECK_CONDITION,
5128 satIOContext->pTiSenseData,
5129 satIOContext->interruptContext );
5130 TI_DBG1(("satTestUnitReady: previous command ended in error\n"));
5135 check removalbe media feature set
5137 if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
5139 TI_DBG5(("satTestUnitReady: sending get media status cmnd\n"));
5140 /* send GET MEDIA STATUS command */
5141 fis->h.fisType = 0x27; /* Reg host to device */
5142 fis->h.c_pmPort = 0x80; /* C Bit is set */
5143 fis->h.command = SAT_GET_MEDIA_STATUS; /* 0xDA */
5144 fis->h.features = 0; /* FIS features NA */
5145 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
5146 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
5147 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
5148 fis->d.device = 0; /* FIS DEV is discared in SATA */
5149 fis->d.lbaLowExp = 0;
5150 fis->d.lbaMidExp = 0;
5151 fis->d.lbaHighExp = 0;
5152 fis->d.featuresExp = 0;
5153 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
5154 fis->d.sectorCountExp = 0;
5155 fis->d.reserved4 = 0;
5156 fis->d.control = 0; /* FIS HOB bit clear */
5157 fis->d.reserved5 = 0;
5158 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5160 /* Initialize CB for SATA completion.
5162 satIOContext->satCompleteCB = &satTestUnitReadyCB;
5165 * Prepare SGL and send FIS to LL layer.
5167 satIOContext->reqType = agRequestType; /* Save it */
5169 status = sataLLIOStart( tiRoot,
5178 number 6) in SAT p42
5179 send ATA CHECK POWER MODE
5181 TI_DBG5(("satTestUnitReady: sending check power mode cmnd\n"));
5182 status = satTestUnitReady_1( tiRoot,
5191 /*****************************************************************************/
5192 /*! \brief SAT implementation for SCSI satTestUnitReady_1.
5194 * SAT implementation for SCSI satTestUnitReady_1.
5196 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5197 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5198 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5199 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5200 * \param satIOContext_t: Pointer to the SAT IO Context
5202 * \return If command is started successfully
5203 * - \e tiSuccess: I/O request successfully initiated.
5204 * - \e tiBusy: No resources available, try again later.
5205 * - \e tiIONoDevice: Invalid device handle.
5206 * - \e tiError: Other errors.
5208 /*****************************************************************************/
5209 GLOBAL bit32 satTestUnitReady_1(
5211 tiIORequest_t *tiIORequest,
5212 tiDeviceHandle_t *tiDeviceHandle,
5213 tiScsiInitiatorRequest_t *tiScsiRequest,
5214 satIOContext_t *satIOContext)
5217 sends SAT_CHECK_POWER_MODE as a part of TESTUNITREADY
5218 internally generated - no directly corresponding scsi
5219 called in satIOCompleted as a part of satTestUnitReady(), SAT, revision8, 8.11.2, p42
5222 bit32 agRequestType;
5223 agsaFisRegHostToDevice_t *fis;
5225 fis = satIOContext->pFis;
5227 TI_DBG5(("satTestUnitReady_1: start\n"));
5230 * Send the ATA CHECK POWER MODE command.
5232 fis->h.fisType = 0x27; /* Reg host to device */
5233 fis->h.c_pmPort = 0x80; /* C Bit is set */
5234 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */
5235 fis->h.features = 0;
5240 fis->d.lbaLowExp = 0;
5241 fis->d.lbaMidExp = 0;
5242 fis->d.lbaHighExp = 0;
5243 fis->d.featuresExp = 0;
5244 fis->d.sectorCount = 0;
5245 fis->d.sectorCountExp = 0;
5246 fis->d.reserved4 = 0;
5247 fis->d.control = 0; /* FIS HOB bit clear */
5248 fis->d.reserved5 = 0;
5250 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5252 /* Initialize CB for SATA completion.
5254 satIOContext->satCompleteCB = &satTestUnitReadyCB;
5257 * Prepare SGL and send FIS to LL layer.
5259 satIOContext->reqType = agRequestType; /* Save it */
5261 status = sataLLIOStart( tiRoot,
5267 TI_DBG5(("satTestUnitReady_1: return\n"));
5273 /*****************************************************************************/
5274 /*! \brief SAT implementation for SCSI satReportLun.
5276 * SAT implementation for SCSI satReportLun. Only LUN0 is reported.
5278 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5279 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5280 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5281 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5282 * \param satIOContext_t: Pointer to the SAT IO Context
5284 * \return If command is started successfully
5285 * - \e tiSuccess: I/O request successfully initiated.
5286 * - \e tiBusy: No resources available, try again later.
5287 * - \e tiIONoDevice: Invalid device handle.
5288 * - \e tiError: Other errors.
5290 /*****************************************************************************/
5291 GLOBAL bit32 satReportLun(
5293 tiIORequest_t *tiIORequest,
5294 tiDeviceHandle_t *tiDeviceHandle,
5295 tiScsiInitiatorRequest_t *tiScsiRequest,
5296 satIOContext_t *satIOContext)
5298 scsiRspSense_t *pSense;
5299 bit32 allocationLen;
5301 scsiReportLun_t *pReportLun;
5302 tiIniScsiCmnd_t *scsiCmnd;
5304 TI_DBG5(("satReportLun entry: tiDeviceHandle=%p tiIORequest=%p\n",
5305 tiDeviceHandle, tiIORequest));
5307 pSense = satIOContext->pSense;
5308 pReportLun = (scsiReportLun_t *) tiScsiRequest->sglVirtualAddr;
5309 scsiCmnd = &tiScsiRequest->scsiCmnd;
5311 // tdhexdump("satReportLun cdb", (bit8 *)scsiCmnd, 16);
5313 /* Find the buffer size allocated by Initiator */
5314 allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) |
5315 (((bit32)scsiCmnd->cdb[7]) << 16) |
5316 (((bit32)scsiCmnd->cdb[8]) << 8 ) |
5317 (((bit32)scsiCmnd->cdb[9]) );
5319 reportLunLen = 16; /* 8 byte header and 8 bytes of LUN0 */
5321 if (allocationLen < reportLunLen)
5323 TI_DBG1(("satReportLun *** ERROR *** insufficient len=0x%x tiDeviceHandle=%p tiIORequest=%p\n",
5324 reportLunLen, tiDeviceHandle, tiIORequest));
5326 satSetSensePayload( pSense,
5327 SCSI_SNSKEY_ILLEGAL_REQUEST,
5329 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5332 ostiInitiatorIOCompleted( tiRoot,
5335 SCSI_STAT_CHECK_CONDITION,
5336 satIOContext->pTiSenseData,
5337 satIOContext->interruptContext );
5342 /* Set length to one entry */
5343 pReportLun->len[0] = 0;
5344 pReportLun->len[1] = 0;
5345 pReportLun->len[2] = 0;
5346 pReportLun->len[3] = sizeof (tiLUN_t);
5348 pReportLun->reserved = 0;
5351 * - address method to 0x00: Peripheral device addressing method,
5352 * - bus identifier to 0
5354 pReportLun->lunList[0].lun[0] = 0;
5355 pReportLun->lunList[0].lun[1] = 0;
5356 pReportLun->lunList[0].lun[2] = 0;
5357 pReportLun->lunList[0].lun[3] = 0;
5358 pReportLun->lunList[0].lun[4] = 0;
5359 pReportLun->lunList[0].lun[5] = 0;
5360 pReportLun->lunList[0].lun[6] = 0;
5361 pReportLun->lunList[0].lun[7] = 0;
5363 if (allocationLen > reportLunLen)
5366 TI_DBG1(("satReportLun reporting underrun reportLunLen=0x%x allocationLen=0x%x \n", reportLunLen, allocationLen));
5368 ostiInitiatorIOCompleted( tiRoot,
5371 allocationLen - reportLunLen,
5373 satIOContext->interruptContext );
5379 ostiInitiatorIOCompleted( tiRoot,
5384 satIOContext->interruptContext);
5390 /*****************************************************************************/
5391 /*! \brief SAT implementation for SCSI REQUEST SENSE.
5393 * SAT implementation for SCSI REQUEST SENSE.
5395 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5396 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5397 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5398 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5399 * \param satIOContext_t: Pointer to the SAT IO Context
5401 * \return If command is started successfully
5402 * - \e tiSuccess: I/O request successfully initiated.
5403 * - \e tiBusy: No resources available, try again later.
5404 * - \e tiIONoDevice: Invalid device handle.
5405 * - \e tiError: Other errors.
5407 /*****************************************************************************/
5408 GLOBAL bit32 satRequestSense(
5410 tiIORequest_t *tiIORequest,
5411 tiDeviceHandle_t *tiDeviceHandle,
5412 tiScsiInitiatorRequest_t *tiScsiRequest,
5413 satIOContext_t *satIOContext)
5416 SAT Rev 8 p38, Table25
5417 sending SMART RETURN STATUS
5418 Checking SMART Treshold Exceeded Condition is done in satRequestSenseCB()
5419 Only fixed format sense data is support. In other words, we don't support DESC bit is set
5423 bit32 agRequestType;
5424 scsiRspSense_t *pSense;
5425 satDeviceData_t *pSatDevData;
5426 tiIniScsiCmnd_t *scsiCmnd;
5427 agsaFisRegHostToDevice_t *fis;
5428 tdIORequestBody_t *tdIORequestBody;
5429 satInternalIo_t *satIntIo = agNULL;
5430 satIOContext_t *satIOContext2;
5432 TI_DBG4(("satRequestSense entry: tiDeviceHandle=%p tiIORequest=%p\n",
5433 tiDeviceHandle, tiIORequest));
5435 pSense = (scsiRspSense_t *) tiScsiRequest->sglVirtualAddr;
5436 pSatDevData = satIOContext->pSatDevData;
5437 scsiCmnd = &tiScsiRequest->scsiCmnd;
5438 fis = satIOContext->pFis;
5440 TI_DBG4(("satRequestSense: pSatDevData=%p\n", pSatDevData));
5442 /* checking CONTROL */
5443 /* NACA == 1 or LINK == 1*/
5444 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
5446 satSetSensePayload( pSense,
5447 SCSI_SNSKEY_ILLEGAL_REQUEST,
5449 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5452 ostiInitiatorIOCompleted( tiRoot,
5455 SCSI_STAT_CHECK_CONDITION,
5456 satIOContext->pTiSenseData,
5457 satIOContext->interruptContext );
5459 TI_DBG1(("satRequestSense: return control\n"));
5464 Only fixed format sense data is support. In other words, we don't support DESC bit is set
5467 if ( scsiCmnd->cdb[1] & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
5469 satSetSensePayload( pSense,
5470 SCSI_SNSKEY_ILLEGAL_REQUEST,
5472 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5475 ostiInitiatorIOCompleted( tiRoot,
5478 SCSI_STAT_CHECK_CONDITION,
5479 satIOContext->pTiSenseData,
5480 satIOContext->interruptContext );
5482 TI_DBG1(("satRequestSense: DESC bit is set, which we don't support\n"));
5487 if (pSatDevData->satSMARTEnabled == agTRUE)
5489 /* sends SMART RETURN STATUS */
5490 fis->h.fisType = 0x27; /* Reg host to device */
5491 fis->h.c_pmPort = 0x80; /* C Bit is set */
5493 fis->h.command = SAT_SMART_RETURN_STATUS; /* 0xB0 */
5494 fis->h.features = 0xDA; /* FIS features */
5495 fis->d.featuresExp = 0; /* FIS reserve */
5496 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
5497 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
5498 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
5499 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
5500 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
5501 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
5502 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
5503 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
5504 fis->d.device = 0; /* FIS DEV is discared in SATA */
5505 fis->d.control = 0; /* FIS HOB bit clear */
5506 fis->d.reserved4 = 0;
5507 fis->d.reserved5 = 0;
5509 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5510 /* Initialize CB for SATA completion.
5512 satIOContext->satCompleteCB = &satRequestSenseCB;
5515 * Prepare SGL and send FIS to LL layer.
5517 satIOContext->reqType = agRequestType; /* Save it */
5519 status = sataLLIOStart( tiRoot,
5525 TI_DBG4(("satRequestSense: if return, status %d\n", status));
5530 /*allocate iocontext for xmitting xmit SAT_CHECK_POWER_MODE
5531 then call satRequestSense2 */
5533 TI_DBG4(("satRequestSense: before satIntIo %p\n", satIntIo));
5534 /* allocate iocontext */
5535 satIntIo = satAllocIntIoResource( tiRoot,
5536 tiIORequest, /* original request */
5538 tiScsiRequest->scsiCmnd.expDataLength,
5541 TI_DBG4(("satRequestSense: after satIntIo %p\n", satIntIo));
5543 if (satIntIo == agNULL)
5545 /* memory allocation failure */
5546 satFreeIntIoResource( tiRoot,
5550 /* failed during sending SMART RETURN STATUS */
5551 satSetSensePayload( pSense,
5552 SCSI_SNSKEY_NO_SENSE,
5554 SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
5557 ostiInitiatorIOCompleted( tiRoot,
5562 satIOContext->interruptContext );
5564 TI_DBG4(("satRequestSense: else fail 1\n"));
5566 } /* end of memory allocation failure */
5570 * Need to initialize all the fields within satIOContext except
5571 * reqType and satCompleteCB which will be set depending on cmd.
5574 if (satIntIo == agNULL)
5576 TI_DBG4(("satRequestSense: satIntIo is NULL\n"));
5580 TI_DBG4(("satRequestSense: satIntIo is NOT NULL\n"));
5582 /* use this --- tttttthe one the same */
5585 satIntIo->satOrgTiIORequest = tiIORequest;
5586 tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
5587 satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
5589 satIOContext2->pSatDevData = pSatDevData;
5590 satIOContext2->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
5591 satIOContext2->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
5592 satIOContext2->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
5593 satIOContext2->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
5594 satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
5595 satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
5596 satIOContext2->interruptContext = satIOContext->interruptContext;
5597 satIOContext2->satIntIoContext = satIntIo;
5598 satIOContext2->ptiDeviceHandle = tiDeviceHandle;
5599 satIOContext2->satOrgIOContext = satIOContext;
5601 TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.len %d\n", satIntIo->satIntTiScsiXchg.agSgl1.len));
5603 TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.upper %d\n", satIntIo->satIntTiScsiXchg.agSgl1.upper));
5605 TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.lower %d\n", satIntIo->satIntTiScsiXchg.agSgl1.lower));
5607 TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.type %d\n", satIntIo->satIntTiScsiXchg.agSgl1.type));
5609 status = satRequestSense_1( tiRoot,
5610 &(satIntIo->satIntTiIORequest),
5612 &(satIntIo->satIntTiScsiXchg),
5615 if (status != tiSuccess)
5617 satFreeIntIoResource( tiRoot,
5621 /* failed during sending SMART RETURN STATUS */
5622 satSetSensePayload( pSense,
5623 SCSI_SNSKEY_NO_SENSE,
5625 SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
5628 ostiInitiatorIOCompleted( tiRoot,
5631 SCSI_STAT_CHECK_CONDITION,
5633 satIOContext->interruptContext );
5635 TI_DBG1(("satRequestSense: else fail 2\n"));
5638 TI_DBG4(("satRequestSense: else return success\n"));
5644 /*****************************************************************************/
5645 /*! \brief SAT implementation for SCSI REQUEST SENSE.
5647 * SAT implementation for SCSI REQUEST SENSE.
5648 * Sub function of satRequestSense
5650 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5651 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5652 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5653 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5654 * \param satIOContext_t: Pointer to the SAT IO Context
5656 * \return If command is started successfully
5657 * - \e tiSuccess: I/O request successfully initiated.
5658 * - \e tiBusy: No resources available, try again later.
5659 * - \e tiIONoDevice: Invalid device handle.
5660 * - \e tiError: Other errors.
5662 /*****************************************************************************/
5663 GLOBAL bit32 satRequestSense_1(
5665 tiIORequest_t *tiIORequest,
5666 tiDeviceHandle_t *tiDeviceHandle,
5667 tiScsiInitiatorRequest_t *tiScsiRequest,
5668 satIOContext_t *satIOContext)
5671 sends SAT_CHECK_POWER_MODE
5674 bit32 agRequestType;
5675 agsaFisRegHostToDevice_t *fis;
5677 TI_DBG4(("satRequestSense_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
5678 tiDeviceHandle, tiIORequest));
5680 fis = satIOContext->pFis;
5682 * Send the ATA CHECK POWER MODE command.
5684 fis->h.fisType = 0x27; /* Reg host to device */
5685 fis->h.c_pmPort = 0x80; /* C Bit is set */
5687 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */
5688 fis->h.features = 0;
5693 fis->d.lbaLowExp = 0;
5694 fis->d.lbaMidExp = 0;
5695 fis->d.lbaHighExp = 0;
5696 fis->d.featuresExp = 0;
5697 fis->d.sectorCount = 0;
5698 fis->d.sectorCountExp = 0;
5699 fis->d.reserved4 = 0;
5700 fis->d.control = 0; /* FIS HOB bit clear */
5701 fis->d.reserved5 = 0;
5703 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5705 /* Initialize CB for SATA completion.
5707 satIOContext->satCompleteCB = &satRequestSenseCB;
5710 * Prepare SGL and send FIS to LL layer.
5712 satIOContext->reqType = agRequestType; /* Save it */
5715 TI_DBG4(("satRequestSense_1: agSgl1.len %d\n", tiScsiRequest->agSgl1.len));
5717 TI_DBG4(("satRequestSense_1: agSgl1.upper %d\n", tiScsiRequest->agSgl1.upper));
5719 TI_DBG4(("satRequestSense_1: agSgl1.lower %d\n", tiScsiRequest->agSgl1.lower));
5721 TI_DBG4(("satRequestSense_1: agSgl1.type %d\n", tiScsiRequest->agSgl1.type));
5723 // tdhexdump("satRequestSense_1", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
5725 status = sataLLIOStart( tiRoot,
5737 /*****************************************************************************/
5738 /*! \brief SAT implementation for SCSI INQUIRY.
5740 * SAT implementation for SCSI INQUIRY.
5742 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5743 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5744 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5745 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5746 * \param satIOContext_t: Pointer to the SAT IO Context
5748 * \return If command is started successfully
5749 * - \e tiSuccess: I/O request successfully initiated.
5750 * - \e tiBusy: No resources available, try again later.
5751 * - \e tiIONoDevice: Invalid device handle.
5752 * - \e tiError: Other errors.
5754 /*****************************************************************************/
5755 GLOBAL bit32 satInquiry(
5757 tiIORequest_t *tiIORequest,
5758 tiDeviceHandle_t *tiDeviceHandle,
5759 tiScsiInitiatorRequest_t *tiScsiRequest,
5760 satIOContext_t *satIOContext)
5763 CMDDT bit is obsolete in SPC-3 and this is assumed in SAT revision 8
5765 scsiRspSense_t *pSense;
5766 tiIniScsiCmnd_t *scsiCmnd;
5767 satDeviceData_t *pSatDevData;
5770 TI_DBG5(("satInquiry: start\n"));
5771 TI_DBG5(("satInquiry entry: tiDeviceHandle=%p tiIORequest=%p\n",
5772 tiDeviceHandle, tiIORequest));
5773 pSense = satIOContext->pSense;
5774 scsiCmnd = &tiScsiRequest->scsiCmnd;
5775 pSatDevData = satIOContext->pSatDevData;
5776 TI_DBG5(("satInquiry: pSatDevData=%p\n", pSatDevData));
5777 //tdhexdump("satInquiry", (bit8 *)scsiCmnd->cdb, 6);
5778 /* checking CONTROL */
5779 /* NACA == 1 or LINK == 1*/
5780 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
5782 satSetSensePayload( pSense,
5783 SCSI_SNSKEY_ILLEGAL_REQUEST,
5785 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5787 ostiInitiatorIOCompleted( tiRoot,
5790 SCSI_STAT_CHECK_CONDITION,
5791 satIOContext->pTiSenseData,
5792 satIOContext->interruptContext );
5793 TI_DBG2(("satInquiry: return control\n"));
5797 /* checking EVPD and Allocation Length */
5798 /* SPC-4 spec 6.4 p141 */
5799 /* EVPD bit == 0 && PAGE CODE != 0 */
5800 if ( !(scsiCmnd->cdb[1] & SCSI_EVPD_MASK) &&
5801 (scsiCmnd->cdb[2] != 0)
5804 satSetSensePayload( pSense,
5805 SCSI_SNSKEY_ILLEGAL_REQUEST,
5807 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5809 ostiInitiatorIOCompleted( tiRoot,
5812 SCSI_STAT_CHECK_CONDITION,
5813 satIOContext->pTiSenseData,
5814 satIOContext->interruptContext );
5815 TI_DBG1(("satInquiry: return EVPD and PAGE CODE\n"));
5818 TI_DBG6(("satInquiry: allocation length 0x%x %d\n", ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4], ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4]));
5820 /* convert OS IO to TD internal IO */
5821 if ( pSatDevData->IDDeviceValid == agFALSE)
5823 status = satStartIDDev(
5830 TI_DBG6(("satInquiry: end status %d\n", status));
5835 TI_DBG6(("satInquiry: calling satInquiryIntCB\n"));
5850 /*****************************************************************************/
5851 /*! \brief SAT implementation for SCSI satReadCapacity10.
5853 * SAT implementation for SCSI satReadCapacity10.
5855 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5856 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5857 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5858 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5859 * \param satIOContext_t: Pointer to the SAT IO Context
5861 * \return If command is started successfully
5862 * - \e tiSuccess: I/O request successfully initiated.
5863 * - \e tiBusy: No resources available, try again later.
5864 * - \e tiIONoDevice: Invalid device handle.
5865 * - \e tiError: Other errors.
5867 /*****************************************************************************/
5868 GLOBAL bit32 satReadCapacity10(
5870 tiIORequest_t *tiIORequest,
5871 tiDeviceHandle_t *tiDeviceHandle,
5872 tiScsiInitiatorRequest_t *tiScsiRequest,
5873 satIOContext_t *satIOContext)
5875 scsiRspSense_t *pSense;
5876 tiIniScsiCmnd_t *scsiCmnd;
5878 satDeviceData_t *pSatDevData;
5879 agsaSATAIdentifyData_t *pSATAIdData;
5884 TI_DBG5(("satReadCapacity10: start: tiDeviceHandle=%p tiIORequest=%p\n",
5885 tiDeviceHandle, tiIORequest));
5887 pSense = satIOContext->pSense;
5888 pVirtAddr = (bit8 *) tiScsiRequest->sglVirtualAddr;
5889 scsiCmnd = &tiScsiRequest->scsiCmnd;
5890 pSatDevData = satIOContext->pSatDevData;
5891 pSATAIdData = &pSatDevData->satIdentifyData;
5894 /* checking CONTROL */
5895 /* NACA == 1 or LINK == 1*/
5896 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
5898 satSetSensePayload( pSense,
5899 SCSI_SNSKEY_ILLEGAL_REQUEST,
5901 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5904 ostiInitiatorIOCompleted( tiRoot,
5907 SCSI_STAT_CHECK_CONDITION,
5908 satIOContext->pTiSenseData,
5909 satIOContext->interruptContext );
5911 TI_DBG1(("satReadCapacity10: return control\n"));
5917 * If Logical block address is not set to zero, return error
5919 if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]))
5921 TI_DBG1(("satReadCapacity10 *** ERROR *** logical address non zero, tiDeviceHandle=%p tiIORequest=%p\n",
5922 tiDeviceHandle, tiIORequest));
5924 satSetSensePayload( pSense,
5925 SCSI_SNSKEY_ILLEGAL_REQUEST,
5927 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5930 ostiInitiatorIOCompleted( tiRoot,
5933 SCSI_STAT_CHECK_CONDITION,
5934 satIOContext->pTiSenseData,
5935 satIOContext->interruptContext );
5941 * If PMI bit is not zero, return error
5943 if ( ((scsiCmnd->cdb[8]) & SCSI_READ_CAPACITY10_PMI_MASK) != 0 )
5945 TI_DBG1(("satReadCapacity10 *** ERROR *** PMI is not zero, tiDeviceHandle=%p tiIORequest=%p\n",
5946 tiDeviceHandle, tiIORequest));
5948 satSetSensePayload( pSense,
5949 SCSI_SNSKEY_ILLEGAL_REQUEST,
5951 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5954 ostiInitiatorIOCompleted( tiRoot,
5957 SCSI_STAT_CHECK_CONDITION,
5958 satIOContext->pTiSenseData,
5959 satIOContext->interruptContext );
5965 filling in Read Capacity parameter data
5966 saved identify device has been already flipped
5967 See ATA spec p125 and p136 and SBC spec p54
5970 * If 48-bit addressing is supported, set capacity information from Identify
5971 * Device Word 100-103.
5973 if (pSatDevData->sat48BitSupport == agTRUE)
5976 * Setting RETURNED LOGICAL BLOCK ADDRESS in READ CAPACITY(10) response data:
5977 * SBC-2 specifies that if the capacity exceeded the 4-byte RETURNED LOGICAL
5978 * BLOCK ADDRESS in READ CAPACITY(10) parameter data, the the RETURNED LOGICAL
5979 * BLOCK ADDRESS should be set to 0xFFFFFFFF so the application client would
5980 * then issue a READ CAPACITY(16) command.
5982 /* ATA Identify Device information word 100 - 103 */
5983 if ( (pSATAIdData->maxLBA32_47 != 0 ) || (pSATAIdData->maxLBA48_63 != 0))
5985 pVirtAddr[0] = 0xFF; /* MSB number of block */
5986 pVirtAddr[1] = 0xFF;
5987 pVirtAddr[2] = 0xFF;
5988 pVirtAddr[3] = 0xFF; /* LSB number of block */
5989 TI_DBG1(("satReadCapacity10: returns 0xFFFFFFFF\n"));
5991 else /* Fit the Readcapacity10 4-bytes response length */
5993 lastLba = (((pSATAIdData->maxLBA16_31) << 16) ) |
5994 (pSATAIdData->maxLBA0_15);
5995 lastLba = lastLba - 1; /* LBA starts from zero */
5999 lastLba = lastLba - (512*10) - 1;
6003 pVirtAddr[0] = (bit8)((lastLba >> 24) & 0xFF); /* MSB */
6004 pVirtAddr[1] = (bit8)((lastLba >> 16) & 0xFF);
6005 pVirtAddr[2] = (bit8)((lastLba >> 8) & 0xFF);
6006 pVirtAddr[3] = (bit8)((lastLba ) & 0xFF); /* LSB */
6008 TI_DBG3(("satReadCapacity10: lastLba is 0x%x %d\n", lastLba, lastLba));
6009 TI_DBG3(("satReadCapacity10: LBA 0 is 0x%x %d\n", pVirtAddr[0], pVirtAddr[0]));
6010 TI_DBG3(("satReadCapacity10: LBA 1 is 0x%x %d\n", pVirtAddr[1], pVirtAddr[1]));
6011 TI_DBG3(("satReadCapacity10: LBA 2 is 0x%x %d\n", pVirtAddr[2], pVirtAddr[2]));
6012 TI_DBG3(("satReadCapacity10: LBA 3 is 0x%x %d\n", pVirtAddr[3], pVirtAddr[3]));
6018 * For 28-bit addressing, set capacity information from Identify
6019 * Device Word 60-61.
6023 /* ATA Identify Device information word 60 - 61 */
6024 lastLba = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
6025 (pSATAIdData->numOfUserAddressableSectorsLo);
6026 lastLba = lastLba - 1; /* LBA starts from zero */
6028 pVirtAddr[0] = (bit8)((lastLba >> 24) & 0xFF); /* MSB */
6029 pVirtAddr[1] = (bit8)((lastLba >> 16) & 0xFF);
6030 pVirtAddr[2] = (bit8)((lastLba >> 8) & 0xFF);
6031 pVirtAddr[3] = (bit8)((lastLba ) & 0xFF); /* LSB */
6034 if (((pSATAIdData->word104_107[2]) & 0x1000) == 0)
6036 TI_DBG5(("satReadCapacity10: Default Block Length is 512\n"));
6038 * Set the block size, fixed at 512 bytes.
6040 pVirtAddr[4] = 0x00; /* MSB block size in bytes */
6041 pVirtAddr[5] = 0x00;
6042 pVirtAddr[6] = 0x02;
6043 pVirtAddr[7] = 0x00; /* LSB block size in bytes */
6047 word118 = pSATAIdData->word112_126[6];
6048 word117 = pSATAIdData->word112_126[5];
6050 word117_118 = (word118 << 16) + word117;
6051 word117_118 = word117_118 * 2;
6052 pVirtAddr[4] = (bit8)((word117_118 >> 24) & 0xFF); /* MSB block size in bytes */
6053 pVirtAddr[5] = (bit8)((word117_118 >> 16) & 0xFF);
6054 pVirtAddr[6] = (bit8)((word117_118 >> 8) & 0xFF);
6055 pVirtAddr[7] = (bit8)(word117_118 & 0xFF); /* LSB block size in bytes */
6057 TI_DBG1(("satReadCapacity10: Nondefault word118 %d 0x%x \n", word118, word118));
6058 TI_DBG1(("satReadCapacity10: Nondefault word117 %d 0x%x \n", word117, word117));
6059 TI_DBG1(("satReadCapacity10: Nondefault Block Length is %d 0x%x \n",word117_118, word117_118));
6063 /* fill in MAX LBA, which is used in satSendDiagnostic_1() */
6064 pSatDevData->satMaxLBA[0] = 0; /* MSB */
6065 pSatDevData->satMaxLBA[1] = 0;
6066 pSatDevData->satMaxLBA[2] = 0;
6067 pSatDevData->satMaxLBA[3] = 0;
6068 pSatDevData->satMaxLBA[4] = pVirtAddr[0];
6069 pSatDevData->satMaxLBA[5] = pVirtAddr[1];
6070 pSatDevData->satMaxLBA[6] = pVirtAddr[2];
6071 pSatDevData->satMaxLBA[7] = pVirtAddr[3]; /* LSB */
6074 TI_DBG4(("satReadCapacity10 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , tiDeviceHandle=%p tiIORequest=%p\n",
6075 pVirtAddr[0], pVirtAddr[1], pVirtAddr[2], pVirtAddr[3],
6076 pVirtAddr[4], pVirtAddr[5], pVirtAddr[6], pVirtAddr[7],
6077 tiDeviceHandle, tiIORequest));
6081 * Send the completion response now.
6083 ostiInitiatorIOCompleted( tiRoot,
6088 satIOContext->interruptContext);
6093 /*****************************************************************************/
6094 /*! \brief SAT implementation for SCSI satReadCapacity16.
6096 * SAT implementation for SCSI satReadCapacity16.
6098 * \param tiRoot: Pointer to TISA initiator driver/port instance.
6099 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
6100 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
6101 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
6102 * \param satIOContext_t: Pointer to the SAT IO Context
6104 * \return If command is started successfully
6105 * - \e tiSuccess: I/O request successfully initiated.
6106 * - \e tiBusy: No resources available, try again later.
6107 * - \e tiIONoDevice: Invalid device handle.
6108 * - \e tiError: Other errors.
6110 /*****************************************************************************/
6111 GLOBAL bit32 satReadCapacity16(
6113 tiIORequest_t *tiIORequest,
6114 tiDeviceHandle_t *tiDeviceHandle,
6115 tiScsiInitiatorRequest_t *tiScsiRequest,
6116 satIOContext_t *satIOContext)
6119 scsiRspSense_t *pSense;
6120 tiIniScsiCmnd_t *scsiCmnd;
6122 satDeviceData_t *pSatDevData;
6123 agsaSATAIdentifyData_t *pSATAIdData;
6125 bit32 allocationLen;
6126 bit32 readCapacityLen = 32;
6128 TI_DBG5(("satReadCapacity16 start: tiDeviceHandle=%p tiIORequest=%p\n",
6129 tiDeviceHandle, tiIORequest));
6131 pSense = satIOContext->pSense;
6132 pVirtAddr = (bit8 *) tiScsiRequest->sglVirtualAddr;
6133 scsiCmnd = &tiScsiRequest->scsiCmnd;
6134 pSatDevData = satIOContext->pSatDevData;
6135 pSATAIdData = &pSatDevData->satIdentifyData;
6137 /* Find the buffer size allocated by Initiator */
6138 allocationLen = (((bit32)scsiCmnd->cdb[10]) << 24) |
6139 (((bit32)scsiCmnd->cdb[11]) << 16) |
6140 (((bit32)scsiCmnd->cdb[12]) << 8 ) |
6141 (((bit32)scsiCmnd->cdb[13]) );
6144 if (allocationLen < readCapacityLen)
6146 TI_DBG1(("satReadCapacity16 *** ERROR *** insufficient len=0x%x readCapacityLen=0x%x\n", allocationLen, readCapacityLen));
6148 satSetSensePayload( pSense,
6149 SCSI_SNSKEY_ILLEGAL_REQUEST,
6151 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6154 ostiInitiatorIOCompleted( tiRoot,
6157 SCSI_STAT_CHECK_CONDITION,
6158 satIOContext->pTiSenseData,
6159 satIOContext->interruptContext );
6164 /* checking CONTROL */
6165 /* NACA == 1 or LINK == 1*/
6166 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
6168 satSetSensePayload( pSense,
6169 SCSI_SNSKEY_ILLEGAL_REQUEST,
6171 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6174 ostiInitiatorIOCompleted( tiRoot,
6177 SCSI_STAT_CHECK_CONDITION,
6178 satIOContext->pTiSenseData,
6179 satIOContext->interruptContext );
6181 TI_DBG1(("satReadCapacity16: return control\n"));
6186 * If Logical blcok address is not set to zero, return error
6188 if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]) ||
6189 (scsiCmnd->cdb[6] || scsiCmnd->cdb[7] || scsiCmnd->cdb[8] || scsiCmnd->cdb[9]) )
6191 TI_DBG1(("satReadCapacity16 *** ERROR *** logical address non zero, tiDeviceHandle=%p tiIORequest=%p\n",
6192 tiDeviceHandle, tiIORequest));
6194 satSetSensePayload( pSense,
6195 SCSI_SNSKEY_ILLEGAL_REQUEST,
6197 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6200 ostiInitiatorIOCompleted( tiRoot,
6203 SCSI_STAT_CHECK_CONDITION,
6204 satIOContext->pTiSenseData,
6205 satIOContext->interruptContext );
6211 * If PMI bit is not zero, return error
6213 if ( ((scsiCmnd->cdb[14]) & SCSI_READ_CAPACITY16_PMI_MASK) != 0 )
6215 TI_DBG1(("satReadCapacity16 *** ERROR *** PMI is not zero, tiDeviceHandle=%p tiIORequest=%p\n",
6216 tiDeviceHandle, tiIORequest));
6218 satSetSensePayload( pSense,
6219 SCSI_SNSKEY_ILLEGAL_REQUEST,
6221 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6224 ostiInitiatorIOCompleted( tiRoot,
6227 SCSI_STAT_CHECK_CONDITION,
6228 satIOContext->pTiSenseData,
6229 satIOContext->interruptContext );
6235 filling in Read Capacity parameter data
6239 * If 48-bit addressing is supported, set capacity information from Identify
6240 * Device Word 100-103.
6242 if (pSatDevData->sat48BitSupport == agTRUE)
6244 pVirtAddr[0] = (bit8)(((pSATAIdData->maxLBA48_63) >> 8) & 0xff); /* MSB */
6245 pVirtAddr[1] = (bit8)((pSATAIdData->maxLBA48_63) & 0xff);
6246 pVirtAddr[2] = (bit8)(((pSATAIdData->maxLBA32_47) >> 8) & 0xff);
6247 pVirtAddr[3] = (bit8)((pSATAIdData->maxLBA32_47) & 0xff);
6249 lastLbaLo = (((pSATAIdData->maxLBA16_31) << 16) ) | (pSATAIdData->maxLBA0_15);
6250 lastLbaLo = lastLbaLo - 1; /* LBA starts from zero */
6252 pVirtAddr[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
6253 pVirtAddr[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
6254 pVirtAddr[6] = (bit8)((lastLbaLo >> 8) & 0xFF);
6255 pVirtAddr[7] = (bit8)((lastLbaLo ) & 0xFF); /* LSB */
6260 * For 28-bit addressing, set capacity information from Identify
6261 * Device Word 60-61.
6265 pVirtAddr[0] = 0; /* MSB */
6270 lastLbaLo = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
6271 (pSATAIdData->numOfUserAddressableSectorsLo);
6272 lastLbaLo = lastLbaLo - 1; /* LBA starts from zero */
6274 pVirtAddr[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
6275 pVirtAddr[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
6276 pVirtAddr[6] = (bit8)((lastLbaLo >> 8) & 0xFF);
6277 pVirtAddr[7] = (bit8)((lastLbaLo ) & 0xFF); /* LSB */
6282 * Set the block size, fixed at 512 bytes.
6284 pVirtAddr[8] = 0x00; /* MSB block size in bytes */
6285 pVirtAddr[9] = 0x00;
6286 pVirtAddr[10] = 0x02;
6287 pVirtAddr[11] = 0x00; /* LSB block size in bytes */
6290 /* fill in MAX LBA, which is used in satSendDiagnostic_1() */
6291 pSatDevData->satMaxLBA[0] = pVirtAddr[0]; /* MSB */
6292 pSatDevData->satMaxLBA[1] = pVirtAddr[1];
6293 pSatDevData->satMaxLBA[2] = pVirtAddr[2];
6294 pSatDevData->satMaxLBA[3] = pVirtAddr[3];
6295 pSatDevData->satMaxLBA[4] = pVirtAddr[4];
6296 pSatDevData->satMaxLBA[5] = pVirtAddr[5];
6297 pSatDevData->satMaxLBA[6] = pVirtAddr[6];
6298 pSatDevData->satMaxLBA[7] = pVirtAddr[7]; /* LSB */
6300 TI_DBG5(("satReadCapacity16 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , tiDeviceHandle=%p tiIORequest=%p\n",
6301 pVirtAddr[0], pVirtAddr[1], pVirtAddr[2], pVirtAddr[3],
6302 pVirtAddr[4], pVirtAddr[5], pVirtAddr[6], pVirtAddr[7],
6303 pVirtAddr[8], pVirtAddr[9], pVirtAddr[10], pVirtAddr[11],
6304 tiDeviceHandle, tiIORequest));
6308 pVirtAddr[i] = 0x00;
6312 * Send the completion response now.
6314 if (allocationLen > readCapacityLen)
6317 TI_DBG1(("satReadCapacity16 reporting underrun readCapacityLen=0x%x allocationLen=0x%x \n", readCapacityLen, allocationLen));
6319 ostiInitiatorIOCompleted( tiRoot,
6322 allocationLen - readCapacityLen,
6324 satIOContext->interruptContext );
6330 ostiInitiatorIOCompleted( tiRoot,
6335 satIOContext->interruptContext);
6342 /*****************************************************************************/
6343 /*! \brief SAT implementation for SCSI MODE SENSE (6).
6345 * SAT implementation for SCSI MODE SENSE (6).
6347 * \param tiRoot: Pointer to TISA initiator driver/port instance.
6348 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
6349 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
6350 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
6351 * \param satIOContext_t: Pointer to the SAT IO Context
6353 * \return If command is started successfully
6354 * - \e tiSuccess: I/O request successfully initiated.
6355 * - \e tiBusy: No resources available, try again later.
6356 * - \e tiIONoDevice: Invalid device handle.
6357 * - \e tiError: Other errors.
6359 /*****************************************************************************/
6360 GLOBAL bit32 satModeSense6(
6362 tiIORequest_t *tiIORequest,
6363 tiDeviceHandle_t *tiDeviceHandle,
6364 tiScsiInitiatorRequest_t *tiScsiRequest,
6365 satIOContext_t *satIOContext)
6368 scsiRspSense_t *pSense;
6370 tiIniScsiCmnd_t *scsiCmnd;
6371 bit32 pageSupported;
6373 bit8 *pModeSense; /* Mode Sense data buffer */
6374 satDeviceData_t *pSatDevData;
6376 bit8 AllPages[MODE_SENSE6_RETURN_ALL_PAGES_LEN];
6377 bit8 Control[MODE_SENSE6_CONTROL_PAGE_LEN];
6378 bit8 RWErrorRecovery[MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN];
6379 bit8 Caching[MODE_SENSE6_CACHING_LEN];
6380 bit8 InfoExceptionCtrl[MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN];
6384 TI_DBG5(("satModeSense6 entry: tiDeviceHandle=%p tiIORequest=%p\n",
6385 tiDeviceHandle, tiIORequest));
6387 pSense = satIOContext->pSense;
6388 scsiCmnd = &tiScsiRequest->scsiCmnd;
6389 pModeSense = (bit8 *) tiScsiRequest->sglVirtualAddr;
6390 pSatDevData = satIOContext->pSatDevData;
6392 //tdhexdump("satModeSense6", (bit8 *)scsiCmnd->cdb, 6);
6393 /* checking CONTROL */
6394 /* NACA == 1 or LINK == 1*/
6395 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
6397 satSetSensePayload( pSense,
6398 SCSI_SNSKEY_ILLEGAL_REQUEST,
6400 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6403 ostiInitiatorIOCompleted( tiRoot,
6406 SCSI_STAT_CHECK_CONDITION,
6407 satIOContext->pTiSenseData,
6408 satIOContext->interruptContext );
6410 TI_DBG2(("satModeSense6: return control\n"));
6414 /* checking PC(Page Control)
6415 SAT revion 8, 8.5.3 p33 and 10.1.2, p66
6417 PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PC_MASK);
6420 satSetSensePayload( pSense,
6421 SCSI_SNSKEY_ILLEGAL_REQUEST,
6423 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6426 ostiInitiatorIOCompleted( tiRoot,
6429 SCSI_STAT_CHECK_CONDITION,
6430 satIOContext->pTiSenseData,
6431 satIOContext->interruptContext );
6433 TI_DBG1(("satModeSense6: return due to PC value pc 0x%x\n", PC >> 6));
6437 /* reading PAGE CODE */
6438 page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PAGE_CODE_MASK);
6441 TI_DBG5(("satModeSense6: page=0x%x, tiDeviceHandle=%p tiIORequest=%p\n",
6442 page, tiDeviceHandle, tiIORequest));
6444 requestLen = scsiCmnd->cdb[4];
6447 Based on page code value, returns a corresponding mode page
6448 note: no support for subpage
6453 case MODESENSE_RETURN_ALL_PAGES:
6454 case MODESENSE_CONTROL_PAGE: /* control */
6455 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
6456 case MODESENSE_CACHING: /* caching */
6457 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
6458 pageSupported = agTRUE;
6460 case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */
6462 pageSupported = agFALSE;
6466 if (pageSupported == agFALSE)
6469 TI_DBG1(("satModeSense6 *** ERROR *** not supported page 0x%x tiDeviceHandle=%p tiIORequest=%p\n",
6470 page, tiDeviceHandle, tiIORequest));
6472 satSetSensePayload( pSense,
6473 SCSI_SNSKEY_ILLEGAL_REQUEST,
6475 SCSI_SNSCODE_INVALID_COMMAND,
6478 ostiInitiatorIOCompleted( tiRoot,
6481 SCSI_STAT_CHECK_CONDITION,
6482 satIOContext->pTiSenseData,
6483 satIOContext->interruptContext );
6489 case MODESENSE_RETURN_ALL_PAGES:
6490 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_RETURN_ALL_PAGES_LEN);
6492 case MODESENSE_CONTROL_PAGE: /* control */
6493 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_CONTROL_PAGE_LEN);
6495 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
6496 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
6498 case MODESENSE_CACHING: /* caching */
6499 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_CACHING_LEN);
6501 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
6502 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
6505 TI_DBG1(("satModeSense6: default error page %d\n", page));
6509 if (page == MODESENSE_RETURN_ALL_PAGES)
6511 TI_DBG5(("satModeSense6: MODESENSE_RETURN_ALL_PAGES\n"));
6512 AllPages[0] = (bit8)(lenRead - 1);
6513 AllPages[1] = 0x00; /* default medium type (currently mounted medium type) */
6514 AllPages[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6515 AllPages[3] = 0x08; /* block descriptor length */
6518 * Fill-up direct-access device block-descriptor, SAT, Table 19
6522 AllPages[4] = 0x04; /* density-code : reserved for direct-access */
6523 /* number of blocks */
6524 AllPages[5] = 0x00; /* unspecified */
6525 AllPages[6] = 0x00; /* unspecified */
6526 AllPages[7] = 0x00; /* unspecified */
6528 AllPages[8] = 0x00; /* reserved */
6531 AllPages[10] = 0x02; /* Block size is always 512 bytes */
6532 AllPages[11] = 0x00;
6534 /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */
6535 AllPages[12] = 0x01; /* page code */
6536 AllPages[13] = 0x0A; /* page length */
6537 AllPages[14] = 0x40; /* ARRE is set */
6538 AllPages[15] = 0x00;
6539 AllPages[16] = 0x00;
6540 AllPages[17] = 0x00;
6541 AllPages[18] = 0x00;
6542 AllPages[19] = 0x00;
6543 AllPages[20] = 0x00;
6544 AllPages[21] = 0x00;
6545 AllPages[22] = 0x00;
6546 AllPages[23] = 0x00;
6547 /* MODESENSE_CACHING */
6548 AllPages[24] = 0x08; /* page code */
6549 AllPages[25] = 0x12; /* page length */
6551 if (pSatDevData->satWriteCacheEnabled == agTRUE)
6553 AllPages[26] = 0x04;/* WCE bit is set */
6557 AllPages[26] = 0x00;/* WCE bit is NOT set */
6560 AllPages[26] = 0x00;/* WCE bit is NOT set */
6562 AllPages[27] = 0x00;
6563 AllPages[28] = 0x00;
6564 AllPages[29] = 0x00;
6565 AllPages[30] = 0x00;
6566 AllPages[31] = 0x00;
6567 AllPages[32] = 0x00;
6568 AllPages[33] = 0x00;
6569 AllPages[34] = 0x00;
6570 AllPages[35] = 0x00;
6571 if (pSatDevData->satLookAheadEnabled == agTRUE)
6573 AllPages[36] = 0x00;/* DRA bit is NOT set */
6577 AllPages[36] = 0x20;/* DRA bit is set */
6579 AllPages[37] = 0x00;
6580 AllPages[38] = 0x00;
6581 AllPages[39] = 0x00;
6582 AllPages[40] = 0x00;
6583 AllPages[41] = 0x00;
6584 AllPages[42] = 0x00;
6585 AllPages[43] = 0x00;
6586 /* MODESENSE_CONTROL_PAGE */
6587 AllPages[44] = 0x0A; /* page code */
6588 AllPages[45] = 0x0A; /* page length */
6589 AllPages[46] = 0x02; /* only GLTSD bit is set */
6590 if (pSatDevData->satNCQ == agTRUE)
6592 AllPages[47] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
6596 AllPages[47] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
6598 AllPages[48] = 0x00;
6599 AllPages[49] = 0x00;
6600 AllPages[50] = 0x00; /* obsolete */
6601 AllPages[51] = 0x00; /* obsolete */
6602 AllPages[52] = 0xFF; /* Busy Timeout Period */
6603 AllPages[53] = 0xFF; /* Busy Timeout Period */
6604 AllPages[54] = 0x00; /* we don't support non-000b value for the self-test code */
6605 AllPages[55] = 0x00; /* we don't support non-000b value for the self-test code */
6606 /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */
6607 AllPages[56] = 0x1C; /* page code */
6608 AllPages[57] = 0x0A; /* page length */
6609 if (pSatDevData->satSMARTEnabled == agTRUE)
6611 AllPages[58] = 0x00;/* DEXCPT bit is NOT set */
6615 AllPages[58] = 0x08;/* DEXCPT bit is set */
6617 AllPages[59] = 0x00; /* We don't support MRIE */
6618 AllPages[60] = 0x00; /* Interval timer vendor-specific */
6619 AllPages[61] = 0x00;
6620 AllPages[62] = 0x00;
6621 AllPages[63] = 0x00;
6622 AllPages[64] = 0x00; /* REPORT-COUNT */
6623 AllPages[65] = 0x00;
6624 AllPages[66] = 0x00;
6625 AllPages[67] = 0x00;
6627 osti_memcpy(pModeSense, &AllPages, lenRead);
6629 else if (page == MODESENSE_CONTROL_PAGE)
6631 TI_DBG5(("satModeSense6: MODESENSE_CONTROL_PAGE\n"));
6632 Control[0] = MODE_SENSE6_CONTROL_PAGE_LEN - 1;
6633 Control[1] = 0x00; /* default medium type (currently mounted medium type) */
6634 Control[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6635 Control[3] = 0x08; /* block descriptor length */
6637 * Fill-up direct-access device block-descriptor, SAT, Table 19
6641 Control[4] = 0x04; /* density-code : reserved for direct-access */
6642 /* number of blocks */
6643 Control[5] = 0x00; /* unspecified */
6644 Control[6] = 0x00; /* unspecified */
6645 Control[7] = 0x00; /* unspecified */
6647 Control[8] = 0x00; /* reserved */
6650 Control[10] = 0x02; /* Block size is always 512 bytes */
6653 * Fill-up control mode page, SAT, Table 65
6655 Control[12] = 0x0A; /* page code */
6656 Control[13] = 0x0A; /* page length */
6657 Control[14] = 0x02; /* only GLTSD bit is set */
6658 if (pSatDevData->satNCQ == agTRUE)
6660 Control[15] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
6664 Control[15] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
6668 Control[18] = 0x00; /* obsolete */
6669 Control[19] = 0x00; /* obsolete */
6670 Control[20] = 0xFF; /* Busy Timeout Period */
6671 Control[21] = 0xFF; /* Busy Timeout Period */
6672 Control[22] = 0x00; /* we don't support non-000b value for the self-test code */
6673 Control[23] = 0x00; /* we don't support non-000b value for the self-test code */
6675 osti_memcpy(pModeSense, &Control, lenRead);
6678 else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
6680 TI_DBG5(("satModeSense6: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
6681 RWErrorRecovery[0] = MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN - 1;
6682 RWErrorRecovery[1] = 0x00; /* default medium type (currently mounted medium type) */
6683 RWErrorRecovery[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6684 RWErrorRecovery[3] = 0x08; /* block descriptor length */
6686 * Fill-up direct-access device block-descriptor, SAT, Table 19
6690 RWErrorRecovery[4] = 0x04; /* density-code : reserved for direct-access */
6691 /* number of blocks */
6692 RWErrorRecovery[5] = 0x00; /* unspecified */
6693 RWErrorRecovery[6] = 0x00; /* unspecified */
6694 RWErrorRecovery[7] = 0x00; /* unspecified */
6696 RWErrorRecovery[8] = 0x00; /* reserved */
6698 RWErrorRecovery[9] = 0x00;
6699 RWErrorRecovery[10] = 0x02; /* Block size is always 512 bytes */
6700 RWErrorRecovery[11] = 0x00;
6702 * Fill-up Read-Write Error Recovery mode page, SAT, Table 66
6704 RWErrorRecovery[12] = 0x01; /* page code */
6705 RWErrorRecovery[13] = 0x0A; /* page length */
6706 RWErrorRecovery[14] = 0x40; /* ARRE is set */
6707 RWErrorRecovery[15] = 0x00;
6708 RWErrorRecovery[16] = 0x00;
6709 RWErrorRecovery[17] = 0x00;
6710 RWErrorRecovery[18] = 0x00;
6711 RWErrorRecovery[19] = 0x00;
6712 RWErrorRecovery[20] = 0x00;
6713 RWErrorRecovery[21] = 0x00;
6714 RWErrorRecovery[22] = 0x00;
6715 RWErrorRecovery[23] = 0x00;
6717 osti_memcpy(pModeSense, &RWErrorRecovery, lenRead);
6720 else if (page == MODESENSE_CACHING)
6722 TI_DBG5(("satModeSense6: MODESENSE_CACHING\n"));
6724 if (requestLen == 4 && page == MODESENSE_CACHING)
6726 TI_DBG5(("satModeSense6: linux 2.6.8.24 support\n"));
6728 pModeSense[0] = 0x20 - 1; /* 32 - 1 */
6729 pModeSense[1] = 0x00; /* default medium type (currently mounted medium type) */
6730 pModeSense[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6731 pModeSense[3] = 0x08; /* block descriptor length */
6732 ostiInitiatorIOCompleted( tiRoot,
6737 satIOContext->interruptContext);
6740 Caching[0] = MODE_SENSE6_CACHING_LEN - 1;
6741 Caching[1] = 0x00; /* default medium type (currently mounted medium type) */
6742 Caching[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6743 Caching[3] = 0x08; /* block descriptor length */
6745 * Fill-up direct-access device block-descriptor, SAT, Table 19
6749 Caching[4] = 0x04; /* density-code : reserved for direct-access */
6750 /* number of blocks */
6751 Caching[5] = 0x00; /* unspecified */
6752 Caching[6] = 0x00; /* unspecified */
6753 Caching[7] = 0x00; /* unspecified */
6755 Caching[8] = 0x00; /* reserved */
6758 Caching[10] = 0x02; /* Block size is always 512 bytes */
6761 * Fill-up Caching mode page, SAT, Table 67
6764 Caching[12] = 0x08; /* page code */
6765 Caching[13] = 0x12; /* page length */
6767 if (pSatDevData->satWriteCacheEnabled == agTRUE)
6769 Caching[14] = 0x04;/* WCE bit is set */
6773 Caching[14] = 0x00;/* WCE bit is NOT set */
6776 Caching[14] = 0x00;/* WCE bit is NOT set */
6787 if (pSatDevData->satLookAheadEnabled == agTRUE)
6789 Caching[24] = 0x00;/* DRA bit is NOT set */
6793 Caching[24] = 0x20;/* DRA bit is set */
6803 osti_memcpy(pModeSense, &Caching, lenRead);
6806 else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
6808 TI_DBG5(("satModeSense6: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
6809 InfoExceptionCtrl[0] = MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN - 1;
6810 InfoExceptionCtrl[1] = 0x00; /* default medium type (currently mounted medium type) */
6811 InfoExceptionCtrl[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6812 InfoExceptionCtrl[3] = 0x08; /* block descriptor length */
6814 * Fill-up direct-access device block-descriptor, SAT, Table 19
6818 InfoExceptionCtrl[4] = 0x04; /* density-code : reserved for direct-access */
6819 /* number of blocks */
6820 InfoExceptionCtrl[5] = 0x00; /* unspecified */
6821 InfoExceptionCtrl[6] = 0x00; /* unspecified */
6822 InfoExceptionCtrl[7] = 0x00; /* unspecified */
6824 InfoExceptionCtrl[8] = 0x00; /* reserved */
6826 InfoExceptionCtrl[9] = 0x00;
6827 InfoExceptionCtrl[10] = 0x02; /* Block size is always 512 bytes */
6828 InfoExceptionCtrl[11] = 0x00;
6830 * Fill-up informational-exceptions control mode page, SAT, Table 68
6832 InfoExceptionCtrl[12] = 0x1C; /* page code */
6833 InfoExceptionCtrl[13] = 0x0A; /* page length */
6834 if (pSatDevData->satSMARTEnabled == agTRUE)
6836 InfoExceptionCtrl[14] = 0x00;/* DEXCPT bit is NOT set */
6840 InfoExceptionCtrl[14] = 0x08;/* DEXCPT bit is set */
6842 InfoExceptionCtrl[15] = 0x00; /* We don't support MRIE */
6843 InfoExceptionCtrl[16] = 0x00; /* Interval timer vendor-specific */
6844 InfoExceptionCtrl[17] = 0x00;
6845 InfoExceptionCtrl[18] = 0x00;
6846 InfoExceptionCtrl[19] = 0x00;
6847 InfoExceptionCtrl[20] = 0x00; /* REPORT-COUNT */
6848 InfoExceptionCtrl[21] = 0x00;
6849 InfoExceptionCtrl[22] = 0x00;
6850 InfoExceptionCtrl[23] = 0x00;
6851 osti_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
6857 TI_DBG1(("satModeSense6: Error page %d\n", page));
6858 satSetSensePayload( pSense,
6859 SCSI_SNSKEY_ILLEGAL_REQUEST,
6861 SCSI_SNSCODE_INVALID_COMMAND,
6864 ostiInitiatorIOCompleted( tiRoot,
6867 SCSI_STAT_CHECK_CONDITION,
6868 satIOContext->pTiSenseData,
6869 satIOContext->interruptContext );
6873 /* there can be only underrun not overrun in error case */
6874 if (requestLen > lenRead)
6876 TI_DBG6(("satModeSense6 reporting underrun lenRead=0x%x requestLen=0x%x tiIORequest=%p\n", lenRead, requestLen, tiIORequest));
6878 ostiInitiatorIOCompleted( tiRoot,
6881 requestLen - lenRead,
6883 satIOContext->interruptContext );
6889 ostiInitiatorIOCompleted( tiRoot,
6894 satIOContext->interruptContext);
6901 /*****************************************************************************/
6902 /*! \brief SAT implementation for SCSI MODE SENSE (10).
6904 * SAT implementation for SCSI MODE SENSE (10).
6906 * \param tiRoot: Pointer to TISA initiator driver/port instance.
6907 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
6908 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
6909 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
6910 * \param satIOContext_t: Pointer to the SAT IO Context
6912 * \return If command is started successfully
6913 * - \e tiSuccess: I/O request successfully initiated.
6914 * - \e tiBusy: No resources available, try again later.
6915 * - \e tiIONoDevice: Invalid device handle.
6916 * - \e tiError: Other errors.
6918 /*****************************************************************************/
6919 GLOBAL bit32 satModeSense10(
6921 tiIORequest_t *tiIORequest,
6922 tiDeviceHandle_t *tiDeviceHandle,
6923 tiScsiInitiatorRequest_t *tiScsiRequest,
6924 satIOContext_t *satIOContext)
6927 scsiRspSense_t *pSense;
6929 tiIniScsiCmnd_t *scsiCmnd;
6930 bit32 pageSupported;
6932 bit8 *pModeSense; /* Mode Sense data buffer */
6933 satDeviceData_t *pSatDevData;
6934 bit8 PC; /* page control */
6935 bit8 LLBAA; /* Long LBA Accepted */
6937 bit8 AllPages[MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN];
6938 bit8 Control[MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN];
6939 bit8 RWErrorRecovery[MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN];
6940 bit8 Caching[MODE_SENSE10_CACHING_LLBAA_LEN];
6941 bit8 InfoExceptionCtrl[MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN];
6944 TI_DBG5(("satModeSense10 entry: tiDeviceHandle=%p tiIORequest=%p\n",
6945 tiDeviceHandle, tiIORequest));
6947 pSense = satIOContext->pSense;
6948 scsiCmnd = &tiScsiRequest->scsiCmnd;
6949 pModeSense = (bit8 *) tiScsiRequest->sglVirtualAddr;
6950 pSatDevData = satIOContext->pSatDevData;
6952 /* checking CONTROL */
6953 /* NACA == 1 or LINK == 1*/
6954 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
6956 satSetSensePayload( pSense,
6957 SCSI_SNSKEY_ILLEGAL_REQUEST,
6959 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6962 ostiInitiatorIOCompleted( tiRoot,
6965 SCSI_STAT_CHECK_CONDITION,
6966 satIOContext->pTiSenseData,
6967 satIOContext->interruptContext );
6969 TI_DBG2(("satModeSense10: return control\n"));
6973 /* checking PC(Page Control)
6974 SAT revion 8, 8.5.3 p33 and 10.1.2, p66
6976 PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PC_MASK);
6979 satSetSensePayload( pSense,
6980 SCSI_SNSKEY_ILLEGAL_REQUEST,
6982 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6985 ostiInitiatorIOCompleted( tiRoot,
6988 SCSI_STAT_CHECK_CONDITION,
6989 satIOContext->pTiSenseData,
6990 satIOContext->interruptContext );
6992 TI_DBG1(("satModeSense10: return due to PC value pc 0x%x\n", PC));
6995 /* finding LLBAA bit */
6996 LLBAA = (bit8)((scsiCmnd->cdb[1]) & SCSI_MODE_SENSE10_LLBAA_MASK);
6997 /* reading PAGE CODE */
6998 page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PAGE_CODE_MASK);
7000 TI_DBG5(("satModeSense10: page=0x%x, tiDeviceHandle=%p tiIORequest=%p\n",
7001 page, tiDeviceHandle, tiIORequest));
7002 requestLen = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
7005 Based on page code value, returns a corresponding mode page
7006 note: no support for subpage
7010 case MODESENSE_RETURN_ALL_PAGES: /* return all pages */
7011 case MODESENSE_CONTROL_PAGE: /* control */
7012 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
7013 case MODESENSE_CACHING: /* caching */
7014 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
7015 pageSupported = agTRUE;
7017 case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */
7019 pageSupported = agFALSE;
7023 if (pageSupported == agFALSE)
7026 TI_DBG1(("satModeSense10 *** ERROR *** not supported page 0x%x tiDeviceHandle=%p tiIORequest=%p\n",
7027 page, tiDeviceHandle, tiIORequest));
7029 satSetSensePayload( pSense,
7030 SCSI_SNSKEY_ILLEGAL_REQUEST,
7032 SCSI_SNSCODE_INVALID_COMMAND,
7035 ostiInitiatorIOCompleted( tiRoot,
7038 SCSI_STAT_CHECK_CONDITION,
7039 satIOContext->pTiSenseData,
7040 satIOContext->interruptContext );
7046 case MODESENSE_RETURN_ALL_PAGES:
7049 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN);
7053 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_RETURN_ALL_PAGES_LEN);
7056 case MODESENSE_CONTROL_PAGE: /* control */
7059 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN);
7063 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CONTROL_PAGE_LEN);
7066 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
7069 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN);
7073 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
7076 case MODESENSE_CACHING: /* caching */
7079 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CACHING_LLBAA_LEN);
7083 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CACHING_LEN);
7086 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
7089 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN);
7093 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
7097 TI_DBG1(("satModeSense10: default error page %d\n", page));
7101 if (page == MODESENSE_RETURN_ALL_PAGES)
7103 TI_DBG5(("satModeSense10: MODESENSE_RETURN_ALL_PAGES\n"));
7105 AllPages[1] = (bit8)(lenRead - 2);
7106 AllPages[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7107 AllPages[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7110 AllPages[4] = 0x00; /* reserved and LONGLBA */
7111 AllPages[4] = (bit8)(AllPages[4] | 0x1); /* LONGLBA is set */
7115 AllPages[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7117 AllPages[5] = 0x00; /* reserved */
7118 AllPages[6] = 0x00; /* block descriptot length */
7121 AllPages[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7125 AllPages[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7129 * Fill-up direct-access device block-descriptor, SAT, Table 19
7135 AllPages[8] = 0x04; /* density-code : reserved for direct-access */
7136 /* number of blocks */
7137 AllPages[9] = 0x00; /* unspecified */
7138 AllPages[10] = 0x00; /* unspecified */
7139 AllPages[11] = 0x00; /* unspecified */
7140 AllPages[12] = 0x00; /* unspecified */
7141 AllPages[13] = 0x00; /* unspecified */
7142 AllPages[14] = 0x00; /* unspecified */
7143 AllPages[15] = 0x00; /* unspecified */
7145 AllPages[16] = 0x00; /* reserved */
7146 AllPages[17] = 0x00; /* reserved */
7147 AllPages[18] = 0x00; /* reserved */
7148 AllPages[19] = 0x00; /* reserved */
7150 AllPages[20] = 0x00;
7151 AllPages[21] = 0x00;
7152 AllPages[22] = 0x02; /* Block size is always 512 bytes */
7153 AllPages[23] = 0x00;
7158 AllPages[8] = 0x04; /* density-code : reserved for direct-access */
7159 /* number of blocks */
7160 AllPages[9] = 0x00; /* unspecified */
7161 AllPages[10] = 0x00; /* unspecified */
7162 AllPages[11] = 0x00; /* unspecified */
7164 AllPages[12] = 0x00; /* reserved */
7166 AllPages[13] = 0x00;
7167 AllPages[14] = 0x02; /* Block size is always 512 bytes */
7168 AllPages[15] = 0x00;
7179 /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */
7180 AllPages[index+0] = 0x01; /* page code */
7181 AllPages[index+1] = 0x0A; /* page length */
7182 AllPages[index+2] = 0x40; /* ARRE is set */
7183 AllPages[index+3] = 0x00;
7184 AllPages[index+4] = 0x00;
7185 AllPages[index+5] = 0x00;
7186 AllPages[index+6] = 0x00;
7187 AllPages[index+7] = 0x00;
7188 AllPages[index+8] = 0x00;
7189 AllPages[index+9] = 0x00;
7190 AllPages[index+10] = 0x00;
7191 AllPages[index+11] = 0x00;
7193 /* MODESENSE_CACHING */
7195 * Fill-up Caching mode page, SAT, Table 67
7198 AllPages[index+12] = 0x08; /* page code */
7199 AllPages[index+13] = 0x12; /* page length */
7201 if (pSatDevData->satWriteCacheEnabled == agTRUE)
7203 AllPages[index+14] = 0x04;/* WCE bit is set */
7207 AllPages[index+14] = 0x00;/* WCE bit is NOT set */
7210 AllPages[index+14] = 0x00;/* WCE bit is NOT set */
7211 AllPages[index+15] = 0x00;
7212 AllPages[index+16] = 0x00;
7213 AllPages[index+17] = 0x00;
7214 AllPages[index+18] = 0x00;
7215 AllPages[index+19] = 0x00;
7216 AllPages[index+20] = 0x00;
7217 AllPages[index+21] = 0x00;
7218 AllPages[index+22] = 0x00;
7219 AllPages[index+23] = 0x00;
7220 if (pSatDevData->satLookAheadEnabled == agTRUE)
7222 AllPages[index+24] = 0x00;/* DRA bit is NOT set */
7226 AllPages[index+24] = 0x20;/* DRA bit is set */
7228 AllPages[index+25] = 0x00;
7229 AllPages[index+26] = 0x00;
7230 AllPages[index+27] = 0x00;
7231 AllPages[index+28] = 0x00;
7232 AllPages[index+29] = 0x00;
7233 AllPages[index+30] = 0x00;
7234 AllPages[index+31] = 0x00;
7236 /* MODESENSE_CONTROL_PAGE */
7238 * Fill-up control mode page, SAT, Table 65
7240 AllPages[index+32] = 0x0A; /* page code */
7241 AllPages[index+33] = 0x0A; /* page length */
7242 AllPages[index+34] = 0x02; /* only GLTSD bit is set */
7243 if (pSatDevData->satNCQ == agTRUE)
7245 AllPages[index+35] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
7249 AllPages[index+35] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
7251 AllPages[index+36] = 0x00;
7252 AllPages[index+37] = 0x00;
7253 AllPages[index+38] = 0x00; /* obsolete */
7254 AllPages[index+39] = 0x00; /* obsolete */
7255 AllPages[index+40] = 0xFF; /* Busy Timeout Period */
7256 AllPages[index+41] = 0xFF; /* Busy Timeout Period */
7257 AllPages[index+42] = 0x00; /* we don't support non-000b value for the self-test code */
7258 AllPages[index+43] = 0x00; /* we don't support non-000b value for the self-test code */
7260 /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */
7262 * Fill-up informational-exceptions control mode page, SAT, Table 68
7264 AllPages[index+44] = 0x1C; /* page code */
7265 AllPages[index+45] = 0x0A; /* page length */
7266 if (pSatDevData->satSMARTEnabled == agTRUE)
7268 AllPages[index+46] = 0x00;/* DEXCPT bit is NOT set */
7272 AllPages[index+46] = 0x08;/* DEXCPT bit is set */
7274 AllPages[index+47] = 0x00; /* We don't support MRIE */
7275 AllPages[index+48] = 0x00; /* Interval timer vendor-specific */
7276 AllPages[index+49] = 0x00;
7277 AllPages[index+50] = 0x00;
7278 AllPages[index+51] = 0x00;
7279 AllPages[index+52] = 0x00; /* REPORT-COUNT */
7280 AllPages[index+53] = 0x00;
7281 AllPages[index+54] = 0x00;
7282 AllPages[index+55] = 0x00;
7284 osti_memcpy(pModeSense, &AllPages, lenRead);
7286 else if (page == MODESENSE_CONTROL_PAGE)
7288 TI_DBG5(("satModeSense10: MODESENSE_CONTROL_PAGE\n"));
7290 Control[1] = (bit8)(lenRead - 2);
7291 Control[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7292 Control[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7295 Control[4] = 0x00; /* reserved and LONGLBA */
7296 Control[4] = (bit8)(Control[4] | 0x1); /* LONGLBA is set */
7300 Control[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7302 Control[5] = 0x00; /* reserved */
7303 Control[6] = 0x00; /* block descriptot length */
7306 Control[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7310 Control[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7314 * Fill-up direct-access device block-descriptor, SAT, Table 19
7320 Control[8] = 0x04; /* density-code : reserved for direct-access */
7321 /* number of blocks */
7322 Control[9] = 0x00; /* unspecified */
7323 Control[10] = 0x00; /* unspecified */
7324 Control[11] = 0x00; /* unspecified */
7325 Control[12] = 0x00; /* unspecified */
7326 Control[13] = 0x00; /* unspecified */
7327 Control[14] = 0x00; /* unspecified */
7328 Control[15] = 0x00; /* unspecified */
7330 Control[16] = 0x00; /* reserved */
7331 Control[17] = 0x00; /* reserved */
7332 Control[18] = 0x00; /* reserved */
7333 Control[19] = 0x00; /* reserved */
7337 Control[22] = 0x02; /* Block size is always 512 bytes */
7343 Control[8] = 0x04; /* density-code : reserved for direct-access */
7344 /* number of blocks */
7345 Control[9] = 0x00; /* unspecified */
7346 Control[10] = 0x00; /* unspecified */
7347 Control[11] = 0x00; /* unspecified */
7349 Control[12] = 0x00; /* reserved */
7352 Control[14] = 0x02; /* Block size is always 512 bytes */
7365 * Fill-up control mode page, SAT, Table 65
7367 Control[index+0] = 0x0A; /* page code */
7368 Control[index+1] = 0x0A; /* page length */
7369 Control[index+2] = 0x02; /* only GLTSD bit is set */
7370 if (pSatDevData->satNCQ == agTRUE)
7372 Control[index+3] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
7376 Control[index+3] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
7378 Control[index+4] = 0x00;
7379 Control[index+5] = 0x00;
7380 Control[index+6] = 0x00; /* obsolete */
7381 Control[index+7] = 0x00; /* obsolete */
7382 Control[index+8] = 0xFF; /* Busy Timeout Period */
7383 Control[index+9] = 0xFF; /* Busy Timeout Period */
7384 Control[index+10] = 0x00; /* we don't support non-000b value for the self-test code */
7385 Control[index+11] = 0x00; /* we don't support non-000b value for the self-test code */
7387 osti_memcpy(pModeSense, &Control, lenRead);
7389 else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
7391 TI_DBG5(("satModeSense10: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
7392 RWErrorRecovery[0] = 0;
7393 RWErrorRecovery[1] = (bit8)(lenRead - 2);
7394 RWErrorRecovery[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7395 RWErrorRecovery[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7398 RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA */
7399 RWErrorRecovery[4] = (bit8)(RWErrorRecovery[4] | 0x1); /* LONGLBA is set */
7403 RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7405 RWErrorRecovery[5] = 0x00; /* reserved */
7406 RWErrorRecovery[6] = 0x00; /* block descriptot length */
7409 RWErrorRecovery[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7413 RWErrorRecovery[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7417 * Fill-up direct-access device block-descriptor, SAT, Table 19
7423 RWErrorRecovery[8] = 0x04; /* density-code : reserved for direct-access */
7424 /* number of blocks */
7425 RWErrorRecovery[9] = 0x00; /* unspecified */
7426 RWErrorRecovery[10] = 0x00; /* unspecified */
7427 RWErrorRecovery[11] = 0x00; /* unspecified */
7428 RWErrorRecovery[12] = 0x00; /* unspecified */
7429 RWErrorRecovery[13] = 0x00; /* unspecified */
7430 RWErrorRecovery[14] = 0x00; /* unspecified */
7431 RWErrorRecovery[15] = 0x00; /* unspecified */
7433 RWErrorRecovery[16] = 0x00; /* reserved */
7434 RWErrorRecovery[17] = 0x00; /* reserved */
7435 RWErrorRecovery[18] = 0x00; /* reserved */
7436 RWErrorRecovery[19] = 0x00; /* reserved */
7438 RWErrorRecovery[20] = 0x00;
7439 RWErrorRecovery[21] = 0x00;
7440 RWErrorRecovery[22] = 0x02; /* Block size is always 512 bytes */
7441 RWErrorRecovery[23] = 0x00;
7446 RWErrorRecovery[8] = 0x04; /* density-code : reserved for direct-access */
7447 /* number of blocks */
7448 RWErrorRecovery[9] = 0x00; /* unspecified */
7449 RWErrorRecovery[10] = 0x00; /* unspecified */
7450 RWErrorRecovery[11] = 0x00; /* unspecified */
7452 RWErrorRecovery[12] = 0x00; /* reserved */
7454 RWErrorRecovery[13] = 0x00;
7455 RWErrorRecovery[14] = 0x02; /* Block size is always 512 bytes */
7456 RWErrorRecovery[15] = 0x00;
7468 * Fill-up Read-Write Error Recovery mode page, SAT, Table 66
7470 RWErrorRecovery[index+0] = 0x01; /* page code */
7471 RWErrorRecovery[index+1] = 0x0A; /* page length */
7472 RWErrorRecovery[index+2] = 0x40; /* ARRE is set */
7473 RWErrorRecovery[index+3] = 0x00;
7474 RWErrorRecovery[index+4] = 0x00;
7475 RWErrorRecovery[index+5] = 0x00;
7476 RWErrorRecovery[index+6] = 0x00;
7477 RWErrorRecovery[index+7] = 0x00;
7478 RWErrorRecovery[index+8] = 0x00;
7479 RWErrorRecovery[index+9] = 0x00;
7480 RWErrorRecovery[index+10] = 0x00;
7481 RWErrorRecovery[index+11] = 0x00;
7483 osti_memcpy(pModeSense, &RWErrorRecovery, lenRead);
7485 else if (page == MODESENSE_CACHING)
7487 TI_DBG5(("satModeSense10: MODESENSE_CACHING\n"));
7489 Caching[1] = (bit8)(lenRead - 2);
7490 Caching[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7491 Caching[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7494 Caching[4] = 0x00; /* reserved and LONGLBA */
7495 Caching[4] = (bit8)(Caching[4] | 0x1); /* LONGLBA is set */
7499 Caching[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7501 Caching[5] = 0x00; /* reserved */
7502 Caching[6] = 0x00; /* block descriptot length */
7505 Caching[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7509 Caching[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7513 * Fill-up direct-access device block-descriptor, SAT, Table 19
7519 Caching[8] = 0x04; /* density-code : reserved for direct-access */
7520 /* number of blocks */
7521 Caching[9] = 0x00; /* unspecified */
7522 Caching[10] = 0x00; /* unspecified */
7523 Caching[11] = 0x00; /* unspecified */
7524 Caching[12] = 0x00; /* unspecified */
7525 Caching[13] = 0x00; /* unspecified */
7526 Caching[14] = 0x00; /* unspecified */
7527 Caching[15] = 0x00; /* unspecified */
7529 Caching[16] = 0x00; /* reserved */
7530 Caching[17] = 0x00; /* reserved */
7531 Caching[18] = 0x00; /* reserved */
7532 Caching[19] = 0x00; /* reserved */
7536 Caching[22] = 0x02; /* Block size is always 512 bytes */
7542 Caching[8] = 0x04; /* density-code : reserved for direct-access */
7543 /* number of blocks */
7544 Caching[9] = 0x00; /* unspecified */
7545 Caching[10] = 0x00; /* unspecified */
7546 Caching[11] = 0x00; /* unspecified */
7548 Caching[12] = 0x00; /* reserved */
7551 Caching[14] = 0x02; /* Block size is always 512 bytes */
7564 * Fill-up Caching mode page, SAT, Table 67
7567 Caching[index+0] = 0x08; /* page code */
7568 Caching[index+1] = 0x12; /* page length */
7570 if (pSatDevData->satWriteCacheEnabled == agTRUE)
7572 Caching[index+2] = 0x04;/* WCE bit is set */
7576 Caching[index+2] = 0x00;/* WCE bit is NOT set */
7579 Caching[index+2] = 0x00;/* WCE bit is NOT set */
7580 Caching[index+3] = 0x00;
7581 Caching[index+4] = 0x00;
7582 Caching[index+5] = 0x00;
7583 Caching[index+6] = 0x00;
7584 Caching[index+7] = 0x00;
7585 Caching[index+8] = 0x00;
7586 Caching[index+9] = 0x00;
7587 Caching[index+10] = 0x00;
7588 Caching[index+11] = 0x00;
7589 if (pSatDevData->satLookAheadEnabled == agTRUE)
7591 Caching[index+12] = 0x00;/* DRA bit is NOT set */
7595 Caching[index+12] = 0x20;/* DRA bit is set */
7597 Caching[index+13] = 0x00;
7598 Caching[index+14] = 0x00;
7599 Caching[index+15] = 0x00;
7600 Caching[index+16] = 0x00;
7601 Caching[index+17] = 0x00;
7602 Caching[index+18] = 0x00;
7603 Caching[index+19] = 0x00;
7604 osti_memcpy(pModeSense, &Caching, lenRead);
7607 else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
7609 TI_DBG5(("satModeSense10: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
7610 InfoExceptionCtrl[0] = 0;
7611 InfoExceptionCtrl[1] = (bit8)(lenRead - 2);
7612 InfoExceptionCtrl[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7613 InfoExceptionCtrl[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7616 InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA */
7617 InfoExceptionCtrl[4] = (bit8)(InfoExceptionCtrl[4] | 0x1); /* LONGLBA is set */
7621 InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7623 InfoExceptionCtrl[5] = 0x00; /* reserved */
7624 InfoExceptionCtrl[6] = 0x00; /* block descriptot length */
7627 InfoExceptionCtrl[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7631 InfoExceptionCtrl[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7635 * Fill-up direct-access device block-descriptor, SAT, Table 19
7641 InfoExceptionCtrl[8] = 0x04; /* density-code : reserved for direct-access */
7642 /* number of blocks */
7643 InfoExceptionCtrl[9] = 0x00; /* unspecified */
7644 InfoExceptionCtrl[10] = 0x00; /* unspecified */
7645 InfoExceptionCtrl[11] = 0x00; /* unspecified */
7646 InfoExceptionCtrl[12] = 0x00; /* unspecified */
7647 InfoExceptionCtrl[13] = 0x00; /* unspecified */
7648 InfoExceptionCtrl[14] = 0x00; /* unspecified */
7649 InfoExceptionCtrl[15] = 0x00; /* unspecified */
7651 InfoExceptionCtrl[16] = 0x00; /* reserved */
7652 InfoExceptionCtrl[17] = 0x00; /* reserved */
7653 InfoExceptionCtrl[18] = 0x00; /* reserved */
7654 InfoExceptionCtrl[19] = 0x00; /* reserved */
7656 InfoExceptionCtrl[20] = 0x00;
7657 InfoExceptionCtrl[21] = 0x00;
7658 InfoExceptionCtrl[22] = 0x02; /* Block size is always 512 bytes */
7659 InfoExceptionCtrl[23] = 0x00;
7664 InfoExceptionCtrl[8] = 0x04; /* density-code : reserved for direct-access */
7665 /* number of blocks */
7666 InfoExceptionCtrl[9] = 0x00; /* unspecified */
7667 InfoExceptionCtrl[10] = 0x00; /* unspecified */
7668 InfoExceptionCtrl[11] = 0x00; /* unspecified */
7670 InfoExceptionCtrl[12] = 0x00; /* reserved */
7672 InfoExceptionCtrl[13] = 0x00;
7673 InfoExceptionCtrl[14] = 0x02; /* Block size is always 512 bytes */
7674 InfoExceptionCtrl[15] = 0x00;
7686 * Fill-up informational-exceptions control mode page, SAT, Table 68
7688 InfoExceptionCtrl[index+0] = 0x1C; /* page code */
7689 InfoExceptionCtrl[index+1] = 0x0A; /* page length */
7690 if (pSatDevData->satSMARTEnabled == agTRUE)
7692 InfoExceptionCtrl[index+2] = 0x00;/* DEXCPT bit is NOT set */
7696 InfoExceptionCtrl[index+2] = 0x08;/* DEXCPT bit is set */
7698 InfoExceptionCtrl[index+3] = 0x00; /* We don't support MRIE */
7699 InfoExceptionCtrl[index+4] = 0x00; /* Interval timer vendor-specific */
7700 InfoExceptionCtrl[index+5] = 0x00;
7701 InfoExceptionCtrl[index+6] = 0x00;
7702 InfoExceptionCtrl[index+7] = 0x00;
7703 InfoExceptionCtrl[index+8] = 0x00; /* REPORT-COUNT */
7704 InfoExceptionCtrl[index+9] = 0x00;
7705 InfoExceptionCtrl[index+10] = 0x00;
7706 InfoExceptionCtrl[index+11] = 0x00;
7707 osti_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
7713 TI_DBG1(("satModeSense10: Error page %d\n", page));
7714 satSetSensePayload( pSense,
7715 SCSI_SNSKEY_ILLEGAL_REQUEST,
7717 SCSI_SNSCODE_INVALID_COMMAND,
7720 ostiInitiatorIOCompleted( tiRoot,
7723 SCSI_STAT_CHECK_CONDITION,
7724 satIOContext->pTiSenseData,
7725 satIOContext->interruptContext );
7729 if (requestLen > lenRead)
7731 TI_DBG1(("satModeSense10 reporting underrun lenRead=0x%x requestLen=0x%x tiIORequest=%p\n", lenRead, requestLen, tiIORequest));
7733 ostiInitiatorIOCompleted( tiRoot,
7736 requestLen - lenRead,
7738 satIOContext->interruptContext );
7744 ostiInitiatorIOCompleted( tiRoot,
7749 satIOContext->interruptContext);
7756 /*****************************************************************************/
7757 /*! \brief SAT implementation for SCSI VERIFY (10).
7759 * SAT implementation for SCSI VERIFY (10).
7761 * \param tiRoot: Pointer to TISA initiator driver/port instance.
7762 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
7763 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
7764 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
7765 * \param satIOContext_t: Pointer to the SAT IO Context
7767 * \return If command is started successfully
7768 * - \e tiSuccess: I/O request successfully initiated.
7769 * - \e tiBusy: No resources available, try again later.
7770 * - \e tiIONoDevice: Invalid device handle.
7771 * - \e tiError: Other errors.
7773 /*****************************************************************************/
7774 GLOBAL bit32 satVerify10(
7776 tiIORequest_t *tiIORequest,
7777 tiDeviceHandle_t *tiDeviceHandle,
7778 tiScsiInitiatorRequest_t *tiScsiRequest,
7779 satIOContext_t *satIOContext)
7782 For simple implementation,
7783 no byte comparison supported as of 4/5/06
7785 scsiRspSense_t *pSense;
7786 tiIniScsiCmnd_t *scsiCmnd;
7787 satDeviceData_t *pSatDevData;
7788 agsaFisRegHostToDevice_t *fis;
7790 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7796 bit32 rangeChk = agFALSE; /* lba and tl range check */
7799 TI_DBG5(("satVerify10 entry: tiDeviceHandle=%p tiIORequest=%p\n",
7800 tiDeviceHandle, tiIORequest));
7802 pSense = satIOContext->pSense;
7803 scsiCmnd = &tiScsiRequest->scsiCmnd;
7804 pSatDevData = satIOContext->pSatDevData;
7805 fis = satIOContext->pFis;
7807 /* checking BYTCHK */
7808 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
7811 should do the byte check
7812 but not supported in this version
7814 satSetSensePayload( pSense,
7815 SCSI_SNSKEY_ILLEGAL_REQUEST,
7817 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7820 ostiInitiatorIOCompleted( tiRoot,
7823 SCSI_STAT_CHECK_CONDITION,
7824 satIOContext->pTiSenseData,
7825 satIOContext->interruptContext );
7827 TI_DBG1(("satVerify10: no byte checking \n"));
7831 /* checking CONTROL */
7832 /* NACA == 1 or LINK == 1*/
7833 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
7835 satSetSensePayload( pSense,
7836 SCSI_SNSKEY_ILLEGAL_REQUEST,
7838 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7841 ostiInitiatorIOCompleted( tiRoot,
7844 SCSI_STAT_CHECK_CONDITION,
7845 satIOContext->pTiSenseData,
7846 satIOContext->interruptContext );
7848 TI_DBG2(("satVerify10: return control\n"));
7852 osti_memset(LBA, 0, sizeof(LBA));
7853 osti_memset(TL, 0, sizeof(TL));
7855 /* do not use memcpy due to indexing in LBA and TL */
7856 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
7857 LBA[1] = scsiCmnd->cdb[3];
7858 LBA[2] = scsiCmnd->cdb[4];
7859 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
7863 TL[2] = scsiCmnd->cdb[7]; /* MSB */
7864 TL[3] = scsiCmnd->cdb[8]; /* LSB */
7866 rangeChk = satAddNComparebit32(LBA, TL);
7868 /* cbd10; computing LBA and transfer length */
7869 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
7870 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
7871 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
7873 if (pSatDevData->satNCQ != agTRUE &&
7874 pSatDevData->sat48BitSupport != agTRUE
7877 if (lba > SAT_TR_LBA_LIMIT - 1)
7879 satSetSensePayload( pSense,
7880 SCSI_SNSKEY_ILLEGAL_REQUEST,
7882 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7885 ostiInitiatorIOCompleted( tiRoot,
7888 SCSI_STAT_CHECK_CONDITION,
7889 satIOContext->pTiSenseData,
7890 satIOContext->interruptContext );
7892 TI_DBG1(("satVerify10: return LBA out of range, not EXT\n"));
7893 TI_DBG1(("satVerify10: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
7894 scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
7895 TI_DBG1(("satVerify10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
7899 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
7901 TI_DBG1(("satVerify10: return LBA+TL out of range, not EXT\n"));
7902 satSetSensePayload( pSense,
7903 SCSI_SNSKEY_ILLEGAL_REQUEST,
7905 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7908 ostiInitiatorIOCompleted( tiRoot,
7911 SCSI_STAT_CHECK_CONDITION,
7912 satIOContext->pTiSenseData,
7913 satIOContext->interruptContext );
7919 if (pSatDevData->sat48BitSupport == agTRUE)
7921 TI_DBG5(("satVerify10: SAT_READ_VERIFY_SECTORS_EXT\n"));
7922 fis->h.fisType = 0x27; /* Reg host to device */
7923 fis->h.c_pmPort = 0x80; /* C Bit is set */
7925 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
7926 fis->h.features = 0; /* FIS reserve */
7927 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
7928 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
7929 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
7930 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
7931 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
7932 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
7933 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
7934 fis->d.featuresExp = 0; /* FIS reserve */
7935 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
7936 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
7938 fis->d.reserved4 = 0;
7939 fis->d.control = 0; /* FIS HOB bit clear */
7940 fis->d.reserved5 = 0;
7942 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7943 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
7947 TI_DBG5(("satVerify10: SAT_READ_VERIFY_SECTORS\n"));
7948 fis->h.fisType = 0x27; /* Reg host to device */
7949 fis->h.c_pmPort = 0x80; /* C bit is set */
7950 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
7951 fis->h.features = 0; /* FIS reserve */
7952 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
7953 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
7954 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
7955 /* FIS LBA mode set LBA (27:24) */
7956 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
7957 fis->d.lbaLowExp = 0;
7958 fis->d.lbaMidExp = 0;
7959 fis->d.lbaHighExp = 0;
7960 fis->d.featuresExp = 0;
7961 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
7962 fis->d.sectorCountExp = 0;
7963 fis->d.reserved4 = 0;
7964 fis->d.control = 0; /* FIS HOB bit clear */
7965 fis->d.reserved5 = 0;
7967 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7968 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
7972 satIOContext->currentLBA = lba;
7973 satIOContext->OrgTL = tl;
7976 computing number of loop and remainder for tl
7977 0xFF in case not ext
7980 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
7982 LoopNum = satComputeLoopNum(tl, 0xFF);
7984 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
7986 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
7987 LoopNum = satComputeLoopNum(tl, 0xFFFF);
7991 TI_DBG1(("satVerify10: error case 1!!!\n"));
7995 satIOContext->LoopNum = LoopNum;
7999 TI_DBG5(("satVerify10: NON CHAINED data\n"));
8000 /* Initialize CB for SATA completion.
8002 satIOContext->satCompleteCB = &satNonChainedVerifyCB;
8006 TI_DBG1(("satVerify10: CHAINED data\n"));
8008 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8010 fis->d.sectorCount = 0xFF;
8012 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8014 fis->d.sectorCount = 0xFF;
8015 fis->d.sectorCountExp = 0xFF;
8019 TI_DBG1(("satVerify10: error case 2!!!\n"));
8022 /* Initialize CB for SATA completion.
8024 satIOContext->satCompleteCB = &satChainedVerifyCB;
8029 * Prepare SGL and send FIS to LL layer.
8031 satIOContext->reqType = agRequestType; /* Save it */
8033 status = sataLLIOStart( tiRoot,
8041 GLOBAL bit32 satChainedVerify(
8043 tiIORequest_t *tiIORequest,
8044 tiDeviceHandle_t *tiDeviceHandle,
8045 tiScsiInitiatorRequest_t *tiScsiRequest,
8046 satIOContext_t *satIOContext)
8049 satIOContext_t *satOrgIOContext = agNULL;
8050 agsaFisRegHostToDevice_t *fis;
8051 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8053 bit32 DenomTL = 0xFF;
8054 bit32 Remainder = 0;
8055 bit8 LBA[4]; /* 0 MSB, 3 LSB */
8057 TI_DBG2(("satChainedVerify: start\n"));
8059 fis = satIOContext->pFis;
8060 satOrgIOContext = satIOContext->satOrgIOContext;
8061 osti_memset(LBA,0, sizeof(LBA));
8063 switch (satOrgIOContext->ATACmd)
8065 case SAT_READ_VERIFY_SECTORS:
8068 case SAT_READ_VERIFY_SECTORS_EXT:
8072 TI_DBG1(("satChainedVerify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
8077 Remainder = satOrgIOContext->OrgTL % DenomTL;
8078 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
8079 lba = satOrgIOContext->currentLBA;
8081 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
8082 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
8083 LBA[2] = (bit8)((lba & 0xF0) >> 8);
8084 LBA[3] = (bit8)(lba & 0xF); /* LSB */
8086 switch (satOrgIOContext->ATACmd)
8088 case SAT_READ_VERIFY_SECTORS:
8089 fis->h.fisType = 0x27; /* Reg host to device */
8090 fis->h.c_pmPort = 0x80; /* C bit is set */
8091 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
8092 fis->h.features = 0; /* FIS reserve */
8093 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
8094 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
8095 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
8097 /* FIS LBA mode set LBA (27:24) */
8098 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
8100 fis->d.lbaLowExp = 0;
8101 fis->d.lbaMidExp = 0;
8102 fis->d.lbaHighExp = 0;
8103 fis->d.featuresExp = 0;
8104 if (satOrgIOContext->LoopNum == 1)
8107 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
8111 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
8113 fis->d.sectorCountExp = 0;
8114 fis->d.reserved4 = 0;
8115 fis->d.control = 0; /* FIS HOB bit clear */
8116 fis->d.reserved5 = 0;
8118 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8121 case SAT_READ_VERIFY_SECTORS_EXT:
8122 fis->h.fisType = 0x27; /* Reg host to device */
8123 fis->h.c_pmPort = 0x80; /* C Bit is set */
8124 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT; /* 0x42 */
8125 fis->h.features = 0; /* FIS reserve */
8126 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
8127 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
8128 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
8129 fis->d.device = 0x40; /* FIS LBA mode set */
8130 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
8131 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
8132 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
8133 fis->d.featuresExp = 0; /* FIS reserve */
8134 if (satOrgIOContext->LoopNum == 1)
8137 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
8138 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
8142 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
8143 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
8145 fis->d.reserved4 = 0;
8146 fis->d.control = 0; /* FIS HOB bit clear */
8147 fis->d.reserved5 = 0;
8149 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8154 TI_DBG1(("satChainedVerify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
8159 /* Initialize CB for SATA completion.
8162 satIOContext->satCompleteCB = &satChainedVerifyCB;
8166 * Prepare SGL and send FIS to LL layer.
8168 satIOContext->reqType = agRequestType; /* Save it */
8170 status = sataLLIOStart( tiRoot,
8176 TI_DBG5(("satChainedVerify: return\n"));
8182 /*****************************************************************************/
8183 /*! \brief SAT implementation for SCSI VERIFY (12).
8185 * SAT implementation for SCSI VERIFY (12).
8187 * \param tiRoot: Pointer to TISA initiator driver/port instance.
8188 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
8189 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
8190 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
8191 * \param satIOContext_t: Pointer to the SAT IO Context
8193 * \return If command is started successfully
8194 * - \e tiSuccess: I/O request successfully initiated.
8195 * - \e tiBusy: No resources available, try again later.
8196 * - \e tiIONoDevice: Invalid device handle.
8197 * - \e tiError: Other errors.
8199 /*****************************************************************************/
8200 GLOBAL bit32 satVerify12(
8202 tiIORequest_t *tiIORequest,
8203 tiDeviceHandle_t *tiDeviceHandle,
8204 tiScsiInitiatorRequest_t *tiScsiRequest,
8205 satIOContext_t *satIOContext)
8208 For simple implementation,
8209 no byte comparison supported as of 4/5/06
8211 scsiRspSense_t *pSense;
8212 tiIniScsiCmnd_t *scsiCmnd;
8213 satDeviceData_t *pSatDevData;
8214 agsaFisRegHostToDevice_t *fis;
8216 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8222 bit32 rangeChk = agFALSE; /* lba and tl range check */
8224 TI_DBG5(("satVerify12 entry: tiDeviceHandle=%p tiIORequest=%p\n",
8225 tiDeviceHandle, tiIORequest));
8227 pSense = satIOContext->pSense;
8228 scsiCmnd = &tiScsiRequest->scsiCmnd;
8229 pSatDevData = satIOContext->pSatDevData;
8230 fis = satIOContext->pFis;
8233 /* checking BYTCHK */
8234 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
8237 should do the byte check
8238 but not supported in this version
8240 satSetSensePayload( pSense,
8241 SCSI_SNSKEY_ILLEGAL_REQUEST,
8243 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8246 ostiInitiatorIOCompleted( tiRoot,
8249 SCSI_STAT_CHECK_CONDITION,
8250 satIOContext->pTiSenseData,
8251 satIOContext->interruptContext );
8253 TI_DBG1(("satVerify12: no byte checking \n"));
8257 /* checking CONTROL */
8258 /* NACA == 1 or LINK == 1*/
8259 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
8261 satSetSensePayload( pSense,
8262 SCSI_SNSKEY_ILLEGAL_REQUEST,
8264 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8267 ostiInitiatorIOCompleted( tiRoot,
8270 SCSI_STAT_CHECK_CONDITION,
8271 satIOContext->pTiSenseData,
8272 satIOContext->interruptContext );
8274 TI_DBG1(("satVerify12: return control\n"));
8278 osti_memset(LBA, 0, sizeof(LBA));
8279 osti_memset(TL, 0, sizeof(TL));
8281 /* do not use memcpy due to indexing in LBA and TL */
8282 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
8283 LBA[1] = scsiCmnd->cdb[3];
8284 LBA[2] = scsiCmnd->cdb[4];
8285 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
8287 TL[0] = scsiCmnd->cdb[6]; /* MSB */
8288 TL[1] = scsiCmnd->cdb[7];
8289 TL[2] = scsiCmnd->cdb[7];
8290 TL[3] = scsiCmnd->cdb[8]; /* LSB */
8292 rangeChk = satAddNComparebit32(LBA, TL);
8294 lba = satComputeCDB12LBA(satIOContext);
8295 tl = satComputeCDB12TL(satIOContext);
8297 if (pSatDevData->satNCQ != agTRUE &&
8298 pSatDevData->sat48BitSupport != agTRUE
8301 if (lba > SAT_TR_LBA_LIMIT - 1)
8303 satSetSensePayload( pSense,
8304 SCSI_SNSKEY_ILLEGAL_REQUEST,
8306 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8309 ostiInitiatorIOCompleted( tiRoot,
8312 SCSI_STAT_CHECK_CONDITION,
8313 satIOContext->pTiSenseData,
8314 satIOContext->interruptContext );
8316 TI_DBG1(("satVerify12: return LBA out of range, not EXT\n"));
8317 TI_DBG1(("satVerify12: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
8318 scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
8319 TI_DBG1(("satVerify12: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
8323 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
8325 TI_DBG1(("satVerify12: return LBA+TL out of range, not EXT\n"));
8326 satSetSensePayload( pSense,
8327 SCSI_SNSKEY_ILLEGAL_REQUEST,
8329 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8332 ostiInitiatorIOCompleted( tiRoot,
8335 SCSI_STAT_CHECK_CONDITION,
8336 satIOContext->pTiSenseData,
8337 satIOContext->interruptContext );
8343 if (pSatDevData->sat48BitSupport == agTRUE)
8345 TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS_EXT\n"));
8346 fis->h.fisType = 0x27; /* Reg host to device */
8347 fis->h.c_pmPort = 0x80; /* C Bit is set */
8349 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
8350 fis->h.features = 0; /* FIS reserve */
8351 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
8352 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
8353 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
8354 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
8355 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
8356 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
8357 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
8358 fis->d.featuresExp = 0; /* FIS reserve */
8359 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
8360 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
8362 fis->d.reserved4 = 0;
8363 fis->d.control = 0; /* FIS HOB bit clear */
8364 fis->d.reserved5 = 0;
8366 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8367 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
8371 TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS\n"));
8372 fis->h.fisType = 0x27; /* Reg host to device */
8373 fis->h.c_pmPort = 0x80; /* C bit is set */
8374 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
8375 fis->h.features = 0; /* FIS reserve */
8376 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
8377 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
8378 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
8379 /* FIS LBA mode set LBA (27:24) */
8380 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
8381 fis->d.lbaLowExp = 0;
8382 fis->d.lbaMidExp = 0;
8383 fis->d.lbaHighExp = 0;
8384 fis->d.featuresExp = 0;
8385 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
8386 fis->d.sectorCountExp = 0;
8387 fis->d.reserved4 = 0;
8388 fis->d.control = 0; /* FIS HOB bit clear */
8389 fis->d.reserved5 = 0;
8391 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8392 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
8396 satIOContext->currentLBA = lba;
8397 satIOContext->OrgTL = tl;
8400 computing number of loop and remainder for tl
8401 0xFF in case not ext
8404 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8406 LoopNum = satComputeLoopNum(tl, 0xFF);
8408 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8410 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
8411 LoopNum = satComputeLoopNum(tl, 0xFFFF);
8415 TI_DBG1(("satVerify12: error case 1!!!\n"));
8419 satIOContext->LoopNum = LoopNum;
8423 TI_DBG5(("satVerify12: NON CHAINED data\n"));
8424 /* Initialize CB for SATA completion.
8426 satIOContext->satCompleteCB = &satNonChainedVerifyCB;
8430 TI_DBG1(("satVerify12: CHAINED data\n"));
8432 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8434 fis->d.sectorCount = 0xFF;
8436 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8438 fis->d.sectorCount = 0xFF;
8439 fis->d.sectorCountExp = 0xFF;
8443 TI_DBG1(("satVerify10: error case 2!!!\n"));
8446 /* Initialize CB for SATA completion.
8448 satIOContext->satCompleteCB = &satChainedVerifyCB;
8453 * Prepare SGL and send FIS to LL layer.
8455 satIOContext->reqType = agRequestType; /* Save it */
8457 status = sataLLIOStart( tiRoot,
8464 /*****************************************************************************/
8465 /*! \brief SAT implementation for SCSI VERIFY (16).
8467 * SAT implementation for SCSI VERIFY (16).
8469 * \param tiRoot: Pointer to TISA initiator driver/port instance.
8470 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
8471 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
8472 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
8473 * \param satIOContext_t: Pointer to the SAT IO Context
8475 * \return If command is started successfully
8476 * - \e tiSuccess: I/O request successfully initiated.
8477 * - \e tiBusy: No resources available, try again later.
8478 * - \e tiIONoDevice: Invalid device handle.
8479 * - \e tiError: Other errors.
8481 /*****************************************************************************/
8482 GLOBAL bit32 satVerify16(
8484 tiIORequest_t *tiIORequest,
8485 tiDeviceHandle_t *tiDeviceHandle,
8486 tiScsiInitiatorRequest_t *tiScsiRequest,
8487 satIOContext_t *satIOContext)
8490 For simple implementation,
8491 no byte comparison supported as of 4/5/06
8493 scsiRspSense_t *pSense;
8494 tiIniScsiCmnd_t *scsiCmnd;
8495 satDeviceData_t *pSatDevData;
8496 agsaFisRegHostToDevice_t *fis;
8498 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8504 bit32 rangeChk = agFALSE; /* lba and tl range check */
8505 bit32 limitChk = agFALSE; /* lba and tl range check */
8507 TI_DBG5(("satVerify16 entry: tiDeviceHandle=%p tiIORequest=%p\n",
8508 tiDeviceHandle, tiIORequest));
8510 pSense = satIOContext->pSense;
8511 scsiCmnd = &tiScsiRequest->scsiCmnd;
8512 pSatDevData = satIOContext->pSatDevData;
8513 fis = satIOContext->pFis;
8515 /* checking BYTCHK */
8516 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
8519 should do the byte check
8520 but not supported in this version
8522 satSetSensePayload( pSense,
8523 SCSI_SNSKEY_ILLEGAL_REQUEST,
8525 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8528 ostiInitiatorIOCompleted( tiRoot,
8531 SCSI_STAT_CHECK_CONDITION,
8532 satIOContext->pTiSenseData,
8533 satIOContext->interruptContext );
8535 TI_DBG1(("satVerify16: no byte checking \n"));
8539 /* checking CONTROL */
8540 /* NACA == 1 or LINK == 1*/
8541 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
8543 satSetSensePayload( pSense,
8544 SCSI_SNSKEY_ILLEGAL_REQUEST,
8546 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8549 ostiInitiatorIOCompleted( tiRoot,
8552 SCSI_STAT_CHECK_CONDITION,
8553 satIOContext->pTiSenseData,
8554 satIOContext->interruptContext );
8556 TI_DBG2(("satVerify16: return control\n"));
8560 osti_memset(LBA, 0, sizeof(LBA));
8561 osti_memset(TL, 0, sizeof(TL));
8564 /* do not use memcpy due to indexing in LBA and TL */
8565 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
8566 LBA[1] = scsiCmnd->cdb[3];
8567 LBA[2] = scsiCmnd->cdb[4];
8568 LBA[3] = scsiCmnd->cdb[5];
8569 LBA[4] = scsiCmnd->cdb[6];
8570 LBA[5] = scsiCmnd->cdb[7];
8571 LBA[6] = scsiCmnd->cdb[8];
8572 LBA[7] = scsiCmnd->cdb[9]; /* LSB */
8578 TL[4] = scsiCmnd->cdb[10]; /* MSB */
8579 TL[5] = scsiCmnd->cdb[11];
8580 TL[6] = scsiCmnd->cdb[12];
8581 TL[7] = scsiCmnd->cdb[13]; /* LSB */
8583 rangeChk = satAddNComparebit64(LBA, TL);
8585 limitChk = satCompareLBALimitbit(LBA);
8587 lba = satComputeCDB16LBA(satIOContext);
8588 tl = satComputeCDB16TL(satIOContext);
8590 if (pSatDevData->satNCQ != agTRUE &&
8591 pSatDevData->sat48BitSupport != agTRUE
8596 TI_DBG1(("satVerify16: return LBA out of range, not EXT\n"));
8597 satSetSensePayload( pSense,
8598 SCSI_SNSKEY_ILLEGAL_REQUEST,
8600 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8603 ostiInitiatorIOCompleted( tiRoot,
8606 SCSI_STAT_CHECK_CONDITION,
8607 satIOContext->pTiSenseData,
8608 satIOContext->interruptContext );
8612 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
8614 TI_DBG1(("satVerify16: return LBA+TL out of range, not EXT\n"));
8615 satSetSensePayload( pSense,
8616 SCSI_SNSKEY_ILLEGAL_REQUEST,
8618 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8621 ostiInitiatorIOCompleted( tiRoot,
8624 SCSI_STAT_CHECK_CONDITION,
8625 satIOContext->pTiSenseData,
8626 satIOContext->interruptContext );
8632 if (pSatDevData->sat48BitSupport == agTRUE)
8634 TI_DBG5(("satVerify16: SAT_READ_VERIFY_SECTORS_EXT\n"));
8635 fis->h.fisType = 0x27; /* Reg host to device */
8636 fis->h.c_pmPort = 0x80; /* C Bit is set */
8638 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
8639 fis->h.features = 0; /* FIS reserve */
8640 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
8641 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
8642 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
8643 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
8644 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
8645 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
8646 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
8647 fis->d.featuresExp = 0; /* FIS reserve */
8648 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
8649 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
8651 fis->d.reserved4 = 0;
8652 fis->d.control = 0; /* FIS HOB bit clear */
8653 fis->d.reserved5 = 0;
8655 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8656 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
8660 TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS\n"));
8661 fis->h.fisType = 0x27; /* Reg host to device */
8662 fis->h.c_pmPort = 0x80; /* C bit is set */
8663 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
8664 fis->h.features = 0; /* FIS reserve */
8665 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
8666 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
8667 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
8668 /* FIS LBA mode set LBA (27:24) */
8669 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
8670 fis->d.lbaLowExp = 0;
8671 fis->d.lbaMidExp = 0;
8672 fis->d.lbaHighExp = 0;
8673 fis->d.featuresExp = 0;
8674 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
8675 fis->d.sectorCountExp = 0;
8676 fis->d.reserved4 = 0;
8677 fis->d.control = 0; /* FIS HOB bit clear */
8678 fis->d.reserved5 = 0;
8680 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8681 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
8685 satIOContext->currentLBA = lba;
8686 satIOContext->OrgTL = tl;
8689 computing number of loop and remainder for tl
8690 0xFF in case not ext
8693 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8695 LoopNum = satComputeLoopNum(tl, 0xFF);
8697 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8699 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
8700 LoopNum = satComputeLoopNum(tl, 0xFFFF);
8704 TI_DBG1(("satVerify12: error case 1!!!\n"));
8708 satIOContext->LoopNum = LoopNum;
8712 TI_DBG5(("satVerify12: NON CHAINED data\n"));
8713 /* Initialize CB for SATA completion.
8715 satIOContext->satCompleteCB = &satNonChainedVerifyCB;
8719 TI_DBG1(("satVerify12: CHAINED data\n"));
8721 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8723 fis->d.sectorCount = 0xFF;
8725 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8727 fis->d.sectorCount = 0xFF;
8728 fis->d.sectorCountExp = 0xFF;
8732 TI_DBG1(("satVerify10: error case 2!!!\n"));
8735 /* Initialize CB for SATA completion.
8737 satIOContext->satCompleteCB = &satChainedVerifyCB;
8742 * Prepare SGL and send FIS to LL layer.
8744 satIOContext->reqType = agRequestType; /* Save it */
8746 status = sataLLIOStart( tiRoot,
8753 /*****************************************************************************/
8754 /*! \brief SAT implementation for SCSI satFormatUnit.
8756 * SAT implementation for SCSI satFormatUnit.
8758 * \param tiRoot: Pointer to TISA initiator driver/port instance.
8759 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
8760 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
8761 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
8762 * \param satIOContext_t: Pointer to the SAT IO Context
8764 * \return If command is started successfully
8765 * - \e tiSuccess: I/O request successfully initiated.
8766 * - \e tiBusy: No resources available, try again later.
8767 * - \e tiIONoDevice: Invalid device handle.
8768 * - \e tiError: Other errors.
8770 /*****************************************************************************/
8771 GLOBAL bit32 satFormatUnit(
8773 tiIORequest_t *tiIORequest,
8774 tiDeviceHandle_t *tiDeviceHandle,
8775 tiScsiInitiatorRequest_t *tiScsiRequest,
8776 satIOContext_t *satIOContext)
8779 note: we don't support media certification in this version and IP bit
8780 satDevData->satFormatState will be agFalse since SAT does not actually sends
8784 scsiRspSense_t *pSense;
8785 tiIniScsiCmnd_t *scsiCmnd;
8788 pSense = satIOContext->pSense;
8789 scsiCmnd = &tiScsiRequest->scsiCmnd;
8791 TI_DBG5(("satFormatUnit:start\n"));
8795 1. FMTDATA bit == 0(no defect list header)
8796 2. FMTDATA bit == 1 and DCRT bit == 1(defect list header is provided
8799 if ( ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) == 0) ||
8800 ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
8801 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK))
8804 ostiInitiatorIOCompleted( tiRoot,
8809 satIOContext->interruptContext);
8811 TI_DBG2(("satFormatUnit: return opcode\n"));
8816 checking DEFECT LIST FORMAT and defect list length
8818 if ( (((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x00) ||
8819 ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x06)) )
8821 /* short parameter header */
8822 if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x00)
8826 /* long parameter header */
8827 if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x01)
8831 /* defect list length */
8832 if ((scsiCmnd->cdb[index] != 0) || (scsiCmnd->cdb[index+1] != 0))
8834 satSetSensePayload( pSense,
8835 SCSI_SNSKEY_ILLEGAL_REQUEST,
8837 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8840 ostiInitiatorIOCompleted( tiRoot,
8843 SCSI_STAT_CHECK_CONDITION,
8844 satIOContext->pTiSenseData,
8845 satIOContext->interruptContext );
8847 TI_DBG1(("satFormatUnit: return defect list format\n"));
8852 /* FMTDATA == 1 && CMPLIST == 1*/
8853 if ( (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
8854 (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_CMPLIST_MASK) )
8856 satSetSensePayload( pSense,
8857 SCSI_SNSKEY_ILLEGAL_REQUEST,
8859 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8862 ostiInitiatorIOCompleted( tiRoot,
8865 SCSI_STAT_CHECK_CONDITION,
8866 satIOContext->pTiSenseData,
8867 satIOContext->interruptContext );
8869 TI_DBG1(("satFormatUnit: return cmplist\n"));
8874 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
8876 satSetSensePayload( pSense,
8877 SCSI_SNSKEY_ILLEGAL_REQUEST,
8879 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8882 ostiInitiatorIOCompleted( tiRoot,
8885 SCSI_STAT_CHECK_CONDITION,
8886 satIOContext->pTiSenseData,
8887 satIOContext->interruptContext );
8889 TI_DBG1(("satFormatUnit: return control\n"));
8893 /* defect list header filed, if exists, SAT rev8, Table 37, p48 */
8894 if (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK)
8897 /* IMMED 1; FOV 0; FOV 1, DCRT 1, IP 0 */
8898 if ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) ||
8899 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK)) ||
8900 ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8901 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8902 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK))
8905 ostiInitiatorIOCompleted( tiRoot,
8910 satIOContext->interruptContext);
8912 TI_DBG5(("satFormatUnit: return defect list case 1\n"));
8917 1. IMMED 0, FOV 1, DCRT 0, IP 0
8918 2. IMMED 0, FOV 1, DCRT 0, IP 1
8919 3. IMMED 0, FOV 1, DCRT 1, IP 1
8922 if ( ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
8923 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8924 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8925 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
8927 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
8928 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8929 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8930 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
8932 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
8933 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8934 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8935 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
8939 satSetSensePayload( pSense,
8940 SCSI_SNSKEY_ILLEGAL_REQUEST,
8942 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
8945 ostiInitiatorIOCompleted( tiRoot,
8948 SCSI_STAT_CHECK_CONDITION,
8949 satIOContext->pTiSenseData,
8950 satIOContext->interruptContext );
8952 TI_DBG5(("satFormatUnit: return defect list case 2\n"));
8960 * Send the completion response now.
8962 ostiInitiatorIOCompleted( tiRoot,
8967 satIOContext->interruptContext);
8969 TI_DBG5(("satFormatUnit: return last\n"));
8974 /*****************************************************************************/
8975 /*! \brief SAT implementation for SCSI satSendDiagnostic.
8977 * SAT implementation for SCSI satSendDiagnostic.
8979 * \param tiRoot: Pointer to TISA initiator driver/port instance.
8980 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
8981 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
8982 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
8983 * \param satIOContext_t: Pointer to the SAT IO Context
8985 * \return If command is started successfully
8986 * - \e tiSuccess: I/O request successfully initiated.
8987 * - \e tiBusy: No resources available, try again later.
8988 * - \e tiIONoDevice: Invalid device handle.
8989 * - \e tiError: Other errors.
8991 /*****************************************************************************/
8992 GLOBAL bit32 satSendDiagnostic(
8994 tiIORequest_t *tiIORequest,
8995 tiDeviceHandle_t *tiDeviceHandle,
8996 tiScsiInitiatorRequest_t *tiScsiRequest,
8997 satIOContext_t *satIOContext)
9000 bit32 agRequestType;
9001 satDeviceData_t *pSatDevData;
9002 scsiRspSense_t *pSense;
9003 tiIniScsiCmnd_t *scsiCmnd;
9004 agsaFisRegHostToDevice_t *fis;
9007 pSense = satIOContext->pSense;
9008 pSatDevData = satIOContext->pSatDevData;
9009 scsiCmnd = &tiScsiRequest->scsiCmnd;
9010 fis = satIOContext->pFis;
9012 TI_DBG5(("satSendDiagnostic:start\n"));
9014 /* reset satVerifyState */
9015 pSatDevData->satVerifyState = 0;
9016 /* no pending diagnostic in background */
9017 pSatDevData->satBGPendingDiag = agFALSE;
9019 /* table 27, 8.10 p39 SAT Rev8 */
9022 2. checking DEVOFFL == 1
9023 3. checking UNITOFFL == 1
9024 4. checking PARAMETER LIST LENGTH != 0
9027 if ( (scsiCmnd->cdb[1] & SCSI_PF_MASK) ||
9028 (scsiCmnd->cdb[1] & SCSI_DEVOFFL_MASK) ||
9029 (scsiCmnd->cdb[1] & SCSI_UNITOFFL_MASK) ||
9030 ( (scsiCmnd->cdb[3] != 0) || (scsiCmnd->cdb[4] != 0) )
9033 satSetSensePayload( pSense,
9034 SCSI_SNSKEY_ILLEGAL_REQUEST,
9036 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9039 ostiInitiatorIOCompleted( tiRoot,
9042 SCSI_STAT_CHECK_CONDITION,
9043 satIOContext->pTiSenseData,
9044 satIOContext->interruptContext );
9046 TI_DBG1(("satSendDiagnostic: return PF, DEVOFFL, UNITOFFL, PARAM LIST\n"));
9050 /* checking CONTROL */
9051 /* NACA == 1 or LINK == 1*/
9052 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
9054 satSetSensePayload( pSense,
9055 SCSI_SNSKEY_ILLEGAL_REQUEST,
9057 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9060 ostiInitiatorIOCompleted( tiRoot,
9063 SCSI_STAT_CHECK_CONDITION,
9064 satIOContext->pTiSenseData,
9065 satIOContext->interruptContext );
9067 TI_DBG2(("satSendDiagnostic: return control\n"));
9071 parmLen = (scsiCmnd->cdb[3] << 8) + scsiCmnd->cdb[4];
9073 /* checking SELFTEST bit*/
9074 /* table 29, 8.10.3, p41 SAT Rev8 */
9076 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9077 (pSatDevData->satSMARTSelfTest == agFALSE)
9080 satSetSensePayload( pSense,
9081 SCSI_SNSKEY_ILLEGAL_REQUEST,
9083 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9086 ostiInitiatorIOCompleted( tiRoot,
9089 SCSI_STAT_CHECK_CONDITION,
9090 satIOContext->pTiSenseData,
9091 satIOContext->interruptContext );
9093 TI_DBG1(("satSendDiagnostic: return Table 29 case 1\n"));
9098 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9099 (pSatDevData->satSMARTSelfTest == agTRUE) &&
9100 (pSatDevData->satSMARTEnabled == agFALSE)
9103 satSetSensePayload( pSense,
9104 SCSI_SNSKEY_ABORTED_COMMAND,
9106 SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
9109 ostiInitiatorIOCompleted( tiRoot,
9112 SCSI_STAT_CHECK_CONDITION,
9113 satIOContext->pTiSenseData,
9114 satIOContext->interruptContext );
9116 TI_DBG5(("satSendDiagnostic: return Table 29 case 2\n"));
9121 see SELF TEST CODE later
9129 sends three ATA verify commands
9132 if ( ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9133 (pSatDevData->satSMARTSelfTest == agFALSE))
9135 ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9136 (pSatDevData->satSMARTSelfTest == agTRUE) &&
9137 (pSatDevData->satSMARTEnabled == agFALSE))
9141 sector count 1, LBA 0
9142 sector count 1, LBA MAX
9143 sector count 1, LBA random
9145 if (pSatDevData->sat48BitSupport == agTRUE)
9147 /* sends READ VERIFY SECTOR(S) EXT*/
9148 fis->h.fisType = 0x27; /* Reg host to device */
9149 fis->h.c_pmPort = 0x80; /* C Bit is set */
9150 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9151 fis->h.features = 0; /* FIS reserve */
9152 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
9153 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
9154 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
9155 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
9156 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
9157 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
9158 fis->d.featuresExp = 0; /* FIS reserve */
9159 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9160 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
9161 fis->d.reserved4 = 0;
9162 fis->d.device = 0x40; /* 01000000 */
9163 fis->d.control = 0; /* FIS HOB bit clear */
9164 fis->d.reserved5 = 0;
9166 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9170 /* READ VERIFY SECTOR(S)*/
9171 fis->h.fisType = 0x27; /* Reg host to device */
9172 fis->h.c_pmPort = 0x80; /* C Bit is set */
9173 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9174 fis->h.features = 0; /* FIS features NA */
9175 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
9176 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
9177 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
9178 fis->d.lbaLowExp = 0;
9179 fis->d.lbaMidExp = 0;
9180 fis->d.lbaHighExp = 0;
9181 fis->d.featuresExp = 0;
9182 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9183 fis->d.sectorCountExp = 0;
9184 fis->d.reserved4 = 0;
9185 fis->d.device = 0x40; /* 01000000 */
9186 fis->d.control = 0; /* FIS HOB bit clear */
9187 fis->d.reserved5 = 0;
9189 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9192 /* Initialize CB for SATA completion.
9194 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9197 * Prepare SGL and send FIS to LL layer.
9199 satIOContext->reqType = agRequestType; /* Save it */
9201 status = sataLLIOStart( tiRoot,
9208 TI_DBG5(("satSendDiagnostic: return Table 29 case 4\n"));
9212 if ( (scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9213 (pSatDevData->satSMARTSelfTest == agTRUE) &&
9214 (pSatDevData->satSMARTEnabled == agTRUE)
9217 /* sends SMART EXECUTE OFF-LINE IMMEDIATE */
9218 fis->h.fisType = 0x27; /* Reg host to device */
9219 fis->h.c_pmPort = 0x80; /* C Bit is set */
9220 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0xB0 */
9221 fis->h.features = 0xD4; /* FIS features NA */
9222 fis->d.lbaLow = 0x81; /* FIS LBA (7 :0 ) */
9223 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
9224 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
9225 fis->d.lbaLowExp = 0;
9226 fis->d.lbaMidExp = 0;
9227 fis->d.lbaHighExp = 0;
9228 fis->d.featuresExp = 0;
9229 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9230 fis->d.sectorCountExp = 0;
9231 fis->d.reserved4 = 0;
9232 fis->d.device = 0; /* FIS DEV is discared in SATA */
9233 fis->d.control = 0; /* FIS HOB bit clear */
9234 fis->d.reserved5 = 0;
9236 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9238 /* Initialize CB for SATA completion.
9240 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9243 * Prepare SGL and send FIS to LL layer.
9245 satIOContext->reqType = agRequestType; /* Save it */
9247 status = sataLLIOStart( tiRoot,
9254 TI_DBG5(("satSendDiagnostic: return Table 29 case 5\n"));
9261 /* SAT rev8 Table29 p41 case 3*/
9262 /* checking SELF TEST CODE*/
9263 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9264 (pSatDevData->satSMARTSelfTest == agTRUE) &&
9265 (pSatDevData->satSMARTEnabled == agTRUE)
9268 /* SAT rev8 Table28 p40 */
9269 /* finding self-test code */
9270 switch ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_TEST_CODE_MASK) >> 5)
9273 pSatDevData->satBGPendingDiag = agTRUE;
9275 ostiInitiatorIOCompleted( tiRoot,
9280 satIOContext->interruptContext );
9281 /* sends SMART EXECUTE OFF-LINE IMMEDIATE */
9282 fis->h.fisType = 0x27; /* Reg host to device */
9283 fis->h.c_pmPort = 0x80; /* C Bit is set */
9284 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9285 fis->h.features = 0xD4; /* FIS features NA */
9286 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */
9287 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
9288 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
9290 fis->d.lbaLowExp = 0;
9291 fis->d.lbaMidExp = 0;
9292 fis->d.lbaHighExp = 0;
9293 fis->d.featuresExp = 0;
9294 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9295 fis->d.sectorCountExp = 0;
9296 fis->d.reserved4 = 0;
9297 fis->d.device = 0; /* FIS DEV is discared in SATA */
9298 fis->d.control = 0; /* FIS HOB bit clear */
9299 fis->d.reserved5 = 0;
9301 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9303 /* Initialize CB for SATA completion.
9305 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9308 * Prepare SGL and send FIS to LL layer.
9310 satIOContext->reqType = agRequestType; /* Save it */
9312 status = sataLLIOStart( tiRoot,
9319 TI_DBG5(("satSendDiagnostic: return Table 28 case 1\n"));
9322 pSatDevData->satBGPendingDiag = agTRUE;
9324 ostiInitiatorIOCompleted( tiRoot,
9329 satIOContext->interruptContext );
9332 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
9333 fis->h.fisType = 0x27; /* Reg host to device */
9334 fis->h.c_pmPort = 0x80; /* C Bit is set */
9335 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9336 fis->h.features = 0xD4; /* FIS features NA */
9337 fis->d.lbaLow = 0x02; /* FIS LBA (7 :0 ) */
9338 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
9339 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
9340 fis->d.lbaLowExp = 0;
9341 fis->d.lbaMidExp = 0;
9342 fis->d.lbaHighExp = 0;
9343 fis->d.featuresExp = 0;
9344 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9345 fis->d.sectorCountExp = 0;
9346 fis->d.reserved4 = 0;
9347 fis->d.device = 0; /* FIS DEV is discared in SATA */
9348 fis->d.control = 0; /* FIS HOB bit clear */
9349 fis->d.reserved5 = 0;
9351 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9353 /* Initialize CB for SATA completion.
9355 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9358 * Prepare SGL and send FIS to LL layer.
9360 satIOContext->reqType = agRequestType; /* Save it */
9362 status = sataLLIOStart( tiRoot,
9369 TI_DBG5(("satSendDiagnostic: return Table 28 case 2\n"));
9372 /* For simplicity, no abort is supported
9374 need a flag in device data for previously sent background Send Diagnostic
9378 /* check condition */
9379 satSetSensePayload( pSense,
9380 SCSI_SNSKEY_ILLEGAL_REQUEST,
9382 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9385 ostiInitiatorIOCompleted( tiRoot,
9388 SCSI_STAT_CHECK_CONDITION,
9389 satIOContext->pTiSenseData,
9390 satIOContext->interruptContext );
9392 TI_DBG1(("satSendDiagnostic: case 4, non zero ParmLen %d\n", parmLen));
9395 if (pSatDevData->satBGPendingDiag == agTRUE)
9397 /* sends SMART EXECUTE OFF-LINE IMMEDIATE abort */
9398 fis->h.fisType = 0x27; /* Reg host to device */
9399 fis->h.c_pmPort = 0x80; /* C Bit is set */
9400 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9401 fis->h.features = 0xD4; /* FIS features NA */
9402 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */
9403 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
9404 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
9406 fis->d.lbaLowExp = 0;
9407 fis->d.lbaMidExp = 0;
9408 fis->d.lbaHighExp = 0;
9409 fis->d.featuresExp = 0;
9410 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9411 fis->d.sectorCountExp = 0;
9412 fis->d.reserved4 = 0;
9413 fis->d.device = 0; /* FIS DEV is discared in SATA */
9414 fis->d.control = 0; /* FIS HOB bit clear */
9415 fis->d.reserved5 = 0;
9417 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9419 /* Initialize CB for SATA completion.
9421 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9424 * Prepare SGL and send FIS to LL layer.
9426 satIOContext->reqType = agRequestType; /* Save it */
9428 status = sataLLIOStart( tiRoot,
9435 TI_DBG5(("satSendDiagnostic: send SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE case 3\n"));
9436 TI_DBG5(("satSendDiagnostic: Table 28 case 4\n"));
9441 /* check condition */
9442 satSetSensePayload( pSense,
9443 SCSI_SNSKEY_ILLEGAL_REQUEST,
9445 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9448 ostiInitiatorIOCompleted( tiRoot,
9451 SCSI_STAT_CHECK_CONDITION,
9452 satIOContext->pTiSenseData,
9453 satIOContext->interruptContext );
9455 TI_DBG1(("satSendDiagnostic: case 4, no pending diagnostic in background\n"));
9456 TI_DBG5(("satSendDiagnostic: Table 28 case 4\n"));
9461 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
9462 fis->h.fisType = 0x27; /* Reg host to device */
9463 fis->h.c_pmPort = 0x80; /* C Bit is set */
9464 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9465 fis->h.features = 0xD4; /* FIS features NA */
9466 fis->d.lbaLow = 0x81; /* FIS LBA (7 :0 ) */
9467 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
9468 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
9469 fis->d.lbaLowExp = 0;
9470 fis->d.lbaMidExp = 0;
9471 fis->d.lbaHighExp = 0;
9472 fis->d.featuresExp = 0;
9473 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9474 fis->d.sectorCountExp = 0;
9475 fis->d.reserved4 = 0;
9476 fis->d.device = 0; /* FIS DEV is discared in SATA */
9477 fis->d.control = 0; /* FIS HOB bit clear */
9478 fis->d.reserved5 = 0;
9480 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9482 /* Initialize CB for SATA completion.
9484 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9487 * Prepare SGL and send FIS to LL layer.
9489 satIOContext->reqType = agRequestType; /* Save it */
9491 status = sataLLIOStart( tiRoot,
9498 TI_DBG5(("satSendDiagnostic: return Table 28 case 5\n"));
9501 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
9502 fis->h.fisType = 0x27; /* Reg host to device */
9503 fis->h.c_pmPort = 0x80; /* C Bit is set */
9504 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9505 fis->h.features = 0xD4; /* FIS features NA */
9506 fis->d.lbaLow = 0x82; /* FIS LBA (7 :0 ) */
9507 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
9508 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
9509 fis->d.lbaLowExp = 0;
9510 fis->d.lbaMidExp = 0;
9511 fis->d.lbaHighExp = 0;
9512 fis->d.featuresExp = 0;
9513 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9514 fis->d.sectorCountExp = 0;
9515 fis->d.reserved4 = 0;
9516 fis->d.device = 0; /* FIS DEV is discared in SATA */
9517 fis->d.control = 0; /* FIS HOB bit clear */
9518 fis->d.reserved5 = 0;
9520 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9522 /* Initialize CB for SATA completion.
9524 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9527 * Prepare SGL and send FIS to LL layer.
9529 satIOContext->reqType = agRequestType; /* Save it */
9531 status = sataLLIOStart( tiRoot,
9538 TI_DBG5(("satSendDiagnostic: return Table 28 case 6\n"));
9541 case 3: /* fall through */
9542 case 7: /* fall through */
9547 /* returns the results of default self-testing, which is good */
9548 ostiInitiatorIOCompleted( tiRoot,
9553 satIOContext->interruptContext );
9555 TI_DBG5(("satSendDiagnostic: return Table 28 case 0,3,7 and default\n"));
9560 ostiInitiatorIOCompleted( tiRoot,
9565 satIOContext->interruptContext );
9568 TI_DBG5(("satSendDiagnostic: return last\n"));
9572 /*****************************************************************************/
9573 /*! \brief SAT implementation for SCSI satSendDiagnostic_1.
9575 * SAT implementation for SCSI satSendDiagnostic_1.
9576 * Sub function of satSendDiagnostic.
9578 * \param tiRoot: Pointer to TISA initiator driver/port instance.
9579 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
9580 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
9581 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
9582 * \param satIOContext_t: Pointer to the SAT IO Context
9584 * \return If command is started successfully
9585 * - \e tiSuccess: I/O request successfully initiated.
9586 * - \e tiBusy: No resources available, try again later.
9587 * - \e tiIONoDevice: Invalid device handle.
9588 * - \e tiError: Other errors.
9590 /*****************************************************************************/
9591 GLOBAL bit32 satSendDiagnostic_1(
9593 tiIORequest_t *tiIORequest,
9594 tiDeviceHandle_t *tiDeviceHandle,
9595 tiScsiInitiatorRequest_t *tiScsiRequest,
9596 satIOContext_t *satIOContext)
9599 SAT Rev9, Table29, p41
9600 send 2nd SAT_READ_VERIFY_SECTORS(_EXT)
9603 bit32 agRequestType;
9604 satDeviceData_t *pSatDevData;
9605 agsaFisRegHostToDevice_t *fis;
9607 TI_DBG5(("satSendDiagnostic_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
9608 tiDeviceHandle, tiIORequest));
9610 pSatDevData = satIOContext->pSatDevData;
9611 fis = satIOContext->pFis;
9614 sector count 1, LBA MAX
9616 if (pSatDevData->sat48BitSupport == agTRUE)
9618 /* sends READ VERIFY SECTOR(S) EXT*/
9619 fis->h.fisType = 0x27; /* Reg host to device */
9620 fis->h.c_pmPort = 0x80; /* C Bit is set */
9621 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9622 fis->h.features = 0; /* FIS reserve */
9623 fis->d.lbaLow = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */
9624 fis->d.lbaMid = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */
9625 fis->d.lbaHigh = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */
9626 fis->d.lbaLowExp = pSatDevData->satMaxLBA[4]; /* FIS LBA (31:24) */
9627 fis->d.lbaMidExp = pSatDevData->satMaxLBA[3]; /* FIS LBA (39:32) */
9628 fis->d.lbaHighExp = pSatDevData->satMaxLBA[2]; /* FIS LBA (47:40) */
9629 fis->d.featuresExp = 0; /* FIS reserve */
9630 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9631 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
9632 fis->d.reserved4 = 0;
9633 fis->d.device = 0x40; /* 01000000 */
9634 fis->d.control = 0; /* FIS HOB bit clear */
9635 fis->d.reserved5 = 0;
9640 /* READ VERIFY SECTOR(S)*/
9641 fis->h.fisType = 0x27; /* Reg host to device */
9642 fis->h.c_pmPort = 0x80; /* C Bit is set */
9643 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9644 fis->h.features = 0; /* FIS features NA */
9645 fis->d.lbaLow = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */
9646 fis->d.lbaMid = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */
9647 fis->d.lbaHigh = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */
9648 fis->d.lbaLowExp = 0;
9649 fis->d.lbaMidExp = 0;
9650 fis->d.lbaHighExp = 0;
9651 fis->d.featuresExp = 0;
9652 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9653 fis->d.sectorCountExp = 0;
9654 fis->d.reserved4 = 0;
9655 fis->d.device = (bit8)((0x4 << 4) | (pSatDevData->satMaxLBA[4] & 0xF));
9656 /* DEV and LBA 27:24 */
9657 fis->d.control = 0; /* FIS HOB bit clear */
9658 fis->d.reserved5 = 0;
9662 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9664 /* Initialize CB for SATA completion.
9666 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9669 * Prepare SGL and send FIS to LL layer.
9671 satIOContext->reqType = agRequestType; /* Save it */
9673 status = sataLLIOStart( tiRoot,
9683 /*****************************************************************************/
9684 /*! \brief SAT implementation for SCSI satSendDiagnostic_2.
9686 * SAT implementation for SCSI satSendDiagnostic_2.
9687 * Sub function of satSendDiagnostic.
9689 * \param tiRoot: Pointer to TISA initiator driver/port instance.
9690 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
9691 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
9692 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
9693 * \param satIOContext_t: Pointer to the SAT IO Context
9695 * \return If command is started successfully
9696 * - \e tiSuccess: I/O request successfully initiated.
9697 * - \e tiBusy: No resources available, try again later.
9698 * - \e tiIONoDevice: Invalid device handle.
9699 * - \e tiError: Other errors.
9701 /*****************************************************************************/
9702 GLOBAL bit32 satSendDiagnostic_2(
9704 tiIORequest_t *tiIORequest,
9705 tiDeviceHandle_t *tiDeviceHandle,
9706 tiScsiInitiatorRequest_t *tiScsiRequest,
9707 satIOContext_t *satIOContext)
9710 SAT Rev9, Table29, p41
9711 send 3rd SAT_READ_VERIFY_SECTORS(_EXT)
9714 bit32 agRequestType;
9715 satDeviceData_t *pSatDevData;
9716 agsaFisRegHostToDevice_t *fis;
9718 TI_DBG5(("satSendDiagnostic_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
9719 tiDeviceHandle, tiIORequest));
9721 pSatDevData = satIOContext->pSatDevData;
9722 fis = satIOContext->pFis;
9725 sector count 1, LBA Random
9727 if (pSatDevData->sat48BitSupport == agTRUE)
9729 /* sends READ VERIFY SECTOR(S) EXT*/
9730 fis->h.fisType = 0x27; /* Reg host to device */
9731 fis->h.c_pmPort = 0x80; /* C Bit is set */
9732 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9733 fis->h.features = 0; /* FIS reserve */
9734 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */
9735 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
9736 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
9737 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
9738 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
9739 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
9740 fis->d.featuresExp = 0; /* FIS reserve */
9741 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9742 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
9743 fis->d.reserved4 = 0;
9744 fis->d.device = 0x40; /* 01000000 */
9745 fis->d.control = 0; /* FIS HOB bit clear */
9746 fis->d.reserved5 = 0;
9751 /* READ VERIFY SECTOR(S)*/
9752 fis->h.fisType = 0x27; /* Reg host to device */
9753 fis->h.c_pmPort = 0x80; /* C Bit is set */
9754 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9755 fis->h.features = 0; /* FIS features NA */
9756 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */
9757 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
9758 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
9759 fis->d.lbaLowExp = 0;
9760 fis->d.lbaMidExp = 0;
9761 fis->d.lbaHighExp = 0;
9762 fis->d.featuresExp = 0;
9763 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9764 fis->d.sectorCountExp = 0;
9765 fis->d.reserved4 = 0;
9766 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
9767 fis->d.control = 0; /* FIS HOB bit clear */
9768 fis->d.reserved5 = 0;
9772 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9774 /* Initialize CB for SATA completion.
9776 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9779 * Prepare SGL and send FIS to LL layer.
9781 satIOContext->reqType = agRequestType; /* Save it */
9783 status = sataLLIOStart( tiRoot,
9792 /*****************************************************************************/
9793 /*! \brief SAT implementation for SCSI satStartStopUnit.
9795 * SAT implementation for SCSI satStartStopUnit.
9797 * \param tiRoot: Pointer to TISA initiator driver/port instance.
9798 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
9799 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
9800 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
9801 * \param satIOContext_t: Pointer to the SAT IO Context
9803 * \return If command is started successfully
9804 * - \e tiSuccess: I/O request successfully initiated.
9805 * - \e tiBusy: No resources available, try again later.
9806 * - \e tiIONoDevice: Invalid device handle.
9807 * - \e tiError: Other errors.
9809 /*****************************************************************************/
9810 GLOBAL bit32 satStartStopUnit(
9812 tiIORequest_t *tiIORequest,
9813 tiDeviceHandle_t *tiDeviceHandle,
9814 tiScsiInitiatorRequest_t *tiScsiRequest,
9815 satIOContext_t *satIOContext)
9818 bit32 agRequestType;
9819 satDeviceData_t *pSatDevData;
9820 scsiRspSense_t *pSense;
9821 tiIniScsiCmnd_t *scsiCmnd;
9822 agsaFisRegHostToDevice_t *fis;
9824 pSense = satIOContext->pSense;
9825 pSatDevData = satIOContext->pSatDevData;
9826 scsiCmnd = &tiScsiRequest->scsiCmnd;
9827 fis = satIOContext->pFis;
9829 TI_DBG5(("satStartStopUnit:start\n"));
9831 /* checking CONTROL */
9832 /* NACA == 1 or LINK == 1*/
9833 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
9835 satSetSensePayload( pSense,
9836 SCSI_SNSKEY_ILLEGAL_REQUEST,
9838 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9841 ostiInitiatorIOCompleted( tiRoot,
9844 SCSI_STAT_CHECK_CONDITION,
9845 satIOContext->pTiSenseData,
9846 satIOContext->interruptContext );
9848 TI_DBG1(("satStartStopUnit: return control\n"));
9852 /* Spec p55, Table 48 checking START and LOEJ bit */
9854 if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
9856 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
9858 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
9859 ostiInitiatorIOCompleted( tiRoot,
9864 satIOContext->interruptContext );
9865 TI_DBG5(("satStartStopUnit: return table48 case 1-1\n"));
9868 /* sends FLUSH CACHE or FLUSH CACHE EXT */
9869 if (pSatDevData->sat48BitSupport == agTRUE)
9871 /* FLUSH CACHE EXT */
9872 fis->h.fisType = 0x27; /* Reg host to device */
9873 fis->h.c_pmPort = 0x80; /* C Bit is set */
9875 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */
9876 fis->h.features = 0; /* FIS reserve */
9877 fis->d.featuresExp = 0; /* FIS reserve */
9878 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9879 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
9880 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
9881 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
9882 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
9883 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
9884 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
9885 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
9886 fis->d.device = 0; /* FIS DEV is discared in SATA */
9887 fis->d.control = 0; /* FIS HOB bit clear */
9888 fis->d.reserved4 = 0;
9889 fis->d.reserved5 = 0;
9891 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9896 fis->h.fisType = 0x27; /* Reg host to device */
9897 fis->h.c_pmPort = 0x80; /* C Bit is set */
9899 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */
9900 fis->h.features = 0; /* FIS features NA */
9901 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
9902 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
9903 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
9904 fis->d.lbaLowExp = 0;
9905 fis->d.lbaMidExp = 0;
9906 fis->d.lbaHighExp = 0;
9907 fis->d.featuresExp = 0;
9908 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9909 fis->d.sectorCountExp = 0;
9910 fis->d.device = 0; /* FIS DEV is discared in SATA */
9911 fis->d.control = 0; /* FIS HOB bit clear */
9912 fis->d.reserved4 = 0;
9913 fis->d.reserved5 = 0;
9915 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9918 /* Initialize CB for SATA completion.
9920 satIOContext->satCompleteCB = &satStartStopUnitCB;
9923 * Prepare SGL and send FIS to LL layer.
9925 satIOContext->reqType = agRequestType; /* Save it */
9927 status = sataLLIOStart( tiRoot,
9934 TI_DBG5(("satStartStopUnit: return table48 case 1\n"));
9938 else if ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
9940 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
9941 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
9943 ostiInitiatorIOCompleted( tiRoot,
9948 satIOContext->interruptContext );
9950 TI_DBG5(("satStartStopUnit: return table48 case 2 1\n"));
9954 sends READ_VERIFY_SECTORS(_EXT)
9955 sector count 1, any LBA between zero to Maximum
9957 if (pSatDevData->sat48BitSupport == agTRUE)
9959 /* READ VERIFY SECTOR(S) EXT*/
9960 fis->h.fisType = 0x27; /* Reg host to device */
9961 fis->h.c_pmPort = 0x80; /* C Bit is set */
9963 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9964 fis->h.features = 0; /* FIS reserve */
9965 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */
9966 fis->d.lbaMid = 0x00; /* FIS LBA (15:8 ) */
9967 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */
9968 fis->d.lbaLowExp = 0x00; /* FIS LBA (31:24) */
9969 fis->d.lbaMidExp = 0x00; /* FIS LBA (39:32) */
9970 fis->d.lbaHighExp = 0x00; /* FIS LBA (47:40) */
9971 fis->d.featuresExp = 0; /* FIS reserve */
9972 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9973 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
9974 fis->d.reserved4 = 0;
9975 fis->d.device = 0x40; /* 01000000 */
9976 fis->d.control = 0; /* FIS HOB bit clear */
9977 fis->d.reserved5 = 0;
9982 /* READ VERIFY SECTOR(S)*/
9983 fis->h.fisType = 0x27; /* Reg host to device */
9984 fis->h.c_pmPort = 0x80; /* C Bit is set */
9986 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9987 fis->h.features = 0; /* FIS features NA */
9988 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */
9989 fis->d.lbaMid = 0x00; /* FIS LBA (15:8 ) */
9990 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */
9991 fis->d.lbaLowExp = 0;
9992 fis->d.lbaMidExp = 0;
9993 fis->d.lbaHighExp = 0;
9994 fis->d.featuresExp = 0;
9995 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9996 fis->d.sectorCountExp = 0;
9997 fis->d.reserved4 = 0;
9998 fis->d.device = 0x40; /* 01000000 */
9999 fis->d.control = 0; /* FIS HOB bit clear */
10000 fis->d.reserved5 = 0;
10004 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10006 /* Initialize CB for SATA completion.
10008 satIOContext->satCompleteCB = &satStartStopUnitCB;
10011 * Prepare SGL and send FIS to LL layer.
10013 satIOContext->reqType = agRequestType; /* Save it */
10015 status = sataLLIOStart( tiRoot,
10021 TI_DBG5(("satStartStopUnit: return table48 case 2 2\n"));
10025 else if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
10027 if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
10029 /* support for removal media */
10030 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
10031 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
10033 ostiInitiatorIOCompleted( tiRoot,
10038 satIOContext->interruptContext );
10040 TI_DBG5(("satStartStopUnit: return table48 case 3 1\n"));
10046 /* Media Eject fis */
10047 fis->h.fisType = 0x27; /* Reg host to device */
10048 fis->h.c_pmPort = 0x80; /* C Bit is set */
10050 fis->h.command = SAT_MEDIA_EJECT; /* 0xED */
10051 fis->h.features = 0; /* FIS features NA */
10052 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
10053 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
10054 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
10055 fis->d.lbaLowExp = 0;
10056 fis->d.lbaMidExp = 0;
10057 fis->d.lbaHighExp = 0;
10058 fis->d.featuresExp = 0;
10059 /* sector count zero */
10060 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
10061 fis->d.sectorCountExp = 0;
10062 fis->d.device = 0; /* FIS DEV is discared in SATA */
10063 fis->d.control = 0; /* FIS HOB bit clear */
10064 fis->d.reserved4 = 0;
10065 fis->d.reserved5 = 0;
10067 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10069 /* Initialize CB for SATA completion.
10071 satIOContext->satCompleteCB = &satStartStopUnitCB;
10074 * Prepare SGL and send FIS to LL layer.
10076 satIOContext->reqType = agRequestType; /* Save it */
10078 status = sataLLIOStart( tiRoot,
10088 /* no support for removal media */
10089 satSetSensePayload( pSense,
10090 SCSI_SNSKEY_ILLEGAL_REQUEST,
10092 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10095 ostiInitiatorIOCompleted( tiRoot,
10098 SCSI_STAT_CHECK_CONDITION,
10099 satIOContext->pTiSenseData,
10100 satIOContext->interruptContext );
10102 TI_DBG5(("satStartStopUnit: return Table 29 case 3 2\n"));
10108 else /* ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) */
10110 satSetSensePayload( pSense,
10111 SCSI_SNSKEY_ILLEGAL_REQUEST,
10113 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10116 ostiInitiatorIOCompleted( tiRoot,
10119 SCSI_STAT_CHECK_CONDITION,
10120 satIOContext->pTiSenseData,
10121 satIOContext->interruptContext );
10123 TI_DBG5(("satStartStopUnit: return Table 29 case 4\n"));
10131 /*****************************************************************************/
10132 /*! \brief SAT implementation for SCSI satStartStopUnit_1.
10134 * SAT implementation for SCSI satStartStopUnit_1.
10135 * Sub function of satStartStopUnit
10137 * \param tiRoot: Pointer to TISA initiator driver/port instance.
10138 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
10139 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
10140 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
10141 * \param satIOContext_t: Pointer to the SAT IO Context
10143 * \return If command is started successfully
10144 * - \e tiSuccess: I/O request successfully initiated.
10145 * - \e tiBusy: No resources available, try again later.
10146 * - \e tiIONoDevice: Invalid device handle.
10147 * - \e tiError: Other errors.
10149 /*****************************************************************************/
10150 GLOBAL bit32 satStartStopUnit_1(
10152 tiIORequest_t *tiIORequest,
10153 tiDeviceHandle_t *tiDeviceHandle,
10154 tiScsiInitiatorRequest_t *tiScsiRequest,
10155 satIOContext_t *satIOContext)
10158 SAT Rev 8, Table 48, 9.11.3 p55
10162 bit32 agRequestType;
10163 agsaFisRegHostToDevice_t *fis;
10165 TI_DBG5(("satStartStopUnit_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10166 tiDeviceHandle, tiIORequest));
10168 fis = satIOContext->pFis;
10171 fis->h.fisType = 0x27; /* Reg host to device */
10172 fis->h.c_pmPort = 0x80; /* C Bit is set */
10174 fis->h.command = SAT_STANDBY; /* 0xE2 */
10175 fis->h.features = 0; /* FIS features NA */
10176 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
10177 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
10178 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
10179 fis->d.lbaLowExp = 0;
10180 fis->d.lbaMidExp = 0;
10181 fis->d.lbaHighExp = 0;
10182 fis->d.featuresExp = 0;
10183 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
10184 fis->d.sectorCountExp = 0;
10185 fis->d.reserved4 = 0;
10186 fis->d.device = 0; /* 0 */
10187 fis->d.control = 0; /* FIS HOB bit clear */
10188 fis->d.reserved5 = 0;
10190 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10192 /* Initialize CB for SATA completion.
10194 satIOContext->satCompleteCB = &satStartStopUnitCB;
10197 * Prepare SGL and send FIS to LL layer.
10199 satIOContext->reqType = agRequestType; /* Save it */
10201 status = sataLLIOStart( tiRoot,
10207 TI_DBG5(("satStartStopUnit_1 return status %d\n", status));
10211 /*****************************************************************************/
10212 /*! \brief SAT implementation for SCSI satRead10_2.
10214 * SAT implementation for SCSI satRead10_2
10215 * Sub function of satRead10
10217 * \param tiRoot: Pointer to TISA initiator driver/port instance.
10218 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
10219 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
10220 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
10221 * \param satIOContext_t: Pointer to the SAT IO Context
10223 * \return If command is started successfully
10224 * - \e tiSuccess: I/O request successfully initiated.
10225 * - \e tiBusy: No resources available, try again later.
10226 * - \e tiIONoDevice: Invalid device handle.
10227 * - \e tiError: Other errors.
10229 /*****************************************************************************/
10230 GLOBAL bit32 satRead10_2(
10232 tiIORequest_t *tiIORequest,
10233 tiDeviceHandle_t *tiDeviceHandle,
10234 tiScsiInitiatorRequest_t *tiScsiRequest,
10235 satIOContext_t *satIOContext)
10238 externally generated ATA cmd, there is corresponding scsi cmnd
10239 called by satStartStopUnit() or maybe satRead10()
10243 bit32 agRequestType;
10244 satDeviceData_t *pSatDevData;
10245 agsaFisRegHostToDevice_t *fis;
10247 pSatDevData = satIOContext->pSatDevData;
10248 fis = satIOContext->pFis;
10250 TI_DBG5(("satReadVerifySectorsNoChain: start\n"));
10252 /* specifying ReadVerifySectors has no chain */
10253 pSatDevData->satVerifyState = 0xFFFFFFFF;
10255 if (pSatDevData->sat48BitSupport == agTRUE)
10257 /* READ VERIFY SECTOR(S) EXT*/
10258 fis->h.fisType = 0x27; /* Reg host to device */
10259 fis->h.c_pmPort = 0x80; /* C Bit is set */
10260 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
10261 fis->h.features = 0; /* FIS reserve */
10262 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */
10263 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
10264 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */
10265 fis->d.lbaLowExp = 0xF1; /* FIS LBA (31:24) */
10266 fis->d.lbaMidExp = 0x5F; /* FIS LBA (39:32) */
10267 fis->d.lbaHighExp = 0xFF; /* FIS LBA (47:40) */
10268 fis->d.featuresExp = 0; /* FIS reserve */
10269 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
10270 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
10271 fis->d.reserved4 = 0;
10272 fis->d.device = 0x4E; /* 01001110 */
10273 fis->d.control = 0; /* FIS HOB bit clear */
10274 fis->d.reserved5 = 0;
10276 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10280 /* READ VERIFY SECTOR(S)*/
10281 fis->h.fisType = 0x27; /* Reg host to device */
10282 fis->h.c_pmPort = 0x80; /* C Bit is set */
10283 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
10284 fis->h.features = 0; /* FIS features NA */
10285 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */
10286 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
10287 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */
10288 fis->d.lbaLowExp = 0;
10289 fis->d.lbaMidExp = 0;
10290 fis->d.lbaHighExp = 0;
10291 fis->d.featuresExp = 0;
10292 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
10293 fis->d.sectorCountExp = 0;
10294 fis->d.reserved4 = 0;
10295 fis->d.device = 0x4E; /* 01001110 */
10296 fis->d.control = 0; /* FIS HOB bit clear */
10297 fis->d.reserved5 = 0;
10299 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10302 /* Initialize CB for SATA completion.
10304 satIOContext->satCompleteCB = &satNonDataIOCB;
10307 * Prepare SGL and send FIS to LL layer.
10309 satIOContext->reqType = agRequestType; /* Save it */
10311 status = sataLLIOStart( tiRoot,
10317 TI_DBG5(("satReadVerifySectorsNoChain: return last\n"));
10323 /*****************************************************************************/
10324 /*! \brief SAT implementation for SCSI satWriteSame10.
10326 * SAT implementation for SCSI satWriteSame10.
10328 * \param tiRoot: Pointer to TISA initiator driver/port instance.
10329 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
10330 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
10331 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
10332 * \param satIOContext_t: Pointer to the SAT IO Context
10334 * \return If command is started successfully
10335 * - \e tiSuccess: I/O request successfully initiated.
10336 * - \e tiBusy: No resources available, try again later.
10337 * - \e tiIONoDevice: Invalid device handle.
10338 * - \e tiError: Other errors.
10340 /*****************************************************************************/
10341 GLOBAL bit32 satWriteSame10(
10343 tiIORequest_t *tiIORequest,
10344 tiDeviceHandle_t *tiDeviceHandle,
10345 tiScsiInitiatorRequest_t *tiScsiRequest,
10346 satIOContext_t *satIOContext)
10349 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
10350 satDeviceData_t *pSatDevData;
10351 scsiRspSense_t *pSense;
10352 tiIniScsiCmnd_t *scsiCmnd;
10353 agsaFisRegHostToDevice_t *fis;
10357 pSense = satIOContext->pSense;
10358 pSatDevData = satIOContext->pSatDevData;
10359 scsiCmnd = &tiScsiRequest->scsiCmnd;
10360 fis = satIOContext->pFis;
10362 TI_DBG5(("satWriteSame10: start\n"));
10364 /* checking CONTROL */
10365 /* NACA == 1 or LINK == 1*/
10366 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
10368 satSetSensePayload( pSense,
10369 SCSI_SNSKEY_ILLEGAL_REQUEST,
10371 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10374 ostiInitiatorIOCompleted( tiRoot,
10377 SCSI_STAT_CHECK_CONDITION,
10378 satIOContext->pTiSenseData,
10379 satIOContext->interruptContext );
10381 TI_DBG1(("satWriteSame10: return control\n"));
10386 /* checking LBDATA and PBDATA */
10388 if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10389 !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
10391 TI_DBG5(("satWriteSame10: case 1\n"));
10392 /* spec 9.26.2, Table 62, p64, case 1*/
10395 just like write in 9.17.1
10398 if ( pSatDevData->sat48BitSupport != agTRUE )
10401 writeSame10 but no support for 48 bit addressing
10402 -> problem in transfer length. Therefore, return check condition
10404 satSetSensePayload( pSense,
10405 SCSI_SNSKEY_ILLEGAL_REQUEST,
10407 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10410 ostiInitiatorIOCompleted( tiRoot,
10413 SCSI_STAT_CHECK_CONDITION,
10414 satIOContext->pTiSenseData,
10415 satIOContext->interruptContext );
10417 TI_DBG1(("satWriteSame10: return internal checking\n"));
10421 /* cdb10; computing LBA and transfer length */
10422 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
10423 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
10424 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
10427 /* Table 34, 9.1, p 46 */
10429 note: As of 2/10/2006, no support for DMA QUEUED
10433 Table 34, 9.1, p 46, b (footnote)
10434 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
10435 return check condition
10437 if (pSatDevData->satNCQ != agTRUE &&
10438 pSatDevData->sat48BitSupport != agTRUE
10441 if (lba > SAT_TR_LBA_LIMIT - 1) /* SAT_TR_LBA_LIMIT is 2^28, 0x10000000 */
10443 satSetSensePayload( pSense,
10444 SCSI_SNSKEY_ILLEGAL_REQUEST,
10446 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
10449 ostiInitiatorIOCompleted( tiRoot,
10452 SCSI_STAT_CHECK_CONDITION,
10453 satIOContext->pTiSenseData,
10454 satIOContext->interruptContext );
10456 TI_DBG1(("satWriteSame10: return LBA out of range\n"));
10461 if (lba + tl <= SAT_TR_LBA_LIMIT)
10463 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
10467 /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */
10468 TI_DBG5(("satWriteSame10: case 1-2 !!! error due to writeSame10\n"));
10469 satSetSensePayload( pSense,
10470 SCSI_SNSKEY_ILLEGAL_REQUEST,
10472 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10475 ostiInitiatorIOCompleted( tiRoot,
10478 SCSI_STAT_CHECK_CONDITION,
10479 satIOContext->pTiSenseData,
10480 satIOContext->interruptContext );
10486 /* WRITE MULTIPLE or WRITE SECTOR(S) */
10487 /* WRITE SECTORS is chosen for easier implemetation */
10488 /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */
10489 TI_DBG5(("satWriteSame10: case 1-1 !!! error due to writesame10\n"));
10490 satSetSensePayload( pSense,
10491 SCSI_SNSKEY_ILLEGAL_REQUEST,
10493 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10496 ostiInitiatorIOCompleted( tiRoot,
10499 SCSI_STAT_CHECK_CONDITION,
10500 satIOContext->pTiSenseData,
10501 satIOContext->interruptContext );
10504 } /* end of case 1 and 2 */
10507 if (pSatDevData->sat48BitSupport == agTRUE)
10509 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
10512 /* WRITE DMA EXT or WRITE DMA FUA EXT */
10513 /* WRITE DMA EXT is chosen since WRITE SAME does not have FUA bit */
10514 TI_DBG5(("satWriteSame10: case 1-3\n"));
10515 fis->h.fisType = 0x27; /* Reg host to device */
10516 fis->h.c_pmPort = 0x80; /* C Bit is set */
10518 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
10520 fis->h.features = 0; /* FIS reserve */
10521 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
10522 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
10523 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
10524 fis->d.device = 0x40; /* FIS LBA mode set */
10525 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
10526 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
10527 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
10528 fis->d.featuresExp = 0; /* FIS reserve */
10532 ATA spec, p125, 6.17.29
10533 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
10534 and allowed value is 0x0FFFFFFF - 1
10536 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
10538 TI_DBG5(("satWriteSame10: case 3 !!! warning can't fit sectors\n"));
10539 satSetSensePayload( pSense,
10540 SCSI_SNSKEY_ILLEGAL_REQUEST,
10542 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10545 ostiInitiatorIOCompleted( tiRoot,
10548 SCSI_STAT_CHECK_CONDITION,
10549 satIOContext->pTiSenseData,
10550 satIOContext->interruptContext );
10554 /* one sector at a time */
10555 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
10556 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
10557 fis->d.reserved4 = 0;
10558 fis->d.control = 0; /* FIS HOB bit clear */
10559 fis->d.reserved5 = 0;
10561 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
10566 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
10567 /* WRITE SECTORS EXT is chosen for easier implemetation */
10568 TI_DBG5(("satWriteSame10: case 1-4\n"));
10569 fis->h.fisType = 0x27; /* Reg host to device */
10570 fis->h.c_pmPort = 0x80; /* C Bit is set */
10572 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
10573 fis->h.features = 0; /* FIS reserve */
10574 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
10575 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
10576 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
10577 fis->d.device = 0x40; /* FIS LBA mode set */
10578 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
10579 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
10580 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
10581 fis->d.featuresExp = 0; /* FIS reserve */
10585 ATA spec, p125, 6.17.29
10586 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
10587 and allowed value is 0x0FFFFFFF - 1
10589 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
10591 TI_DBG5(("satWriteSame10: case 4 !!! warning can't fit sectors\n"));
10592 satSetSensePayload( pSense,
10593 SCSI_SNSKEY_ILLEGAL_REQUEST,
10595 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10598 ostiInitiatorIOCompleted( tiRoot,
10601 SCSI_STAT_CHECK_CONDITION,
10602 satIOContext->pTiSenseData,
10603 satIOContext->interruptContext );
10607 /* one sector at a time */
10608 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
10609 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
10610 fis->d.reserved4 = 0;
10611 fis->d.control = 0; /* FIS HOB bit clear */
10612 fis->d.reserved5 = 0;
10614 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
10619 if (pSatDevData->satNCQ == agTRUE)
10621 /* WRITE FPDMA QUEUED */
10622 if (pSatDevData->sat48BitSupport != agTRUE)
10624 TI_DBG5(("satWriteSame10: case 1-5 !!! error NCQ but 28 bit address support \n"));
10625 satSetSensePayload( pSense,
10626 SCSI_SNSKEY_ILLEGAL_REQUEST,
10628 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10631 ostiInitiatorIOCompleted( tiRoot,
10634 SCSI_STAT_CHECK_CONDITION,
10635 satIOContext->pTiSenseData,
10636 satIOContext->interruptContext );
10639 TI_DBG5(("satWriteSame10: case 1-5\n"));
10641 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
10643 fis->h.fisType = 0x27; /* Reg host to device */
10644 fis->h.c_pmPort = 0x80; /* C Bit is set */
10645 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
10650 ATA spec, p125, 6.17.29
10651 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
10652 and allowed value is 0x0FFFFFFF - 1
10654 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
10656 TI_DBG5(("satWriteSame10: case 4 !!! warning can't fit sectors\n"));
10657 satSetSensePayload( pSense,
10658 SCSI_SNSKEY_ILLEGAL_REQUEST,
10660 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10663 ostiInitiatorIOCompleted( tiRoot,
10666 SCSI_STAT_CHECK_CONDITION,
10667 satIOContext->pTiSenseData,
10668 satIOContext->interruptContext );
10672 /* one sector at a time */
10673 fis->h.features = 1; /* FIS sector count (7:0) */
10674 fis->d.featuresExp = 0; /* FIS sector count (15:8) */
10677 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
10678 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
10679 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
10681 /* NO FUA bit in the WRITE SAME 10 */
10682 fis->d.device = 0x40; /* FIS FUA clear */
10684 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
10685 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
10686 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
10687 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
10688 fis->d.sectorCountExp = 0;
10689 fis->d.reserved4 = 0;
10690 fis->d.control = 0; /* FIS HOB bit clear */
10691 fis->d.reserved5 = 0;
10693 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
10695 /* Initialize CB for SATA completion.
10697 satIOContext->satCompleteCB = &satWriteSame10CB;
10700 * Prepare SGL and send FIS to LL layer.
10702 satIOContext->reqType = agRequestType; /* Save it */
10704 status = sataLLIOStart( tiRoot,
10712 } /* end of case 1 */
10713 else if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10714 (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
10716 /* spec 9.26.2, Table 62, p64, case 2*/
10717 satSetSensePayload( pSense,
10718 SCSI_SNSKEY_ILLEGAL_REQUEST,
10720 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10723 ostiInitiatorIOCompleted( tiRoot,
10726 SCSI_STAT_CHECK_CONDITION,
10727 satIOContext->pTiSenseData,
10728 satIOContext->interruptContext );
10730 TI_DBG5(("satWriteSame10: return Table 62 case 2\n"));
10733 else if ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10734 !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
10736 TI_DBG5(("satWriteSame10: Table 62 case 3\n"));
10739 else /* ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10740 (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) */
10743 /* spec 9.26.2, Table 62, p64, case 4*/
10744 satSetSensePayload( pSense,
10745 SCSI_SNSKEY_ILLEGAL_REQUEST,
10747 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10750 ostiInitiatorIOCompleted( tiRoot,
10753 SCSI_STAT_CHECK_CONDITION,
10754 satIOContext->pTiSenseData,
10755 satIOContext->interruptContext );
10757 TI_DBG5(("satWriteSame10: return Table 62 case 4\n"));
10765 /*****************************************************************************/
10766 /*! \brief SAT implementation for SCSI satWriteSame10_1.
10768 * SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer.
10769 * This is used when WRITESAME10 is divided into multiple ATA commands
10771 * \param tiRoot: Pointer to TISA initiator driver/port instance.
10772 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
10773 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
10774 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
10775 * \param satIOContext_t: Pointer to the SAT IO Context
10778 * \return If command is started successfully
10779 * - \e tiSuccess: I/O request successfully initiated.
10780 * - \e tiBusy: No resources available, try again later.
10781 * - \e tiIONoDevice: Invalid device handle.
10782 * - \e tiError: Other errors.
10784 /*****************************************************************************/
10785 GLOBAL bit32 satWriteSame10_1(
10787 tiIORequest_t *tiIORequest,
10788 tiDeviceHandle_t *tiDeviceHandle,
10789 tiScsiInitiatorRequest_t *tiScsiRequest,
10790 satIOContext_t *satIOContext,
10795 sends SAT_WRITE_DMA_EXT
10799 bit32 agRequestType;
10800 agsaFisRegHostToDevice_t *fis;
10801 bit8 lba1, lba2 ,lba3, lba4;
10803 TI_DBG5(("satWriteSame10_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10804 tiDeviceHandle, tiIORequest));
10806 fis = satIOContext->pFis;
10809 lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
10810 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
10811 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
10813 lba4 = (bit8)(lba & 0x000000FF);
10815 /* SAT_WRITE_DMA_EXT */
10816 fis->h.fisType = 0x27; /* Reg host to device */
10817 fis->h.c_pmPort = 0x80; /* C Bit is set */
10819 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
10821 fis->h.features = 0; /* FIS reserve */
10822 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */
10823 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */
10824 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */
10825 fis->d.device = 0x40; /* FIS LBA mode set */
10826 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */
10827 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
10828 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
10829 fis->d.featuresExp = 0; /* FIS reserve */
10830 /* one sector at a time */
10831 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
10832 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
10834 fis->d.reserved4 = 0;
10835 fis->d.control = 0; /* FIS HOB bit clear */
10836 fis->d.reserved5 = 0;
10839 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
10841 /* Initialize CB for SATA completion.
10843 satIOContext->satCompleteCB = &satWriteSame10CB;
10846 * Prepare SGL and send FIS to LL layer.
10848 satIOContext->reqType = agRequestType; /* Save it */
10850 status = sataLLIOStart( tiRoot,
10856 TI_DBG5(("satWriteSame10_1 return status %d\n", status));
10860 /*****************************************************************************/
10861 /*! \brief SAT implementation for SCSI satWriteSame10_2.
10863 * SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer.
10864 * This is used when WRITESAME10 is divided into multiple ATA commands
10866 * \param tiRoot: Pointer to TISA initiator driver/port instance.
10867 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
10868 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
10869 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
10870 * \param satIOContext_t: Pointer to the SAT IO Context
10873 * \return If command is started successfully
10874 * - \e tiSuccess: I/O request successfully initiated.
10875 * - \e tiBusy: No resources available, try again later.
10876 * - \e tiIONoDevice: Invalid device handle.
10877 * - \e tiError: Other errors.
10879 /*****************************************************************************/
10880 GLOBAL bit32 satWriteSame10_2(
10882 tiIORequest_t *tiIORequest,
10883 tiDeviceHandle_t *tiDeviceHandle,
10884 tiScsiInitiatorRequest_t *tiScsiRequest,
10885 satIOContext_t *satIOContext,
10890 sends SAT_WRITE_SECTORS_EXT
10894 bit32 agRequestType;
10895 agsaFisRegHostToDevice_t *fis;
10896 bit8 lba1, lba2 ,lba3, lba4;
10898 TI_DBG5(("satWriteSame10_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10899 tiDeviceHandle, tiIORequest));
10901 fis = satIOContext->pFis;
10904 lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
10905 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
10906 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
10908 lba4 = (bit8)(lba & 0x000000FF);
10911 /* SAT_WRITE_SECTORS_EXT */
10912 fis->h.fisType = 0x27; /* Reg host to device */
10913 fis->h.c_pmPort = 0x80; /* C Bit is set */
10915 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
10916 fis->h.features = 0; /* FIS reserve */
10917 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */
10918 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */
10919 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */
10920 fis->d.device = 0x40; /* FIS LBA mode set */
10921 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */
10922 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
10923 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
10924 fis->d.featuresExp = 0; /* FIS reserve */
10925 /* one sector at a time */
10926 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
10927 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
10929 fis->d.reserved4 = 0;
10930 fis->d.control = 0; /* FIS HOB bit clear */
10931 fis->d.reserved5 = 0;
10934 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
10936 /* Initialize CB for SATA completion.
10938 satIOContext->satCompleteCB = &satWriteSame10CB;
10941 * Prepare SGL and send FIS to LL layer.
10943 satIOContext->reqType = agRequestType; /* Save it */
10945 status = sataLLIOStart( tiRoot,
10951 TI_DBG5(("satWriteSame10_2 return status %d\n", status));
10955 /*****************************************************************************/
10956 /*! \brief SAT implementation for SCSI satWriteSame10_3.
10958 * SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer.
10959 * This is used when WRITESAME10 is divided into multiple ATA commands
10961 * \param tiRoot: Pointer to TISA initiator driver/port instance.
10962 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
10963 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
10964 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
10965 * \param satIOContext_t: Pointer to the SAT IO Context
10968 * \return If command is started successfully
10969 * - \e tiSuccess: I/O request successfully initiated.
10970 * - \e tiBusy: No resources available, try again later.
10971 * - \e tiIONoDevice: Invalid device handle.
10972 * - \e tiError: Other errors.
10974 /*****************************************************************************/
10975 GLOBAL bit32 satWriteSame10_3(
10977 tiIORequest_t *tiIORequest,
10978 tiDeviceHandle_t *tiDeviceHandle,
10979 tiScsiInitiatorRequest_t *tiScsiRequest,
10980 satIOContext_t *satIOContext,
10985 sends SAT_WRITE_FPDMA_QUEUED
10989 bit32 agRequestType;
10990 agsaFisRegHostToDevice_t *fis;
10991 bit8 lba1, lba2 ,lba3, lba4;
10993 TI_DBG5(("satWriteSame10_3 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10994 tiDeviceHandle, tiIORequest));
10996 fis = satIOContext->pFis;
10999 lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
11000 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
11001 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
11003 lba4 = (bit8)(lba & 0x000000FF);
11005 /* SAT_WRITE_FPDMA_QUEUED */
11006 fis->h.fisType = 0x27; /* Reg host to device */
11007 fis->h.c_pmPort = 0x80; /* C Bit is set */
11008 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
11011 /* one sector at a time */
11012 fis->h.features = 1; /* FIS sector count (7:0) */
11013 fis->d.featuresExp = 0; /* FIS sector count (15:8) */
11016 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */
11017 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */
11018 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */
11020 /* NO FUA bit in the WRITE SAME 10 */
11021 fis->d.device = 0x40; /* FIS FUA clear */
11023 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */
11024 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
11025 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
11026 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
11027 fis->d.sectorCountExp = 0;
11028 fis->d.reserved4 = 0;
11029 fis->d.control = 0; /* FIS HOB bit clear */
11030 fis->d.reserved5 = 0;
11032 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
11034 /* Initialize CB for SATA completion.
11036 satIOContext->satCompleteCB = &satWriteSame10CB;
11039 * Prepare SGL and send FIS to LL layer.
11041 satIOContext->reqType = agRequestType; /* Save it */
11043 status = sataLLIOStart( tiRoot,
11049 TI_DBG5(("satWriteSame10_2 return status %d\n", status));
11052 /*****************************************************************************/
11053 /*! \brief SAT implementation for SCSI satWriteSame16.
11055 * SAT implementation for SCSI satWriteSame16.
11057 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11058 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11059 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11060 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11061 * \param satIOContext_t: Pointer to the SAT IO Context
11063 * \return If command is started successfully
11064 * - \e tiSuccess: I/O request successfully initiated.
11065 * - \e tiBusy: No resources available, try again later.
11066 * - \e tiIONoDevice: Invalid device handle.
11067 * - \e tiError: Other errors.
11069 /*****************************************************************************/
11070 GLOBAL bit32 satWriteSame16(
11072 tiIORequest_t *tiIORequest,
11073 tiDeviceHandle_t *tiDeviceHandle,
11074 tiScsiInitiatorRequest_t *tiScsiRequest,
11075 satIOContext_t *satIOContext)
11077 scsiRspSense_t *pSense;
11079 pSense = satIOContext->pSense;
11081 TI_DBG5(("satWriteSame16:start\n"));
11084 satSetSensePayload( pSense,
11085 SCSI_SNSKEY_NO_SENSE,
11087 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
11090 ostiInitiatorIOCompleted( tiRoot,
11091 tiIORequest, /* == &satIntIo->satOrgTiIORequest */
11093 SCSI_STAT_CHECK_CONDITION,
11094 satIOContext->pTiSenseData,
11095 satIOContext->interruptContext );
11096 TI_DBG5(("satWriteSame16: return internal checking\n"));
11100 /*****************************************************************************/
11101 /*! \brief SAT implementation for SCSI satLogSense_1.
11103 * Part of SAT implementation for SCSI satLogSense.
11105 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11106 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11107 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11108 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11109 * \param satIOContext_t: Pointer to the SAT IO Context
11111 * \return If command is started successfully
11112 * - \e tiSuccess: I/O request successfully initiated.
11113 * - \e tiBusy: No resources available, try again later.
11114 * - \e tiIONoDevice: Invalid device handle.
11115 * - \e tiError: Other errors.
11117 /*****************************************************************************/
11118 GLOBAL bit32 satLogSense_1(
11120 tiIORequest_t *tiIORequest,
11121 tiDeviceHandle_t *tiDeviceHandle,
11122 tiScsiInitiatorRequest_t *tiScsiRequest,
11123 satIOContext_t *satIOContext)
11126 bit32 agRequestType;
11127 satDeviceData_t *pSatDevData;
11128 agsaFisRegHostToDevice_t *fis;
11130 pSatDevData = satIOContext->pSatDevData;
11131 fis = satIOContext->pFis;
11133 TI_DBG5(("satLogSense_1: start\n"));
11136 /* SAT Rev 8, 10.2.4 p74 */
11137 if ( pSatDevData->sat48BitSupport == agTRUE )
11139 TI_DBG5(("satLogSense_1: case 2-1 sends READ LOG EXT\n"));
11140 /* sends READ LOG EXT */
11141 fis->h.fisType = 0x27; /* Reg host to device */
11142 fis->h.c_pmPort = 0x80; /* C Bit is set */
11144 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */
11145 fis->h.features = 0; /* FIS reserve */
11146 fis->d.lbaLow = 0x07; /* 0x07 */
11147 fis->d.lbaMid = 0; /* */
11148 fis->d.lbaHigh = 0; /* */
11149 fis->d.device = 0; /* */
11150 fis->d.lbaLowExp = 0; /* */
11151 fis->d.lbaMidExp = 0; /* */
11152 fis->d.lbaHighExp = 0; /* */
11153 fis->d.featuresExp = 0; /* FIS reserve */
11154 fis->d.sectorCount = 0x01; /* 1 sector counts */
11155 fis->d.sectorCountExp = 0x00; /* 1 sector counts */
11156 fis->d.reserved4 = 0;
11157 fis->d.control = 0; /* FIS HOB bit clear */
11158 fis->d.reserved5 = 0;
11160 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11162 /* Initialize CB for SATA completion.
11164 satIOContext->satCompleteCB = &satLogSenseCB;
11167 * Prepare SGL and send FIS to LL layer.
11169 satIOContext->reqType = agRequestType; /* Save it */
11171 status = sataLLIOStart( tiRoot,
11181 TI_DBG5(("satLogSense_1: case 2-2 sends SMART READ LOG\n"));
11182 /* sends SMART READ LOG */
11183 fis->h.fisType = 0x27; /* Reg host to device */
11184 fis->h.c_pmPort = 0x80; /* C Bit is set */
11186 fis->h.command = SAT_SMART_READ_LOG; /* 0x2F */
11187 fis->h.features = 0x00; /* 0xd5 */
11188 fis->d.lbaLow = 0x06; /* 0x06 */
11189 fis->d.lbaMid = 0x00; /* 0x4f */
11190 fis->d.lbaHigh = 0x00; /* 0xc2 */
11191 fis->d.device = 0; /* */
11192 fis->d.lbaLowExp = 0; /* */
11193 fis->d.lbaMidExp = 0; /* */
11194 fis->d.lbaHighExp = 0; /* */
11195 fis->d.featuresExp = 0; /* FIS reserve */
11196 fis->d.sectorCount = 0x01; /* */
11197 fis->d.sectorCountExp = 0x00; /* */
11198 fis->d.reserved4 = 0;
11199 fis->d.control = 0; /* FIS HOB bit clear */
11200 fis->d.reserved5 = 0;
11202 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11204 /* Initialize CB for SATA completion.
11206 satIOContext->satCompleteCB = &satLogSenseCB;
11209 * Prepare SGL and send FIS to LL layer.
11211 satIOContext->reqType = agRequestType; /* Save it */
11213 status = sataLLIOStart( tiRoot,
11223 /*****************************************************************************/
11224 /*! \brief SAT implementation for SCSI satSMARTEnable.
11226 * Part of SAT implementation for SCSI satLogSense.
11228 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11229 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11230 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11231 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11232 * \param satIOContext_t: Pointer to the SAT IO Context
11234 * \return If command is started successfully
11235 * - \e tiSuccess: I/O request successfully initiated.
11236 * - \e tiBusy: No resources available, try again later.
11237 * - \e tiIONoDevice: Invalid device handle.
11238 * - \e tiError: Other errors.
11240 /*****************************************************************************/
11241 GLOBAL bit32 satSMARTEnable(
11243 tiIORequest_t *tiIORequest,
11244 tiDeviceHandle_t *tiDeviceHandle,
11245 tiScsiInitiatorRequest_t *tiScsiRequest,
11246 satIOContext_t *satIOContext)
11249 bit32 agRequestType;
11250 agsaFisRegHostToDevice_t *fis;
11252 TI_DBG4(("satSMARTEnable entry: tiDeviceHandle=%p tiIORequest=%p\n",
11253 tiDeviceHandle, tiIORequest));
11255 fis = satIOContext->pFis;
11258 * Send the SAT_SMART_ENABLE_OPERATIONS command.
11260 fis->h.fisType = 0x27; /* Reg host to device */
11261 fis->h.c_pmPort = 0x80; /* C Bit is set */
11263 fis->h.command = SAT_SMART_ENABLE_OPERATIONS; /* 0xB0 */
11264 fis->h.features = 0xD8;
11266 fis->d.lbaMid = 0x4F;
11267 fis->d.lbaHigh = 0xC2;
11269 fis->d.lbaLowExp = 0;
11270 fis->d.lbaMidExp = 0;
11271 fis->d.lbaHighExp = 0;
11272 fis->d.featuresExp = 0;
11273 fis->d.sectorCount = 0;
11274 fis->d.sectorCountExp = 0;
11275 fis->d.reserved4 = 0;
11276 fis->d.control = 0; /* FIS HOB bit clear */
11277 fis->d.reserved5 = 0;
11279 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11281 /* Initialize CB for SATA completion.
11283 satIOContext->satCompleteCB = &satSMARTEnableCB;
11286 * Prepare SGL and send FIS to LL layer.
11288 satIOContext->reqType = agRequestType; /* Save it */
11290 status = sataLLIOStart( tiRoot,
11300 /*****************************************************************************/
11301 /*! \brief SAT implementation for SCSI satLogSense_3.
11303 * Part of SAT implementation for SCSI satLogSense.
11305 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11306 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11307 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11308 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11309 * \param satIOContext_t: Pointer to the SAT IO Context
11311 * \return If command is started successfully
11312 * - \e tiSuccess: I/O request successfully initiated.
11313 * - \e tiBusy: No resources available, try again later.
11314 * - \e tiIONoDevice: Invalid device handle.
11315 * - \e tiError: Other errors.
11317 /*****************************************************************************/
11318 GLOBAL bit32 satLogSense_3(
11320 tiIORequest_t *tiIORequest,
11321 tiDeviceHandle_t *tiDeviceHandle,
11322 tiScsiInitiatorRequest_t *tiScsiRequest,
11323 satIOContext_t *satIOContext)
11326 bit32 agRequestType;
11327 agsaFisRegHostToDevice_t *fis;
11329 TI_DBG4(("satLogSense_3 entry: tiDeviceHandle=%p tiIORequest=%p\n",
11330 tiDeviceHandle, tiIORequest));
11332 fis = satIOContext->pFis;
11333 /* sends READ LOG EXT */
11334 fis->h.fisType = 0x27; /* Reg host to device */
11335 fis->h.c_pmPort = 0x80; /* C Bit is set */
11337 fis->h.command = SAT_SMART_READ_LOG; /* 0x2F */
11338 fis->h.features = 0xD5; /* 0xd5 */
11339 fis->d.lbaLow = 0x06; /* 0x06 */
11340 fis->d.lbaMid = 0x4F; /* 0x4f */
11341 fis->d.lbaHigh = 0xC2; /* 0xc2 */
11342 fis->d.device = 0; /* */
11343 fis->d.lbaLowExp = 0; /* */
11344 fis->d.lbaMidExp = 0; /* */
11345 fis->d.lbaHighExp = 0; /* */
11346 fis->d.featuresExp = 0; /* FIS reserve */
11347 fis->d.sectorCount = 0x01; /* 1 sector counts */
11348 fis->d.sectorCountExp = 0x00; /* 1 sector counts */
11349 fis->d.reserved4 = 0;
11350 fis->d.control = 0; /* FIS HOB bit clear */
11351 fis->d.reserved5 = 0;
11353 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11355 /* Initialize CB for SATA completion.
11357 satIOContext->satCompleteCB = &satLogSenseCB;
11360 * Prepare SGL and send FIS to LL layer.
11362 satIOContext->reqType = agRequestType; /* Save it */
11364 status = sataLLIOStart( tiRoot,
11372 /*****************************************************************************/
11373 /*! \brief SAT implementation for SCSI satLogSense_2.
11375 * Part of SAT implementation for SCSI satLogSense.
11377 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11378 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11379 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11380 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11381 * \param satIOContext_t: Pointer to the SAT IO Context
11383 * \return If command is started successfully
11384 * - \e tiSuccess: I/O request successfully initiated.
11385 * - \e tiBusy: No resources available, try again later.
11386 * - \e tiIONoDevice: Invalid device handle.
11387 * - \e tiError: Other errors.
11389 /*****************************************************************************/
11390 GLOBAL bit32 satLogSense_2(
11392 tiIORequest_t *tiIORequest,
11393 tiDeviceHandle_t *tiDeviceHandle,
11394 tiScsiInitiatorRequest_t *tiScsiRequest,
11395 satIOContext_t *satIOContext)
11398 bit32 agRequestType;
11399 agsaFisRegHostToDevice_t *fis;
11401 TI_DBG4(("satLogSense_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
11402 tiDeviceHandle, tiIORequest));
11404 fis = satIOContext->pFis;
11405 /* sends READ LOG EXT */
11406 fis->h.fisType = 0x27; /* Reg host to device */
11407 fis->h.c_pmPort = 0x80; /* C Bit is set */
11409 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */
11410 fis->h.features = 0; /* FIS reserve */
11411 fis->d.lbaLow = 0x07; /* 0x07 */
11412 fis->d.lbaMid = 0; /* */
11413 fis->d.lbaHigh = 0; /* */
11414 fis->d.device = 0; /* */
11415 fis->d.lbaLowExp = 0; /* */
11416 fis->d.lbaMidExp = 0; /* */
11417 fis->d.lbaHighExp = 0; /* */
11418 fis->d.featuresExp = 0; /* FIS reserve */
11419 fis->d.sectorCount = 0x01; /* 1 sector counts */
11420 fis->d.sectorCountExp = 0x00; /* 1 sector counts */
11421 fis->d.reserved4 = 0;
11422 fis->d.control = 0; /* FIS HOB bit clear */
11423 fis->d.reserved5 = 0;
11425 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11427 /* Initialize CB for SATA completion.
11429 satIOContext->satCompleteCB = &satLogSenseCB;
11432 * Prepare SGL and send FIS to LL layer.
11434 satIOContext->reqType = agRequestType; /* Save it */
11436 status = sataLLIOStart( tiRoot,
11444 /*****************************************************************************/
11445 /*! \brief SAT implementation for SCSI satLogSenseAllocate.
11447 * Part of SAT implementation for SCSI satLogSense.
11449 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11450 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11451 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11452 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11453 * \param satIOContext_t: Pointer to the SAT IO Context
11454 * \param payloadSize: size of payload to be allocated.
11455 * \param flag: flag value
11457 * \return If command is started successfully
11458 * - \e tiSuccess: I/O request successfully initiated.
11459 * - \e tiBusy: No resources available, try again later.
11460 * - \e tiIONoDevice: Invalid device handle.
11461 * - \e tiError: Other errors.
11463 * - flag values: LOG_SENSE_0, LOG_SENSE_1, LOG_SENSE_2
11465 /*****************************************************************************/
11466 GLOBAL bit32 satLogSenseAllocate(
11468 tiIORequest_t *tiIORequest,
11469 tiDeviceHandle_t *tiDeviceHandle,
11470 tiScsiInitiatorRequest_t *tiScsiRequest,
11471 satIOContext_t *satIOContext,
11476 satDeviceData_t *pSatDevData;
11477 tdIORequestBody_t *tdIORequestBody;
11478 satInternalIo_t *satIntIo = agNULL;
11479 satIOContext_t *satIOContext2;
11482 TI_DBG4(("satLogSense_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
11483 tiDeviceHandle, tiIORequest));
11485 pSatDevData = satIOContext->pSatDevData;
11487 /* create internal satIOContext */
11488 satIntIo = satAllocIntIoResource( tiRoot,
11489 tiIORequest, /* original request */
11494 if (satIntIo == agNULL)
11496 /* memory allocation failure */
11497 satFreeIntIoResource( tiRoot,
11501 ostiInitiatorIOCompleted( tiRoot,
11504 tiDetailOtherError,
11506 satIOContext->interruptContext );
11508 TI_DBG4(("satLogSense_2: fail in allocation\n"));
11510 } /* end of memory allocation failure */
11512 satIntIo->satOrgTiIORequest = tiIORequest;
11513 tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
11514 satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
11516 satIOContext2->pSatDevData = pSatDevData;
11517 satIOContext2->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
11518 satIOContext2->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
11519 satIOContext2->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
11520 satIOContext2->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
11521 satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
11522 satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
11523 satIOContext2->interruptContext = satIOContext->interruptContext;
11524 satIOContext2->satIntIoContext = satIntIo;
11525 satIOContext2->ptiDeviceHandle = tiDeviceHandle;
11526 satIOContext2->satOrgIOContext = satIOContext;
11528 if (flag == LOG_SENSE_0)
11530 /* SAT_SMART_ENABLE_OPERATIONS */
11531 status = satSMARTEnable( tiRoot,
11532 &(satIntIo->satIntTiIORequest),
11534 &(satIntIo->satIntTiScsiXchg),
11537 else if (flag == LOG_SENSE_1)
11539 /* SAT_READ_LOG_EXT */
11540 status = satLogSense_2( tiRoot,
11541 &(satIntIo->satIntTiIORequest),
11543 &(satIntIo->satIntTiScsiXchg),
11548 /* SAT_SMART_READ_LOG */
11549 /* SAT_READ_LOG_EXT */
11550 status = satLogSense_3( tiRoot,
11551 &(satIntIo->satIntTiIORequest),
11553 &(satIntIo->satIntTiScsiXchg),
11557 if (status != tiSuccess)
11559 satFreeIntIoResource( tiRoot,
11563 ostiInitiatorIOCompleted( tiRoot,
11566 tiDetailOtherError,
11568 satIOContext->interruptContext );
11577 /*****************************************************************************/
11578 /*! \brief SAT implementation for SCSI satLogSense.
11580 * SAT implementation for SCSI satLogSense.
11582 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11583 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11584 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11585 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11586 * \param satIOContext_t: Pointer to the SAT IO Context
11588 * \return If command is started successfully
11589 * - \e tiSuccess: I/O request successfully initiated.
11590 * - \e tiBusy: No resources available, try again later.
11591 * - \e tiIONoDevice: Invalid device handle.
11592 * - \e tiError: Other errors.
11594 /*****************************************************************************/
11595 GLOBAL bit32 satLogSense(
11597 tiIORequest_t *tiIORequest,
11598 tiDeviceHandle_t *tiDeviceHandle,
11599 tiScsiInitiatorRequest_t *tiScsiRequest,
11600 satIOContext_t *satIOContext)
11603 bit32 agRequestType;
11604 satDeviceData_t *pSatDevData;
11605 scsiRspSense_t *pSense;
11606 tiIniScsiCmnd_t *scsiCmnd;
11607 agsaFisRegHostToDevice_t *fis;
11608 bit8 *pLogPage; /* Log Page data buffer */
11610 bit16 AllocLen = 0; /* allocation length */
11611 bit8 AllLogPages[8];
11614 pSense = satIOContext->pSense;
11615 pSatDevData = satIOContext->pSatDevData;
11616 scsiCmnd = &tiScsiRequest->scsiCmnd;
11617 fis = satIOContext->pFis;
11618 pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr;
11620 TI_DBG5(("satLogSense: start\n"));
11622 osti_memset(&AllLogPages, 0, 8);
11623 /* checking CONTROL */
11624 /* NACA == 1 or LINK == 1*/
11625 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
11627 satSetSensePayload( pSense,
11628 SCSI_SNSKEY_ILLEGAL_REQUEST,
11630 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11633 ostiInitiatorIOCompleted( tiRoot,
11636 SCSI_STAT_CHECK_CONDITION,
11637 satIOContext->pTiSenseData,
11638 satIOContext->interruptContext );
11640 TI_DBG2(("satLogSense: return control\n"));
11645 AllocLen = (bit8)((scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]);
11647 /* checking PC (Page Control) */
11650 /* special cases */
11653 TI_DBG1(("satLogSense: AllocLen is 4\n"));
11654 switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
11656 case LOGSENSE_SUPPORTED_LOG_PAGES:
11657 TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
11659 /* SAT Rev 8, 10.2.5 p76 */
11660 if (pSatDevData->satSMARTFeatureSet == agTRUE)
11662 /* add informational exception log */
11664 if (pSatDevData->satSMARTSelfTest == agTRUE)
11666 /* add Self-Test results log page */
11672 /* only supported, no informational exception log, no Self-Test results log page */
11676 AllLogPages[0] = LOGSENSE_SUPPORTED_LOG_PAGES; /* page code */
11677 AllLogPages[1] = 0; /* reserved */
11681 /* only supported */
11682 AllLogPages[2] = 0; /* page length */
11683 AllLogPages[3] = 1; /* page length */
11686 /* supported and informational exception log */
11687 AllLogPages[2] = 0; /* page length */
11688 AllLogPages[3] = 2; /* page length */
11691 /* supported and informational exception log */
11692 AllLogPages[2] = 0; /* page length */
11693 AllLogPages[3] = 3; /* page length */
11696 TI_DBG1(("satLogSense: error unallowed flag value %d\n", flag));
11699 osti_memcpy(pLogPage, &AllLogPages, lenRead);
11701 case LOGSENSE_SELFTEST_RESULTS_PAGE:
11702 TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
11704 AllLogPages[0] = LOGSENSE_SELFTEST_RESULTS_PAGE; /* page code */
11705 AllLogPages[1] = 0; /* reserved */
11706 /* page length = SELFTEST_RESULTS_LOG_PAGE_LENGTH - 1 - 3 = 400 = 0x190 */
11707 AllLogPages[2] = 0x01;
11708 AllLogPages[3] = 0x90; /* page length */
11709 osti_memcpy(pLogPage, &AllLogPages, lenRead);
11712 case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
11713 TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
11715 AllLogPages[0] = LOGSENSE_INFORMATION_EXCEPTIONS_PAGE; /* page code */
11716 AllLogPages[1] = 0; /* reserved */
11717 AllLogPages[2] = 0; /* page length */
11718 AllLogPages[3] = INFORMATION_EXCEPTIONS_LOG_PAGE_LENGTH - 1 - 3; /* page length */
11719 osti_memcpy(pLogPage, &AllLogPages, lenRead);
11722 TI_DBG1(("satLogSense: default Page Code 0x%x\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
11723 satSetSensePayload( pSense,
11724 SCSI_SNSKEY_ILLEGAL_REQUEST,
11726 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11729 ostiInitiatorIOCompleted( tiRoot,
11732 SCSI_STAT_CHECK_CONDITION,
11733 satIOContext->pTiSenseData,
11734 satIOContext->interruptContext );
11737 ostiInitiatorIOCompleted( tiRoot,
11742 satIOContext->interruptContext);
11747 /* SAT rev8 Table 11 p30*/
11748 /* checking Page Code */
11749 switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
11751 case LOGSENSE_SUPPORTED_LOG_PAGES:
11752 TI_DBG5(("satLogSense: case 1\n"));
11754 /* SAT Rev 8, 10.2.5 p76 */
11756 if (pSatDevData->satSMARTFeatureSet == agTRUE)
11758 /* add informational exception log */
11760 if (pSatDevData->satSMARTSelfTest == agTRUE)
11762 /* add Self-Test results log page */
11768 /* only supported, no informational exception log, no Self-Test results log page */
11771 AllLogPages[0] = 0; /* page code */
11772 AllLogPages[1] = 0; /* reserved */
11776 /* only supported */
11777 AllLogPages[2] = 0; /* page length */
11778 AllLogPages[3] = 1; /* page length */
11779 AllLogPages[4] = 0x00; /* supported page list */
11780 lenRead = (bit8)(MIN(AllocLen, 5));
11783 /* supported and informational exception log */
11784 AllLogPages[2] = 0; /* page length */
11785 AllLogPages[3] = 2; /* page length */
11786 AllLogPages[4] = 0x00; /* supported page list */
11787 AllLogPages[5] = 0x10; /* supported page list */
11788 lenRead = (bit8)(MIN(AllocLen, 6));
11791 /* supported and informational exception log */
11792 AllLogPages[2] = 0; /* page length */
11793 AllLogPages[3] = 3; /* page length */
11794 AllLogPages[4] = 0x00; /* supported page list */
11795 AllLogPages[5] = 0x10; /* supported page list */
11796 AllLogPages[6] = 0x2F; /* supported page list */
11797 lenRead = (bit8)(MIN(AllocLen, 7));
11800 TI_DBG1(("satLogSense: error unallowed flag value %d\n", flag));
11804 osti_memcpy(pLogPage, &AllLogPages, lenRead);
11805 /* comparing allocation length to Log Page byte size */
11806 /* SPC-4, 4.3.4.6, p28 */
11807 if (AllocLen > lenRead )
11809 TI_DBG1(("satLogSense reporting underrun lenRead=0x%x AllocLen=0x%x tiIORequest=%p\n", lenRead, AllocLen, tiIORequest));
11810 ostiInitiatorIOCompleted( tiRoot,
11813 AllocLen - lenRead,
11815 satIOContext->interruptContext );
11819 ostiInitiatorIOCompleted( tiRoot,
11824 satIOContext->interruptContext);
11827 case LOGSENSE_SELFTEST_RESULTS_PAGE:
11828 TI_DBG5(("satLogSense: case 2\n"));
11829 /* checking SMART self-test */
11830 if (pSatDevData->satSMARTSelfTest == agFALSE)
11832 TI_DBG5(("satLogSense: case 2 no SMART Self Test\n"));
11833 satSetSensePayload( pSense,
11834 SCSI_SNSKEY_ILLEGAL_REQUEST,
11836 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11839 ostiInitiatorIOCompleted( tiRoot,
11842 SCSI_STAT_CHECK_CONDITION,
11843 satIOContext->pTiSenseData,
11844 satIOContext->interruptContext );
11848 /* if satSMARTEnabled is false, send SMART_ENABLE_OPERATIONS */
11849 if (pSatDevData->satSMARTEnabled == agFALSE)
11851 TI_DBG5(("satLogSense: case 2 calling satSMARTEnable\n"));
11852 status = satLogSenseAllocate(tiRoot,
11866 /* SAT Rev 8, 10.2.4 p74 */
11867 if ( pSatDevData->sat48BitSupport == agTRUE )
11869 TI_DBG5(("satLogSense: case 2-1 sends READ LOG EXT\n"));
11870 status = satLogSenseAllocate(tiRoot,
11883 TI_DBG5(("satLogSense: case 2-2 sends SMART READ LOG\n"));
11884 status = satLogSenseAllocate(tiRoot,
11898 case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
11899 TI_DBG5(("satLogSense: case 3\n"));
11900 /* checking SMART feature set */
11901 if (pSatDevData->satSMARTFeatureSet == agFALSE)
11903 satSetSensePayload( pSense,
11904 SCSI_SNSKEY_ILLEGAL_REQUEST,
11906 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11909 ostiInitiatorIOCompleted( tiRoot,
11912 SCSI_STAT_CHECK_CONDITION,
11913 satIOContext->pTiSenseData,
11914 satIOContext->interruptContext );
11918 /* checking SMART feature enabled */
11919 if (pSatDevData->satSMARTEnabled == agFALSE)
11921 satSetSensePayload( pSense,
11922 SCSI_SNSKEY_ABORTED_COMMAND,
11924 SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
11927 ostiInitiatorIOCompleted( tiRoot,
11930 SCSI_STAT_CHECK_CONDITION,
11931 satIOContext->pTiSenseData,
11932 satIOContext->interruptContext );
11936 /* SAT Rev 8, 10.2.3 p72 */
11937 TI_DBG5(("satLogSense: case 3 sends SMART RETURN STATUS\n"));
11939 /* sends SMART RETURN STATUS */
11940 fis->h.fisType = 0x27; /* Reg host to device */
11941 fis->h.c_pmPort = 0x80; /* C Bit is set */
11943 fis->h.command = SAT_SMART_RETURN_STATUS;/* 0xB0 */
11944 fis->h.features = 0xDA; /* FIS features */
11945 fis->d.featuresExp = 0; /* FIS reserve */
11946 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
11947 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
11948 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
11949 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
11950 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
11951 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
11952 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
11953 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
11954 fis->d.device = 0; /* FIS DEV is discared in SATA */
11955 fis->d.control = 0; /* FIS HOB bit clear */
11956 fis->d.reserved4 = 0;
11957 fis->d.reserved5 = 0;
11959 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11960 /* Initialize CB for SATA completion.
11962 satIOContext->satCompleteCB = &satLogSenseCB;
11965 * Prepare SGL and send FIS to LL layer.
11967 satIOContext->reqType = agRequestType; /* Save it */
11969 status = sataLLIOStart( tiRoot,
11981 TI_DBG1(("satLogSense: default Page Code 0x%x\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
11982 satSetSensePayload( pSense,
11983 SCSI_SNSKEY_ILLEGAL_REQUEST,
11985 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11988 ostiInitiatorIOCompleted( tiRoot,
11991 SCSI_STAT_CHECK_CONDITION,
11992 satIOContext->pTiSenseData,
11993 satIOContext->interruptContext );
12003 /*****************************************************************************/
12004 /*! \brief SAT implementation for SCSI satModeSelect6.
12006 * SAT implementation for SCSI satModeSelect6.
12008 * \param tiRoot: Pointer to TISA initiator driver/port instance.
12009 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
12010 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
12011 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
12012 * \param satIOContext_t: Pointer to the SAT IO Context
12014 * \return If command is started successfully
12015 * - \e tiSuccess: I/O request successfully initiated.
12016 * - \e tiBusy: No resources available, try again later.
12017 * - \e tiIONoDevice: Invalid device handle.
12018 * - \e tiError: Other errors.
12020 /*****************************************************************************/
12021 GLOBAL bit32 satModeSelect6(
12023 tiIORequest_t *tiIORequest,
12024 tiDeviceHandle_t *tiDeviceHandle,
12025 tiScsiInitiatorRequest_t *tiScsiRequest,
12026 satIOContext_t *satIOContext)
12029 bit32 agRequestType;
12030 satDeviceData_t *pSatDevData;
12031 scsiRspSense_t *pSense;
12032 tiIniScsiCmnd_t *scsiCmnd;
12033 agsaFisRegHostToDevice_t *fis;
12034 bit8 *pLogPage; /* Log Page data buffer */
12035 bit32 StartingIndex = 0;
12037 bit32 chkCnd = agFALSE;
12039 pSense = satIOContext->pSense;
12040 pSatDevData = satIOContext->pSatDevData;
12041 scsiCmnd = &tiScsiRequest->scsiCmnd;
12042 fis = satIOContext->pFis;
12043 pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr;
12045 TI_DBG5(("satModeSelect6: start\n"));
12047 /* checking CONTROL */
12048 /* NACA == 1 or LINK == 1*/
12049 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
12051 satSetSensePayload( pSense,
12052 SCSI_SNSKEY_ILLEGAL_REQUEST,
12054 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12057 ostiInitiatorIOCompleted( tiRoot,
12060 SCSI_STAT_CHECK_CONDITION,
12061 satIOContext->pTiSenseData,
12062 satIOContext->interruptContext );
12064 TI_DBG2(("satModeSelect6: return control\n"));
12068 /* checking PF bit */
12069 if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT6_PF_MASK))
12071 satSetSensePayload( pSense,
12072 SCSI_SNSKEY_ILLEGAL_REQUEST,
12074 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12077 ostiInitiatorIOCompleted( tiRoot,
12080 SCSI_STAT_CHECK_CONDITION,
12081 satIOContext->pTiSenseData,
12082 satIOContext->interruptContext );
12084 TI_DBG1(("satModeSelect6: PF bit check \n"));
12089 /* checking Block Descriptor Length on Mode parameter header(6)*/
12090 if (pLogPage[3] == 8)
12092 /* mode parameter block descriptor exists */
12093 PageCode = (bit8)(pLogPage[12] & 0x3F); /* page code and index is 4 + 8 */
12094 StartingIndex = 12;
12096 else if (pLogPage[3] == 0)
12098 /* mode parameter block descriptor does not exist */
12099 PageCode = (bit8)(pLogPage[4] & 0x3F); /* page code and index is 4 + 0 */
12101 ostiInitiatorIOCompleted( tiRoot,
12106 satIOContext->interruptContext);
12111 TI_DBG1(("satModeSelect6: return mode parameter block descriptor 0x%x\n", pLogPage[3]));
12112 /* no more than one mode parameter block descriptor shall be supported */
12113 satSetSensePayload( pSense,
12114 SCSI_SNSKEY_NO_SENSE,
12116 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12119 ostiInitiatorIOCompleted( tiRoot,
12122 SCSI_STAT_CHECK_CONDITION,
12123 satIOContext->pTiSenseData,
12124 satIOContext->interruptContext );
12130 switch (PageCode) /* page code */
12132 case MODESELECT_CONTROL_PAGE:
12133 TI_DBG1(("satModeSelect6: Control mode page\n"));
12135 compare pLogPage to expected value (SAT Table 65, p67)
12136 If not match, return check condition
12138 if ( pLogPage[StartingIndex+1] != 0x0A ||
12139 pLogPage[StartingIndex+2] != 0x02 ||
12140 (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
12141 (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
12142 (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */
12143 (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12144 (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12146 (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */
12147 (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */
12148 (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */
12149 (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */
12151 pLogPage[StartingIndex+8] != 0xFF ||
12152 pLogPage[StartingIndex+9] != 0xFF ||
12153 pLogPage[StartingIndex+10] != 0x00 ||
12154 pLogPage[StartingIndex+11] != 0x00
12159 if (chkCnd == agTRUE)
12161 satSetSensePayload( pSense,
12162 SCSI_SNSKEY_ILLEGAL_REQUEST,
12164 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12167 ostiInitiatorIOCompleted( tiRoot,
12170 SCSI_STAT_CHECK_CONDITION,
12171 satIOContext->pTiSenseData,
12172 satIOContext->interruptContext );
12174 TI_DBG1(("satModeSelect10: unexpected values\n"));
12178 ostiInitiatorIOCompleted( tiRoot,
12183 satIOContext->interruptContext);
12187 case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
12188 TI_DBG1(("satModeSelect6: Read-Write Error Recovery mode page\n"));
12190 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_AWRE_MASK) ||
12191 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_RC_MASK) ||
12192 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_EER_MASK) ||
12193 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PER_MASK) ||
12194 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DTE_MASK) ||
12195 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DCR_MASK) ||
12196 (pLogPage[StartingIndex + 10]) ||
12197 (pLogPage[StartingIndex + 11])
12200 TI_DBG5(("satModeSelect6: return check condition \n"));
12202 satSetSensePayload( pSense,
12203 SCSI_SNSKEY_ILLEGAL_REQUEST,
12205 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12208 ostiInitiatorIOCompleted( tiRoot,
12211 SCSI_STAT_CHECK_CONDITION,
12212 satIOContext->pTiSenseData,
12213 satIOContext->interruptContext );
12218 TI_DBG5(("satModeSelect6: return GOOD \n"));
12219 ostiInitiatorIOCompleted( tiRoot,
12224 satIOContext->interruptContext);
12229 case MODESELECT_CACHING:
12230 /* SAT rev8 Table67, p69*/
12231 TI_DBG5(("satModeSelect6: Caching mode page\n"));
12232 if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */
12233 (pLogPage[StartingIndex + 3]) ||
12234 (pLogPage[StartingIndex + 4]) ||
12235 (pLogPage[StartingIndex + 5]) ||
12236 (pLogPage[StartingIndex + 6]) ||
12237 (pLogPage[StartingIndex + 7]) ||
12238 (pLogPage[StartingIndex + 8]) ||
12239 (pLogPage[StartingIndex + 9]) ||
12240 (pLogPage[StartingIndex + 10]) ||
12241 (pLogPage[StartingIndex + 11]) ||
12243 (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */
12244 (pLogPage[StartingIndex + 13]) ||
12245 (pLogPage[StartingIndex + 14]) ||
12246 (pLogPage[StartingIndex + 15])
12249 TI_DBG1(("satModeSelect6: return check condition \n"));
12251 satSetSensePayload( pSense,
12252 SCSI_SNSKEY_ILLEGAL_REQUEST,
12254 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12257 ostiInitiatorIOCompleted( tiRoot,
12260 SCSI_STAT_CHECK_CONDITION,
12261 satIOContext->pTiSenseData,
12262 satIOContext->interruptContext );
12268 /* sends ATA SET FEATURES based on WCE bit */
12269 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_WCE_MASK) )
12271 TI_DBG5(("satModeSelect6: disable write cache\n"));
12272 /* sends SET FEATURES */
12273 fis->h.fisType = 0x27; /* Reg host to device */
12274 fis->h.c_pmPort = 0x80; /* C Bit is set */
12276 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
12277 fis->h.features = 0x82; /* disable write cache */
12278 fis->d.lbaLow = 0; /* */
12279 fis->d.lbaMid = 0; /* */
12280 fis->d.lbaHigh = 0; /* */
12281 fis->d.device = 0; /* */
12282 fis->d.lbaLowExp = 0; /* */
12283 fis->d.lbaMidExp = 0; /* */
12284 fis->d.lbaHighExp = 0; /* */
12285 fis->d.featuresExp = 0; /* */
12286 fis->d.sectorCount = 0; /* */
12287 fis->d.sectorCountExp = 0; /* */
12288 fis->d.reserved4 = 0;
12289 fis->d.control = 0; /* FIS HOB bit clear */
12290 fis->d.reserved5 = 0;
12292 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12294 /* Initialize CB for SATA completion.
12296 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12299 * Prepare SGL and send FIS to LL layer.
12301 satIOContext->reqType = agRequestType; /* Save it */
12303 status = sataLLIOStart( tiRoot,
12312 TI_DBG5(("satModeSelect6: enable write cache\n"));
12313 /* sends SET FEATURES */
12314 fis->h.fisType = 0x27; /* Reg host to device */
12315 fis->h.c_pmPort = 0x80; /* C Bit is set */
12317 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
12318 fis->h.features = 0x02; /* enable write cache */
12319 fis->d.lbaLow = 0; /* */
12320 fis->d.lbaMid = 0; /* */
12321 fis->d.lbaHigh = 0; /* */
12322 fis->d.device = 0; /* */
12323 fis->d.lbaLowExp = 0; /* */
12324 fis->d.lbaMidExp = 0; /* */
12325 fis->d.lbaHighExp = 0; /* */
12326 fis->d.featuresExp = 0; /* */
12327 fis->d.sectorCount = 0; /* */
12328 fis->d.sectorCountExp = 0; /* */
12329 fis->d.reserved4 = 0;
12330 fis->d.control = 0; /* FIS HOB bit clear */
12331 fis->d.reserved5 = 0;
12333 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12335 /* Initialize CB for SATA completion.
12337 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12340 * Prepare SGL and send FIS to LL layer.
12342 satIOContext->reqType = agRequestType; /* Save it */
12344 status = sataLLIOStart( tiRoot,
12354 case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
12355 TI_DBG5(("satModeSelect6: Informational Exception Control mode page\n"));
12356 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PERF_MASK) ||
12357 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_TEST_MASK)
12360 TI_DBG1(("satModeSelect6: return check condition \n"));
12362 satSetSensePayload( pSense,
12363 SCSI_SNSKEY_ILLEGAL_REQUEST,
12365 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12368 ostiInitiatorIOCompleted( tiRoot,
12371 SCSI_STAT_CHECK_CONDITION,
12372 satIOContext->pTiSenseData,
12373 satIOContext->interruptContext );
12378 /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */
12379 if ( !(pLogPage[StartingIndex + 2] & 0x08) )
12381 TI_DBG5(("satModeSelect6: enable information exceptions reporting\n"));
12382 /* sends SMART ENABLE OPERATIONS */
12383 fis->h.fisType = 0x27; /* Reg host to device */
12384 fis->h.c_pmPort = 0x80; /* C Bit is set */
12386 fis->h.command = SAT_SMART_ENABLE_OPERATIONS; /* 0xB0 */
12387 fis->h.features = 0xD8; /* enable */
12388 fis->d.lbaLow = 0; /* */
12389 fis->d.lbaMid = 0x4F; /* 0x4F */
12390 fis->d.lbaHigh = 0xC2; /* 0xC2 */
12391 fis->d.device = 0; /* */
12392 fis->d.lbaLowExp = 0; /* */
12393 fis->d.lbaMidExp = 0; /* */
12394 fis->d.lbaHighExp = 0; /* */
12395 fis->d.featuresExp = 0; /* */
12396 fis->d.sectorCount = 0; /* */
12397 fis->d.sectorCountExp = 0; /* */
12398 fis->d.reserved4 = 0;
12399 fis->d.control = 0; /* FIS HOB bit clear */
12400 fis->d.reserved5 = 0;
12402 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12404 /* Initialize CB for SATA completion.
12406 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12409 * Prepare SGL and send FIS to LL layer.
12411 satIOContext->reqType = agRequestType; /* Save it */
12413 status = sataLLIOStart( tiRoot,
12422 TI_DBG5(("satModeSelect6: disable information exceptions reporting\n"));
12423 /* sends SMART DISABLE OPERATIONS */
12424 fis->h.fisType = 0x27; /* Reg host to device */
12425 fis->h.c_pmPort = 0x80; /* C Bit is set */
12427 fis->h.command = SAT_SMART_DISABLE_OPERATIONS; /* 0xB0 */
12428 fis->h.features = 0xD9; /* disable */
12429 fis->d.lbaLow = 0; /* */
12430 fis->d.lbaMid = 0x4F; /* 0x4F */
12431 fis->d.lbaHigh = 0xC2; /* 0xC2 */
12432 fis->d.device = 0; /* */
12433 fis->d.lbaLowExp = 0; /* */
12434 fis->d.lbaMidExp = 0; /* */
12435 fis->d.lbaHighExp = 0; /* */
12436 fis->d.featuresExp = 0; /* */
12437 fis->d.sectorCount = 0; /* */
12438 fis->d.sectorCountExp = 0; /* */
12439 fis->d.reserved4 = 0;
12440 fis->d.control = 0; /* FIS HOB bit clear */
12441 fis->d.reserved5 = 0;
12443 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12445 /* Initialize CB for SATA completion.
12447 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12450 * Prepare SGL and send FIS to LL layer.
12452 satIOContext->reqType = agRequestType; /* Save it */
12454 status = sataLLIOStart( tiRoot,
12465 TI_DBG1(("satModeSelect6: Error unknown page code 0x%x\n", pLogPage[12]));
12466 satSetSensePayload( pSense,
12467 SCSI_SNSKEY_NO_SENSE,
12469 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12472 ostiInitiatorIOCompleted( tiRoot,
12475 SCSI_STAT_CHECK_CONDITION,
12476 satIOContext->pTiSenseData,
12477 satIOContext->interruptContext );
12483 /*****************************************************************************/
12484 /*! \brief SAT implementation for SCSI satModeSelect6n10_1.
12486 * This function is part of implementation of ModeSelect6 and ModeSelect10.
12487 * When ModeSelect6 or ModeSelect10 is coverted into multiple ATA commands,
12488 * this function is used.
12490 * \param tiRoot: Pointer to TISA initiator driver/port instance.
12491 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
12492 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
12493 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
12494 * \param satIOContext_t: Pointer to the SAT IO Context
12496 * \return If command is started successfully
12497 * - \e tiSuccess: I/O request successfully initiated.
12498 * - \e tiBusy: No resources available, try again later.
12499 * - \e tiIONoDevice: Invalid device handle.
12500 * - \e tiError: Other errors.
12502 /*****************************************************************************/
12503 GLOBAL bit32 satModeSelect6n10_1(
12505 tiIORequest_t *tiIORequest,
12506 tiDeviceHandle_t *tiDeviceHandle,
12507 tiScsiInitiatorRequest_t *tiScsiRequest,
12508 satIOContext_t *satIOContext)
12510 /* sends either ATA SET FEATURES based on DRA bit */
12512 bit32 agRequestType;
12513 agsaFisRegHostToDevice_t *fis;
12514 bit8 *pLogPage; /* Log Page data buffer */
12515 bit32 StartingIndex = 0;
12517 fis = satIOContext->pFis;
12518 pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr;
12519 TI_DBG5(("satModeSelect6_1: start\n"));
12520 /* checking Block Descriptor Length on Mode parameter header(6)*/
12521 if (pLogPage[3] == 8)
12523 /* mode parameter block descriptor exists */
12524 StartingIndex = 12;
12528 /* mode parameter block descriptor does not exist */
12532 /* sends ATA SET FEATURES based on DRA bit */
12533 if ( !(pLogPage[StartingIndex + 12] & SCSI_MODE_SELECT6_DRA_MASK) )
12535 TI_DBG5(("satModeSelect6_1: enable read look-ahead feature\n"));
12536 /* sends SET FEATURES */
12537 fis->h.fisType = 0x27; /* Reg host to device */
12538 fis->h.c_pmPort = 0x80; /* C Bit is set */
12540 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
12541 fis->h.features = 0xAA; /* enable read look-ahead */
12542 fis->d.lbaLow = 0; /* */
12543 fis->d.lbaMid = 0; /* */
12544 fis->d.lbaHigh = 0; /* */
12545 fis->d.device = 0; /* */
12546 fis->d.lbaLowExp = 0; /* */
12547 fis->d.lbaMidExp = 0; /* */
12548 fis->d.lbaHighExp = 0; /* */
12549 fis->d.featuresExp = 0; /* */
12550 fis->d.sectorCount = 0; /* */
12551 fis->d.sectorCountExp = 0; /* */
12552 fis->d.reserved4 = 0;
12553 fis->d.control = 0; /* FIS HOB bit clear */
12554 fis->d.reserved5 = 0;
12556 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12558 /* Initialize CB for SATA completion.
12560 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12563 * Prepare SGL and send FIS to LL layer.
12565 satIOContext->reqType = agRequestType; /* Save it */
12567 status = sataLLIOStart( tiRoot,
12576 TI_DBG5(("satModeSelect6_1: disable read look-ahead feature\n"));
12577 /* sends SET FEATURES */
12578 fis->h.fisType = 0x27; /* Reg host to device */
12579 fis->h.c_pmPort = 0x80; /* C Bit is set */
12581 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
12582 fis->h.features = 0x55; /* disable read look-ahead */
12583 fis->d.lbaLow = 0; /* */
12584 fis->d.lbaMid = 0; /* */
12585 fis->d.lbaHigh = 0; /* */
12586 fis->d.device = 0; /* */
12587 fis->d.lbaLowExp = 0; /* */
12588 fis->d.lbaMidExp = 0; /* */
12589 fis->d.lbaHighExp = 0; /* */
12590 fis->d.featuresExp = 0; /* */
12591 fis->d.sectorCount = 0; /* */
12592 fis->d.sectorCountExp = 0; /* */
12593 fis->d.reserved4 = 0;
12594 fis->d.control = 0; /* FIS HOB bit clear */
12595 fis->d.reserved5 = 0;
12597 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12599 /* Initialize CB for SATA completion.
12601 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12604 * Prepare SGL and send FIS to LL layer.
12606 satIOContext->reqType = agRequestType; /* Save it */
12608 status = sataLLIOStart( tiRoot,
12619 /*****************************************************************************/
12620 /*! \brief SAT implementation for SCSI satModeSelect10.
12622 * SAT implementation for SCSI satModeSelect10.
12624 * \param tiRoot: Pointer to TISA initiator driver/port instance.
12625 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
12626 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
12627 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
12628 * \param satIOContext_t: Pointer to the SAT IO Context
12630 * \return If command is started successfully
12631 * - \e tiSuccess: I/O request successfully initiated.
12632 * - \e tiBusy: No resources available, try again later.
12633 * - \e tiIONoDevice: Invalid device handle.
12634 * - \e tiError: Other errors.
12636 /*****************************************************************************/
12637 GLOBAL bit32 satModeSelect10(
12639 tiIORequest_t *tiIORequest,
12640 tiDeviceHandle_t *tiDeviceHandle,
12641 tiScsiInitiatorRequest_t *tiScsiRequest,
12642 satIOContext_t *satIOContext)
12645 bit32 agRequestType;
12646 satDeviceData_t *pSatDevData;
12647 scsiRspSense_t *pSense;
12648 tiIniScsiCmnd_t *scsiCmnd;
12649 agsaFisRegHostToDevice_t *fis;
12650 bit8 *pLogPage; /* Log Page data buffer */
12651 bit16 BlkDescLen = 0; /* Block Descriptor Length */
12652 bit32 StartingIndex = 0;
12654 bit32 chkCnd = agFALSE;
12656 pSense = satIOContext->pSense;
12657 pSatDevData = satIOContext->pSatDevData;
12658 scsiCmnd = &tiScsiRequest->scsiCmnd;
12659 fis = satIOContext->pFis;
12660 pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr;
12662 TI_DBG5(("satModeSelect10: start\n"));
12664 /* checking CONTROL */
12665 /* NACA == 1 or LINK == 1*/
12666 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
12668 satSetSensePayload( pSense,
12669 SCSI_SNSKEY_ILLEGAL_REQUEST,
12671 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12674 ostiInitiatorIOCompleted( tiRoot,
12677 SCSI_STAT_CHECK_CONDITION,
12678 satIOContext->pTiSenseData,
12679 satIOContext->interruptContext );
12681 TI_DBG2(("satModeSelect10: return control\n"));
12685 /* checking PF bit */
12686 if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT10_PF_MASK))
12688 satSetSensePayload( pSense,
12689 SCSI_SNSKEY_ILLEGAL_REQUEST,
12691 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12694 ostiInitiatorIOCompleted( tiRoot,
12697 SCSI_STAT_CHECK_CONDITION,
12698 satIOContext->pTiSenseData,
12699 satIOContext->interruptContext );
12701 TI_DBG1(("satModeSelect10: PF bit check \n"));
12706 BlkDescLen = (bit8)((pLogPage[6] << 8) + pLogPage[7]);
12708 /* checking Block Descriptor Length on Mode parameter header(10) and LONGLBA bit*/
12709 if ( (BlkDescLen == 8) && !(pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
12711 /* mode parameter block descriptor exists and length is 8 byte */
12712 PageCode = (bit8)(pLogPage[16] & 0x3F); /* page code and index is 8 + 8 */
12713 StartingIndex = 16;
12715 else if ( (BlkDescLen == 16) && (pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
12717 /* mode parameter block descriptor exists and length is 16 byte */
12718 PageCode = (bit8)(pLogPage[24] & 0x3F); /* page code and index is 8 + 16 */
12719 StartingIndex = 24;
12721 else if (BlkDescLen == 0)
12724 mode parameter block descriptor does not exist
12726 PageCode = (bit8)(pLogPage[8] & 0x3F); /* page code and index is 8 + 0 */
12728 ostiInitiatorIOCompleted( tiRoot,
12733 satIOContext->interruptContext);
12738 TI_DBG1(("satModeSelect10: return mode parameter block descriptor 0x%x\n", BlkDescLen));
12739 /* no more than one mode parameter block descriptor shall be supported */
12740 satSetSensePayload( pSense,
12741 SCSI_SNSKEY_NO_SENSE,
12743 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12746 ostiInitiatorIOCompleted( tiRoot,
12749 SCSI_STAT_CHECK_CONDITION,
12750 satIOContext->pTiSenseData,
12751 satIOContext->interruptContext );
12757 if (StartingIndex == 8)
12759 tdhexdump("startingindex 8", (bit8 *)pLogPage, 8);
12761 else if(StartingIndex == 16)
12763 if (PageCode == MODESELECT_CACHING)
12765 tdhexdump("startingindex 16", (bit8 *)pLogPage, 16+20);
12769 tdhexdump("startingindex 16", (bit8 *)pLogPage, 16+12);
12774 if (PageCode == MODESELECT_CACHING)
12776 tdhexdump("startingindex 24", (bit8 *)pLogPage, 24+20);
12780 tdhexdump("startingindex 24", (bit8 *)pLogPage, 24+12);
12783 switch (PageCode) /* page code */
12785 case MODESELECT_CONTROL_PAGE:
12786 TI_DBG5(("satModeSelect10: Control mode page\n"));
12788 compare pLogPage to expected value (SAT Table 65, p67)
12789 If not match, return check condition
12791 if ( pLogPage[StartingIndex+1] != 0x0A ||
12792 pLogPage[StartingIndex+2] != 0x02 ||
12793 (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
12794 (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
12795 (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */
12796 (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12797 (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12799 (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */
12800 (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */
12801 (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */
12802 (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */
12804 pLogPage[StartingIndex+8] != 0xFF ||
12805 pLogPage[StartingIndex+9] != 0xFF ||
12806 pLogPage[StartingIndex+10] != 0x00 ||
12807 pLogPage[StartingIndex+11] != 0x00
12812 if (chkCnd == agTRUE)
12814 satSetSensePayload( pSense,
12815 SCSI_SNSKEY_ILLEGAL_REQUEST,
12817 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12820 ostiInitiatorIOCompleted( tiRoot,
12823 SCSI_STAT_CHECK_CONDITION,
12824 satIOContext->pTiSenseData,
12825 satIOContext->interruptContext );
12827 TI_DBG1(("satModeSelect10: unexpected values\n"));
12831 ostiInitiatorIOCompleted( tiRoot,
12836 satIOContext->interruptContext);
12840 case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
12841 TI_DBG5(("satModeSelect10: Read-Write Error Recovery mode page\n"));
12842 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_AWRE_MASK) ||
12843 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_RC_MASK) ||
12844 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_EER_MASK) ||
12845 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PER_MASK) ||
12846 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DTE_MASK) ||
12847 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DCR_MASK) ||
12848 (pLogPage[StartingIndex + 10]) ||
12849 (pLogPage[StartingIndex + 11])
12852 TI_DBG1(("satModeSelect10: return check condition \n"));
12854 satSetSensePayload( pSense,
12855 SCSI_SNSKEY_ILLEGAL_REQUEST,
12857 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12860 ostiInitiatorIOCompleted( tiRoot,
12863 SCSI_STAT_CHECK_CONDITION,
12864 satIOContext->pTiSenseData,
12865 satIOContext->interruptContext );
12870 TI_DBG2(("satModeSelect10: return GOOD \n"));
12871 ostiInitiatorIOCompleted( tiRoot,
12876 satIOContext->interruptContext);
12881 case MODESELECT_CACHING:
12882 /* SAT rev8 Table67, p69*/
12883 TI_DBG5(("satModeSelect10: Caching mode page\n"));
12884 if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */
12885 (pLogPage[StartingIndex + 3]) ||
12886 (pLogPage[StartingIndex + 4]) ||
12887 (pLogPage[StartingIndex + 5]) ||
12888 (pLogPage[StartingIndex + 6]) ||
12889 (pLogPage[StartingIndex + 7]) ||
12890 (pLogPage[StartingIndex + 8]) ||
12891 (pLogPage[StartingIndex + 9]) ||
12892 (pLogPage[StartingIndex + 10]) ||
12893 (pLogPage[StartingIndex + 11]) ||
12895 (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */
12896 (pLogPage[StartingIndex + 13]) ||
12897 (pLogPage[StartingIndex + 14]) ||
12898 (pLogPage[StartingIndex + 15])
12901 TI_DBG1(("satModeSelect10: return check condition \n"));
12903 satSetSensePayload( pSense,
12904 SCSI_SNSKEY_ILLEGAL_REQUEST,
12906 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12909 ostiInitiatorIOCompleted( tiRoot,
12912 SCSI_STAT_CHECK_CONDITION,
12913 satIOContext->pTiSenseData,
12914 satIOContext->interruptContext );
12920 /* sends ATA SET FEATURES based on WCE bit */
12921 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_WCE_MASK) )
12923 TI_DBG5(("satModeSelect10: disable write cache\n"));
12924 /* sends SET FEATURES */
12925 fis->h.fisType = 0x27; /* Reg host to device */
12926 fis->h.c_pmPort = 0x80; /* C Bit is set */
12928 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
12929 fis->h.features = 0x82; /* disable write cache */
12930 fis->d.lbaLow = 0; /* */
12931 fis->d.lbaMid = 0; /* */
12932 fis->d.lbaHigh = 0; /* */
12933 fis->d.device = 0; /* */
12934 fis->d.lbaLowExp = 0; /* */
12935 fis->d.lbaMidExp = 0; /* */
12936 fis->d.lbaHighExp = 0; /* */
12937 fis->d.featuresExp = 0; /* */
12938 fis->d.sectorCount = 0; /* */
12939 fis->d.sectorCountExp = 0; /* */
12940 fis->d.reserved4 = 0;
12941 fis->d.control = 0; /* FIS HOB bit clear */
12942 fis->d.reserved5 = 0;
12944 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12946 /* Initialize CB for SATA completion.
12948 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12951 * Prepare SGL and send FIS to LL layer.
12953 satIOContext->reqType = agRequestType; /* Save it */
12955 status = sataLLIOStart( tiRoot,
12964 TI_DBG5(("satModeSelect10: enable write cache\n"));
12965 /* sends SET FEATURES */
12966 fis->h.fisType = 0x27; /* Reg host to device */
12967 fis->h.c_pmPort = 0x80; /* C Bit is set */
12969 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
12970 fis->h.features = 0x02; /* enable write cache */
12971 fis->d.lbaLow = 0; /* */
12972 fis->d.lbaMid = 0; /* */
12973 fis->d.lbaHigh = 0; /* */
12974 fis->d.device = 0; /* */
12975 fis->d.lbaLowExp = 0; /* */
12976 fis->d.lbaMidExp = 0; /* */
12977 fis->d.lbaHighExp = 0; /* */
12978 fis->d.featuresExp = 0; /* */
12979 fis->d.sectorCount = 0; /* */
12980 fis->d.sectorCountExp = 0; /* */
12981 fis->d.reserved4 = 0;
12982 fis->d.control = 0; /* FIS HOB bit clear */
12983 fis->d.reserved5 = 0;
12985 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12987 /* Initialize CB for SATA completion.
12989 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12992 * Prepare SGL and send FIS to LL layer.
12994 satIOContext->reqType = agRequestType; /* Save it */
12996 status = sataLLIOStart( tiRoot,
13006 case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
13007 TI_DBG5(("satModeSelect10: Informational Exception Control mode page\n"));
13009 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PERF_MASK) ||
13010 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_TEST_MASK)
13013 TI_DBG1(("satModeSelect10: return check condition \n"));
13015 satSetSensePayload( pSense,
13016 SCSI_SNSKEY_ILLEGAL_REQUEST,
13018 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
13021 ostiInitiatorIOCompleted( tiRoot,
13024 SCSI_STAT_CHECK_CONDITION,
13025 satIOContext->pTiSenseData,
13026 satIOContext->interruptContext );
13031 /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */
13032 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DEXCPT_MASK) )
13034 TI_DBG5(("satModeSelect10: enable information exceptions reporting\n"));
13035 /* sends SMART ENABLE OPERATIONS */
13036 fis->h.fisType = 0x27; /* Reg host to device */
13037 fis->h.c_pmPort = 0x80; /* C Bit is set */
13039 fis->h.command = SAT_SMART_ENABLE_OPERATIONS; /* 0xB0 */
13040 fis->h.features = 0xD8; /* enable */
13041 fis->d.lbaLow = 0; /* */
13042 fis->d.lbaMid = 0x4F; /* 0x4F */
13043 fis->d.lbaHigh = 0xC2; /* 0xC2 */
13044 fis->d.device = 0; /* */
13045 fis->d.lbaLowExp = 0; /* */
13046 fis->d.lbaMidExp = 0; /* */
13047 fis->d.lbaHighExp = 0; /* */
13048 fis->d.featuresExp = 0; /* */
13049 fis->d.sectorCount = 0; /* */
13050 fis->d.sectorCountExp = 0; /* */
13051 fis->d.reserved4 = 0;
13052 fis->d.control = 0; /* FIS HOB bit clear */
13053 fis->d.reserved5 = 0;
13055 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13057 /* Initialize CB for SATA completion.
13059 satIOContext->satCompleteCB = &satModeSelect6n10CB;
13062 * Prepare SGL and send FIS to LL layer.
13064 satIOContext->reqType = agRequestType; /* Save it */
13066 status = sataLLIOStart( tiRoot,
13075 TI_DBG5(("satModeSelect10: disable information exceptions reporting\n"));
13076 /* sends SMART DISABLE OPERATIONS */
13077 fis->h.fisType = 0x27; /* Reg host to device */
13078 fis->h.c_pmPort = 0x80; /* C Bit is set */
13080 fis->h.command = SAT_SMART_DISABLE_OPERATIONS; /* 0xB0 */
13081 fis->h.features = 0xD9; /* disable */
13082 fis->d.lbaLow = 0; /* */
13083 fis->d.lbaMid = 0x4F; /* 0x4F */
13084 fis->d.lbaHigh = 0xC2; /* 0xC2 */
13085 fis->d.device = 0; /* */
13086 fis->d.lbaLowExp = 0; /* */
13087 fis->d.lbaMidExp = 0; /* */
13088 fis->d.lbaHighExp = 0; /* */
13089 fis->d.featuresExp = 0; /* */
13090 fis->d.sectorCount = 0; /* */
13091 fis->d.sectorCountExp = 0; /* */
13092 fis->d.reserved4 = 0;
13093 fis->d.control = 0; /* FIS HOB bit clear */
13094 fis->d.reserved5 = 0;
13096 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13098 /* Initialize CB for SATA completion.
13100 satIOContext->satCompleteCB = &satModeSelect6n10CB;
13103 * Prepare SGL and send FIS to LL layer.
13105 satIOContext->reqType = agRequestType; /* Save it */
13107 status = sataLLIOStart( tiRoot,
13118 TI_DBG1(("satModeSelect10: Error unknown page code 0x%x\n", pLogPage[12]));
13119 satSetSensePayload( pSense,
13120 SCSI_SNSKEY_NO_SENSE,
13122 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
13125 ostiInitiatorIOCompleted( tiRoot,
13128 SCSI_STAT_CHECK_CONDITION,
13129 satIOContext->pTiSenseData,
13130 satIOContext->interruptContext );
13137 /*****************************************************************************/
13138 /*! \brief SAT implementation for SCSI satSynchronizeCache10.
13140 * SAT implementation for SCSI satSynchronizeCache10.
13142 * \param tiRoot: Pointer to TISA initiator driver/port instance.
13143 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
13144 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
13145 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
13146 * \param satIOContext_t: Pointer to the SAT IO Context
13148 * \return If command is started successfully
13149 * - \e tiSuccess: I/O request successfully initiated.
13150 * - \e tiBusy: No resources available, try again later.
13151 * - \e tiIONoDevice: Invalid device handle.
13152 * - \e tiError: Other errors.
13154 /*****************************************************************************/
13155 GLOBAL bit32 satSynchronizeCache10(
13157 tiIORequest_t *tiIORequest,
13158 tiDeviceHandle_t *tiDeviceHandle,
13159 tiScsiInitiatorRequest_t *tiScsiRequest,
13160 satIOContext_t *satIOContext)
13163 bit32 agRequestType;
13164 satDeviceData_t *pSatDevData;
13165 scsiRspSense_t *pSense;
13166 tiIniScsiCmnd_t *scsiCmnd;
13167 agsaFisRegHostToDevice_t *fis;
13169 pSense = satIOContext->pSense;
13170 pSatDevData = satIOContext->pSatDevData;
13171 scsiCmnd = &tiScsiRequest->scsiCmnd;
13172 fis = satIOContext->pFis;
13174 TI_DBG5(("satSynchronizeCache10: start\n"));
13176 /* checking CONTROL */
13177 /* NACA == 1 or LINK == 1*/
13178 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13180 satSetSensePayload( pSense,
13181 SCSI_SNSKEY_ILLEGAL_REQUEST,
13183 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13186 ostiInitiatorIOCompleted( tiRoot,
13189 SCSI_STAT_CHECK_CONDITION,
13190 satIOContext->pTiSenseData,
13191 satIOContext->interruptContext );
13193 TI_DBG2(("satSynchronizeCache10: return control\n"));
13197 /* checking IMMED bit */
13198 if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
13200 TI_DBG1(("satSynchronizeCache10: GOOD status due to IMMED bit\n"));
13202 /* return GOOD status first here */
13203 ostiInitiatorIOCompleted( tiRoot,
13208 satIOContext->interruptContext);
13211 /* sends FLUSH CACHE or FLUSH CACHE EXT */
13212 if (pSatDevData->sat48BitSupport == agTRUE)
13214 TI_DBG5(("satSynchronizeCache10: sends FLUSH CACHE EXT\n"));
13215 /* FLUSH CACHE EXT */
13216 fis->h.fisType = 0x27; /* Reg host to device */
13217 fis->h.c_pmPort = 0x80; /* C Bit is set */
13219 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */
13220 fis->h.features = 0; /* FIS reserve */
13221 fis->d.featuresExp = 0; /* FIS reserve */
13222 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
13223 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
13224 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
13225 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
13226 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
13227 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
13228 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
13229 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
13230 fis->d.device = 0; /* FIS DEV is discared in SATA */
13231 fis->d.control = 0; /* FIS HOB bit clear */
13232 fis->d.reserved4 = 0;
13233 fis->d.reserved5 = 0;
13238 TI_DBG5(("satSynchronizeCache10: sends FLUSH CACHE\n"));
13240 fis->h.fisType = 0x27; /* Reg host to device */
13241 fis->h.c_pmPort = 0x80; /* C Bit is set */
13243 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */
13244 fis->h.features = 0; /* FIS features NA */
13245 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
13246 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
13247 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
13248 fis->d.lbaLowExp = 0;
13249 fis->d.lbaMidExp = 0;
13250 fis->d.lbaHighExp = 0;
13251 fis->d.featuresExp = 0;
13252 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
13253 fis->d.sectorCountExp = 0;
13254 fis->d.device = 0; /* FIS DEV is discared in SATA */
13255 fis->d.control = 0; /* FIS HOB bit clear */
13256 fis->d.reserved4 = 0;
13257 fis->d.reserved5 = 0;
13261 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13263 /* Initialize CB for SATA completion.
13265 satIOContext->satCompleteCB = &satSynchronizeCache10n16CB;
13268 * Prepare SGL and send FIS to LL layer.
13270 satIOContext->reqType = agRequestType; /* Save it */
13272 status = sataLLIOStart( tiRoot,
13282 /*****************************************************************************/
13283 /*! \brief SAT implementation for SCSI satSynchronizeCache16.
13285 * SAT implementation for SCSI satSynchronizeCache16.
13287 * \param tiRoot: Pointer to TISA initiator driver/port instance.
13288 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
13289 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
13290 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
13291 * \param satIOContext_t: Pointer to the SAT IO Context
13293 * \return If command is started successfully
13294 * - \e tiSuccess: I/O request successfully initiated.
13295 * - \e tiBusy: No resources available, try again later.
13296 * - \e tiIONoDevice: Invalid device handle.
13297 * - \e tiError: Other errors.
13299 /*****************************************************************************/
13300 GLOBAL bit32 satSynchronizeCache16(
13302 tiIORequest_t *tiIORequest,
13303 tiDeviceHandle_t *tiDeviceHandle,
13304 tiScsiInitiatorRequest_t *tiScsiRequest,
13305 satIOContext_t *satIOContext)
13308 bit32 agRequestType;
13309 satDeviceData_t *pSatDevData;
13310 scsiRspSense_t *pSense;
13311 tiIniScsiCmnd_t *scsiCmnd;
13312 agsaFisRegHostToDevice_t *fis;
13314 pSense = satIOContext->pSense;
13315 pSatDevData = satIOContext->pSatDevData;
13316 scsiCmnd = &tiScsiRequest->scsiCmnd;
13317 fis = satIOContext->pFis;
13319 TI_DBG5(("satSynchronizeCache16: start\n"));
13321 /* checking CONTROL */
13322 /* NACA == 1 or LINK == 1*/
13323 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
13325 satSetSensePayload( pSense,
13326 SCSI_SNSKEY_ILLEGAL_REQUEST,
13328 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13331 ostiInitiatorIOCompleted( tiRoot,
13334 SCSI_STAT_CHECK_CONDITION,
13335 satIOContext->pTiSenseData,
13336 satIOContext->interruptContext );
13338 TI_DBG1(("satSynchronizeCache16: return control\n"));
13343 /* checking IMMED bit */
13344 if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
13346 TI_DBG1(("satSynchronizeCache16: GOOD status due to IMMED bit\n"));
13348 /* return GOOD status first here */
13349 ostiInitiatorIOCompleted( tiRoot,
13354 satIOContext->interruptContext);
13357 /* sends FLUSH CACHE or FLUSH CACHE EXT */
13358 if (pSatDevData->sat48BitSupport == agTRUE)
13360 TI_DBG5(("satSynchronizeCache16: sends FLUSH CACHE EXT\n"));
13361 /* FLUSH CACHE EXT */
13362 fis->h.fisType = 0x27; /* Reg host to device */
13363 fis->h.c_pmPort = 0x80; /* C Bit is set */
13365 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */
13366 fis->h.features = 0; /* FIS reserve */
13367 fis->d.featuresExp = 0; /* FIS reserve */
13368 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
13369 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
13370 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
13371 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
13372 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
13373 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
13374 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
13375 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
13376 fis->d.device = 0; /* FIS DEV is discared in SATA */
13377 fis->d.control = 0; /* FIS HOB bit clear */
13378 fis->d.reserved4 = 0;
13379 fis->d.reserved5 = 0;
13384 TI_DBG5(("satSynchronizeCache16: sends FLUSH CACHE\n"));
13386 fis->h.fisType = 0x27; /* Reg host to device */
13387 fis->h.c_pmPort = 0x80; /* C Bit is set */
13389 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */
13390 fis->h.features = 0; /* FIS features NA */
13391 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
13392 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
13393 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
13394 fis->d.lbaLowExp = 0;
13395 fis->d.lbaMidExp = 0;
13396 fis->d.lbaHighExp = 0;
13397 fis->d.featuresExp = 0;
13398 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
13399 fis->d.sectorCountExp = 0;
13400 fis->d.device = 0; /* FIS DEV is discared in SATA */
13401 fis->d.control = 0; /* FIS HOB bit clear */
13402 fis->d.reserved4 = 0;
13403 fis->d.reserved5 = 0;
13407 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13409 /* Initialize CB for SATA completion.
13411 satIOContext->satCompleteCB = &satSynchronizeCache10n16CB;
13414 * Prepare SGL and send FIS to LL layer.
13416 satIOContext->reqType = agRequestType; /* Save it */
13418 status = sataLLIOStart( tiRoot,
13429 /*****************************************************************************/
13430 /*! \brief SAT implementation for SCSI satWriteAndVerify10.
13432 * SAT implementation for SCSI satWriteAndVerify10.
13434 * \param tiRoot: Pointer to TISA initiator driver/port instance.
13435 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
13436 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
13437 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
13438 * \param satIOContext_t: Pointer to the SAT IO Context
13440 * \return If command is started successfully
13441 * - \e tiSuccess: I/O request successfully initiated.
13442 * - \e tiBusy: No resources available, try again later.
13443 * - \e tiIONoDevice: Invalid device handle.
13444 * - \e tiError: Other errors.
13446 /*****************************************************************************/
13447 GLOBAL bit32 satWriteAndVerify10(
13449 tiIORequest_t *tiIORequest,
13450 tiDeviceHandle_t *tiDeviceHandle,
13451 tiScsiInitiatorRequest_t *tiScsiRequest,
13452 satIOContext_t *satIOContext)
13455 combination of write10 and verify10
13459 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13460 satDeviceData_t *pSatDevData;
13461 scsiRspSense_t *pSense;
13462 tiIniScsiCmnd_t *scsiCmnd;
13463 agsaFisRegHostToDevice_t *fis;
13469 bit32 rangeChk = agFALSE; /* lba and tl range check */
13471 pSense = satIOContext->pSense;
13472 pSatDevData = satIOContext->pSatDevData;
13473 scsiCmnd = &tiScsiRequest->scsiCmnd;
13474 fis = satIOContext->pFis;
13476 TI_DBG5(("satWriteAndVerify10: start\n"));
13479 /* checking BYTCHK bit */
13480 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
13482 satSetSensePayload( pSense,
13483 SCSI_SNSKEY_ILLEGAL_REQUEST,
13485 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13488 ostiInitiatorIOCompleted( tiRoot,
13491 SCSI_STAT_CHECK_CONDITION,
13492 satIOContext->pTiSenseData,
13493 satIOContext->interruptContext );
13495 TI_DBG1(("satWriteAndVerify10: BYTCHK bit checking \n"));
13500 /* checking CONTROL */
13501 /* NACA == 1 or LINK == 1*/
13502 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13504 satSetSensePayload( pSense,
13505 SCSI_SNSKEY_ILLEGAL_REQUEST,
13507 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13510 ostiInitiatorIOCompleted( tiRoot,
13513 SCSI_STAT_CHECK_CONDITION,
13514 satIOContext->pTiSenseData,
13515 satIOContext->interruptContext );
13517 TI_DBG1(("satWriteAndVerify10: return control\n"));
13521 osti_memset(LBA, 0, sizeof(LBA));
13522 osti_memset(TL, 0, sizeof(TL));
13524 /* do not use memcpy due to indexing in LBA and TL */
13525 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
13526 LBA[1] = scsiCmnd->cdb[3];
13527 LBA[2] = scsiCmnd->cdb[4];
13528 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
13532 TL[2] = scsiCmnd->cdb[7]; /* MSB */
13533 TL[3] = scsiCmnd->cdb[8]; /* LSB */
13535 rangeChk = satAddNComparebit32(LBA, TL);
13537 /* cbd10; computing LBA and transfer length */
13538 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
13539 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
13540 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
13543 /* Table 34, 9.1, p 46 */
13545 note: As of 2/10/2006, no support for DMA QUEUED
13549 Table 34, 9.1, p 46, b
13550 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
13551 return check condition
13553 if (pSatDevData->satNCQ != agTRUE &&
13554 pSatDevData->sat48BitSupport != agTRUE
13557 if (lba > SAT_TR_LBA_LIMIT - 1)
13559 satSetSensePayload( pSense,
13560 SCSI_SNSKEY_ILLEGAL_REQUEST,
13562 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
13565 ostiInitiatorIOCompleted( tiRoot,
13568 SCSI_STAT_CHECK_CONDITION,
13569 satIOContext->pTiSenseData,
13570 satIOContext->interruptContext );
13572 TI_DBG1(("satWriteAndVerify10: return LBA out of range\n"));
13576 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
13578 TI_DBG1(("satWrite10: return LBA+TL out of range, not EXT\n"));
13579 satSetSensePayload( pSense,
13580 SCSI_SNSKEY_ILLEGAL_REQUEST,
13582 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
13585 ostiInitiatorIOCompleted( tiRoot,
13588 SCSI_STAT_CHECK_CONDITION,
13589 satIOContext->pTiSenseData,
13590 satIOContext->interruptContext );
13598 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
13600 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
13604 /* can't fit the transfer length */
13605 TI_DBG5(("satWriteAndVerify10: case 2 !!!\n"));
13606 fis->h.fisType = 0x27; /* Reg host to device */
13607 fis->h.c_pmPort = 0x80; /* C bit is set */
13608 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
13609 fis->h.features = 0; /* FIS reserve */
13610 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
13611 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
13612 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
13614 /* FIS LBA mode set LBA (27:24) */
13615 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
13617 fis->d.lbaLowExp = 0;
13618 fis->d.lbaMidExp = 0;
13619 fis->d.lbaHighExp = 0;
13620 fis->d.featuresExp = 0;
13621 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
13622 fis->d.sectorCountExp = 0;
13623 fis->d.reserved4 = 0;
13624 fis->d.control = 0; /* FIS HOB bit clear */
13625 fis->d.reserved5 = 0;
13627 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13628 satIOContext->ATACmd = SAT_WRITE_DMA;
13633 /* WRITE MULTIPLE or WRITE SECTOR(S) */
13634 /* WRITE SECTORS for easier implemetation */
13635 /* can't fit the transfer length */
13636 TI_DBG5(("satWriteAndVerify10: case 1 !!!\n"));
13637 fis->h.fisType = 0x27; /* Reg host to device */
13638 fis->h.c_pmPort = 0x80; /* C bit is set */
13639 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
13640 fis->h.features = 0; /* FIS reserve */
13641 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
13642 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
13643 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
13645 /* FIS LBA mode set LBA (27:24) */
13646 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
13648 fis->d.lbaLowExp = 0;
13649 fis->d.lbaMidExp = 0;
13650 fis->d.lbaHighExp = 0;
13651 fis->d.featuresExp = 0;
13652 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
13653 fis->d.sectorCountExp = 0;
13654 fis->d.reserved4 = 0;
13655 fis->d.control = 0; /* FIS HOB bit clear */
13656 fis->d.reserved5 = 0;
13658 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
13659 satIOContext->ATACmd = SAT_WRITE_SECTORS;
13665 if (pSatDevData->sat48BitSupport == agTRUE)
13667 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
13670 /* WRITE DMA EXT or WRITE DMA FUA EXT */
13671 TI_DBG5(("satWriteAndVerify10: case 3\n"));
13672 fis->h.fisType = 0x27; /* Reg host to device */
13673 fis->h.c_pmPort = 0x80; /* C Bit is set */
13675 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
13676 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
13678 fis->h.features = 0; /* FIS reserve */
13679 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
13680 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
13681 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
13682 fis->d.device = 0x40; /* FIS LBA mode set */
13683 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
13684 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
13685 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
13686 fis->d.featuresExp = 0; /* FIS reserve */
13687 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
13688 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
13689 fis->d.reserved4 = 0;
13690 fis->d.control = 0; /* FIS HOB bit clear */
13691 fis->d.reserved5 = 0;
13693 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13694 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
13699 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
13700 /* WRITE SECTORS EXT for easier implemetation */
13701 TI_DBG5(("satWriteAndVerify10: case 4\n"));
13702 fis->h.fisType = 0x27; /* Reg host to device */
13703 fis->h.c_pmPort = 0x80; /* C Bit is set */
13704 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
13706 fis->h.features = 0; /* FIS reserve */
13707 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
13708 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
13709 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
13710 fis->d.device = 0x40; /* FIS LBA mode set */
13711 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
13712 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
13713 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
13714 fis->d.featuresExp = 0; /* FIS reserve */
13715 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
13716 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
13717 fis->d.reserved4 = 0;
13718 fis->d.control = 0; /* FIS HOB bit clear */
13719 fis->d.reserved5 = 0;
13721 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
13722 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
13726 if (pSatDevData->satNCQ == agTRUE)
13728 /* WRITE FPDMA QUEUED */
13729 if (pSatDevData->sat48BitSupport != agTRUE)
13731 TI_DBG5(("satWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support \n"));
13732 satSetSensePayload( pSense,
13733 SCSI_SNSKEY_ILLEGAL_REQUEST,
13735 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13738 ostiInitiatorIOCompleted( tiRoot,
13741 SCSI_STAT_CHECK_CONDITION,
13742 satIOContext->pTiSenseData,
13743 satIOContext->interruptContext );
13746 TI_DBG5(("satWriteAndVerify10: case 5\n"));
13748 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
13750 fis->h.fisType = 0x27; /* Reg host to device */
13751 fis->h.c_pmPort = 0x80; /* C Bit is set */
13752 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
13753 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
13754 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
13755 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
13756 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
13758 /* Check FUA bit */
13759 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK)
13760 fis->d.device = 0xC0; /* FIS FUA set */
13762 fis->d.device = 0x40; /* FIS FUA clear */
13764 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
13765 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
13766 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
13767 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
13768 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
13769 fis->d.sectorCountExp = 0;
13770 fis->d.reserved4 = 0;
13771 fis->d.control = 0; /* FIS HOB bit clear */
13772 fis->d.reserved5 = 0;
13774 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
13775 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
13778 satIOContext->currentLBA = lba;
13779 satIOContext->OrgTL = tl;
13782 computing number of loop and remainder for tl
13783 0xFF in case not ext
13786 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
13788 LoopNum = satComputeLoopNum(tl, 0xFF);
13790 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
13791 fis->h.command == SAT_WRITE_DMA_EXT ||
13792 fis->h.command == SAT_WRITE_DMA_FUA_EXT
13795 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
13796 LoopNum = satComputeLoopNum(tl, 0xFFFF);
13800 /* SAT_WRITE_FPDMA_QUEUED */
13801 LoopNum = satComputeLoopNum(tl, 0xFFFF);
13804 satIOContext->LoopNum = LoopNum;
13809 TI_DBG5(("satWriteAndVerify10: NON CHAINED data\n"));
13810 /* Initialize CB for SATA completion.
13812 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
13816 TI_DBG1(("satWriteAndVerify10: CHAINED data\n"));
13817 /* re-setting tl */
13818 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
13820 fis->d.sectorCount = 0xFF;
13822 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
13823 fis->h.command == SAT_WRITE_DMA_EXT ||
13824 fis->h.command == SAT_WRITE_DMA_FUA_EXT
13827 fis->d.sectorCount = 0xFF;
13828 fis->d.sectorCountExp = 0xFF;
13832 /* SAT_WRITE_FPDMA_QUEUED */
13833 fis->h.features = 0xFF;
13834 fis->d.featuresExp = 0xFF;
13837 /* Initialize CB for SATA completion.
13839 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
13844 * Prepare SGL and send FIS to LL layer.
13846 satIOContext->reqType = agRequestType; /* Save it */
13848 status = sataLLIOStart( tiRoot,
13863 GLOBAL bit32 satWriteAndVerify10(
13865 tiIORequest_t *tiIORequest,
13866 tiDeviceHandle_t *tiDeviceHandle,
13867 tiScsiInitiatorRequest_t *tiScsiRequest,
13868 satIOContext_t *satIOContext)
13871 combination of write10 and verify10
13875 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13876 satDeviceData_t *pSatDevData;
13877 scsiRspSense_t *pSense;
13878 tiIniScsiCmnd_t *scsiCmnd;
13879 agsaFisRegHostToDevice_t *fis;
13883 pSense = satIOContext->pSense;
13884 pSatDevData = satIOContext->pSatDevData;
13885 scsiCmnd = &tiScsiRequest->scsiCmnd;
13886 fis = satIOContext->pFis;
13888 TI_DBG5(("satWriteAndVerify10: start\n"));
13891 /* checking BYTCHK bit */
13892 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
13894 satSetSensePayload( pSense,
13895 SCSI_SNSKEY_ILLEGAL_REQUEST,
13897 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13900 ostiInitiatorIOCompleted( tiRoot,
13903 SCSI_STAT_CHECK_CONDITION,
13904 satIOContext->pTiSenseData,
13905 satIOContext->interruptContext );
13907 TI_DBG1(("satWriteAndVerify10: BYTCHK bit checking \n"));
13912 /* checking CONTROL */
13913 /* NACA == 1 or LINK == 1*/
13914 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13916 satSetSensePayload( pSense,
13917 SCSI_SNSKEY_ILLEGAL_REQUEST,
13919 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13922 ostiInitiatorIOCompleted( tiRoot,
13925 SCSI_STAT_CHECK_CONDITION,
13926 satIOContext->pTiSenseData,
13927 satIOContext->interruptContext );
13929 TI_DBG2(("satWriteAndVerify10: return control\n"));
13933 /* let's do write10 */
13934 if ( pSatDevData->sat48BitSupport != agTRUE )
13937 writeandverify10 but no support for 48 bit addressing -> problem in transfer
13938 length(sector count)
13940 satSetSensePayload( pSense,
13941 SCSI_SNSKEY_ILLEGAL_REQUEST,
13943 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13946 ostiInitiatorIOCompleted( tiRoot,
13949 SCSI_STAT_CHECK_CONDITION,
13950 satIOContext->pTiSenseData,
13951 satIOContext->interruptContext );
13953 TI_DBG1(("satWriteAndVerify10: return internal checking\n"));
13957 /* cbd10; computing LBA and transfer length */
13958 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
13959 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
13960 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
13963 /* Table 34, 9.1, p 46 */
13965 note: As of 2/10/2006, no support for DMA QUEUED
13969 Table 34, 9.1, p 46, b
13970 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
13971 return check condition
13973 if (pSatDevData->satNCQ != agTRUE &&
13974 pSatDevData->sat48BitSupport != agTRUE
13977 if (lba > SAT_TR_LBA_LIMIT - 1)
13979 satSetSensePayload( pSense,
13980 SCSI_SNSKEY_ILLEGAL_REQUEST,
13982 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
13985 ostiInitiatorIOCompleted( tiRoot,
13988 SCSI_STAT_CHECK_CONDITION,
13989 satIOContext->pTiSenseData,
13990 satIOContext->interruptContext );
13992 TI_DBG1(("satWriteAndVerify10: return LBA out of range\n"));
13999 if (lba + tl <= SAT_TR_LBA_LIMIT)
14001 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14005 /* can't fit the transfer length */
14006 TI_DBG5(("satWriteAndVerify10: case 2 !!!\n"));
14007 fis->h.fisType = 0x27; /* Reg host to device */
14008 fis->h.c_pmPort = 0x80; /* C bit is set */
14009 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
14010 fis->h.features = 0; /* FIS reserve */
14011 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14012 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14013 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14015 /* FIS LBA mode set LBA (27:24) */
14016 fis->d.device = (0x4 << 4) | (scsiCmnd->cdb[2] & 0xF);
14018 fis->d.lbaLowExp = 0;
14019 fis->d.lbaMidExp = 0;
14020 fis->d.lbaHighExp = 0;
14021 fis->d.featuresExp = 0;
14022 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14023 fis->d.sectorCountExp = 0;
14024 fis->d.reserved4 = 0;
14025 fis->d.control = 0; /* FIS HOB bit clear */
14026 fis->d.reserved5 = 0;
14028 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14029 satIOContext->ATACmd = SAT_WRITE_DMA;
14034 /* WRITE MULTIPLE or WRITE SECTOR(S) */
14035 /* WRITE SECTORS for easier implemetation */
14036 /* can't fit the transfer length */
14037 TI_DBG5(("satWriteAndVerify10: case 1 !!!\n"));
14038 fis->h.fisType = 0x27; /* Reg host to device */
14039 fis->h.c_pmPort = 0x80; /* C bit is set */
14040 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
14041 fis->h.features = 0; /* FIS reserve */
14042 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14043 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14044 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14046 /* FIS LBA mode set LBA (27:24) */
14047 fis->d.device = (0x4 << 4) | (scsiCmnd->cdb[2] & 0xF);
14049 fis->d.lbaLowExp = 0;
14050 fis->d.lbaMidExp = 0;
14051 fis->d.lbaHighExp = 0;
14052 fis->d.featuresExp = 0;
14053 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14054 fis->d.sectorCountExp = 0;
14055 fis->d.reserved4 = 0;
14056 fis->d.control = 0; /* FIS HOB bit clear */
14057 fis->d.reserved5 = 0;
14059 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14060 satIOContext->ATACmd = SAT_WRITE_SECTORS;
14066 if (pSatDevData->sat48BitSupport == agTRUE)
14068 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14071 /* WRITE DMA EXT or WRITE DMA FUA EXT */
14072 TI_DBG5(("satWriteAndVerify10: case 3\n"));
14073 fis->h.fisType = 0x27; /* Reg host to device */
14074 fis->h.c_pmPort = 0x80; /* C Bit is set */
14076 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
14077 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
14079 fis->h.features = 0; /* FIS reserve */
14080 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14081 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14082 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14083 fis->d.device = 0x40; /* FIS LBA mode set */
14084 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14085 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14086 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14087 fis->d.featuresExp = 0; /* FIS reserve */
14088 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14089 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
14090 fis->d.reserved4 = 0;
14091 fis->d.control = 0; /* FIS HOB bit clear */
14092 fis->d.reserved5 = 0;
14094 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14099 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
14100 /* WRITE SECTORS EXT for easier implemetation */
14101 TI_DBG5(("satWriteAndVerify10: case 4\n"));
14102 fis->h.fisType = 0x27; /* Reg host to device */
14103 fis->h.c_pmPort = 0x80; /* C Bit is set */
14104 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
14106 fis->h.features = 0; /* FIS reserve */
14107 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14108 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14109 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14110 fis->d.device = 0x40; /* FIS LBA mode set */
14111 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14112 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14113 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14114 fis->d.featuresExp = 0; /* FIS reserve */
14115 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14116 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
14117 fis->d.reserved4 = 0;
14118 fis->d.control = 0; /* FIS HOB bit clear */
14119 fis->d.reserved5 = 0;
14121 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14125 if (pSatDevData->satNCQ == agTRUE)
14127 /* WRITE FPDMA QUEUED */
14128 if (pSatDevData->sat48BitSupport != agTRUE)
14130 TI_DBG5(("satWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support \n"));
14131 satSetSensePayload( pSense,
14132 SCSI_SNSKEY_ILLEGAL_REQUEST,
14134 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14137 ostiInitiatorIOCompleted( tiRoot,
14140 SCSI_STAT_CHECK_CONDITION,
14141 satIOContext->pTiSenseData,
14142 satIOContext->interruptContext );
14145 TI_DBG5(("satWriteAndVerify10: case 5\n"));
14147 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
14149 fis->h.fisType = 0x27; /* Reg host to device */
14150 fis->h.c_pmPort = 0x80; /* C Bit is set */
14151 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
14152 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14153 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14154 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14155 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14157 /* Check FUA bit */
14158 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK)
14159 fis->d.device = 0xC0; /* FIS FUA set */
14161 fis->d.device = 0x40; /* FIS FUA clear */
14163 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14164 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14165 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14166 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
14167 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
14168 fis->d.sectorCountExp = 0;
14169 fis->d.reserved4 = 0;
14170 fis->d.control = 0; /* FIS HOB bit clear */
14171 fis->d.reserved5 = 0;
14173 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
14176 /* Initialize CB for SATA completion.
14178 satIOContext->satCompleteCB = &satWriteAndVerify10CB;
14181 * Prepare SGL and send FIS to LL layer.
14183 satIOContext->reqType = agRequestType; /* Save it */
14185 status = sataLLIOStart( tiRoot,
14193 #endif /* REMOVED */
14196 /*****************************************************************************/
14197 /*! \brief SAT implementation for SCSI satWriteAndVerify10_1.
14199 * SAT implementation for SCSI satWriteAndVerify10_1.
14200 * Sub function of satWriteAndVerify10
14202 * \param tiRoot: Pointer to TISA initiator driver/port instance.
14203 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
14204 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
14205 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
14206 * \param satIOContext_t: Pointer to the SAT IO Context
14208 * \return If command is started successfully
14209 * - \e tiSuccess: I/O request successfully initiated.
14210 * - \e tiBusy: No resources available, try again later.
14211 * - \e tiIONoDevice: Invalid device handle.
14212 * - \e tiError: Other errors.
14214 /*****************************************************************************/
14215 GLOBAL bit32 satWriteAndVerify10_1(
14217 tiIORequest_t *tiIORequest,
14218 tiDeviceHandle_t *tiDeviceHandle,
14219 tiScsiInitiatorRequest_t *tiScsiRequest,
14220 satIOContext_t *satIOContext)
14223 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14224 satDeviceData_t *pSatDevData;
14225 scsiRspSense_t *pSense;
14226 tiIniScsiCmnd_t *scsiCmnd;
14227 agsaFisRegHostToDevice_t *fis;
14229 pSense = satIOContext->pSense;
14230 pSatDevData = satIOContext->pSatDevData;
14231 scsiCmnd = &tiScsiRequest->scsiCmnd;
14232 fis = satIOContext->pFis;
14234 TI_DBG5(("satWriteAndVerify10_1: start\n"));
14236 if (pSatDevData->sat48BitSupport == agTRUE)
14238 fis->h.fisType = 0x27; /* Reg host to device */
14239 fis->h.c_pmPort = 0x80; /* C Bit is set */
14241 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
14242 fis->h.features = 0; /* FIS reserve */
14243 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14244 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14245 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14246 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
14247 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14248 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14249 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14250 fis->d.featuresExp = 0; /* FIS reserve */
14251 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14252 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
14254 fis->d.reserved4 = 0;
14255 fis->d.control = 0; /* FIS HOB bit clear */
14256 fis->d.reserved5 = 0;
14258 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14260 /* Initialize CB for SATA completion.
14262 satIOContext->satCompleteCB = &satWriteAndVerify10CB;
14265 * Prepare SGL and send FIS to LL layer.
14267 satIOContext->reqType = agRequestType; /* Save it */
14269 status = sataLLIOStart( tiRoot,
14276 TI_DBG1(("satWriteAndVerify10_1: return status %d\n", status));
14281 /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */
14282 TI_DBG1(("satWriteAndVerify10_1: can't fit in SAT_READ_VERIFY_SECTORS\n"));
14289 #endif /* REMOVED */
14291 /*****************************************************************************/
14292 /*! \brief SAT implementation for SCSI satWriteAndVerify12.
14294 * SAT implementation for SCSI satWriteAndVerify12.
14296 * \param tiRoot: Pointer to TISA initiator driver/port instance.
14297 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
14298 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
14299 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
14300 * \param satIOContext_t: Pointer to the SAT IO Context
14302 * \return If command is started successfully
14303 * - \e tiSuccess: I/O request successfully initiated.
14304 * - \e tiBusy: No resources available, try again later.
14305 * - \e tiIONoDevice: Invalid device handle.
14306 * - \e tiError: Other errors.
14308 /*****************************************************************************/
14309 GLOBAL bit32 satWriteAndVerify12(
14311 tiIORequest_t *tiIORequest,
14312 tiDeviceHandle_t *tiDeviceHandle,
14313 tiScsiInitiatorRequest_t *tiScsiRequest,
14314 satIOContext_t *satIOContext)
14317 combination of write12 and verify12
14318 temp: since write12 is not support (due to internal checking), no support
14321 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14322 satDeviceData_t *pSatDevData;
14323 scsiRspSense_t *pSense;
14324 tiIniScsiCmnd_t *scsiCmnd;
14325 agsaFisRegHostToDevice_t *fis;
14331 bit32 rangeChk = agFALSE; /* lba and tl range check */
14333 pSense = satIOContext->pSense;
14334 pSatDevData = satIOContext->pSatDevData;
14335 scsiCmnd = &tiScsiRequest->scsiCmnd;
14336 fis = satIOContext->pFis;
14338 TI_DBG5(("satWriteAndVerify12: start\n"));
14340 /* checking BYTCHK bit */
14341 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
14343 satSetSensePayload( pSense,
14344 SCSI_SNSKEY_ILLEGAL_REQUEST,
14346 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14349 ostiInitiatorIOCompleted( tiRoot,
14352 SCSI_STAT_CHECK_CONDITION,
14353 satIOContext->pTiSenseData,
14354 satIOContext->interruptContext );
14356 TI_DBG1(("satWriteAndVerify12: BYTCHK bit checking \n"));
14360 /* checking CONTROL */
14361 /* NACA == 1 or LINK == 1*/
14362 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
14364 satSetSensePayload( pSense,
14365 SCSI_SNSKEY_ILLEGAL_REQUEST,
14367 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14370 ostiInitiatorIOCompleted( tiRoot,
14373 SCSI_STAT_CHECK_CONDITION,
14374 satIOContext->pTiSenseData,
14375 satIOContext->interruptContext );
14377 TI_DBG2(("satWriteAndVerify12: return control\n"));
14381 osti_memset(LBA, 0, sizeof(LBA));
14382 osti_memset(TL, 0, sizeof(TL));
14384 /* do not use memcpy due to indexing in LBA and TL */
14385 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
14386 LBA[1] = scsiCmnd->cdb[3];
14387 LBA[2] = scsiCmnd->cdb[4];
14388 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
14390 TL[0] = scsiCmnd->cdb[6]; /* MSB */
14391 TL[1] = scsiCmnd->cdb[7];
14392 TL[2] = scsiCmnd->cdb[7];
14393 TL[3] = scsiCmnd->cdb[8]; /* LSB */
14395 rangeChk = satAddNComparebit32(LBA, TL);
14397 lba = satComputeCDB12LBA(satIOContext);
14398 tl = satComputeCDB12TL(satIOContext);
14401 /* Table 34, 9.1, p 46 */
14403 note: As of 2/10/2006, no support for DMA QUEUED
14407 Table 34, 9.1, p 46, b
14408 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
14409 return check condition
14411 if (pSatDevData->satNCQ != agTRUE &&
14412 pSatDevData->sat48BitSupport != agTRUE
14415 if (lba > SAT_TR_LBA_LIMIT - 1)
14417 satSetSensePayload( pSense,
14418 SCSI_SNSKEY_ILLEGAL_REQUEST,
14420 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
14423 ostiInitiatorIOCompleted( tiRoot,
14426 SCSI_STAT_CHECK_CONDITION,
14427 satIOContext->pTiSenseData,
14428 satIOContext->interruptContext );
14430 TI_DBG1(("satWriteAndVerify12: return LBA out of range, not EXT\n"));
14434 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
14436 TI_DBG1(("satWriteAndVerify12: return LBA+TL out of range, not EXT\n"));
14437 satSetSensePayload( pSense,
14438 SCSI_SNSKEY_ILLEGAL_REQUEST,
14440 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
14443 ostiInitiatorIOCompleted( tiRoot,
14446 SCSI_STAT_CHECK_CONDITION,
14447 satIOContext->pTiSenseData,
14448 satIOContext->interruptContext );
14455 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
14457 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14461 /* In case that we can't fit the transfer length, we loop */
14462 TI_DBG5(("satWriteAndVerify12: case 2\n"));
14463 fis->h.fisType = 0x27; /* Reg host to device */
14464 fis->h.c_pmPort = 0x80; /* C bit is set */
14465 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
14466 fis->h.features = 0; /* FIS reserve */
14467 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14468 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14469 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14471 /* FIS LBA mode set LBA (27:24) */
14472 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
14474 fis->d.lbaLowExp = 0;
14475 fis->d.lbaMidExp = 0;
14476 fis->d.lbaHighExp = 0;
14477 fis->d.featuresExp = 0;
14478 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
14479 fis->d.sectorCountExp = 0;
14480 fis->d.reserved4 = 0;
14481 fis->d.control = 0; /* FIS HOB bit clear */
14482 fis->d.reserved5 = 0;
14484 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14485 satIOContext->ATACmd = SAT_WRITE_DMA;
14490 /* WRITE MULTIPLE or WRITE SECTOR(S) */
14491 /* WRITE SECTORS for easier implemetation */
14492 /* In case that we can't fit the transfer length, we loop */
14493 TI_DBG5(("satWriteAndVerify12: case 1\n"));
14494 fis->h.fisType = 0x27; /* Reg host to device */
14495 fis->h.c_pmPort = 0x80; /* C bit is set */
14496 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
14497 fis->h.features = 0; /* FIS reserve */
14498 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14499 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14500 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14502 /* FIS LBA mode set LBA (27:24) */
14503 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
14505 fis->d.lbaLowExp = 0;
14506 fis->d.lbaMidExp = 0;
14507 fis->d.lbaHighExp = 0;
14508 fis->d.featuresExp = 0;
14509 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
14510 fis->d.sectorCountExp = 0;
14511 fis->d.reserved4 = 0;
14512 fis->d.control = 0; /* FIS HOB bit clear */
14513 fis->d.reserved5 = 0;
14515 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14516 satIOContext->ATACmd = SAT_WRITE_SECTORS;
14521 if (pSatDevData->sat48BitSupport == agTRUE)
14523 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14526 /* WRITE DMA EXT or WRITE DMA FUA EXT */
14527 TI_DBG5(("satWriteAndVerify12: case 3\n"));
14528 fis->h.fisType = 0x27; /* Reg host to device */
14529 fis->h.c_pmPort = 0x80; /* C Bit is set */
14531 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
14532 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
14534 fis->h.features = 0; /* FIS reserve */
14535 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14536 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14537 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14538 fis->d.device = 0x40; /* FIS LBA mode set */
14539 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14540 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14541 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14542 fis->d.featuresExp = 0; /* FIS reserve */
14543 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
14544 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
14545 fis->d.reserved4 = 0;
14546 fis->d.control = 0; /* FIS HOB bit clear */
14547 fis->d.reserved5 = 0;
14549 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14550 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
14555 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
14556 /* WRITE SECTORS EXT for easier implemetation */
14557 TI_DBG5(("satWriteAndVerify12: case 4\n"));
14558 fis->h.fisType = 0x27; /* Reg host to device */
14559 fis->h.c_pmPort = 0x80; /* C Bit is set */
14560 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
14562 fis->h.features = 0; /* FIS reserve */
14563 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14564 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14565 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14566 fis->d.device = 0x40; /* FIS LBA mode set */
14567 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14568 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14569 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14570 fis->d.featuresExp = 0; /* FIS reserve */
14571 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
14572 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
14573 fis->d.reserved4 = 0;
14574 fis->d.control = 0; /* FIS HOB bit clear */
14575 fis->d.reserved5 = 0;
14577 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14578 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
14583 if (pSatDevData->satNCQ == agTRUE)
14585 /* WRITE FPDMA QUEUED */
14586 if (pSatDevData->sat48BitSupport != agTRUE)
14588 TI_DBG5(("satWriteAndVerify12: case 5 !!! error NCQ but 28 bit address support \n"));
14589 satSetSensePayload( pSense,
14590 SCSI_SNSKEY_ILLEGAL_REQUEST,
14592 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14595 ostiInitiatorIOCompleted( tiRoot,
14598 SCSI_STAT_CHECK_CONDITION,
14599 satIOContext->pTiSenseData,
14600 satIOContext->interruptContext );
14603 TI_DBG6(("satWriteAndVerify12: case 5\n"));
14605 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
14607 fis->h.fisType = 0x27; /* Reg host to device */
14608 fis->h.c_pmPort = 0x80; /* C Bit is set */
14609 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
14610 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
14611 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14612 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14613 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14615 /* Check FUA bit */
14616 if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
14617 fis->d.device = 0xC0; /* FIS FUA set */
14619 fis->d.device = 0x40; /* FIS FUA clear */
14621 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14622 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14623 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14624 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
14625 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
14626 fis->d.sectorCountExp = 0;
14627 fis->d.reserved4 = 0;
14628 fis->d.control = 0; /* FIS HOB bit clear */
14629 fis->d.reserved5 = 0;
14631 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
14632 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
14635 satIOContext->currentLBA = lba;
14636 // satIOContext->OrgLBA = lba;
14637 satIOContext->OrgTL = tl;
14640 computing number of loop and remainder for tl
14641 0xFF in case not ext
14644 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
14646 LoopNum = satComputeLoopNum(tl, 0xFF);
14648 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
14649 fis->h.command == SAT_WRITE_DMA_EXT ||
14650 fis->h.command == SAT_WRITE_DMA_FUA_EXT
14653 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
14654 LoopNum = satComputeLoopNum(tl, 0xFFFF);
14658 /* SAT_WRITE_FPDMA_QUEUEDK */
14659 LoopNum = satComputeLoopNum(tl, 0xFFFF);
14662 satIOContext->LoopNum = LoopNum;
14663 satIOContext->LoopNum2 = LoopNum;
14668 TI_DBG5(("satWriteAndVerify12: NON CHAINED data\n"));
14669 /* Initialize CB for SATA completion.
14671 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
14675 TI_DBG1(("satWriteAndVerify12: CHAINED data\n"));
14676 /* re-setting tl */
14677 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
14679 fis->d.sectorCount = 0xFF;
14681 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
14682 fis->h.command == SAT_WRITE_DMA_EXT ||
14683 fis->h.command == SAT_WRITE_DMA_FUA_EXT
14686 fis->d.sectorCount = 0xFF;
14687 fis->d.sectorCountExp = 0xFF;
14691 /* SAT_WRITE_FPDMA_QUEUED */
14692 fis->h.features = 0xFF;
14693 fis->d.featuresExp = 0xFF;
14696 /* Initialize CB for SATA completion.
14698 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
14703 * Prepare SGL and send FIS to LL layer.
14705 satIOContext->reqType = agRequestType; /* Save it */
14707 status = sataLLIOStart( tiRoot,
14715 GLOBAL bit32 satNonChainedWriteNVerify_Verify(
14717 tiIORequest_t *tiIORequest,
14718 tiDeviceHandle_t *tiDeviceHandle,
14719 tiScsiInitiatorRequest_t *tiScsiRequest,
14720 satIOContext_t *satIOContext)
14723 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14724 satDeviceData_t *pSatDevData;
14725 tiIniScsiCmnd_t *scsiCmnd;
14726 agsaFisRegHostToDevice_t *fis;
14728 pSatDevData = satIOContext->pSatDevData;
14729 scsiCmnd = &tiScsiRequest->scsiCmnd;
14730 fis = satIOContext->pFis;
14732 TI_DBG5(("satNonChainedWriteNVerify_Verify: start\n"));
14734 if (pSatDevData->sat48BitSupport == agTRUE)
14736 fis->h.fisType = 0x27; /* Reg host to device */
14737 fis->h.c_pmPort = 0x80; /* C Bit is set */
14739 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
14740 fis->h.features = 0; /* FIS reserve */
14741 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14742 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14743 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14744 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
14745 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14746 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14747 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14748 fis->d.featuresExp = 0; /* FIS reserve */
14749 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14750 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
14752 fis->d.reserved4 = 0;
14753 fis->d.control = 0; /* FIS HOB bit clear */
14754 fis->d.reserved5 = 0;
14756 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14758 /* Initialize CB for SATA completion.
14760 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
14763 * Prepare SGL and send FIS to LL layer.
14765 satIOContext->reqType = agRequestType; /* Save it */
14767 status = sataLLIOStart( tiRoot,
14774 TI_DBG1(("satNonChainedWriteNVerify_Verify: return status %d\n", status));
14779 /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */
14780 TI_DBG1(("satNonChainedWriteNVerify_Verify: can't fit in SAT_READ_VERIFY_SECTORS\n"));
14786 GLOBAL bit32 satChainedWriteNVerify_Write(
14788 tiIORequest_t *tiIORequest,
14789 tiDeviceHandle_t *tiDeviceHandle,
14790 tiScsiInitiatorRequest_t *tiScsiRequest,
14791 satIOContext_t *satIOContext)
14794 Assumption: error check on lba and tl has been done in satWrite*()
14798 satIOContext_t *satOrgIOContext = agNULL;
14799 tiIniScsiCmnd_t *scsiCmnd;
14800 agsaFisRegHostToDevice_t *fis;
14801 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14803 bit32 DenomTL = 0xFF;
14804 bit32 Remainder = 0;
14805 bit8 LBA[4]; /* 0 MSB, 3 LSB */
14807 TI_DBG1(("satChainedWriteNVerify_Write: start\n"));
14809 fis = satIOContext->pFis;
14810 satOrgIOContext = satIOContext->satOrgIOContext;
14811 scsiCmnd = satOrgIOContext->pScsiCmnd;
14813 osti_memset(LBA,0, sizeof(LBA));
14815 switch (satOrgIOContext->ATACmd)
14817 case SAT_WRITE_DMA:
14820 case SAT_WRITE_SECTORS:
14823 case SAT_WRITE_DMA_EXT:
14826 case SAT_WRITE_DMA_FUA_EXT:
14829 case SAT_WRITE_SECTORS_EXT:
14832 case SAT_WRITE_FPDMA_QUEUED:
14836 TI_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
14841 Remainder = satOrgIOContext->OrgTL % DenomTL;
14842 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
14843 lba = satOrgIOContext->currentLBA;
14845 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
14846 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
14847 LBA[2] = (bit8)((lba & 0xF0) >> 8);
14848 LBA[3] = (bit8)(lba & 0xF); /* LSB */
14850 switch (satOrgIOContext->ATACmd)
14852 case SAT_WRITE_DMA:
14853 fis->h.fisType = 0x27; /* Reg host to device */
14854 fis->h.c_pmPort = 0x80; /* C bit is set */
14855 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
14856 fis->h.features = 0; /* FIS reserve */
14857 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
14858 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
14859 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
14861 /* FIS LBA mode set LBA (27:24) */
14862 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
14864 fis->d.lbaLowExp = 0;
14865 fis->d.lbaMidExp = 0;
14866 fis->d.lbaHighExp = 0;
14867 fis->d.featuresExp = 0;
14868 if (satOrgIOContext->LoopNum == 1)
14871 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
14875 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
14877 fis->d.sectorCountExp = 0;
14878 fis->d.reserved4 = 0;
14879 fis->d.control = 0; /* FIS HOB bit clear */
14880 fis->d.reserved5 = 0;
14882 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14885 case SAT_WRITE_SECTORS:
14886 fis->h.fisType = 0x27; /* Reg host to device */
14887 fis->h.c_pmPort = 0x80; /* C bit is set */
14888 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
14889 fis->h.features = 0; /* FIS reserve */
14890 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
14891 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
14892 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
14894 /* FIS LBA mode set LBA (27:24) */
14895 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
14897 fis->d.lbaLowExp = 0;
14898 fis->d.lbaMidExp = 0;
14899 fis->d.lbaHighExp = 0;
14900 fis->d.featuresExp = 0;
14901 if (satOrgIOContext->LoopNum == 1)
14904 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
14908 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
14910 fis->d.sectorCountExp = 0;
14911 fis->d.reserved4 = 0;
14912 fis->d.control = 0; /* FIS HOB bit clear */
14913 fis->d.reserved5 = 0;
14915 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14918 case SAT_WRITE_DMA_EXT:
14919 fis->h.fisType = 0x27; /* Reg host to device */
14920 fis->h.c_pmPort = 0x80; /* C Bit is set */
14921 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x3D */
14922 fis->h.features = 0; /* FIS reserve */
14923 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
14924 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
14925 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
14926 fis->d.device = 0x40; /* FIS LBA mode set */
14927 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
14928 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14929 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14930 fis->d.featuresExp = 0; /* FIS reserve */
14931 if (satOrgIOContext->LoopNum == 1)
14934 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
14935 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
14939 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
14940 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
14942 fis->d.reserved4 = 0;
14943 fis->d.control = 0; /* FIS HOB bit clear */
14944 fis->d.reserved5 = 0;
14946 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14949 case SAT_WRITE_SECTORS_EXT:
14950 fis->h.fisType = 0x27; /* Reg host to device */
14951 fis->h.c_pmPort = 0x80; /* C Bit is set */
14952 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
14954 fis->h.features = 0; /* FIS reserve */
14955 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
14956 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
14957 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
14958 fis->d.device = 0x40; /* FIS LBA mode set */
14959 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
14960 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14961 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14962 fis->d.featuresExp = 0; /* FIS reserve */
14963 if (satOrgIOContext->LoopNum == 1)
14966 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
14967 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
14971 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
14972 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
14974 fis->d.reserved4 = 0;
14975 fis->d.control = 0; /* FIS HOB bit clear */
14976 fis->d.reserved5 = 0;
14978 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14981 case SAT_WRITE_FPDMA_QUEUED:
14982 fis->h.fisType = 0x27; /* Reg host to device */
14983 fis->h.c_pmPort = 0x80; /* C Bit is set */
14984 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
14985 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
14986 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
14987 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
14989 /* Check FUA bit */
14990 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
14991 fis->d.device = 0xC0; /* FIS FUA set */
14993 fis->d.device = 0x40; /* FIS FUA clear */
14995 fis->d.lbaLowExp = LBA[0];; /* FIS LBA (31:24) */
14996 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14997 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14998 if (satOrgIOContext->LoopNum == 1)
15001 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
15002 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
15006 fis->h.features = 0xFF; /* FIS sector count (7:0) */
15007 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */
15009 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
15010 fis->d.sectorCountExp = 0;
15011 fis->d.reserved4 = 0;
15012 fis->d.control = 0; /* FIS HOB bit clear */
15013 fis->d.reserved5 = 0;
15015 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
15019 TI_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
15024 /* Initialize CB for SATA completion.
15027 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15031 * Prepare SGL and send FIS to LL layer.
15033 satIOContext->reqType = agRequestType; /* Save it */
15035 status = sataLLIOStart( tiRoot,
15041 TI_DBG5(("satChainedWriteNVerify_Write: return\n"));
15047 similar to write12 and verify10;
15048 this will be similar to verify12
15050 GLOBAL bit32 satChainedWriteNVerify_Start_Verify(
15052 tiIORequest_t *tiIORequest,
15053 tiDeviceHandle_t *tiDeviceHandle,
15054 tiScsiInitiatorRequest_t *tiScsiRequest,
15055 satIOContext_t *satIOContext)
15058 deal with transfer length; others have been handled previously at this point;
15059 no LBA check; no range check;
15062 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15063 satDeviceData_t *pSatDevData;
15064 tiIniScsiCmnd_t *scsiCmnd;
15065 agsaFisRegHostToDevice_t *fis;
15072 pSatDevData = satIOContext->pSatDevData;
15073 scsiCmnd = &tiScsiRequest->scsiCmnd;
15074 fis = satIOContext->pFis;
15076 TI_DBG5(("satChainedWriteNVerify_Start_Verify: start\n"));
15078 osti_memset(LBA, 0, sizeof(LBA));
15079 osti_memset(TL, 0, sizeof(TL));
15081 /* do not use memcpy due to indexing in LBA and TL */
15082 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
15083 LBA[1] = scsiCmnd->cdb[3];
15084 LBA[2] = scsiCmnd->cdb[4];
15085 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
15087 TL[0] = scsiCmnd->cdb[6]; /* MSB */
15088 TL[1] = scsiCmnd->cdb[7];
15089 TL[2] = scsiCmnd->cdb[7];
15090 TL[3] = scsiCmnd->cdb[8]; /* LSB */
15092 lba = satComputeCDB12LBA(satIOContext);
15093 tl = satComputeCDB12TL(satIOContext);
15095 if (pSatDevData->sat48BitSupport == agTRUE)
15097 TI_DBG5(("satChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS_EXT\n"));
15098 fis->h.fisType = 0x27; /* Reg host to device */
15099 fis->h.c_pmPort = 0x80; /* C Bit is set */
15101 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
15102 fis->h.features = 0; /* FIS reserve */
15103 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
15104 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
15105 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
15106 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
15107 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
15108 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
15109 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
15110 fis->d.featuresExp = 0; /* FIS reserve */
15111 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
15112 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
15114 fis->d.reserved4 = 0;
15115 fis->d.control = 0; /* FIS HOB bit clear */
15116 fis->d.reserved5 = 0;
15118 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15119 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
15123 TI_DBG5(("satChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS\n"));
15124 fis->h.fisType = 0x27; /* Reg host to device */
15125 fis->h.c_pmPort = 0x80; /* C bit is set */
15126 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
15127 fis->h.features = 0; /* FIS reserve */
15128 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
15129 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
15130 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
15131 /* FIS LBA mode set LBA (27:24) */
15132 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15133 fis->d.lbaLowExp = 0;
15134 fis->d.lbaMidExp = 0;
15135 fis->d.lbaHighExp = 0;
15136 fis->d.featuresExp = 0;
15137 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
15138 fis->d.sectorCountExp = 0;
15139 fis->d.reserved4 = 0;
15140 fis->d.control = 0; /* FIS HOB bit clear */
15141 fis->d.reserved5 = 0;
15143 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15144 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
15148 satIOContext->currentLBA = lba;
15149 satIOContext->OrgTL = tl;
15152 computing number of loop and remainder for tl
15153 0xFF in case not ext
15156 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
15158 LoopNum = satComputeLoopNum(tl, 0xFF);
15160 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
15162 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
15163 LoopNum = satComputeLoopNum(tl, 0xFFFF);
15167 TI_DBG1(("satChainedWriteNVerify_Start_Verify: error case 1!!!\n"));
15171 satIOContext->LoopNum = LoopNum;
15175 TI_DBG5(("satChainedWriteNVerify_Start_Verify: NON CHAINED data\n"));
15176 /* Initialize CB for SATA completion.
15178 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
15182 TI_DBG1(("satChainedWriteNVerify_Start_Verify: CHAINED data\n"));
15183 /* re-setting tl */
15184 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
15186 fis->d.sectorCount = 0xFF;
15188 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
15190 fis->d.sectorCount = 0xFF;
15191 fis->d.sectorCountExp = 0xFF;
15195 TI_DBG1(("satChainedWriteNVerify_Start_Verify: error case 2!!!\n"));
15198 /* Initialize CB for SATA completion.
15200 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15205 * Prepare SGL and send FIS to LL layer.
15207 satIOContext->reqType = agRequestType; /* Save it */
15209 status = sataLLIOStart( tiRoot,
15217 GLOBAL bit32 satChainedWriteNVerify_Verify(
15219 tiIORequest_t *tiIORequest,
15220 tiDeviceHandle_t *tiDeviceHandle,
15221 tiScsiInitiatorRequest_t *tiScsiRequest,
15222 satIOContext_t *satIOContext)
15225 satIOContext_t *satOrgIOContext = agNULL;
15226 agsaFisRegHostToDevice_t *fis;
15227 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15229 bit32 DenomTL = 0xFF;
15230 bit32 Remainder = 0;
15231 bit8 LBA[4]; /* 0 MSB, 3 LSB */
15233 TI_DBG2(("satChainedWriteNVerify_Verify: start\n"));
15235 fis = satIOContext->pFis;
15236 satOrgIOContext = satIOContext->satOrgIOContext;
15238 osti_memset(LBA,0, sizeof(LBA));
15240 switch (satOrgIOContext->ATACmd)
15242 case SAT_READ_VERIFY_SECTORS:
15245 case SAT_READ_VERIFY_SECTORS_EXT:
15249 TI_DBG1(("satChainedWriteNVerify_Verify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
15254 Remainder = satOrgIOContext->OrgTL % DenomTL;
15255 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
15256 lba = satOrgIOContext->currentLBA;
15258 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
15259 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
15260 LBA[2] = (bit8)((lba & 0xF0) >> 8);
15261 LBA[3] = (bit8)(lba & 0xF); /* LSB */
15263 switch (satOrgIOContext->ATACmd)
15265 case SAT_READ_VERIFY_SECTORS:
15266 fis->h.fisType = 0x27; /* Reg host to device */
15267 fis->h.c_pmPort = 0x80; /* C bit is set */
15268 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
15269 fis->h.features = 0; /* FIS reserve */
15270 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
15271 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
15272 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
15274 /* FIS LBA mode set LBA (27:24) */
15275 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
15277 fis->d.lbaLowExp = 0;
15278 fis->d.lbaMidExp = 0;
15279 fis->d.lbaHighExp = 0;
15280 fis->d.featuresExp = 0;
15281 if (satOrgIOContext->LoopNum == 1)
15284 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
15288 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
15290 fis->d.sectorCountExp = 0;
15291 fis->d.reserved4 = 0;
15292 fis->d.control = 0; /* FIS HOB bit clear */
15293 fis->d.reserved5 = 0;
15295 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15298 case SAT_READ_VERIFY_SECTORS_EXT:
15299 fis->h.fisType = 0x27; /* Reg host to device */
15300 fis->h.c_pmPort = 0x80; /* C Bit is set */
15301 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT; /* 0x42 */
15302 fis->h.features = 0; /* FIS reserve */
15303 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
15304 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
15305 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
15306 fis->d.device = 0x40; /* FIS LBA mode set */
15307 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
15308 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
15309 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
15310 fis->d.featuresExp = 0; /* FIS reserve */
15311 if (satOrgIOContext->LoopNum == 1)
15314 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
15315 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
15319 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
15320 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
15322 fis->d.reserved4 = 0;
15323 fis->d.control = 0; /* FIS HOB bit clear */
15324 fis->d.reserved5 = 0;
15326 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15331 TI_DBG1(("satChainedWriteNVerify_Verify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
15336 /* Initialize CB for SATA completion.
15339 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15343 * Prepare SGL and send FIS to LL layer.
15345 satIOContext->reqType = agRequestType; /* Save it */
15347 status = sataLLIOStart( tiRoot,
15353 TI_DBG5(("satChainedWriteNVerify_Verify: return\n"));
15359 /*****************************************************************************/
15360 /*! \brief SAT implementation for SCSI satWriteAndVerify16.
15362 * SAT implementation for SCSI satWriteAndVerify16.
15364 * \param tiRoot: Pointer to TISA initiator driver/port instance.
15365 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
15366 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
15367 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
15368 * \param satIOContext_t: Pointer to the SAT IO Context
15370 * \return If command is started successfully
15371 * - \e tiSuccess: I/O request successfully initiated.
15372 * - \e tiBusy: No resources available, try again later.
15373 * - \e tiIONoDevice: Invalid device handle.
15374 * - \e tiError: Other errors.
15376 /*****************************************************************************/
15377 GLOBAL bit32 satWriteAndVerify16(
15379 tiIORequest_t *tiIORequest,
15380 tiDeviceHandle_t *tiDeviceHandle,
15381 tiScsiInitiatorRequest_t *tiScsiRequest,
15382 satIOContext_t *satIOContext)
15385 combination of write16 and verify16
15386 since write16 has 8 bytes LBA -> problem ATA LBA(upto 6 bytes), no support
15389 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15390 satDeviceData_t *pSatDevData;
15391 scsiRspSense_t *pSense;
15392 tiIniScsiCmnd_t *scsiCmnd;
15393 agsaFisRegHostToDevice_t *fis;
15399 bit32 rangeChk = agFALSE; /* lba and tl range check */
15400 bit32 limitChk = agFALSE; /* lba and tl range check */
15402 pSense = satIOContext->pSense;
15403 pSatDevData = satIOContext->pSatDevData;
15404 scsiCmnd = &tiScsiRequest->scsiCmnd;
15405 fis = satIOContext->pFis;
15406 TI_DBG5(("satWriteAndVerify16:start\n"));
15408 /* checking BYTCHK bit */
15409 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
15411 satSetSensePayload( pSense,
15412 SCSI_SNSKEY_ILLEGAL_REQUEST,
15414 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15417 ostiInitiatorIOCompleted( tiRoot,
15420 SCSI_STAT_CHECK_CONDITION,
15421 satIOContext->pTiSenseData,
15422 satIOContext->interruptContext );
15424 TI_DBG1(("satWriteAndVerify16: BYTCHK bit checking \n"));
15429 /* checking CONTROL */
15430 /* NACA == 1 or LINK == 1*/
15431 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
15433 satSetSensePayload( pSense,
15434 SCSI_SNSKEY_ILLEGAL_REQUEST,
15436 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15439 ostiInitiatorIOCompleted( tiRoot,
15442 SCSI_STAT_CHECK_CONDITION,
15443 satIOContext->pTiSenseData,
15444 satIOContext->interruptContext );
15446 TI_DBG2(("satWriteAndVerify16: return control\n"));
15450 osti_memset(LBA, 0, sizeof(LBA));
15451 osti_memset(TL, 0, sizeof(TL));
15454 /* do not use memcpy due to indexing in LBA and TL */
15455 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
15456 LBA[1] = scsiCmnd->cdb[3];
15457 LBA[2] = scsiCmnd->cdb[4];
15458 LBA[3] = scsiCmnd->cdb[5];
15459 LBA[4] = scsiCmnd->cdb[6];
15460 LBA[5] = scsiCmnd->cdb[7];
15461 LBA[6] = scsiCmnd->cdb[8];
15462 LBA[7] = scsiCmnd->cdb[9]; /* LSB */
15468 TL[4] = scsiCmnd->cdb[10]; /* MSB */
15469 TL[5] = scsiCmnd->cdb[11];
15470 TL[6] = scsiCmnd->cdb[12];
15471 TL[7] = scsiCmnd->cdb[13]; /* LSB */
15473 rangeChk = satAddNComparebit64(LBA, TL);
15475 limitChk = satCompareLBALimitbit(LBA);
15477 lba = satComputeCDB16LBA(satIOContext);
15478 tl = satComputeCDB16TL(satIOContext);
15481 /* Table 34, 9.1, p 46 */
15483 note: As of 2/10/2006, no support for DMA QUEUED
15487 Table 34, 9.1, p 46, b
15488 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
15489 return check condition
15491 if (pSatDevData->satNCQ != agTRUE &&
15492 pSatDevData->sat48BitSupport != agTRUE
15497 TI_DBG1(("satWriteAndVerify16: return LBA out of range, not EXT\n"));
15498 satSetSensePayload( pSense,
15499 SCSI_SNSKEY_ILLEGAL_REQUEST,
15501 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15504 ostiInitiatorIOCompleted( tiRoot,
15507 SCSI_STAT_CHECK_CONDITION,
15508 satIOContext->pTiSenseData,
15509 satIOContext->interruptContext );
15513 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
15515 TI_DBG1(("satWriteAndVerify16: return LBA+TL out of range, not EXT\n"));
15516 satSetSensePayload( pSense,
15517 SCSI_SNSKEY_ILLEGAL_REQUEST,
15519 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15522 ostiInitiatorIOCompleted( tiRoot,
15525 SCSI_STAT_CHECK_CONDITION,
15526 satIOContext->pTiSenseData,
15527 satIOContext->interruptContext );
15535 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
15537 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15541 /* In case that we can't fit the transfer length, we loop */
15542 TI_DBG5(("satWriteAndVerify16: case 2\n"));
15543 fis->h.fisType = 0x27; /* Reg host to device */
15544 fis->h.c_pmPort = 0x80; /* C bit is set */
15545 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
15546 fis->h.features = 0; /* FIS reserve */
15547 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
15548 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
15549 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
15551 /* FIS LBA mode set LBA (27:24) */
15552 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
15554 fis->d.lbaLowExp = 0;
15555 fis->d.lbaMidExp = 0;
15556 fis->d.lbaHighExp = 0;
15557 fis->d.featuresExp = 0;
15558 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
15559 fis->d.sectorCountExp = 0;
15560 fis->d.reserved4 = 0;
15561 fis->d.control = 0; /* FIS HOB bit clear */
15562 fis->d.reserved5 = 0;
15564 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15565 satIOContext->ATACmd = SAT_WRITE_DMA;
15570 /* WRITE MULTIPLE or WRITE SECTOR(S) */
15571 /* WRITE SECTORS for easier implemetation */
15572 /* In case that we can't fit the transfer length, we loop */
15573 TI_DBG5(("satWriteAndVerify16: case 1\n"));
15574 fis->h.fisType = 0x27; /* Reg host to device */
15575 fis->h.c_pmPort = 0x80; /* C bit is set */
15576 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
15577 fis->h.features = 0; /* FIS reserve */
15578 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
15579 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
15580 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
15582 /* FIS LBA mode set LBA (27:24) */
15583 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
15585 fis->d.lbaLowExp = 0;
15586 fis->d.lbaMidExp = 0;
15587 fis->d.lbaHighExp = 0;
15588 fis->d.featuresExp = 0;
15589 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
15590 fis->d.sectorCountExp = 0;
15591 fis->d.reserved4 = 0;
15592 fis->d.control = 0; /* FIS HOB bit clear */
15593 fis->d.reserved5 = 0;
15595 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15596 satIOContext->ATACmd = SAT_WRITE_SECTORS;
15601 if (pSatDevData->sat48BitSupport == agTRUE)
15603 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15606 /* WRITE DMA EXT or WRITE DMA FUA EXT */
15607 TI_DBG5(("satWriteAndVerify16: case 3\n"));
15608 fis->h.fisType = 0x27; /* Reg host to device */
15609 fis->h.c_pmPort = 0x80; /* C Bit is set */
15611 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
15612 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
15614 fis->h.features = 0; /* FIS reserve */
15615 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
15616 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
15617 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
15618 fis->d.device = 0x40; /* FIS LBA mode set */
15619 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
15620 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
15621 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
15622 fis->d.featuresExp = 0; /* FIS reserve */
15623 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
15624 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
15625 fis->d.reserved4 = 0;
15626 fis->d.control = 0; /* FIS HOB bit clear */
15627 fis->d.reserved5 = 0;
15629 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15630 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
15635 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
15636 /* WRITE SECTORS EXT for easier implemetation */
15637 TI_DBG5(("satWriteAndVerify16: case 4\n"));
15638 fis->h.fisType = 0x27; /* Reg host to device */
15639 fis->h.c_pmPort = 0x80; /* C Bit is set */
15640 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
15642 fis->h.features = 0; /* FIS reserve */
15643 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
15644 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
15645 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
15646 fis->d.device = 0x40; /* FIS LBA mode set */
15647 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
15648 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
15649 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
15650 fis->d.featuresExp = 0; /* FIS reserve */
15651 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
15652 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
15653 fis->d.reserved4 = 0;
15654 fis->d.control = 0; /* FIS HOB bit clear */
15655 fis->d.reserved5 = 0;
15657 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15658 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
15663 if (pSatDevData->satNCQ == agTRUE)
15665 /* WRITE FPDMA QUEUED */
15666 if (pSatDevData->sat48BitSupport != agTRUE)
15668 TI_DBG5(("satWriteAndVerify16: case 5 !!! error NCQ but 28 bit address support \n"));
15669 satSetSensePayload( pSense,
15670 SCSI_SNSKEY_ILLEGAL_REQUEST,
15672 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15675 ostiInitiatorIOCompleted( tiRoot,
15678 SCSI_STAT_CHECK_CONDITION,
15679 satIOContext->pTiSenseData,
15680 satIOContext->interruptContext );
15683 TI_DBG6(("satWriteAndVerify16: case 5\n"));
15685 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
15687 fis->h.fisType = 0x27; /* Reg host to device */
15688 fis->h.c_pmPort = 0x80; /* C Bit is set */
15689 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
15690 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
15691 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
15692 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
15693 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
15695 /* Check FUA bit */
15696 if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
15697 fis->d.device = 0xC0; /* FIS FUA set */
15699 fis->d.device = 0x40; /* FIS FUA clear */
15701 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
15702 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
15703 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
15704 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
15705 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
15706 fis->d.sectorCountExp = 0;
15707 fis->d.reserved4 = 0;
15708 fis->d.control = 0; /* FIS HOB bit clear */
15709 fis->d.reserved5 = 0;
15711 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
15712 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
15715 satIOContext->currentLBA = lba;
15716 satIOContext->OrgTL = tl;
15719 computing number of loop and remainder for tl
15720 0xFF in case not ext
15723 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15725 LoopNum = satComputeLoopNum(tl, 0xFF);
15727 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15728 fis->h.command == SAT_WRITE_DMA_EXT ||
15729 fis->h.command == SAT_WRITE_DMA_FUA_EXT
15732 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
15733 LoopNum = satComputeLoopNum(tl, 0xFFFF);
15737 /* SAT_WRITE_FPDMA_QUEUEDK */
15738 LoopNum = satComputeLoopNum(tl, 0xFFFF);
15741 satIOContext->LoopNum = LoopNum;
15746 TI_DBG5(("satWriteAndVerify16: NON CHAINED data\n"));
15747 /* Initialize CB for SATA completion.
15749 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
15753 TI_DBG1(("satWriteAndVerify16: CHAINED data\n"));
15754 /* re-setting tl */
15755 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15757 fis->d.sectorCount = 0xFF;
15759 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15760 fis->h.command == SAT_WRITE_DMA_EXT ||
15761 fis->h.command == SAT_WRITE_DMA_FUA_EXT
15764 fis->d.sectorCount = 0xFF;
15765 fis->d.sectorCountExp = 0xFF;
15769 /* SAT_WRITE_FPDMA_QUEUED */
15770 fis->h.features = 0xFF;
15771 fis->d.featuresExp = 0xFF;
15774 /* Initialize CB for SATA completion.
15776 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15781 * Prepare SGL and send FIS to LL layer.
15783 satIOContext->reqType = agRequestType; /* Save it */
15785 status = sataLLIOStart( tiRoot,
15793 /*****************************************************************************/
15794 /*! \brief SAT implementation for SCSI satReadMediaSerialNumber.
15796 * SAT implementation for SCSI Read Media Serial Number.
15798 * \param tiRoot: Pointer to TISA initiator driver/port instance.
15799 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
15800 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
15801 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
15802 * \param satIOContext_t: Pointer to the SAT IO Context
15804 * \return If command is started successfully
15805 * - \e tiSuccess: I/O request successfully initiated.
15806 * - \e tiBusy: No resources available, try again later.
15807 * - \e tiIONoDevice: Invalid device handle.
15808 * - \e tiError: Other errors.
15810 /*****************************************************************************/
15811 GLOBAL bit32 satReadMediaSerialNumber(
15813 tiIORequest_t *tiIORequest,
15814 tiDeviceHandle_t *tiDeviceHandle,
15815 tiScsiInitiatorRequest_t *tiScsiRequest,
15816 satIOContext_t *satIOContext)
15819 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
15820 satDeviceData_t *pSatDevData;
15821 scsiRspSense_t *pSense;
15822 tiIniScsiCmnd_t *scsiCmnd;
15823 agsaFisRegHostToDevice_t *fis;
15824 agsaSATAIdentifyData_t *pSATAIdData;
15825 bit8 *pSerialNumber;
15827 pSense = satIOContext->pSense;
15828 pSatDevData = satIOContext->pSatDevData;
15829 scsiCmnd = &tiScsiRequest->scsiCmnd;
15830 fis = satIOContext->pFis;
15831 pSATAIdData = &(pSatDevData->satIdentifyData);
15832 pSerialNumber = (bit8 *) tiScsiRequest->sglVirtualAddr;
15835 TI_DBG1(("satReadMediaSerialNumber: start\n"));
15837 /* checking CONTROL */
15838 /* NACA == 1 or LINK == 1*/
15839 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
15841 satSetSensePayload( pSense,
15842 SCSI_SNSKEY_ILLEGAL_REQUEST,
15844 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15847 ostiInitiatorIOCompleted( tiRoot,
15850 SCSI_STAT_CHECK_CONDITION,
15851 satIOContext->pTiSenseData,
15852 satIOContext->interruptContext );
15854 TI_DBG1(("satReadMediaSerialNumber: return control\n"));
15858 if (tiScsiRequest->scsiCmnd.expDataLength == 4)
15860 if (pSATAIdData->commandSetFeatureDefault & 0x4)
15862 TI_DBG1(("satReadMediaSerialNumber: Media serial number returning only length\n"));
15863 /* SPC-3 6.16 p192; filling in length */
15864 pSerialNumber[0] = 0;
15865 pSerialNumber[1] = 0;
15866 pSerialNumber[2] = 0;
15867 pSerialNumber[3] = 0x3C;
15871 /* 1 sector - 4 = 512 - 4 to avoid underflow; 0x1fc*/
15872 pSerialNumber[0] = 0;
15873 pSerialNumber[1] = 0;
15874 pSerialNumber[2] = 0x1;
15875 pSerialNumber[3] = 0xfc;
15878 ostiInitiatorIOCompleted( tiRoot,
15883 satIOContext->interruptContext);
15888 if ( pSatDevData->IDDeviceValid == agTRUE)
15890 if (pSATAIdData->commandSetFeatureDefault & 0x4)
15892 /* word87 bit2 Media serial number is valid */
15893 /* read word 176 to 205; length is 2*30 = 60 = 0x3C*/
15894 tdhexdump("ID satReadMediaSerialNumber", (bit8*)pSATAIdData->currentMediaSerialNumber, 2*30);
15895 /* SPC-3 6.16 p192; filling in length */
15896 pSerialNumber[0] = 0;
15897 pSerialNumber[1] = 0;
15898 pSerialNumber[2] = 0;
15899 pSerialNumber[3] = 0x3C;
15900 osti_memcpy(&pSerialNumber[4], (void *)pSATAIdData->currentMediaSerialNumber, 60);
15901 tdhexdump("satReadMediaSerialNumber", (bit8*)pSerialNumber, 2*30 + 4);
15903 ostiInitiatorIOCompleted( tiRoot,
15908 satIOContext->interruptContext);
15915 /* word87 bit2 Media serial number is NOT valid */
15916 TI_DBG1(("satReadMediaSerialNumber: Media serial number is NOT valid \n"));
15918 if (pSatDevData->sat48BitSupport == agTRUE)
15920 /* READ VERIFY SECTORS EXT */
15921 fis->h.fisType = 0x27; /* Reg host to device */
15922 fis->h.c_pmPort = 0x80; /* C Bit is set */
15923 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
15925 fis->h.features = 0; /* FIS reserve */
15926 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
15927 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
15928 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
15929 fis->d.device = 0x40; /* FIS LBA mode set */
15930 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
15931 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
15932 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
15933 fis->d.featuresExp = 0; /* FIS reserve */
15934 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
15935 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
15936 fis->d.reserved4 = 0;
15937 fis->d.control = 0; /* FIS HOB bit clear */
15938 fis->d.reserved5 = 0;
15940 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
15944 /* READ VERIFY SECTORS */
15945 fis->h.fisType = 0x27; /* Reg host to device */
15946 fis->h.c_pmPort = 0x80; /* C Bit is set */
15947 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
15948 fis->h.features = 0; /* FIS reserve */
15949 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
15950 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
15951 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
15952 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */
15953 fis->d.lbaLowExp = 0;
15954 fis->d.lbaMidExp = 0;
15955 fis->d.lbaHighExp = 0;
15956 fis->d.featuresExp = 0;
15957 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
15958 fis->d.sectorCountExp = 0;
15959 fis->d.reserved4 = 0;
15960 fis->d.control = 0; /* FIS HOB bit clear */
15961 fis->d.reserved5 = 0;
15964 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
15966 satIOContext->satCompleteCB = &satReadMediaSerialNumberCB;
15967 satIOContext->reqType = agRequestType; /* Save it */
15968 status = sataLLIOStart( tiRoot,
15979 /* temporary failure */
15980 ostiInitiatorIOCompleted( tiRoot,
15983 tiDetailOtherError,
15985 satIOContext->interruptContext);
15993 /*****************************************************************************/
15994 /*! \brief SAT implementation for SCSI satReadBuffer.
15996 * SAT implementation for SCSI Read Buffer.
15998 * \param tiRoot: Pointer to TISA initiator driver/port instance.
15999 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
16000 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
16001 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
16002 * \param satIOContext_t: Pointer to the SAT IO Context
16004 * \return If command is started successfully
16005 * - \e tiSuccess: I/O request successfully initiated.
16006 * - \e tiBusy: No resources available, try again later.
16007 * - \e tiIONoDevice: Invalid device handle.
16008 * - \e tiError: Other errors.
16010 /*****************************************************************************/
16011 /* SAT-2, Revision 00*/
16012 GLOBAL bit32 satReadBuffer(
16014 tiIORequest_t *tiIORequest,
16015 tiDeviceHandle_t *tiDeviceHandle,
16016 tiScsiInitiatorRequest_t *tiScsiRequest,
16017 satIOContext_t *satIOContext)
16019 bit32 status = tiSuccess;
16020 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16021 scsiRspSense_t *pSense;
16022 tiIniScsiCmnd_t *scsiCmnd;
16023 agsaFisRegHostToDevice_t *fis;
16024 bit32 bufferOffset;
16030 pSense = satIOContext->pSense;
16031 scsiCmnd = &tiScsiRequest->scsiCmnd;
16032 fis = satIOContext->pFis;
16033 pBuff = (bit8 *) tiScsiRequest->sglVirtualAddr;
16035 TI_DBG2(("satReadBuffer: start\n"));
16036 /* checking CONTROL */
16037 /* NACA == 1 or LINK == 1*/
16038 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
16040 satSetSensePayload( pSense,
16041 SCSI_SNSKEY_ILLEGAL_REQUEST,
16043 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16045 ostiInitiatorIOCompleted( tiRoot,
16048 SCSI_STAT_CHECK_CONDITION,
16049 satIOContext->pTiSenseData,
16050 satIOContext->interruptContext );
16051 TI_DBG1(("satReadBuffer: return control\n"));
16055 bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
16056 tl = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
16058 mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
16059 bufferID = scsiCmnd->cdb[2];
16061 if (mode == READ_BUFFER_DATA_MODE) /* 2 */
16063 if (bufferID == 0 && bufferOffset == 0 && tl == 512)
16065 /* send ATA READ BUFFER */
16066 fis->h.fisType = 0x27; /* Reg host to device */
16067 fis->h.c_pmPort = 0x80; /* C Bit is set */
16068 fis->h.command = SAT_READ_BUFFER; /* 0xE4 */
16069 fis->h.features = 0; /* FIS reserve */
16070 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
16071 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
16072 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
16073 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */
16074 fis->d.lbaLowExp = 0;
16075 fis->d.lbaMidExp = 0;
16076 fis->d.lbaHighExp = 0;
16077 fis->d.featuresExp = 0;
16078 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
16079 fis->d.sectorCountExp = 0;
16080 fis->d.reserved4 = 0;
16081 fis->d.control = 0; /* FIS HOB bit clear */
16082 fis->d.reserved5 = 0;
16084 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16085 satIOContext->satCompleteCB = &satReadBufferCB;
16086 satIOContext->reqType = agRequestType; /* Save it */
16088 status = sataLLIOStart( tiRoot,
16095 if (bufferID == 0 && bufferOffset == 0 && tl != 512)
16097 satSetSensePayload( pSense,
16098 SCSI_SNSKEY_ILLEGAL_REQUEST,
16100 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16102 ostiInitiatorIOCompleted( tiRoot,
16105 SCSI_STAT_CHECK_CONDITION,
16106 satIOContext->pTiSenseData,
16107 satIOContext->interruptContext );
16108 TI_DBG1(("satReadBuffer: allocation length is not 512; it is %d\n", tl));
16111 if (bufferID == 0 && bufferOffset != 0)
16113 satSetSensePayload( pSense,
16114 SCSI_SNSKEY_ILLEGAL_REQUEST,
16116 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16118 ostiInitiatorIOCompleted( tiRoot,
16121 SCSI_STAT_CHECK_CONDITION,
16122 satIOContext->pTiSenseData,
16123 satIOContext->interruptContext );
16124 TI_DBG1(("satReadBuffer: buffer offset is not 0; it is %d\n", bufferOffset));
16127 /* all other cases unsupported */
16128 TI_DBG1(("satReadBuffer: unsupported case 1\n"));
16129 satSetSensePayload( pSense,
16130 SCSI_SNSKEY_ILLEGAL_REQUEST,
16132 SCSI_SNSCODE_INVALID_COMMAND,
16135 ostiInitiatorIOCompleted( tiRoot,
16138 SCSI_STAT_CHECK_CONDITION,
16139 satIOContext->pTiSenseData,
16140 satIOContext->interruptContext );
16143 else if (mode == READ_BUFFER_DESCRIPTOR_MODE) /* 3 */
16145 if (tl < READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN) /* 4 */
16147 satSetSensePayload( pSense,
16148 SCSI_SNSKEY_ILLEGAL_REQUEST,
16150 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16152 ostiInitiatorIOCompleted( tiRoot,
16155 SCSI_STAT_CHECK_CONDITION,
16156 satIOContext->pTiSenseData,
16157 satIOContext->interruptContext );
16158 TI_DBG1(("satReadBuffer: tl < 4; tl is %d\n", tl));
16163 /* SPC-4, 6.15.5, p189; SAT-2 Rev00, 8.7.2.3, p41*/
16168 if (READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN < tl)
16171 TI_DBG1(("satReadBuffer: underrun tl %d data %d\n", tl, READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN));
16172 ostiInitiatorIOCompleted( tiRoot,
16175 tl - READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN,
16177 satIOContext->interruptContext );
16182 ostiInitiatorIOCompleted( tiRoot,
16187 satIOContext->interruptContext);
16193 /* We don't support other than bufferID 0 */
16194 satSetSensePayload( pSense,
16195 SCSI_SNSKEY_ILLEGAL_REQUEST,
16197 SCSI_SNSCODE_INVALID_COMMAND,
16200 ostiInitiatorIOCompleted( tiRoot,
16203 SCSI_STAT_CHECK_CONDITION,
16204 satIOContext->pTiSenseData,
16205 satIOContext->interruptContext );
16211 /* We don't support any other mode */
16212 TI_DBG1(("satReadBuffer: unsupported mode %d\n", mode));
16213 satSetSensePayload( pSense,
16214 SCSI_SNSKEY_ILLEGAL_REQUEST,
16216 SCSI_SNSCODE_INVALID_COMMAND,
16219 ostiInitiatorIOCompleted( tiRoot,
16222 SCSI_STAT_CHECK_CONDITION,
16223 satIOContext->pTiSenseData,
16224 satIOContext->interruptContext );
16229 /*****************************************************************************/
16230 /*! \brief SAT implementation for SCSI satWriteBuffer.
16232 * SAT implementation for SCSI Write Buffer.
16234 * \param tiRoot: Pointer to TISA initiator driver/port instance.
16235 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
16236 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
16237 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
16238 * \param satIOContext_t: Pointer to the SAT IO Context
16240 * \return If command is started successfully
16241 * - \e tiSuccess: I/O request successfully initiated.
16242 * - \e tiBusy: No resources available, try again later.
16243 * - \e tiIONoDevice: Invalid device handle.
16244 * - \e tiError: Other errors.
16246 /*****************************************************************************/
16247 /* SAT-2, Revision 00*/
16248 GLOBAL bit32 satWriteBuffer(
16250 tiIORequest_t *tiIORequest,
16251 tiDeviceHandle_t *tiDeviceHandle,
16252 tiScsiInitiatorRequest_t *tiScsiRequest,
16253 satIOContext_t *satIOContext)
16256 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16258 scsiRspSense_t *pSense;
16259 tiIniScsiCmnd_t *scsiCmnd;
16260 bit32 bufferOffset;
16266 pSense = satIOContext->pSense;
16267 scsiCmnd = &tiScsiRequest->scsiCmnd;
16268 pBuff = (bit8 *) tiScsiRequest->sglVirtualAddr;
16270 TI_DBG2(("satWriteBuffer: start\n"));
16272 /* checking CONTROL */
16273 /* NACA == 1 or LINK == 1*/
16274 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
16276 satSetSensePayload( pSense,
16277 SCSI_SNSKEY_ILLEGAL_REQUEST,
16279 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16282 ostiInitiatorIOCompleted( tiRoot,
16285 SCSI_STAT_CHECK_CONDITION,
16286 satIOContext->pTiSenseData,
16287 satIOContext->interruptContext );
16289 TI_DBG1(("satWriteBuffer: return control\n"));
16293 bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
16294 parmLen = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
16296 mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
16297 bufferID = scsiCmnd->cdb[2];
16299 /* for debugging only */
16300 tdhexdump("satWriteBuffer pBuff", (bit8 *)pBuff, 24);
16302 if (mode == WRITE_BUFFER_DATA_MODE) /* 2 */
16304 if (bufferID == 0 && bufferOffset == 0 && parmLen == 512)
16306 TI_DBG1(("satWriteBuffer: sending ATA WRITE BUFFER\n"));
16307 /* send ATA WRITE BUFFER */
16309 fis->h.fisType = 0x27; /* Reg host to device */
16310 fis->h.c_pmPort = 0x80; /* C Bit is set */
16311 fis->h.command = SAT_WRITE_BUFFER; /* 0xE8 */
16312 fis->h.features = 0; /* FIS reserve */
16313 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
16314 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
16315 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
16316 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */
16317 fis->d.lbaLowExp = 0;
16318 fis->d.lbaMidExp = 0;
16319 fis->d.lbaHighExp = 0;
16320 fis->d.featuresExp = 0;
16321 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
16322 fis->d.sectorCountExp = 0;
16323 fis->d.reserved4 = 0;
16324 fis->d.control = 0; /* FIS HOB bit clear */
16325 fis->d.reserved5 = 0;
16328 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16330 satIOContext->satCompleteCB = &satWriteBufferCB;
16332 satIOContext->reqType = agRequestType; /* Save it */
16334 status = sataLLIOStart( tiRoot,
16342 ostiInitiatorIOCompleted( tiRoot,
16347 satIOContext->interruptContext);
16350 if ( (bufferID == 0 && bufferOffset != 0) ||
16351 (bufferID == 0 && parmLen != 512)
16354 satSetSensePayload( pSense,
16355 SCSI_SNSKEY_ILLEGAL_REQUEST,
16357 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16360 ostiInitiatorIOCompleted( tiRoot,
16363 SCSI_STAT_CHECK_CONDITION,
16364 satIOContext->pTiSenseData,
16365 satIOContext->interruptContext );
16367 TI_DBG1(("satWriteBuffer: wrong buffer offset %d or parameter length parmLen %d\n", bufferOffset, parmLen));
16371 /* all other cases unsupported */
16372 TI_DBG1(("satWriteBuffer: unsupported case 1\n"));
16373 satSetSensePayload( pSense,
16374 SCSI_SNSKEY_ILLEGAL_REQUEST,
16376 SCSI_SNSCODE_INVALID_COMMAND,
16379 ostiInitiatorIOCompleted( tiRoot,
16382 SCSI_STAT_CHECK_CONDITION,
16383 satIOContext->pTiSenseData,
16384 satIOContext->interruptContext );
16389 else if (mode == WRITE_BUFFER_DL_MICROCODE_SAVE_MODE) /* 5 */
16391 TI_DBG1(("satWriteBuffer: not yet supported mode %d\n", mode));
16392 satSetSensePayload( pSense,
16393 SCSI_SNSKEY_ILLEGAL_REQUEST,
16395 SCSI_SNSCODE_INVALID_COMMAND,
16398 ostiInitiatorIOCompleted( tiRoot,
16401 SCSI_STAT_CHECK_CONDITION,
16402 satIOContext->pTiSenseData,
16403 satIOContext->interruptContext );
16409 /* We don't support any other mode */
16410 TI_DBG1(("satWriteBuffer: unsupported mode %d\n", mode));
16411 satSetSensePayload( pSense,
16412 SCSI_SNSKEY_ILLEGAL_REQUEST,
16414 SCSI_SNSCODE_INVALID_COMMAND,
16417 ostiInitiatorIOCompleted( tiRoot,
16420 SCSI_STAT_CHECK_CONDITION,
16421 satIOContext->pTiSenseData,
16422 satIOContext->interruptContext );
16429 /*****************************************************************************/
16430 /*! \brief SAT implementation for SCSI satReassignBlocks.
16432 * SAT implementation for SCSI Reassign Blocks.
16434 * \param tiRoot: Pointer to TISA initiator driver/port instance.
16435 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
16436 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
16437 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
16438 * \param satIOContext_t: Pointer to the SAT IO Context
16440 * \return If command is started successfully
16441 * - \e tiSuccess: I/O request successfully initiated.
16442 * - \e tiBusy: No resources available, try again later.
16443 * - \e tiIONoDevice: Invalid device handle.
16444 * - \e tiError: Other errors.
16446 /*****************************************************************************/
16447 GLOBAL bit32 satReassignBlocks(
16449 tiIORequest_t *tiIORequest,
16450 tiDeviceHandle_t *tiDeviceHandle,
16451 tiScsiInitiatorRequest_t *tiScsiRequest,
16452 satIOContext_t *satIOContext)
16455 assumes all LBA fits in ATA command; no boundary condition is checked here yet
16458 bit32 agRequestType;
16459 satDeviceData_t *pSatDevData;
16460 scsiRspSense_t *pSense;
16461 tiIniScsiCmnd_t *scsiCmnd;
16462 agsaFisRegHostToDevice_t *fis;
16463 bit8 *pParmList; /* Log Page data buffer */
16466 bit32 defectListLen;
16468 bit32 startingIndex;
16470 pSense = satIOContext->pSense;
16471 pSatDevData = satIOContext->pSatDevData;
16472 scsiCmnd = &tiScsiRequest->scsiCmnd;
16473 fis = satIOContext->pFis;
16474 pParmList = (bit8 *) tiScsiRequest->sglVirtualAddr;
16476 TI_DBG5(("satReassignBlocks: start\n"));
16478 /* checking CONTROL */
16479 /* NACA == 1 or LINK == 1*/
16480 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
16482 satSetSensePayload( pSense,
16483 SCSI_SNSKEY_ILLEGAL_REQUEST,
16485 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16488 ostiInitiatorIOCompleted( tiRoot,
16491 SCSI_STAT_CHECK_CONDITION,
16492 satIOContext->pTiSenseData,
16493 satIOContext->interruptContext );
16495 TI_DBG1(("satReassignBlocks: return control\n"));
16499 osti_memset(satIOContext->LBA, 0, 8);
16500 satIOContext->ParmIndex = 0;
16501 satIOContext->ParmLen = 0;
16503 LongList = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLIST_MASK);
16504 LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
16505 osti_memset(LBA, 0, sizeof(LBA));
16509 defectListLen = (pParmList[2] << 8) + pParmList[3];
16513 defectListLen = (pParmList[0] << (8*3)) + (pParmList[1] << (8*2))
16514 + (pParmList[2] << 8) + pParmList[3];
16516 /* SBC 5.16.2, p61*/
16517 satIOContext->ParmLen = defectListLen + 4 /* header size */;
16523 LBA[4] = pParmList[startingIndex]; /* MSB */
16524 LBA[5] = pParmList[startingIndex+1];
16525 LBA[6] = pParmList[startingIndex+2];
16526 LBA[7] = pParmList[startingIndex+3]; /* LSB */
16527 startingIndex = startingIndex + 4;
16531 LBA[0] = pParmList[startingIndex]; /* MSB */
16532 LBA[1] = pParmList[startingIndex+1];
16533 LBA[2] = pParmList[startingIndex+2];
16534 LBA[3] = pParmList[startingIndex+3];
16535 LBA[4] = pParmList[startingIndex+4];
16536 LBA[5] = pParmList[startingIndex+5];
16537 LBA[6] = pParmList[startingIndex+6];
16538 LBA[7] = pParmList[startingIndex+7]; /* LSB */
16539 startingIndex = startingIndex + 8;
16542 tdhexdump("satReassignBlocks Parameter list", (bit8 *)pParmList, 4 + defectListLen);
16544 if (pSatDevData->sat48BitSupport == agTRUE)
16546 /* sends READ VERIFY SECTOR(S) EXT*/
16547 fis->h.fisType = 0x27; /* Reg host to device */
16548 fis->h.c_pmPort = 0x80; /* C Bit is set */
16549 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
16550 fis->h.features = 0; /* FIS reserve */
16551 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16552 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16553 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16554 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */
16555 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */
16556 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */
16557 fis->d.featuresExp = 0; /* FIS reserve */
16558 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16559 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
16560 fis->d.reserved4 = 0;
16561 fis->d.device = 0x40; /* 01000000 */
16562 fis->d.control = 0; /* FIS HOB bit clear */
16563 fis->d.reserved5 = 0;
16567 /* READ VERIFY SECTOR(S)*/
16568 fis->h.fisType = 0x27; /* Reg host to device */
16569 fis->h.c_pmPort = 0x80; /* C Bit is set */
16570 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
16571 fis->h.features = 0; /* FIS features NA */
16572 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16573 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16574 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16575 fis->d.lbaLowExp = 0;
16576 fis->d.lbaMidExp = 0;
16577 fis->d.lbaHighExp = 0;
16578 fis->d.featuresExp = 0;
16579 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16580 fis->d.sectorCountExp = 0;
16581 fis->d.reserved4 = 0;
16582 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16583 /* DEV and LBA 27:24 */
16584 fis->d.control = 0; /* FIS HOB bit clear */
16585 fis->d.reserved5 = 0;
16588 osti_memcpy(satIOContext->LBA, LBA, 8);
16589 satIOContext->ParmIndex = startingIndex;
16591 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
16593 /* Initialize CB for SATA completion.
16595 satIOContext->satCompleteCB = &satReassignBlocksCB;
16598 * Prepare SGL and send FIS to LL layer.
16600 satIOContext->reqType = agRequestType; /* Save it */
16602 status = sataLLIOStart( tiRoot,
16611 /*****************************************************************************/
16612 /*! \brief SAT implementation for SCSI satReassignBlocks_1.
16614 * SAT implementation for SCSI Reassign Blocks. This is helper function for
16615 * satReassignBlocks and satReassignBlocksCB. This sends ATA verify command.
16617 * \param tiRoot: Pointer to TISA initiator driver/port instance.
16618 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
16619 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
16620 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
16621 * \param satIOContext_t: Pointer to the SAT IO Context
16623 * \return If command is started successfully
16624 * - \e tiSuccess: I/O request successfully initiated.
16625 * - \e tiBusy: No resources available, try again later.
16626 * - \e tiIONoDevice: Invalid device handle.
16627 * - \e tiError: Other errors.
16629 /*****************************************************************************/
16630 /* next LBA; sends READ VERIFY SECTOR; update LBA and ParmIdx */
16631 GLOBAL bit32 satReassignBlocks_1(
16633 tiIORequest_t *tiIORequest,
16634 tiDeviceHandle_t *tiDeviceHandle,
16635 tiScsiInitiatorRequest_t *tiScsiRequest,
16636 satIOContext_t *satIOContext,
16637 satIOContext_t *satOrgIOContext
16641 assumes all LBA fits in ATA command; no boundary condition is checked here yet
16642 tiScsiRequest is OS generated; needs for accessing parameter list
16644 bit32 agRequestType;
16645 satDeviceData_t *pSatDevData;
16646 tiIniScsiCmnd_t *scsiCmnd;
16647 agsaFisRegHostToDevice_t *fis;
16648 bit8 *pParmList; /* Log Page data buffer */
16651 bit32 startingIndex;
16653 pSatDevData = satIOContext->pSatDevData;
16654 scsiCmnd = &tiScsiRequest->scsiCmnd;
16655 fis = satIOContext->pFis;
16656 pParmList = (bit8 *) tiScsiRequest->sglVirtualAddr;
16658 TI_DBG5(("satReassignBlocks_1: start\n"));
16660 LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
16661 osti_memset(LBA, 0, sizeof(LBA));
16663 startingIndex = satOrgIOContext->ParmIndex;
16667 LBA[4] = pParmList[startingIndex];
16668 LBA[5] = pParmList[startingIndex+1];
16669 LBA[6] = pParmList[startingIndex+2];
16670 LBA[7] = pParmList[startingIndex+3];
16671 startingIndex = startingIndex + 4;
16675 LBA[0] = pParmList[startingIndex];
16676 LBA[1] = pParmList[startingIndex+1];
16677 LBA[2] = pParmList[startingIndex+2];
16678 LBA[3] = pParmList[startingIndex+3];
16679 LBA[4] = pParmList[startingIndex+4];
16680 LBA[5] = pParmList[startingIndex+5];
16681 LBA[6] = pParmList[startingIndex+6];
16682 LBA[7] = pParmList[startingIndex+7];
16683 startingIndex = startingIndex + 8;
16686 if (pSatDevData->sat48BitSupport == agTRUE)
16688 /* sends READ VERIFY SECTOR(S) EXT*/
16689 fis->h.fisType = 0x27; /* Reg host to device */
16690 fis->h.c_pmPort = 0x80; /* C Bit is set */
16691 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
16692 fis->h.features = 0; /* FIS reserve */
16693 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16694 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16695 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16696 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */
16697 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */
16698 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */
16699 fis->d.featuresExp = 0; /* FIS reserve */
16700 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16701 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
16702 fis->d.reserved4 = 0;
16703 fis->d.device = 0x40; /* 01000000 */
16704 fis->d.control = 0; /* FIS HOB bit clear */
16705 fis->d.reserved5 = 0;
16709 /* READ VERIFY SECTOR(S)*/
16710 fis->h.fisType = 0x27; /* Reg host to device */
16711 fis->h.c_pmPort = 0x80; /* C Bit is set */
16712 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
16713 fis->h.features = 0; /* FIS features NA */
16714 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16715 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16716 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16717 fis->d.lbaLowExp = 0;
16718 fis->d.lbaMidExp = 0;
16719 fis->d.lbaHighExp = 0;
16720 fis->d.featuresExp = 0;
16721 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16722 fis->d.sectorCountExp = 0;
16723 fis->d.reserved4 = 0;
16724 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16725 /* DEV and LBA 27:24 */
16726 fis->d.control = 0; /* FIS HOB bit clear */
16727 fis->d.reserved5 = 0;
16729 osti_memcpy(satOrgIOContext->LBA, LBA, 8);
16730 satOrgIOContext->ParmIndex = startingIndex;
16731 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
16732 /* Initialize CB for SATA completion.
16734 satIOContext->satCompleteCB = &satReassignBlocksCB;
16736 * Prepare SGL and send FIS to LL layer.
16738 satIOContext->reqType = agRequestType; /* Save it */
16740 sataLLIOStart( tiRoot,
16748 /*****************************************************************************/
16749 /*! \brief SAT implementation for SCSI satReassignBlocks_2.
16751 * SAT implementation for SCSI Reassign Blocks. This is helper function for
16752 * satReassignBlocks and satReassignBlocksCB. This sends ATA write command.
16754 * \param tiRoot: Pointer to TISA initiator driver/port instance.
16755 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
16756 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
16757 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
16758 * \param satIOContext_t: Pointer to the SAT IO Context
16759 * \param LBA: Pointer to the LBA to be processed
16761 * \return If command is started successfully
16762 * - \e tiSuccess: I/O request successfully initiated.
16763 * - \e tiBusy: No resources available, try again later.
16764 * - \e tiIONoDevice: Invalid device handle.
16765 * - \e tiError: Other errors.
16767 /*****************************************************************************/
16768 /* current LBA; sends WRITE */
16769 GLOBAL bit32 satReassignBlocks_2(
16771 tiIORequest_t *tiIORequest,
16772 tiDeviceHandle_t *tiDeviceHandle,
16773 tiScsiInitiatorRequest_t *tiScsiRequest,
16774 satIOContext_t *satIOContext,
16779 assumes all LBA fits in ATA command; no boundary condition is checked here yet
16780 tiScsiRequest is TD generated for writing
16783 bit32 agRequestType;
16784 satDeviceData_t *pSatDevData;
16785 scsiRspSense_t *pSense;
16786 agsaFisRegHostToDevice_t *fis;
16788 pSense = satIOContext->pSense;
16789 pSatDevData = satIOContext->pSatDevData;
16790 fis = satIOContext->pFis;
16792 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
16796 /* can't fit the transfer length */
16797 TI_DBG5(("satReassignBlocks_2: case 2\n"));
16798 fis->h.fisType = 0x27; /* Reg host to device */
16799 fis->h.c_pmPort = 0x80; /* C bit is set */
16800 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
16801 fis->h.features = 0; /* FIS reserve */
16802 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16803 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16804 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16806 /* FIS LBA mode set LBA (27:24) */
16807 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16809 fis->d.lbaLowExp = 0;
16810 fis->d.lbaMidExp = 0;
16811 fis->d.lbaHighExp = 0;
16812 fis->d.featuresExp = 0;
16813 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16814 fis->d.sectorCountExp = 0;
16815 fis->d.reserved4 = 0;
16816 fis->d.control = 0; /* FIS HOB bit clear */
16817 fis->d.reserved5 = 0;
16819 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
16820 satIOContext->ATACmd = SAT_WRITE_DMA;
16825 /* WRITE MULTIPLE or WRITE SECTOR(S) */
16826 /* WRITE SECTORS for easier implemetation */
16827 /* can't fit the transfer length */
16828 TI_DBG5(("satReassignBlocks_2: case 1\n"));
16829 fis->h.fisType = 0x27; /* Reg host to device */
16830 fis->h.c_pmPort = 0x80; /* C bit is set */
16831 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
16832 fis->h.features = 0; /* FIS reserve */
16833 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16834 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16835 fis->d.lbaHigh = LBA[7]; /* FIS LBA (23:16) */
16837 /* FIS LBA mode set LBA (27:24) */
16838 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16840 fis->d.lbaLowExp = 0;
16841 fis->d.lbaMidExp = 0;
16842 fis->d.lbaHighExp = 0;
16843 fis->d.featuresExp = 0;
16844 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16845 fis->d.sectorCountExp = 0;
16846 fis->d.reserved4 = 0;
16847 fis->d.control = 0; /* FIS HOB bit clear */
16848 fis->d.reserved5 = 0;
16850 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16851 satIOContext->ATACmd = SAT_WRITE_SECTORS;
16855 if (pSatDevData->sat48BitSupport == agTRUE)
16857 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
16860 /* WRITE DMA EXT or WRITE DMA FUA EXT */
16861 TI_DBG5(("satReassignBlocks_2: case 3\n"));
16862 fis->h.fisType = 0x27; /* Reg host to device */
16863 fis->h.c_pmPort = 0x80; /* C Bit is set */
16865 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
16866 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
16867 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
16869 fis->h.features = 0; /* FIS reserve */
16870 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16871 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16872 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16873 fis->d.device = 0x40; /* FIS LBA mode set */
16874 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */
16875 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */
16876 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */
16877 fis->d.featuresExp = 0; /* FIS reserve */
16878 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16879 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
16880 fis->d.reserved4 = 0;
16881 fis->d.control = 0; /* FIS HOB bit clear */
16882 fis->d.reserved5 = 0;
16884 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
16889 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
16890 /* WRITE SECTORS EXT for easier implemetation */
16891 TI_DBG5(("satReassignBlocks_2: case 4\n"));
16892 fis->h.fisType = 0x27; /* Reg host to device */
16893 fis->h.c_pmPort = 0x80; /* C Bit is set */
16894 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
16896 fis->h.features = 0; /* FIS reserve */
16897 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16898 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16899 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16900 fis->d.device = 0x40; /* FIS LBA mode set */
16901 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */
16902 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */
16903 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */
16904 fis->d.featuresExp = 0; /* FIS reserve */
16905 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16906 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
16907 fis->d.reserved4 = 0;
16908 fis->d.control = 0; /* FIS HOB bit clear */
16909 fis->d.reserved5 = 0;
16911 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16912 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
16916 if (pSatDevData->satNCQ == agTRUE)
16918 /* WRITE FPDMA QUEUED */
16919 if (pSatDevData->sat48BitSupport != agTRUE)
16921 TI_DBG5(("satReassignBlocks_2: case 5 !!! error NCQ but 28 bit address support \n"));
16922 satSetSensePayload( pSense,
16923 SCSI_SNSKEY_HARDWARE_ERROR,
16925 SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED,
16928 ostiInitiatorIOCompleted( tiRoot,
16931 SCSI_STAT_CHECK_CONDITION,
16932 satIOContext->pTiSenseData,
16933 satIOContext->interruptContext );
16936 TI_DBG6(("satWrite10: case 5\n"));
16938 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
16940 fis->h.fisType = 0x27; /* Reg host to device */
16941 fis->h.c_pmPort = 0x80; /* C Bit is set */
16942 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
16943 fis->h.features = 1; /* FIS sector count (7:0) */
16944 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16945 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16946 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16948 /* Check FUA bit */
16949 fis->d.device = 0x40; /* FIS FUA clear */
16951 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */
16952 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */
16953 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */
16954 fis->d.featuresExp = 0; /* FIS sector count (15:8) */
16955 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
16956 fis->d.sectorCountExp = 0;
16957 fis->d.reserved4 = 0;
16958 fis->d.control = 0; /* FIS HOB bit clear */
16959 fis->d.reserved5 = 0;
16961 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
16962 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
16965 satIOContext->satCompleteCB = &satReassignBlocksCB;
16968 * Prepare SGL and send FIS to LL layer.
16970 satIOContext->reqType = agRequestType; /* Save it */
16972 status = sataLLIOStart( tiRoot,
16975 /* not the original, should be the TD generated one */
16982 /*****************************************************************************/
16983 /*! \brief SAT implementation for SCSI satPrepareNewIO.
16985 * This function fills in the fields of internal IO generated by TD layer.
16986 * This is mostly used in the callback functions.
16988 * \param satNewIntIo: Pointer to the internal IO structure.
16989 * \param tiOrgIORequest: Pointer to the original tiIOrequest sent by OS layer
16990 * \param satDevData: Pointer to the device data.
16991 * \param scsiCmnd: Pointer to SCSI command.
16992 * \param satOrgIOContext: Pointer to the original SAT IO Context
16995 * - \e Pointer to the new SAT IO Context
16997 /*****************************************************************************/
16998 GLOBAL satIOContext_t *satPrepareNewIO(
16999 satInternalIo_t *satNewIntIo,
17000 tiIORequest_t *tiOrgIORequest,
17001 satDeviceData_t *satDevData,
17002 tiIniScsiCmnd_t *scsiCmnd,
17003 satIOContext_t *satOrgIOContext
17006 satIOContext_t *satNewIOContext;
17007 tdIORequestBody_t *tdNewIORequestBody;
17009 TI_DBG2(("satPrepareNewIO: start\n"));
17011 /* the one to be used; good 8/2/07 */
17012 satNewIntIo->satOrgTiIORequest = tiOrgIORequest; /* this is already done in
17013 satAllocIntIoResource() */
17015 tdNewIORequestBody = (tdIORequestBody_t *)satNewIntIo->satIntRequestBody;
17016 satNewIOContext = &(tdNewIORequestBody->transport.SATA.satIOContext);
17018 satNewIOContext->pSatDevData = satDevData;
17019 satNewIOContext->pFis = &(tdNewIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
17020 satNewIOContext->pScsiCmnd = &(satNewIntIo->satIntTiScsiXchg.scsiCmnd);
17021 if (scsiCmnd != agNULL)
17023 /* saves only CBD; not scsi command for LBA and number of blocks */
17024 osti_memcpy(satNewIOContext->pScsiCmnd->cdb, scsiCmnd->cdb, 16);
17026 satNewIOContext->pSense = &(tdNewIORequestBody->transport.SATA.sensePayload);
17027 satNewIOContext->pTiSenseData = &(tdNewIORequestBody->transport.SATA.tiSenseData);
17028 satNewIOContext->pTiSenseData->senseData = satNewIOContext->pSense;
17029 satNewIOContext->tiRequestBody = satNewIntIo->satIntRequestBody;
17030 satNewIOContext->interruptContext = satNewIOContext->interruptContext;
17031 satNewIOContext->satIntIoContext = satNewIntIo;
17032 satNewIOContext->ptiDeviceHandle = satOrgIOContext->ptiDeviceHandle;
17033 satNewIOContext->satOrgIOContext = satOrgIOContext;
17034 /* saves tiScsiXchg; only for writesame10() */
17035 satNewIOContext->tiScsiXchg = satOrgIOContext->tiScsiXchg;
17037 return satNewIOContext;
17039 /*****************************************************************************
17040 *! \brief satIOAbort
17042 * This routine is called to initiate a I/O abort to SATL.
17043 * This routine is independent of HW/LL API.
17045 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17046 * \param taskTag: Pointer to TISA I/O request context/tag to be aborted.
17050 * \e tiSuccess: I/O request successfully initiated.
17051 * \e tiBusy: No resources available, try again later.
17052 * \e tiError: Other errors that prevent the I/O request to be started.
17055 *****************************************************************************/
17056 GLOBAL bit32 satIOAbort(
17058 tiIORequest_t *taskTag )
17061 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
17062 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
17063 agsaRoot_t *agRoot;
17064 tdIORequestBody_t *tdIORequestBody;
17065 tdIORequestBody_t *tdIONewRequestBody;
17066 agsaIORequest_t *agIORequest;
17068 agsaIORequest_t *agAbortIORequest;
17069 tdIORequestBody_t *tdAbortIORequestBody;
17072 bit32 memAllocStatus;
17074 satIOContext_t *satIOContext;
17075 satInternalIo_t *satIntIo;
17077 TI_DBG2(("satIOAbort: start\n"));
17079 agRoot = &(tdsaAllShared->agRootNonInt);
17080 tdIORequestBody = (tdIORequestBody_t *)taskTag->tdData;
17082 /* needs to distinguish internally generated or externally generated */
17083 satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
17084 satIntIo = satIOContext->satIntIoContext;
17085 if (satIntIo == agNULL)
17087 TI_DBG1(("satIOAbort: External, OS generated\n"));
17088 agIORequest = &(tdIORequestBody->agIORequest);
17092 TI_DBG1(("satIOAbort: Internal, TD generated\n"));
17093 tdIONewRequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
17094 agIORequest = &(tdIONewRequestBody->agIORequest);
17097 /* allocating agIORequest for abort itself */
17098 memAllocStatus = ostiAllocMemory(
17101 (void **)&tdAbortIORequestBody,
17105 sizeof(tdIORequestBody_t),
17108 if (memAllocStatus != tiSuccess)
17110 /* let os process IO */
17111 TI_DBG1(("satIOAbort: ostiAllocMemory failed...\n"));
17115 if (tdAbortIORequestBody == agNULL)
17117 /* let os process IO */
17118 TI_DBG1(("satIOAbort: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
17122 /* setup task management structure */
17123 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
17124 tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle;
17126 /* initialize agIORequest */
17127 agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
17128 agAbortIORequest->osData = (void *) tdAbortIORequestBody;
17129 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
17131 /* remember IO to be aborted */
17132 tdAbortIORequestBody->tiIOToBeAbortedRequest = taskTag;
17134 status = saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agIORequest, agNULL );
17136 TI_DBG5(("satIOAbort: return status=0x%x\n", status));
17138 if (status == AGSA_RC_SUCCESS)
17146 /*****************************************************************************
17149 * This routine is called to initiate a TM request to SATL.
17150 * This routine is independent of HW/LL API.
17152 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17153 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
17154 * \param task: SAM-3 task management request.
17155 * \param lun: Pointer to LUN.
17156 * \param taskTag: Pointer to the associated task where the TM
17157 * command is to be applied.
17158 * \param currentTaskTag: Pointer to tag/context for this TM request.
17162 * \e tiSuccess: I/O request successfully initiated.
17163 * \e tiBusy: No resources available, try again later.
17164 * \e tiIONoDevice: Invalid device handle.
17165 * \e tiError: Other errors that prevent the I/O request to be started.
17168 *****************************************************************************/
17169 /* save task in satIOContext */
17170 osGLOBAL bit32 satTM(
17172 tiDeviceHandle_t *tiDeviceHandle,
17175 tiIORequest_t *taskTag,
17176 tiIORequest_t *currentTaskTag,
17177 tdIORequestBody_t *tiRequestBody,
17181 tdIORequestBody_t *tdIORequestBody = agNULL;
17182 satIOContext_t *satIOContext = agNULL;
17183 tdsaDeviceData_t *oneDeviceData = agNULL;
17186 TI_DBG3(("satTM: tiDeviceHandle=%p task=0x%x\n", tiDeviceHandle, task ));
17188 /* set satIOContext fields and etc */
17189 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17192 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
17193 satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
17195 satIOContext->pSatDevData = &oneDeviceData->satDevData;
17196 satIOContext->pFis =
17197 &tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
17200 satIOContext->tiRequestBody = tiRequestBody;
17201 satIOContext->ptiDeviceHandle = tiDeviceHandle;
17202 satIOContext->satIntIoContext = agNULL;
17203 satIOContext->satOrgIOContext = agNULL;
17205 /* followings are used only for internal IO */
17206 satIOContext->currentLBA = 0;
17207 satIOContext->OrgTL = 0;
17209 /* saving task in satIOContext */
17210 satIOContext->TMF = task;
17212 satIOContext->satToBeAbortedIOContext = agNULL;
17214 if (NotifyOS == agTRUE)
17216 satIOContext->NotifyOS = agTRUE;
17220 satIOContext->NotifyOS = agFALSE;
17223 * Our SAT supports RESET LUN and partially support ABORT TASK (only if there
17224 * is no more than one I/O pending on the drive.
17227 if (task == AG_LOGICAL_UNIT_RESET)
17229 status = satTmResetLUN( tiRoot,
17237 #ifdef TO_BE_REMOVED
17238 else if (task == AG_TARGET_WARM_RESET)
17240 status = satTmWarmReset( tiRoot,
17249 else if (task == AG_ABORT_TASK)
17251 status = satTmAbortTask( tiRoot,
17260 else if (task == TD_INTERNAL_TM_RESET)
17262 status = satTDInternalTmReset( tiRoot,
17271 TI_DBG1(("satTM: tiDeviceHandle=%p UNSUPPORTED TM task=0x%x\n",
17272 tiDeviceHandle, task ));
17274 /* clean up TD layer's IORequestBody */
17277 tiRequestBody->IOType.InitiatorTMIO.osMemHandle,
17278 sizeof(tdIORequestBody_t)
17286 /*****************************************************************************
17287 *! \brief satTmResetLUN
17289 * This routine is called to initiate a TM RESET LUN request to SATL.
17290 * This routine is independent of HW/LL API.
17292 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17293 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
17294 * \param lun: Pointer to LUN.
17295 * \param currentTaskTag: Pointer to tag/context for this TM request.
17299 * \e tiSuccess: I/O request successfully initiated.
17300 * \e tiBusy: No resources available, try again later.
17301 * \e tiIONoDevice: Invalid device handle.
17302 * \e tiError: Other errors that prevent the I/O request to be started.
17305 *****************************************************************************/
17306 osGLOBAL bit32 satTmResetLUN(
17308 tiIORequest_t *tiIORequest, /* current task tag */
17309 tiDeviceHandle_t *tiDeviceHandle,
17310 tiScsiInitiatorRequest_t *tiScsiRequest,
17311 satIOContext_t *satIOContext,
17315 tdsaDeviceData_t *tdsaDeviceData;
17316 satDeviceData_t *satDevData;
17318 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17319 satDevData = &tdsaDeviceData->satDevData;
17321 TI_DBG1(("satTmResetLUN: tiDeviceHandle=%p.\n", tiDeviceHandle ));
17324 * Only support LUN 0
17326 if ( (lun->lun[0] | lun->lun[1] | lun->lun[2] | lun->lun[3] |
17327 lun->lun[4] | lun->lun[5] | lun->lun[6] | lun->lun[7] ) != 0 )
17329 TI_DBG1(("satTmResetLUN: *** REJECT *** LUN not zero, tiDeviceHandle=%p\n",
17335 * Check if there is other TM request pending
17337 if (satDevData->satTmTaskTag != agNULL)
17339 TI_DBG1(("satTmResetLUN: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
17345 * Save tiIORequest, will be returned at device reset completion to return
17346 * the TM completion.
17348 satDevData->satTmTaskTag = tiIORequest;
17351 * Set flag to indicate device in recovery mode.
17353 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17356 * Issue SATA device reset. Set flag to indicate NOT to automatically abort
17357 * at the completion of SATA device reset.
17359 satDevData->satAbortAfterReset = agFALSE;
17361 /* SAT rev8 6.3.6 p22 */
17362 satStartResetDevice(
17364 tiIORequest, /* currentTaskTag */
17375 /*****************************************************************************
17376 *! \brief satTmWarmReset
17378 * This routine is called to initiate a TM warm RESET request to SATL.
17379 * This routine is independent of HW/LL API.
17381 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17382 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
17383 * \param currentTaskTag: Pointer to tag/context for this TM request.
17387 * \e tiSuccess: I/O request successfully initiated.
17388 * \e tiBusy: No resources available, try again later.
17389 * \e tiIONoDevice: Invalid device handle.
17390 * \e tiError: Other errors that prevent the I/O request to be started.
17393 *****************************************************************************/
17394 osGLOBAL bit32 satTmWarmReset(
17396 tiIORequest_t *tiIORequest, /* current task tag */
17397 tiDeviceHandle_t *tiDeviceHandle,
17398 tiScsiInitiatorRequest_t *tiScsiRequest,
17399 satIOContext_t *satIOContext)
17402 tdsaDeviceData_t *tdsaDeviceData;
17403 satDeviceData_t *satDevData;
17405 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17406 satDevData = &tdsaDeviceData->satDevData;
17408 TI_DBG1(("satTmWarmReset: tiDeviceHandle=%p.\n", tiDeviceHandle ));
17411 * Check if there is other TM request pending
17413 if (satDevData->satTmTaskTag != agNULL)
17415 TI_DBG1(("satTmWarmReset: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
17421 * Save tiIORequest, will be returned at device reset completion to return
17422 * the TM completion.
17424 satDevData->satTmTaskTag = tiIORequest;
17427 * Set flag to indicate device in recovery mode.
17429 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17432 * Issue SATA device reset. Set flag to indicate NOT to automatically abort
17433 * at the completion of SATA device reset.
17435 satDevData->satAbortAfterReset = agFALSE;
17437 /* SAT rev8 6.3.6 p22 */
17438 satStartResetDevice(
17440 tiIORequest, /* currentTaskTag */
17450 osGLOBAL bit32 satTDInternalTmReset(
17452 tiIORequest_t *tiIORequest, /* current task tag */
17453 tiDeviceHandle_t *tiDeviceHandle,
17454 tiScsiInitiatorRequest_t *tiScsiRequest,
17455 satIOContext_t *satIOContext)
17458 tdsaDeviceData_t *tdsaDeviceData;
17459 satDeviceData_t *satDevData;
17461 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17462 satDevData = &tdsaDeviceData->satDevData;
17464 TI_DBG1(("satTmWarmReset: tiDeviceHandle=%p.\n", tiDeviceHandle ));
17467 * Check if there is other TM request pending
17469 if (satDevData->satTmTaskTag != agNULL)
17471 TI_DBG1(("satTmWarmReset: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
17477 * Save tiIORequest, will be returned at device reset completion to return
17478 * the TM completion.
17480 satDevData->satTmTaskTag = tiIORequest;
17483 * Set flag to indicate device in recovery mode.
17485 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17488 * Issue SATA device reset. Set flag to indicate NOT to automatically abort
17489 * at the completion of SATA device reset.
17491 satDevData->satAbortAfterReset = agFALSE;
17493 /* SAT rev8 6.3.6 p22 */
17494 satStartResetDevice(
17496 tiIORequest, /* currentTaskTag */
17506 /*****************************************************************************
17507 *! \brief satTmAbortTask
17509 * This routine is called to initiate a TM ABORT TASK request to SATL.
17510 * This routine is independent of HW/LL API.
17512 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17513 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
17514 * \param taskTag: Pointer to the associated task where the TM
17515 * command is to be applied.
17516 * \param currentTaskTag: Pointer to tag/context for this TM request.
17520 * \e tiSuccess: I/O request successfully initiated.
17521 * \e tiBusy: No resources available, try again later.
17522 * \e tiIONoDevice: Invalid device handle.
17523 * \e tiError: Other errors that prevent the I/O request to be started.
17526 *****************************************************************************/
17527 osGLOBAL bit32 satTmAbortTask(
17529 tiIORequest_t *tiIORequest, /* current task tag */
17530 tiDeviceHandle_t *tiDeviceHandle,
17531 tiScsiInitiatorRequest_t *tiScsiRequest, /* NULL */
17532 satIOContext_t *satIOContext,
17533 tiIORequest_t *taskTag)
17536 tdsaDeviceData_t *tdsaDeviceData;
17537 satDeviceData_t *satDevData;
17538 satIOContext_t *satTempIOContext = agNULL;
17539 tdIORequestBody_t *tdIORequestBody;
17540 tdIORequestBody_t *TMtdIORequestBody;
17541 tdList_t *elementHdr;
17542 bit32 found = agFALSE;
17543 tiIORequest_t *tiIOReq;
17545 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17546 satDevData = &tdsaDeviceData->satDevData;
17547 TMtdIORequestBody = (tdIORequestBody_t *)tiIORequest->tdData;
17549 TI_DBG1(("satTmAbortTask: tiDeviceHandle=%p taskTag=%p.\n", tiDeviceHandle, taskTag ));
17551 * Check if there is other TM request pending
17553 if (satDevData->satTmTaskTag != agNULL)
17555 TI_DBG1(("satTmAbortTask: REJECT other TM pending, tiDeviceHandle=%p\n",
17557 /* clean up TD layer's IORequestBody */
17560 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
17561 sizeof(tdIORequestBody_t)
17568 * Check if there is only one I/O pending.
17570 if (satDevData->satPendingIO > 0)
17572 TI_DBG1(("satTmAbortTask: REJECT num pending I/O, tiDeviceHandle=%p, satPendingIO=0x%x\n",
17573 tiDeviceHandle, satDevData->satPendingIO));
17574 /* clean up TD layer's IORequestBody */
17577 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
17578 sizeof(tdIORequestBody_t)
17586 * Check that the only pending I/O matches taskTag. If not return tiError.
17588 elementHdr = satDevData->satIoLinkList.flink;
17590 while (elementHdr != &satDevData->satIoLinkList)
17592 satTempIOContext = TDLIST_OBJECT_BASE( satIOContext_t,
17596 tdIORequestBody = (tdIORequestBody_t *) satTempIOContext->tiRequestBody;
17597 tiIOReq = tdIORequestBody->tiIORequest;
17599 elementHdr = elementHdr->flink; /* for the next while loop */
17602 * Check if the tag matches
17604 if ( tiIOReq == taskTag)
17607 satIOContext->satToBeAbortedIOContext = satTempIOContext;
17608 TI_DBG1(("satTmAbortTask: found matching tag.\n"));
17612 } /* if matching tag */
17617 if (found == agFALSE )
17619 TI_DBG1(("satTmAbortTask: *** REJECT *** no match, tiDeviceHandle=%p\n",
17622 /* clean up TD layer's IORequestBody */
17625 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
17626 sizeof(tdIORequestBody_t)
17633 * Save tiIORequest, will be returned at device reset completion to return
17634 * the TM completion.
17636 satDevData->satTmTaskTag = tiIORequest;
17639 * Set flag to indicate device in recovery mode.
17641 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17645 * Issue SATA device reset or check power mode. Set flag to to automatically abort
17646 * at the completion of SATA device reset.
17649 satDevData->satAbortAfterReset = agTRUE;
17651 if ( (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
17652 (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ)
17655 TI_DBG1(("satTmAbortTask: calling satStartCheckPowerMode\n"));
17656 /* send check power mode */
17657 satStartCheckPowerMode(
17659 tiIORequest, /* currentTaskTag */
17667 TI_DBG1(("satTmAbortTask: calling satStartResetDevice\n"));
17668 /* send AGSA_SATA_PROTOCOL_SRST_ASSERT */
17669 satStartResetDevice(
17671 tiIORequest, /* currentTaskTag */
17682 /*****************************************************************************
17683 *! \brief osSatResetCB
17685 * This routine is called to notify the completion of SATA device reset
17686 * which was initiated previously through the call to sataLLReset().
17687 * This routine is independent of HW/LL API.
17689 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17690 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
17691 * \param resetStatus: Reset status either tiSuccess or tiError.
17692 * \param respFis: Pointer to the Register Device-To-Host FIS
17693 * received from the device.
17697 *****************************************************************************/
17698 osGLOBAL void osSatResetCB(
17700 tiDeviceHandle_t *tiDeviceHandle,
17705 agsaRoot_t *agRoot;
17706 tdsaDeviceData_t *tdsaDeviceData;
17707 satDeviceData_t *satDevData;
17708 satIOContext_t *satIOContext;
17709 tdIORequestBody_t *tdIORequestBodyTmp;
17710 tdList_t *elementHdr;
17711 agsaIORequest_t *agAbortIORequest;
17712 tdIORequestBody_t *tdAbortIORequestBody;
17715 bit32 memAllocStatus;
17718 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17719 agRoot = tdsaDeviceData->agRoot;
17720 satDevData = &tdsaDeviceData->satDevData;
17722 TI_DBG5(("osSatResetCB: tiDeviceHandle=%p resetStatus=0x%x\n",
17723 tiDeviceHandle, resetStatus ));
17725 /* We may need to check FIS to check device operating condition */
17729 * Check if need to abort all pending I/Os
17731 if ( satDevData->satAbortAfterReset == agTRUE )
17734 * Issue abort to LL layer to all other pending I/Os for the same SATA drive
17736 elementHdr = satDevData->satIoLinkList.flink;
17737 while (elementHdr != &satDevData->satIoLinkList)
17739 satIOContext = TDLIST_OBJECT_BASE( satIOContext_t,
17743 tdIORequestBodyTmp = (tdIORequestBody_t *)satIOContext->tiRequestBody;
17748 TI_DBG5(("osSatResetCB: issuing ABORT tiDeviceHandle=%p agIORequest=%p\n",
17749 tiDeviceHandle, &tdIORequestBodyTmp->agIORequest ));
17751 /* allocating agIORequest for abort itself */
17752 memAllocStatus = ostiAllocMemory(
17755 (void **)&tdAbortIORequestBody,
17759 sizeof(tdIORequestBody_t),
17763 if (memAllocStatus != tiSuccess)
17765 /* let os process IO */
17766 TI_DBG1(("osSatResetCB: ostiAllocMemory failed...\n"));
17770 if (tdAbortIORequestBody == agNULL)
17772 /* let os process IO */
17773 TI_DBG1(("osSatResetCB: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
17776 /* setup task management structure */
17777 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
17778 tdAbortIORequestBody->tiDevHandle = tiDeviceHandle;
17780 /* initialize agIORequest */
17781 agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
17782 agAbortIORequest->osData = (void *) tdAbortIORequestBody;
17783 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
17785 saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, &(tdIORequestBodyTmp->agIORequest), agNULL );
17786 elementHdr = elementHdr->flink; /* for the next while loop */
17791 satDevData->satAbortAfterReset = agFALSE;
17797 * Check if the device reset if the result of TM request.
17799 if ( satDevData->satTmTaskTag != agNULL )
17801 TI_DBG5(("osSatResetCB: calling TM completion tiDeviceHandle=%p satTmTaskTag=%p\n",
17802 tiDeviceHandle, satDevData->satTmTaskTag ));
17804 ostiInitiatorEvent( tiRoot,
17805 agNULL, /* portalContext not used */
17807 tiIntrEventTypeTaskManagement,
17809 satDevData->satTmTaskTag);
17813 satDevData->satTmTaskTag = agNULL;
17819 /*****************************************************************************
17820 *! \brief osSatIOCompleted
17822 * This routine is a callback for SATA completion that required FIS status
17823 * translation to SCSI status.
17825 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17826 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
17827 * \param respFis: Pointer to status FIS to read.
17828 * \param respFisLen: Length of response FIS to read.
17829 * \param satIOContext: Pointer to SAT context.
17830 * \param interruptContext: Interrupt context
17834 *****************************************************************************/
17835 osGLOBAL void osSatIOCompleted(
17837 tiIORequest_t *tiIORequest,
17838 agsaFisHeader_t *agFirstDword,
17840 agsaFrameHandle_t agFrameHandle,
17841 satIOContext_t *satIOContext,
17842 bit32 interruptContext)
17845 satDeviceData_t *pSatDevData;
17846 scsiRspSense_t *pSense;
17847 #ifdef TD_DEBUG_ENABLE
17848 tiIniScsiCmnd_t *pScsiCmnd;
17850 agsaFisRegHostToDevice_t *hostToDevFis = agNULL;
17851 bit32 ataStatus = 0;
17853 satInternalIo_t *satIntIo = agNULL;
17855 tiDeviceHandle_t *tiDeviceHandle;
17856 satIOContext_t *satIOContext2;
17857 tdIORequestBody_t *tdIORequestBody;
17858 agsaFisRegD2HHeader_t *statDevToHostFisHeader = agNULL;
17859 agsaFisSetDevBitsHeader_t *statSetDevBitFisHeader = agNULL;
17860 tiIORequest_t tiIORequestTMP;
17862 pSense = satIOContext->pSense;
17863 pSatDevData = satIOContext->pSatDevData;
17864 #ifdef TD_DEBUG_ENABLE
17865 pScsiCmnd = satIOContext->pScsiCmnd;
17867 hostToDevFis = satIOContext->pFis;
17869 tiDeviceHandle = &((tdsaDeviceData_t *)(pSatDevData->satSaDeviceData))->tiDeviceHandle;
17871 * Find out the type of response FIS:
17872 * Set Device Bit FIS or Reg Device To Host FIS.
17875 /* First assume it is Reg Device to Host FIS */
17876 statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
17877 ataStatus = statDevToHostFisHeader->status; /* ATA Status register */
17878 ataError = statDevToHostFisHeader->error; /* ATA Eror register */
17880 /* for debugging */
17881 TI_DBG1(("osSatIOCompleted: H to D command 0x%x\n", hostToDevFis->h.command));
17882 TI_DBG1(("osSatIOCompleted: D to H fistype 0x%x\n", statDevToHostFisHeader->fisType));
17885 if (statDevToHostFisHeader->fisType == SET_DEV_BITS_FIS)
17887 /* It is Set Device Bits FIS */
17888 statSetDevBitFisHeader = (agsaFisSetDevBitsHeader_t *)&(agFirstDword->D2H);
17889 /* Get ATA Status register */
17890 ataStatus = (statSetDevBitFisHeader->statusHi_Lo & 0x70); /* bits 4,5,6 */
17891 ataStatus = ataStatus | (statSetDevBitFisHeader->statusHi_Lo & 0x07); /* bits 0,1,2 */
17893 /* ATA Eror register */
17894 ataError = statSetDevBitFisHeader->error;
17896 statDevToHostFisHeader = agNULL;
17899 else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
17901 TI_DBG1(("osSatIOCompleted: *** UNEXPECTED RESP FIS TYPE 0x%x *** tiIORequest=%p\n",
17902 statDevToHostFisHeader->fisType, tiIORequest));
17904 satSetSensePayload( pSense,
17905 SCSI_SNSKEY_HARDWARE_ERROR,
17907 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
17910 ostiInitiatorIOCompleted( tiRoot,
17913 SCSI_STAT_CHECK_CONDITION,
17914 satIOContext->pTiSenseData,
17915 interruptContext );
17920 if ( ataStatus & DF_ATA_STATUS_MASK )
17922 pSatDevData->satDeviceFaultState = agTRUE;
17926 pSatDevData->satDeviceFaultState = agFALSE;
17929 TI_DBG5(("osSatIOCompleted: tiIORequest=%p CDB=0x%x ATA CMD =0x%x\n",
17930 tiIORequest, pScsiCmnd->cdb[0], hostToDevFis->h.command));
17933 * Decide which ATA command is the translation needed
17935 switch(hostToDevFis->h.command)
17937 case SAT_READ_FPDMA_QUEUED:
17938 case SAT_WRITE_FPDMA_QUEUED:
17940 /************************************************************************
17942 * !!!! See Section 13.5.2.4 of SATA 2.5 specs. !!!!
17943 * !!!! If the NCQ error ends up here, it means that the device sent !!!!
17944 * !!!! Set Device Bit FIS (which has SActive register) instead of !!!!
17945 * !!!! Register Device To Host FIS (which does not have SActive !!!!
17946 * !!!! register). The callback ossaSATAEvent() deals with the case !!!!
17947 * !!!! where Register Device To Host FIS was sent by the device. !!!!
17949 * For NCQ we need to issue READ LOG EXT command with log page 10h
17950 * to get the error and to allow other I/Os to continue.
17952 * Here is the basic flow or sequence of error recovery, note that due
17953 * to the SATA HW assist that we have, this sequence is slighly different
17954 * from the one described in SATA 2.5:
17956 * 1. Set SATA device flag to indicate error condition and returning busy
17957 * for all new request.
17958 * return tiSuccess;
17960 * 2. Because the HW/LL layer received Set Device Bit FIS, it can get the
17961 * tag or I/O context for NCQ request, SATL would translate the ATA error
17962 * to SCSI status and return the original NCQ I/O with the appopriate
17965 * 3. Prepare READ LOG EXT page 10h command. Set flag to indicate that
17966 * the failed I/O has been returned to the OS Layer. Send command.
17968 * 4. When the device receives READ LOG EXT page 10h request all other
17969 * pending I/O are implicitly aborted. No completion (aborted) status
17970 * will be sent to the host for these aborted commands.
17972 * 5. SATL receives the completion for READ LOG EXT command in
17973 * satReadLogExtCB(). Steps 6,7,8,9 below are the step 1,2,3,4 in
17974 * satReadLogExtCB().
17976 * 6. Check flag that indicates whether the failed I/O has been returned
17977 * to the OS Layer. If not, search the I/O context in device data
17978 * looking for a matched tag. Then return the completion of the failed
17979 * NCQ command with the appopriate/trasnlated SCSI status.
17981 * 7. Issue abort to LL layer to all other pending I/Os for the same SATA
17984 * 8. Free resource allocated for the internally generated READ LOG EXT.
17986 * 9. At the completion of abort, in the context of ossaSATACompleted(),
17987 * return the I/O with error status to the OS-App Specific layer.
17988 * When all I/O aborts are completed, clear SATA device flag to
17989 * indicate ready to process new request.
17991 ***********************************************************************/
17993 TI_DBG1(("osSatIOCompleted: NCQ ERROR tiIORequest=%p ataStatus=0x%x ataError=0x%x\n",
17994 tiIORequest, ataStatus, ataError ));
17996 /* Set flag to indicate we are in recovery */
17997 pSatDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17999 /* Return the failed NCQ I/O to OS-Apps Specifiic layer */
18000 osSatDefaultTranslation( tiRoot,
18006 interruptContext );
18009 * Allocate resource for READ LOG EXT page 10h
18011 satIntIo = satAllocIntIoResource( tiRoot,
18012 &(tiIORequestTMP), /* anything but NULL */
18014 sizeof (satReadLogExtPage10h_t),
18017 if (satIntIo == agNULL)
18019 TI_DBG1(("osSatIOCompleted: can't send RLE due to resource lack\n"));
18021 /* Abort I/O after completion of device reset */
18022 pSatDevData->satAbortAfterReset = agTRUE;
18024 /* needs further investigation */
18025 /* no report to OS layer */
18028 TD_INTERNAL_TM_RESET,
18036 TI_DBG1(("osSatIOCompleted: calling saSATADeviceReset 1\n"));
18042 * Set flag to indicate that the failed I/O has been returned to the
18043 * OS-App specific Layer.
18045 satIntIo->satIntFlag = AG_SAT_INT_IO_FLAG_ORG_IO_COMPLETED;
18047 /* compare to satPrepareNewIO() */
18048 /* Send READ LOG EXIT page 10h command */
18051 * Need to initialize all the fields within satIOContext except
18052 * reqType and satCompleteCB which will be set depending on cmd.
18055 tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
18056 satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
18058 satIOContext2->pSatDevData = pSatDevData;
18059 satIOContext2->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
18060 satIOContext2->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
18061 satIOContext2->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
18062 satIOContext2->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
18063 satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
18065 satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
18066 satIOContext2->interruptContext = interruptContext;
18067 satIOContext2->satIntIoContext = satIntIo;
18069 satIOContext2->ptiDeviceHandle = tiDeviceHandle;
18070 satIOContext2->satOrgIOContext = agNULL;
18071 satIOContext2->tiScsiXchg = agNULL;
18073 status = satSendReadLogExt( tiRoot,
18074 &satIntIo->satIntTiIORequest,
18076 &satIntIo->satIntTiScsiXchg,
18079 if (status != tiSuccess)
18081 TI_DBG1(("osSatIOCompleted: can't send RLE due to LL api failure\n"));
18082 satFreeIntIoResource( tiRoot,
18086 /* Abort I/O after completion of device reset */
18087 pSatDevData->satAbortAfterReset = agTRUE;
18089 /* needs further investigation */
18090 /* no report to OS layer */
18093 TD_INTERNAL_TM_RESET,
18100 TI_DBG1(("osSatIOCompleted: calling saSATADeviceReset 2\n"));
18106 case SAT_READ_DMA_EXT:
18108 /* Use default status/error translation */
18112 /* Use default status/error translation */
18115 osSatDefaultTranslation( tiRoot,
18121 interruptContext );
18128 /*****************************************************************************/
18129 /*! \brief SAT implementation for SCSI STANDARD INQUIRY.
18131 * SAT implementation for SCSI STANDARD INQUIRY.
18133 * \param pInquiry: Pointer to Inquiry Data buffer.
18134 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data.
18138 /*****************************************************************************/
18139 GLOBAL void satInquiryStandard(
18141 agsaSATAIdentifyData_t *pSATAIdData,
18142 tiIniScsiCmnd_t *scsiCmnd
18146 pLun = &scsiCmnd->lun;
18149 Assumption: Basic Task Mangement is supported
18150 -> BQUE 1 and CMDQUE 0, SPC-4, Table96, p147
18153 See SPC-4, 6.4.2, p 143
18154 and SAT revision 8, 8.1.2, p 28
18157 TI_DBG5(("satInquiryStandard: start\n"));
18159 if (pInquiry == agNULL)
18161 TI_DBG1(("satInquiryStandard: pInquiry is NULL, wrong\n"));
18166 TI_DBG5(("satInquiryStandard: pInquiry is NOT NULL\n"));
18169 * Reject all other LUN other than LUN 0.
18171 if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
18172 pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) )
18174 /* SAT Spec Table 8, p27, footnote 'a' */
18175 pInquiry[0] = 0x7F;
18180 pInquiry[0] = 0x00;
18183 if (pSATAIdData->rm_ataDevice & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
18185 pInquiry[1] = 0x80;
18189 pInquiry[1] = 0x00;
18191 pInquiry[2] = 0x05; /* SPC-3 */
18192 pInquiry[3] = 0x12; /* set HiSup 1; resp data format set to 2 */
18193 pInquiry[4] = 0x1F; /* 35 - 4 = 31; Additional length */
18194 pInquiry[5] = 0x00;
18195 /* The following two are for task management. SAT Rev8, p20 */
18196 if (pSATAIdData->sataCapabilities & 0x100)
18198 /* NCQ supported; multiple outstanding SCSI IO are supported */
18199 pInquiry[6] = 0x00; /* BQUE bit is not set */
18200 pInquiry[7] = 0x02; /* CMDQUE bit is set */
18204 pInquiry[6] = 0x80; /* BQUE bit is set */
18205 pInquiry[7] = 0x00; /* CMDQUE bit is not set */
18210 osti_strncpy((char*)&pInquiry[8], AG_SAT_VENDOR_ID_STRING,8); /* 8 bytes */
18215 /* when flipped by LL */
18216 pInquiry[16] = pSATAIdData->modelNumber[1];
18217 pInquiry[17] = pSATAIdData->modelNumber[0];
18218 pInquiry[18] = pSATAIdData->modelNumber[3];
18219 pInquiry[19] = pSATAIdData->modelNumber[2];
18220 pInquiry[20] = pSATAIdData->modelNumber[5];
18221 pInquiry[21] = pSATAIdData->modelNumber[4];
18222 pInquiry[22] = pSATAIdData->modelNumber[7];
18223 pInquiry[23] = pSATAIdData->modelNumber[6];
18224 pInquiry[24] = pSATAIdData->modelNumber[9];
18225 pInquiry[25] = pSATAIdData->modelNumber[8];
18226 pInquiry[26] = pSATAIdData->modelNumber[11];
18227 pInquiry[27] = pSATAIdData->modelNumber[10];
18228 pInquiry[28] = pSATAIdData->modelNumber[13];
18229 pInquiry[29] = pSATAIdData->modelNumber[12];
18230 pInquiry[30] = pSATAIdData->modelNumber[15];
18231 pInquiry[31] = pSATAIdData->modelNumber[14];
18235 * Product Revision level.
18239 * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA
18240 * device are ASCII spaces (20h), do this translation.
18242 if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
18243 (pSATAIdData->firmwareVersion[5] == 0x00 ) &&
18244 (pSATAIdData->firmwareVersion[6] == 0x20 ) &&
18245 (pSATAIdData->firmwareVersion[7] == 0x00 )
18248 pInquiry[32] = pSATAIdData->firmwareVersion[1];
18249 pInquiry[33] = pSATAIdData->firmwareVersion[0];
18250 pInquiry[34] = pSATAIdData->firmwareVersion[3];
18251 pInquiry[35] = pSATAIdData->firmwareVersion[2];
18255 pInquiry[32] = pSATAIdData->firmwareVersion[5];
18256 pInquiry[33] = pSATAIdData->firmwareVersion[4];
18257 pInquiry[34] = pSATAIdData->firmwareVersion[7];
18258 pInquiry[35] = pSATAIdData->firmwareVersion[6];
18266 /* when flipped by LL */
18267 pInquiry[16] = pSATAIdData->modelNumber[0];
18268 pInquiry[17] = pSATAIdData->modelNumber[1];
18269 pInquiry[18] = pSATAIdData->modelNumber[2];
18270 pInquiry[19] = pSATAIdData->modelNumber[3];
18271 pInquiry[20] = pSATAIdData->modelNumber[4];
18272 pInquiry[21] = pSATAIdData->modelNumber[5];
18273 pInquiry[22] = pSATAIdData->modelNumber[6];
18274 pInquiry[23] = pSATAIdData->modelNumber[7];
18275 pInquiry[24] = pSATAIdData->modelNumber[8];
18276 pInquiry[25] = pSATAIdData->modelNumber[9];
18277 pInquiry[26] = pSATAIdData->modelNumber[10];
18278 pInquiry[27] = pSATAIdData->modelNumber[11];
18279 pInquiry[28] = pSATAIdData->modelNumber[12];
18280 pInquiry[29] = pSATAIdData->modelNumber[13];
18281 pInquiry[30] = pSATAIdData->modelNumber[14];
18282 pInquiry[31] = pSATAIdData->modelNumber[15];
18286 * Product Revision level.
18290 * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA
18291 * device are ASCII spaces (20h), do this translation.
18293 if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
18294 (pSATAIdData->firmwareVersion[5] == 0x00 ) &&
18295 (pSATAIdData->firmwareVersion[6] == 0x20 ) &&
18296 (pSATAIdData->firmwareVersion[7] == 0x00 )
18299 pInquiry[32] = pSATAIdData->firmwareVersion[0];
18300 pInquiry[33] = pSATAIdData->firmwareVersion[1];
18301 pInquiry[34] = pSATAIdData->firmwareVersion[2];
18302 pInquiry[35] = pSATAIdData->firmwareVersion[3];
18306 pInquiry[32] = pSATAIdData->firmwareVersion[4];
18307 pInquiry[33] = pSATAIdData->firmwareVersion[5];
18308 pInquiry[34] = pSATAIdData->firmwareVersion[6];
18309 pInquiry[35] = pSATAIdData->firmwareVersion[7];
18313 TI_DBG5(("satInquiryStandard: end\n"));
18318 /*****************************************************************************/
18319 /*! \brief SAT implementation for SCSI INQUIRY page 0.
18321 * SAT implementation for SCSI INQUIRY page 0.
18323 * \param pInquiry: Pointer to Inquiry Data buffer.
18324 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data.
18328 /*****************************************************************************/
18329 GLOBAL void satInquiryPage0(
18331 agsaSATAIdentifyData_t *pSATAIdData)
18334 TI_DBG5(("satInquiryPage0: entry\n"));
18337 See SPC-4, 7.6.9, p 345
18338 and SAT revision 8, 10.3.2, p 77
18340 pInquiry[0] = 0x00;
18341 pInquiry[1] = 0x00; /* page code */
18342 pInquiry[2] = 0x00; /* reserved */
18343 pInquiry[3] = 7 - 3; /* last index(in this case, 6) - 3; page length */
18345 /* supported vpd page list */
18346 pInquiry[4] = 0x00; /* page 0x00 supported */
18347 pInquiry[5] = 0x80; /* page 0x80 supported */
18348 pInquiry[6] = 0x83; /* page 0x83 supported */
18349 pInquiry[7] = 0x89; /* page 0x89 supported */
18354 /*****************************************************************************/
18355 /*! \brief SAT implementation for SCSI INQUIRY page 83.
18357 * SAT implementation for SCSI INQUIRY page 83.
18359 * \param pInquiry: Pointer to Inquiry Data buffer.
18360 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data.
18364 /*****************************************************************************/
18365 GLOBAL void satInquiryPage83(
18367 agsaSATAIdentifyData_t *pSATAIdData,
18368 satDeviceData_t *pSatDevData)
18371 satSimpleSATAIdentifyData_t *pSimpleData;
18374 * When translating the fields, in some cases using the simple form of SATA
18375 * Identify Device Data is easier. So we define it here.
18376 * Both pSimpleData and pSATAIdData points to the same data.
18378 pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
18380 TI_DBG5(("satInquiryPage83: entry\n"));
18382 pInquiry[0] = 0x00;
18383 pInquiry[1] = 0x83; /* page code */
18384 pInquiry[2] = 0; /* Reserved */
18387 * If the ATA device returns word 87 bit 8 set to one in its IDENTIFY DEVICE
18388 * data indicating that it supports the WORLD WIDE NAME field
18389 * (i.e., words 108-111), the SATL shall include an identification descriptor
18390 * containing a logical unit name.
18392 if ( pSatDevData->satWWNSupport)
18394 /* Fill in SAT Rev8 Table85 */
18396 * Logical unit name derived from the world wide name.
18398 pInquiry[3] = 12; /* 15-3; page length, no addition ID descriptor assumed*/
18401 * Identifier descriptor
18403 pInquiry[4] = 0x01; /* Code set: binary codes */
18404 pInquiry[5] = 0x03; /* Identifier type : NAA */
18405 pInquiry[6] = 0x00; /* Reserved */
18406 pInquiry[7] = 0x08; /* Identifier length */
18408 /* Bit 4-7 NAA field, bit 0-3 MSB of IEEE Company ID */
18409 pInquiry[8] = (bit8)((pSATAIdData->namingAuthority) >> 8);
18410 pInquiry[9] = (bit8)((pSATAIdData->namingAuthority) & 0xFF); /* IEEE Company ID */
18411 pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8); /* IEEE Company ID */
18412 /* Bit 4-7 LSB of IEEE Company ID, bit 0-3 MSB of Vendor Specific ID */
18413 pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF);
18414 pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8); /* Vendor Specific ID */
18415 pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF); /* Vendor Specific ID */
18416 pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8); /* Vendor Specific ID */
18417 pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF); /* Vendor Specific ID */
18422 /* Fill in SAT Rev8 Table86 */
18424 * Logical unit name derived from the model number and serial number.
18426 pInquiry[3] = 72; /* 75 - 3; page length */
18429 * Identifier descriptor
18431 pInquiry[4] = 0x02; /* Code set: ASCII codes */
18432 pInquiry[5] = 0x01; /* Identifier type : T10 vendor ID based */
18433 pInquiry[6] = 0x00; /* Reserved */
18434 pInquiry[7] = 0x44; /* 0x44, 68 Identifier length */
18436 /* Byte 8 to 15 is the vendor id string 'ATA '. */
18437 osti_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8);
18441 * Byte 16 to 75 is vendor specific id
18443 pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8);
18444 pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff);
18445 pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8);
18446 pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff);
18447 pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8);
18448 pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff);
18449 pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8);
18450 pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff);
18451 pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8);
18452 pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff);
18453 pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8);
18454 pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff);
18455 pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8);
18456 pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff);
18457 pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8);
18458 pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff);
18459 pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8);
18460 pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff);
18461 pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8);
18462 pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff);
18463 pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8);
18464 pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff);
18465 pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8);
18466 pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff);
18467 pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8);
18468 pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff);
18469 pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8);
18470 pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff);
18471 pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8);
18472 pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff);
18473 pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8);
18474 pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff);
18475 pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8);
18476 pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff);
18477 pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8);
18478 pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff);
18479 pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8);
18480 pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff);
18481 pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8);
18482 pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff);
18484 pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8);
18485 pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff);
18486 pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8);
18487 pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff);
18488 pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8);
18489 pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff);
18490 pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8);
18491 pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff);
18492 pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8);
18493 pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff);
18494 pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8);
18495 pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff);
18496 pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8);
18497 pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff);
18498 pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8);
18499 pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff);
18500 pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8);
18501 pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff);
18502 pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8);
18503 pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff);
18508 /*****************************************************************************/
18509 /*! \brief SAT implementation for SCSI INQUIRY page 89.
18511 * SAT implementation for SCSI INQUIRY page 89.
18513 * \param pInquiry: Pointer to Inquiry Data buffer.
18514 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data.
18515 * \param pSatDevData Pointer to internal device data structure
18519 /*****************************************************************************/
18520 GLOBAL void satInquiryPage89(
18522 agsaSATAIdentifyData_t *pSATAIdData,
18523 satDeviceData_t *pSatDevData)
18526 SAT revision 8, 10.3.5, p 83
18528 satSimpleSATAIdentifyData_t *pSimpleData;
18531 * When translating the fields, in some cases using the simple form of SATA
18532 * Identify Device Data is easier. So we define it here.
18533 * Both pSimpleData and pSATAIdData points to the same data.
18535 pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
18537 TI_DBG5(("satInquiryPage89: start\n"));
18539 pInquiry[0] = 0x00; /* Peripheral Qualifier and Peripheral Device Type */
18540 pInquiry[1] = 0x89; /* page code */
18542 /* Page length 0x238 */
18543 pInquiry[2] = 0x02;
18544 pInquiry[3] = 0x38;
18546 pInquiry[4] = 0x0; /* reserved */
18547 pInquiry[5] = 0x0; /* reserved */
18548 pInquiry[6] = 0x0; /* reserved */
18549 pInquiry[7] = 0x0; /* reserved */
18551 /* SAT Vendor Identification */
18552 osti_strncpy((char*)&pInquiry[8], "PMC-SIERRA", 8); /* 8 bytes */
18554 /* SAT Product Idetification */
18555 osti_strncpy((char*)&pInquiry[16], "Tachyon-SPC ", 16); /* 16 bytes */
18557 /* SAT Product Revision Level */
18558 osti_strncpy((char*)&pInquiry[32], "01", 4); /* 4 bytes */
18560 /* Signature, SAT revision8, Table88, p85 */
18563 pInquiry[36] = 0x34; /* FIS type */
18564 if (pSatDevData->satDeviceType == SATA_ATA_DEVICE)
18566 /* interrupt assume to be 0 */
18567 pInquiry[37] = (bit8)((pSatDevData->satPMField) >> (4 * 7)); /* first four bits of PM field */
18571 /* interrupt assume to be 1 */
18572 pInquiry[37] = (bit8)(0x40 + (bit8)(((pSatDevData->satPMField) >> (4 * 7)))); /* first four bits of PM field */
18577 if (pSatDevData->satDeviceType == SATA_ATA_DEVICE)
18579 pInquiry[40] = 0x01; /* LBA Low */
18580 pInquiry[41] = 0x00; /* LBA Mid */
18581 pInquiry[42] = 0x00; /* LBA High */
18582 pInquiry[43] = 0x00; /* Device */
18583 pInquiry[44] = 0x00; /* LBA Low Exp */
18584 pInquiry[45] = 0x00; /* LBA Mid Exp */
18585 pInquiry[46] = 0x00; /* LBA High Exp */
18586 pInquiry[47] = 0x00; /* Reserved */
18587 pInquiry[48] = 0x01; /* Sector Count */
18588 pInquiry[49] = 0x00; /* Sector Count Exp */
18592 pInquiry[40] = 0x01; /* LBA Low */
18593 pInquiry[41] = 0x00; /* LBA Mid */
18594 pInquiry[42] = 0x00; /* LBA High */
18595 pInquiry[43] = 0x00; /* Device */
18596 pInquiry[44] = 0x00; /* LBA Low Exp */
18597 pInquiry[45] = 0x00; /* LBA Mid Exp */
18598 pInquiry[46] = 0x00; /* LBA High Exp */
18599 pInquiry[47] = 0x00; /* Reserved */
18600 pInquiry[48] = 0x01; /* Sector Count */
18601 pInquiry[49] = 0x00; /* Sector Count Exp */
18605 pInquiry[50] = 0x00;
18606 pInquiry[51] = 0x00;
18607 pInquiry[52] = 0x00;
18608 pInquiry[53] = 0x00;
18609 pInquiry[54] = 0x00;
18610 pInquiry[55] = 0x00;
18613 if (pSatDevData->satDeviceType == SATA_ATA_DEVICE)
18615 pInquiry[56] = 0xEC; /* IDENTIFY DEVICE */
18619 pInquiry[56] = 0xA1; /* IDENTIFY PACKET DEVICE */
18622 pInquiry[57] = 0x0;
18623 pInquiry[58] = 0x0;
18624 pInquiry[59] = 0x0;
18626 /* Identify Device */
18627 osti_memcpy(&pInquiry[60], pSimpleData, sizeof(satSimpleSATAIdentifyData_t));
18631 /*****************************************************************************/
18632 /*! \brief SAT implementation for SCSI INQUIRY page 0.
18634 * SAT implementation for SCSI INQUIRY page 0.
18636 * \param pInquiry: Pointer to Inquiry Data buffer.
18637 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data.
18641 /*****************************************************************************/
18642 GLOBAL void satInquiryPage80(
18644 agsaSATAIdentifyData_t *pSATAIdData)
18647 TI_DBG5(("satInquiryPage80: entry\n"));
18650 See SPC-4, 7.6.9, p 345
18651 and SAT revision 8, 10.3.3, p 77
18653 pInquiry[0] = 0x00;
18654 pInquiry[1] = 0x80; /* page code */
18655 pInquiry[2] = 0x00; /* reserved */
18656 pInquiry[3] = 0x14; /* page length */
18658 /* supported vpd page list */
18659 pInquiry[4] = pSATAIdData->serialNumber[1];
18660 pInquiry[5] = pSATAIdData->serialNumber[0];
18661 pInquiry[6] = pSATAIdData->serialNumber[3];
18662 pInquiry[7] = pSATAIdData->serialNumber[2];
18663 pInquiry[8] = pSATAIdData->serialNumber[5];
18664 pInquiry[9] = pSATAIdData->serialNumber[4];
18665 pInquiry[10] = pSATAIdData->serialNumber[7];
18666 pInquiry[11] = pSATAIdData->serialNumber[6];
18667 pInquiry[12] = pSATAIdData->serialNumber[9];
18668 pInquiry[13] = pSATAIdData->serialNumber[8];
18669 pInquiry[14] = pSATAIdData->serialNumber[11];
18670 pInquiry[15] = pSATAIdData->serialNumber[10];
18671 pInquiry[16] = pSATAIdData->serialNumber[13];
18672 pInquiry[17] = pSATAIdData->serialNumber[12];
18673 pInquiry[18] = pSATAIdData->serialNumber[15];
18674 pInquiry[19] = pSATAIdData->serialNumber[14];
18675 pInquiry[20] = pSATAIdData->serialNumber[17];
18676 pInquiry[21] = pSATAIdData->serialNumber[16];
18677 pInquiry[22] = pSATAIdData->serialNumber[19];
18678 pInquiry[23] = pSATAIdData->serialNumber[18];
18685 /*****************************************************************************/
18686 /*! \brief Send READ LOG EXT ATA PAGE 10h command to sata drive.
18688 * Send READ LOG EXT ATA command PAGE 10h request to LL layer.
18690 * \param tiRoot: Pointer to TISA initiator driver/port instance.
18691 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
18692 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
18693 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
18694 * \param satIOContext_t: Pointer to the SAT IO Context
18696 * \return If command is started successfully
18697 * - \e tiSuccess: I/O request successfully initiated.
18698 * - \e tiBusy: No resources available, try again later.
18699 * - \e tiIONoDevice: Invalid device handle.
18700 * - \e tiError: Other errors.
18702 /*****************************************************************************/
18703 GLOBAL bit32 satSendReadLogExt(
18705 tiIORequest_t *tiIORequest,
18706 tiDeviceHandle_t *tiDeviceHandle,
18707 tiScsiInitiatorRequest_t *tiScsiRequest,
18708 satIOContext_t *satIOContext)
18713 bit32 agRequestType;
18714 agsaFisRegHostToDevice_t *fis;
18716 fis = satIOContext->pFis;
18718 TI_DBG1(("satSendReadLogExt: tiDeviceHandle=%p tiIORequest=%p\n",
18719 tiDeviceHandle, tiIORequest));
18721 fis->h.fisType = 0x27; /* Reg host to device */
18722 fis->h.c_pmPort = 0x80; /* C Bit is set */
18723 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */
18724 fis->h.features = 0; /* FIS reserve */
18725 fis->d.lbaLow = 0x10; /* Page number */
18726 fis->d.lbaMid = 0; /* */
18727 fis->d.lbaHigh = 0; /* */
18728 fis->d.device = 0; /* DEV is ignored in SATA */
18729 fis->d.lbaLowExp = 0; /* */
18730 fis->d.lbaMidExp = 0; /* */
18731 fis->d.lbaHighExp = 0; /* */
18732 fis->d.featuresExp = 0; /* FIS reserve */
18733 fis->d.sectorCount = 0x01; /* 1 sector counts*/
18734 fis->d.sectorCountExp = 0x00; /* 1 sector counts */
18735 fis->d.reserved4 = 0;
18736 fis->d.control = 0; /* FIS HOB bit clear */
18737 fis->d.reserved5 = 0;
18739 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
18741 /* Initialize CB for SATA completion.
18743 satIOContext->satCompleteCB = &satReadLogExtCB;
18746 * Prepare SGL and send FIS to LL layer.
18748 satIOContext->reqType = agRequestType; /* Save it */
18750 status = sataLLIOStart( tiRoot,
18756 TI_DBG1(("satSendReadLogExt: end status %d\n", status));
18763 /*****************************************************************************/
18764 /*! \brief SAT default ATA status and ATA error translation to SCSI.
18766 * SSAT default ATA status and ATA error translation to SCSI.
18768 * \param tiRoot: Pointer to TISA initiator driver/port instance.
18769 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
18770 * \param satIOContext: Pointer to the SAT IO Context
18771 * \param pSense: Pointer to scsiRspSense_t
18772 * \param ataStatus: ATA status register
18773 * \param ataError: ATA error register
18774 * \param interruptContext: Interrupt context
18778 /*****************************************************************************/
18779 GLOBAL void osSatDefaultTranslation(
18781 tiIORequest_t *tiIORequest,
18782 satIOContext_t *satIOContext,
18783 scsiRspSense_t *pSense,
18786 bit32 interruptContext )
18790 * Check for device fault case
18792 if ( ataStatus & DF_ATA_STATUS_MASK )
18794 satSetSensePayload( pSense,
18795 SCSI_SNSKEY_HARDWARE_ERROR,
18797 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
18800 ostiInitiatorIOCompleted( tiRoot,
18803 SCSI_STAT_CHECK_CONDITION,
18804 satIOContext->pTiSenseData,
18805 interruptContext );
18810 * If status error bit it set, need to check the error register
18812 if ( ataStatus & ERR_ATA_STATUS_MASK )
18814 if ( ataError & NM_ATA_ERROR_MASK )
18816 TI_DBG1(("osSatDefaultTranslation: NM_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18817 ataError, tiIORequest));
18818 satSetSensePayload( pSense,
18819 SCSI_SNSKEY_NOT_READY,
18821 SCSI_SNSCODE_MEDIUM_NOT_PRESENT,
18825 else if (ataError & UNC_ATA_ERROR_MASK)
18827 TI_DBG1(("osSatDefaultTranslation: UNC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18828 ataError, tiIORequest));
18829 satSetSensePayload( pSense,
18830 SCSI_SNSKEY_MEDIUM_ERROR,
18832 SCSI_SNSCODE_UNRECOVERED_READ_ERROR,
18836 else if (ataError & IDNF_ATA_ERROR_MASK)
18838 TI_DBG1(("osSatDefaultTranslation: IDNF_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18839 ataError, tiIORequest));
18840 satSetSensePayload( pSense,
18841 SCSI_SNSKEY_MEDIUM_ERROR,
18843 SCSI_SNSCODE_RECORD_NOT_FOUND,
18847 else if (ataError & MC_ATA_ERROR_MASK)
18849 TI_DBG1(("osSatDefaultTranslation: MC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18850 ataError, tiIORequest));
18851 satSetSensePayload( pSense,
18852 SCSI_SNSKEY_UNIT_ATTENTION,
18854 SCSI_SNSCODE_NOT_READY_TO_READY_CHANGE,
18858 else if (ataError & MCR_ATA_ERROR_MASK)
18860 TI_DBG1(("osSatDefaultTranslation: MCR_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18861 ataError, tiIORequest));
18862 satSetSensePayload( pSense,
18863 SCSI_SNSKEY_UNIT_ATTENTION,
18865 SCSI_SNSCODE_OPERATOR_MEDIUM_REMOVAL_REQUEST,
18869 else if (ataError & ICRC_ATA_ERROR_MASK)
18871 TI_DBG1(("osSatDefaultTranslation: ICRC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18872 ataError, tiIORequest));
18873 satSetSensePayload( pSense,
18874 SCSI_SNSKEY_ABORTED_COMMAND,
18876 SCSI_SNSCODE_INFORMATION_UNIT_CRC_ERROR,
18880 else if (ataError & ABRT_ATA_ERROR_MASK)
18882 TI_DBG1(("osSatDefaultTranslation: ABRT_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18883 ataError, tiIORequest));
18884 satSetSensePayload( pSense,
18885 SCSI_SNSKEY_ABORTED_COMMAND,
18887 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
18893 TI_DBG1(("osSatDefaultTranslation: **** UNEXPECTED ATA_ERROR **** ataError= 0x%x, tiIORequest=%p\n",
18894 ataError, tiIORequest));
18895 satSetSensePayload( pSense,
18896 SCSI_SNSKEY_HARDWARE_ERROR,
18898 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
18902 /* Send the completion response now */
18903 ostiInitiatorIOCompleted( tiRoot,
18906 SCSI_STAT_CHECK_CONDITION,
18907 satIOContext->pTiSenseData,
18908 interruptContext );
18914 else /* (ataStatus & ERR_ATA_STATUS_MASK ) is false */
18916 /* This case should never happen */
18917 TI_DBG1(("osSatDefaultTranslation: *** UNEXPECTED ATA status 0x%x *** tiIORequest=%p\n",
18918 ataStatus, tiIORequest));
18919 satSetSensePayload( pSense,
18920 SCSI_SNSKEY_HARDWARE_ERROR,
18922 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
18925 ostiInitiatorIOCompleted( tiRoot,
18928 SCSI_STAT_CHECK_CONDITION,
18929 satIOContext->pTiSenseData,
18930 interruptContext );
18938 /*****************************************************************************/
18939 /*! \brief Allocate resource for SAT intervally generated I/O.
18941 * Allocate resource for SAT intervally generated I/O.
18943 * \param tiRoot: Pointer to TISA driver/port instance.
18944 * \param satDevData: Pointer to SAT specific device data.
18945 * \param allocLength: Length in byte of the DMA mem to allocate, upto
18947 * \param satIntIo: Pointer (output) to context for SAT internally
18948 * generated I/O that is allocated by this routine.
18950 * \return If command is started successfully
18951 * - \e tiSuccess: Success.
18952 * - \e tiError: Failed allocating resource.
18954 /*****************************************************************************/
18955 GLOBAL satInternalIo_t * satAllocIntIoResource(
18957 tiIORequest_t *tiIORequest,
18958 satDeviceData_t *satDevData,
18959 bit32 dmaAllocLength,
18960 satInternalIo_t *satIntIo)
18962 tdList_t *tdList = agNULL;
18963 bit32 memAllocStatus;
18965 TI_DBG1(("satAllocIntIoResource: start\n"));
18966 TI_DBG6(("satAllocIntIoResource: satIntIo %p\n", satIntIo));
18967 if (satDevData == agNULL)
18969 TI_DBG1(("satAllocIntIoResource: ***** ASSERT satDevData is null\n"));
18973 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
18974 if (!TDLIST_EMPTY(&(satDevData->satFreeIntIoLinkList)))
18976 TDLIST_DEQUEUE_FROM_HEAD(&tdList, &(satDevData->satFreeIntIoLinkList));
18980 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
18981 TI_DBG1(("satAllocIntIoResource() no more internal free link.\n"));
18985 if (tdList == agNULL)
18987 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
18988 TI_DBG1(("satAllocIntIoResource() FAIL to alloc satIntIo.\n"));
18992 satIntIo = TDLIST_OBJECT_BASE( satInternalIo_t, satIntIoLink, tdList);
18993 TI_DBG6(("satAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
18995 /* Put in active list */
18996 TDLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
18997 TDLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satActiveIntIoLinkList));
18998 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19001 /* Put in active list */
19002 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19003 TDLIST_DEQUEUE_THIS (tdList);
19004 TDLIST_ENQUEUE_AT_TAIL (tdList, &(satDevData->satActiveIntIoLinkList));
19005 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19007 satIntIo = TDLIST_OBJECT_BASE( satInternalIo_t, satIntIoLink, tdList);
19008 TI_DBG6(("satAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
19014 tdList_t satIntIoLink;
19015 tiIORequest_t satIntTiIORequest;
19016 void *satIntRequestBody;
19017 tiScsiInitiatorRequest_t satIntTiScsiXchg;
19018 tiMem_t satIntDmaMem;
19019 tiMem_t satIntReqBodyMem;
19025 * Allocate mem for Request Body
19027 satIntIo->satIntReqBodyMem.totalLength = sizeof(tdIORequestBody_t);
19029 memAllocStatus = ostiAllocMemory( tiRoot,
19030 &satIntIo->satIntReqBodyMem.osHandle,
19031 (void **)&satIntIo->satIntRequestBody,
19032 &satIntIo->satIntReqBodyMem.physAddrUpper,
19033 &satIntIo->satIntReqBodyMem.physAddrLower,
19035 satIntIo->satIntReqBodyMem.totalLength,
19038 if (memAllocStatus != tiSuccess)
19040 TI_DBG1(("satAllocIntIoResource() FAIL to alloc mem for Req Body.\n"));
19042 * Return satIntIo to the free list
19044 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19045 TDLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
19046 TDLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
19047 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19053 * Allocate DMA memory if required
19055 if (dmaAllocLength != 0)
19057 satIntIo->satIntDmaMem.totalLength = dmaAllocLength;
19059 memAllocStatus = ostiAllocMemory( tiRoot,
19060 &satIntIo->satIntDmaMem.osHandle,
19061 (void **)&satIntIo->satIntDmaMem.virtPtr,
19062 &satIntIo->satIntDmaMem.physAddrUpper,
19063 &satIntIo->satIntDmaMem.physAddrLower,
19065 satIntIo->satIntDmaMem.totalLength,
19067 TI_DBG6(("satAllocIntIoResource: len %d \n", satIntIo->satIntDmaMem.totalLength));
19068 TI_DBG6(("satAllocIntIoResource: pointer %p \n", satIntIo->satIntDmaMem.osHandle));
19070 if (memAllocStatus != tiSuccess)
19072 TI_DBG1(("satAllocIntIoResource() FAIL to alloc mem for DMA mem.\n"));
19074 * Return satIntIo to the free list
19076 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19077 TDLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
19078 TDLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
19079 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19082 * Free mem allocated for Req body
19084 ostiFreeMemory( tiRoot,
19085 satIntIo->satIntReqBodyMem.osHandle,
19086 satIntIo->satIntReqBodyMem.totalLength);
19095 tdList_t satIntIoLink;
19096 tiIORequest_t satIntTiIORequest;
19097 void *satIntRequestBody;
19098 tiScsiInitiatorRequest_t satIntTiScsiXchg;
19099 tiMem_t satIntDmaMem;
19100 tiMem_t satIntReqBodyMem;
19106 * Initialize satIntTiIORequest field
19108 satIntIo->satIntTiIORequest.osData = agNULL; /* Not used for internal SAT I/O */
19109 satIntIo->satIntTiIORequest.tdData = satIntIo->satIntRequestBody;
19112 * saves the original tiIOrequest
19114 satIntIo->satOrgTiIORequest = tiIORequest;
19116 typedef struct tiIniScsiCmnd
19119 bit32 expDataLength;
19120 bit32 taskAttribute;
19125 typedef struct tiScsiInitiatorExchange
19127 void *sglVirtualAddr;
19128 tiIniScsiCmnd_t scsiCmnd;
19131 tiDataDirection_t dataDirection;
19132 } tiScsiInitiatorRequest_t;
19137 * Initialize satIntTiScsiXchg. Since the internal SAT request is NOT
19138 * originated from SCSI request, only the following fields are initialized:
19139 * - sglVirtualAddr if DMA transfer is involved
19140 * - agSgl1 if DMA transfer is involved
19141 * - expDataLength in scsiCmnd since this field is read by sataLLIOStart()
19143 if (dmaAllocLength != 0)
19145 satIntIo->satIntTiScsiXchg.sglVirtualAddr = satIntIo->satIntDmaMem.virtPtr;
19147 OSSA_WRITE_LE_32(agNULL, &satIntIo->satIntTiScsiXchg.agSgl1.len, 0,
19148 satIntIo->satIntDmaMem.totalLength);
19149 satIntIo->satIntTiScsiXchg.agSgl1.lower = satIntIo->satIntDmaMem.physAddrLower;
19150 satIntIo->satIntTiScsiXchg.agSgl1.upper = satIntIo->satIntDmaMem.physAddrUpper;
19151 satIntIo->satIntTiScsiXchg.agSgl1.type = tiSgl;
19153 satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = satIntIo->satIntDmaMem.totalLength;
19157 satIntIo->satIntTiScsiXchg.sglVirtualAddr = agNULL;
19159 satIntIo->satIntTiScsiXchg.agSgl1.len = 0;
19160 satIntIo->satIntTiScsiXchg.agSgl1.lower = 0;
19161 satIntIo->satIntTiScsiXchg.agSgl1.upper = 0;
19162 satIntIo->satIntTiScsiXchg.agSgl1.type = tiSgl;
19164 satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = 0;
19167 TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.len %d\n", satIntIo->satIntTiScsiXchg.agSgl1.len));
19169 TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.upper %d\n", satIntIo->satIntTiScsiXchg.agSgl1.upper));
19171 TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.lower %d\n", satIntIo->satIntTiScsiXchg.agSgl1.lower));
19173 TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.type %d\n", satIntIo->satIntTiScsiXchg.agSgl1.type));
19174 TI_DBG5(("satAllocIntIoResource: return satIntIo %p\n", satIntIo));
19179 /*****************************************************************************/
19180 /*! \brief Free resource for SAT intervally generated I/O.
19182 * Free resource for SAT intervally generated I/O that was previously
19183 * allocated in satAllocIntIoResource().
19185 * \param tiRoot: Pointer to TISA driver/port instance.
19186 * \param satDevData: Pointer to SAT specific device data.
19187 * \param satIntIo: Pointer to context for SAT internal I/O that was
19188 * previously allocated in satAllocIntIoResource().
19192 /*****************************************************************************/
19193 GLOBAL void satFreeIntIoResource(
19195 satDeviceData_t *satDevData,
19196 satInternalIo_t *satIntIo)
19198 TI_DBG6(("satFreeIntIoResource: start\n"));
19200 if (satIntIo == agNULL)
19202 TI_DBG6(("satFreeIntIoResource: allowed call\n"));
19206 /* sets the original tiIOrequest to agNULL for internally generated ATA cmnd */
19207 satIntIo->satOrgTiIORequest = agNULL;
19210 * Free DMA memory if previosly alocated
19212 if (satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength != 0)
19214 TI_DBG1(("satFreeIntIoResource: DMA len %d\n", satIntIo->satIntDmaMem.totalLength));
19215 TI_DBG6(("satFreeIntIoResource: pointer %p\n", satIntIo->satIntDmaMem.osHandle));
19217 ostiFreeMemory( tiRoot,
19218 satIntIo->satIntDmaMem.osHandle,
19219 satIntIo->satIntDmaMem.totalLength);
19220 satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = 0;
19223 if (satIntIo->satIntReqBodyMem.totalLength != 0)
19225 TI_DBG1(("satFreeIntIoResource: req body len %d\n", satIntIo->satIntReqBodyMem.totalLength));
19227 * Free mem allocated for Req body
19229 ostiFreeMemory( tiRoot,
19230 satIntIo->satIntReqBodyMem.osHandle,
19231 satIntIo->satIntReqBodyMem.totalLength);
19233 satIntIo->satIntReqBodyMem.totalLength = 0;
19236 TI_DBG6(("satFreeIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
19238 * Return satIntIo to the free list
19240 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19241 TDLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
19242 TDLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satFreeIntIoLinkList));
19243 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19248 /*****************************************************************************/
19249 /*! \brief SAT implementation for SCSI INQUIRY.
19251 * SAT implementation for SCSI INQUIRY.
19252 * This function sends ATA Identify Device data command for SCSI INQUIRY
19254 * \param tiRoot: Pointer to TISA initiator driver/port instance.
19255 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
19256 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
19257 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
19258 * \param satIOContext_t: Pointer to the SAT IO Context
19260 * \return If command is started successfully
19261 * - \e tiSuccess: I/O request successfully initiated.
19262 * - \e tiBusy: No resources available, try again later.
19263 * - \e tiIONoDevice: Invalid device handle.
19264 * - \e tiError: Other errors.
19266 /*****************************************************************************/
19267 GLOBAL bit32 satSendIDDev(
19269 tiIORequest_t *tiIORequest,
19270 tiDeviceHandle_t *tiDeviceHandle,
19271 tiScsiInitiatorRequest_t *tiScsiRequest,
19272 satIOContext_t *satIOContext)
19276 bit32 agRequestType;
19277 satDeviceData_t *pSatDevData;
19278 agsaFisRegHostToDevice_t *fis;
19279 #ifdef TD_DEBUG_ENABLE
19280 satInternalIo_t *satIntIoContext;
19281 tdsaDeviceData_t *oneDeviceData;
19282 tdIORequestBody_t *tdIORequestBody;
19285 pSatDevData = satIOContext->pSatDevData;
19286 fis = satIOContext->pFis;
19288 TI_DBG5(("satSendIDDev: start\n"));
19289 #ifdef TD_DEBUG_ENABLE
19290 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
19292 TI_DBG5(("satSendIDDev: did %d\n", oneDeviceData->id));
19295 #ifdef TD_DEBUG_ENABLE
19296 satIntIoContext = satIOContext->satIntIoContext;
19297 tdIORequestBody = satIntIoContext->satIntRequestBody;
19300 TI_DBG5(("satSendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
19302 fis->h.fisType = 0x27; /* Reg host to device */
19303 fis->h.c_pmPort = 0x80; /* C Bit is set */
19304 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
19305 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0x40 */
19307 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */
19308 fis->h.features = 0; /* FIS reserve */
19309 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
19310 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
19311 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
19312 fis->d.device = 0; /* FIS LBA mode */
19313 fis->d.lbaLowExp = 0;
19314 fis->d.lbaMidExp = 0;
19315 fis->d.lbaHighExp = 0;
19316 fis->d.featuresExp = 0;
19317 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
19318 fis->d.sectorCountExp = 0;
19319 fis->d.reserved4 = 0;
19320 fis->d.control = 0; /* FIS HOB bit clear */
19321 fis->d.reserved5 = 0;
19323 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
19325 /* Initialize CB for SATA completion.
19327 satIOContext->satCompleteCB = &satInquiryCB;
19330 * Prepare SGL and send FIS to LL layer.
19332 satIOContext->reqType = agRequestType; /* Save it */
19334 #ifdef TD_INTERNAL_DEBUG
19335 tdhexdump("satSendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
19336 #ifdef TD_DEBUG_ENABLE
19337 tdhexdump("satSendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
19341 status = sataLLIOStart( tiRoot,
19347 TI_DBG6(("satSendIDDev: end status %d\n", status));
19352 /*****************************************************************************/
19353 /*! \brief SAT implementation for SCSI INQUIRY.
19355 * SAT implementation for SCSI INQUIRY.
19356 * This function prepares TD layer internal resource to send ATA
19357 * Identify Device data command for SCSI INQUIRY
19359 * \param tiRoot: Pointer to TISA initiator driver/port instance.
19360 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
19361 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
19362 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
19363 * \param satIOContext_t: Pointer to the SAT IO Context
19365 * \return If command is started successfully
19366 * - \e tiSuccess: I/O request successfully initiated.
19367 * - \e tiBusy: No resources available, try again later.
19368 * - \e tiIONoDevice: Invalid device handle.
19369 * - \e tiError: Other errors.
19371 /*****************************************************************************/
19372 /* prerequsite: tdsaDeviceData and agdevhandle must exist; in other words, LL discovered the device
19375 convert OS generated IO to TD generated IO due to difference in sgl
19377 GLOBAL bit32 satStartIDDev(
19379 tiIORequest_t *tiIORequest,
19380 tiDeviceHandle_t *tiDeviceHandle,
19381 tiScsiInitiatorRequest_t *tiScsiRequest,
19382 satIOContext_t *satIOContext
19385 satInternalIo_t *satIntIo = agNULL;
19386 satDeviceData_t *satDevData = agNULL;
19387 tdIORequestBody_t *tdIORequestBody;
19388 satIOContext_t *satNewIOContext;
19391 TI_DBG6(("satStartIDDev: start\n"));
19393 satDevData = satIOContext->pSatDevData;
19395 TI_DBG6(("satStartIDDev: before alloc\n"));
19397 /* allocate identify device command */
19398 satIntIo = satAllocIntIoResource( tiRoot,
19401 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
19404 TI_DBG6(("satStartIDDev: before after\n"));
19406 if (satIntIo == agNULL)
19408 TI_DBG1(("satStartIDDev: can't alloacate\n"));
19411 ostiInitiatorIOCompleted (
19415 tiDetailOtherError,
19417 satIOContext->interruptContext
19424 /* fill in fields */
19425 /* real ttttttthe one worked and the same; 5/21/07/ */
19426 satIntIo->satOrgTiIORequest = tiIORequest; /* changed */
19427 tdIORequestBody = satIntIo->satIntRequestBody;
19428 satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
19430 satNewIOContext->pSatDevData = satDevData;
19431 satNewIOContext->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
19432 satNewIOContext->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
19433 satNewIOContext->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
19434 satNewIOContext->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
19435 satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */
19436 satNewIOContext->interruptContext = tiInterruptContext;
19437 satNewIOContext->satIntIoContext = satIntIo;
19439 satNewIOContext->ptiDeviceHandle = agNULL;
19440 satNewIOContext->satOrgIOContext = satIOContext; /* changed */
19442 /* this is valid only for TD layer generated (not triggered by OS at all) IO */
19443 satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
19446 TI_DBG6(("satStartIDDev: OS satIOContext %p \n", satIOContext));
19447 TI_DBG6(("satStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
19448 TI_DBG6(("satStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
19449 TI_DBG6(("satStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
19453 TI_DBG1(("satStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
19455 status = satSendIDDev( tiRoot,
19456 &satIntIo->satIntTiIORequest, /* New tiIORequest */
19458 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
19461 if (status != tiSuccess)
19463 TI_DBG1(("satStartIDDev: failed in sending\n"));
19465 satFreeIntIoResource( tiRoot,
19470 ostiInitiatorIOCompleted (
19474 tiDetailOtherError,
19476 satIOContext->interruptContext
19484 TI_DBG6(("satStartIDDev: end\n"));
19491 /*****************************************************************************/
19492 /*! \brief satComputeCDB10LBA.
19494 * This fuctions computes LBA of CDB10.
19496 * \param satIOContext_t: Pointer to the SAT IO Context
19501 /*****************************************************************************/
19502 bit32 satComputeCDB10LBA(satIOContext_t *satIOContext)
19504 tiIniScsiCmnd_t *scsiCmnd;
19505 tiScsiInitiatorRequest_t *tiScsiRequest;
19508 TI_DBG5(("satComputeCDB10LBA: start\n"));
19509 tiScsiRequest = satIOContext->tiScsiXchg;
19510 scsiCmnd = &(tiScsiRequest->scsiCmnd);
19512 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
19513 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
19518 /*****************************************************************************/
19519 /*! \brief satComputeCDB10TL.
19521 * This fuctions computes transfer length of CDB10.
19523 * \param satIOContext_t: Pointer to the SAT IO Context
19528 /*****************************************************************************/
19529 bit32 satComputeCDB10TL(satIOContext_t *satIOContext)
19532 tiIniScsiCmnd_t *scsiCmnd;
19533 tiScsiInitiatorRequest_t *tiScsiRequest;
19536 TI_DBG5(("satComputeCDB10TL: start\n"));
19537 tiScsiRequest = satIOContext->tiScsiXchg;
19538 scsiCmnd = &(tiScsiRequest->scsiCmnd);
19540 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
19544 /*****************************************************************************/
19545 /*! \brief satComputeCDB12LBA.
19547 * This fuctions computes LBA of CDB12.
19549 * \param satIOContext_t: Pointer to the SAT IO Context
19554 /*****************************************************************************/
19555 bit32 satComputeCDB12LBA(satIOContext_t *satIOContext)
19557 tiIniScsiCmnd_t *scsiCmnd;
19558 tiScsiInitiatorRequest_t *tiScsiRequest;
19561 TI_DBG5(("satComputeCDB10LBA: start\n"));
19562 tiScsiRequest = satIOContext->tiScsiXchg;
19563 scsiCmnd = &(tiScsiRequest->scsiCmnd);
19565 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
19566 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
19571 /*****************************************************************************/
19572 /*! \brief satComputeCDB12TL.
19574 * This fuctions computes transfer length of CDB12.
19576 * \param satIOContext_t: Pointer to the SAT IO Context
19581 /*****************************************************************************/
19582 bit32 satComputeCDB12TL(satIOContext_t *satIOContext)
19585 tiIniScsiCmnd_t *scsiCmnd;
19586 tiScsiInitiatorRequest_t *tiScsiRequest;
19589 TI_DBG5(("satComputeCDB10TL: start\n"));
19590 tiScsiRequest = satIOContext->tiScsiXchg;
19591 scsiCmnd = &(tiScsiRequest->scsiCmnd);
19593 tl = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
19594 + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
19599 /*****************************************************************************/
19600 /*! \brief satComputeCDB16LBA.
19602 * This fuctions computes LBA of CDB16.
19604 * \param satIOContext_t: Pointer to the SAT IO Context
19609 /*****************************************************************************/
19611 CBD16 has bit64 LBA
19612 But it has to be less than (2^28 - 1)
19613 Therefore, use last four bytes to compute LBA is OK
19615 bit32 satComputeCDB16LBA(satIOContext_t *satIOContext)
19617 tiIniScsiCmnd_t *scsiCmnd;
19618 tiScsiInitiatorRequest_t *tiScsiRequest;
19621 TI_DBG5(("satComputeCDB10LBA: start\n"));
19622 tiScsiRequest = satIOContext->tiScsiXchg;
19623 scsiCmnd = &(tiScsiRequest->scsiCmnd);
19625 lba = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
19626 + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
19631 /*****************************************************************************/
19632 /*! \brief satComputeCDB16TL.
19634 * This fuctions computes transfer length of CDB16.
19636 * \param satIOContext_t: Pointer to the SAT IO Context
19641 /*****************************************************************************/
19642 bit32 satComputeCDB16TL(satIOContext_t *satIOContext)
19645 tiIniScsiCmnd_t *scsiCmnd;
19646 tiScsiInitiatorRequest_t *tiScsiRequest;
19649 TI_DBG5(("satComputeCDB10TL: start\n"));
19650 tiScsiRequest = satIOContext->tiScsiXchg;
19651 scsiCmnd = &(tiScsiRequest->scsiCmnd);
19653 tl = (scsiCmnd->cdb[10] << (8*3)) + (scsiCmnd->cdb[11] << (8*2))
19654 + (scsiCmnd->cdb[12] << 8) + scsiCmnd->cdb[13];
19658 /*****************************************************************************/
19659 /*! \brief satComputeLoopNum.
19661 * This fuctions computes the number of interation needed for a transfer
19662 * length with a specific number.
19664 * \param a: a numerator
19665 * \param b: a denominator
19668 * - \e number of interation
19670 /*****************************************************************************/
19673 tl can be upto bit32 because CDB16 has bit32 tl
19675 either (tl, 0xFF) or (tl, 0xFFFF)
19677 bit32 satComputeLoopNum(bit32 a, bit32 b)
19680 bit32 quo = 0, rem = 0;
19683 TI_DBG5(("satComputeLoopNum: start\n"));
19707 /*****************************************************************************/
19708 /*! \brief satAddNComparebit64.
19717 * - \e TRUE if (lba + tl > SAT_TR_LBA_LIMIT)
19718 * - \e FALSE otherwise
19719 * \note: a and b must be in the same length
19721 /*****************************************************************************/
19723 input: bit8 a[8], bit8 b[8] (lba, tl) must be in same length
19724 if (lba + tl > SAT_TR_LBA_LIMIT)
19729 bit32 satAddNComparebit64(bit8 *a, bit8 *b)
19731 bit16 ans[8]; // 0 MSB, 8 LSB
19732 bit8 final_ans[9]; // 0 MSB, 9 LSB
19736 TI_DBG5(("satAddNComparebit64: start\n"));
19738 osti_memset(ans, 0, sizeof(ans));
19739 osti_memset(final_ans, 0, sizeof(final_ans));
19740 osti_memset(max, 0, sizeof(max));
19742 max[0] = 0x1; //max = 0x1 0000 0000 0000 0000
19744 // adding from LSB to MSB
19747 ans[i] = (bit16)(a[i] + b[i]);
19750 ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
19755 filling in the final answer
19757 final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
19758 final_ans[1] = (bit8)(ans[0] & 0xFF);
19762 final_ans[i] = (bit8)(ans[i-1] & 0xFF);
19765 //compare final_ans to max
19768 if (final_ans[i] > max[i])
19770 TI_DBG5(("satAddNComparebit64: yes at %d\n", i));
19773 else if (final_ans[i] < max[i])
19775 TI_DBG5(("satAddNComparebit64: no at %d\n", i));
19788 /*****************************************************************************/
19789 /*! \brief satAddNComparebit32.
19798 * - \e TRUE if (lba + tl > SAT_TR_LBA_LIMIT)
19799 * - \e FALSE otherwise
19800 * \note: a and b must be in the same length
19802 /*****************************************************************************/
19804 input: bit8 a[4], bit8 b[4] (lba, tl) must be in same length
19805 if (lba + tl > SAT_TR_LBA_LIMIT)
19810 bit32 satAddNComparebit32(bit8 *a, bit8 *b)
19812 bit16 ans[4]; // 0 MSB, 4 LSB
19813 bit8 final_ans[5]; // 0 MSB, 5 LSB
19817 TI_DBG5(("satAddNComparebit32: start\n"));
19819 osti_memset(ans, 0, sizeof(ans));
19820 osti_memset(final_ans, 0, sizeof(final_ans));
19821 osti_memset(max, 0, sizeof(max));
19823 max[0] = 0x10; // max =0x1000 0000
19825 // adding from LSB to MSB
19828 ans[i] = (bit16)(a[i] + b[i]);
19831 ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
19837 filling in the final answer
19839 final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
19840 final_ans[1] = (bit8)(ans[0] & 0xFF);
19844 final_ans[i] = (bit8)(ans[i-1] & 0xFF);
19847 //compare final_ans to max
19848 if (final_ans[0] != 0)
19850 TI_DBG5(("satAddNComparebit32: yes bigger and out of range\n"));
19855 if (final_ans[i] > max[i-1])
19857 TI_DBG5(("satAddNComparebit32: yes at %d\n", i));
19860 else if (final_ans[i] < max[i-1])
19862 TI_DBG5(("satAddNComparebit32: no at %d\n", i));
19875 /*****************************************************************************/
19876 /*! \brief satCompareLBALimitbit.
19884 * - \e TRUE if (lba > SAT_TR_LBA_LIMIT - 1)
19885 * - \e FALSE otherwise
19886 * \note: a and b must be in the same length
19888 /*****************************************************************************/
19895 if (lba > SAT_TR_LBA_LIMIT - 1)
19900 bit32 satCompareLBALimitbit(bit8 *lba)
19905 /* limit is 0xF FF FF = 2^28 - 1 */
19906 limit[0] = 0x0; /* MSB */
19913 limit[7] = 0xFF; /* LSB */
19915 //compare lba to limit
19918 if (lba[i] > limit[i])
19920 TI_DBG5(("satCompareLBALimitbit64: yes at %d\n", i));
19923 else if (lba[i] < limit[i])
19925 TI_DBG5(("satCompareLBALimitbit64: no at %d\n", i));
19938 /*****************************************************************************
19940 * Purpose: bitwise set
19943 * data - input output buffer
19944 * index - bit to set
19949 *****************************************************************************/
19951 satBitSet(bit8 *data, bit32 index)
19953 data[index/8] |= (1 << (index%8));
19956 /*****************************************************************************
19958 * Purpose: bitwise clear
19961 * data - input output buffer
19962 * index - bit to clear
19967 *****************************************************************************/
19969 satBitClear(bit8 *data, bit32 index)
19971 data[index/8] &= ~(1 << (index%8));
19974 /*****************************************************************************
19976 * Purpose: bitwise test
19979 * data - input output buffer
19980 * index - bit to test
19986 *****************************************************************************/
19988 satBitTest(bit8 *data, bit32 index)
19990 return ( (BOOLEAN)((data[index/8] & (1 << (index%8)) ) ? 1: 0));
19994 /******************************************************************************/
19995 /*! \brief allocate an available SATA tag
19997 * allocate an available SATA tag
19999 * \param tiRoot Pointer to TISA initiator driver/port instance.
20000 * \param pSatDevData
20003 * \return -Success or fail-
20005 /*******************************************************************************/
20006 GLOBAL bit32 satTagAlloc(
20008 satDeviceData_t *pSatDevData,
20012 bit32 retCode = agFALSE;
20015 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
20016 for ( i = 0; i < pSatDevData->satNCQMaxIO; i ++ )
20018 if ( 0 == satBitTest((bit8 *)&pSatDevData->freeSATAFDMATagBitmap, i) )
20020 satBitSet((bit8*)&pSatDevData->freeSATAFDMATagBitmap, i);
20026 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
20030 /******************************************************************************/
20031 /*! \brief release an SATA tag
20033 * release an available SATA tag
20035 * \param tiRoot Pointer to TISA initiator driver/port instance.
20036 * \param pSatDevData
20039 * \return -the tag-
20041 /*******************************************************************************/
20042 GLOBAL bit32 satTagRelease(
20044 satDeviceData_t *pSatDevData,
20048 bit32 retCode = agFALSE;
20050 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
20051 if ( tag < pSatDevData->satNCQMaxIO )
20053 satBitClear( (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, (bit32)tag);
20056 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
20060 /*****************************************************************************
20063 * This routine is called to initiate a TM request to SATL.
20064 * This routine is independent of HW/LL API.
20066 * \param tiRoot: Pointer to TISA initiator driver/port instance.
20067 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
20068 * \param task: SAM-3 task management request.
20069 * \param lun: Pointer to LUN.
20070 * \param taskTag: Pointer to the associated task where the TM
20071 * command is to be applied.
20072 * \param currentTaskTag: Pointer to tag/context for this TM request.
20073 * \param NotifyOS flag determines whether notify OS layer or not
20077 * \e tiSuccess: I/O request successfully initiated.
20078 * \e tiBusy: No resources available, try again later.
20079 * \e tiIONoDevice: Invalid device handle.
20080 * \e tiError: Other errors that prevent the I/O request to be started.
20083 * This funcion is triggered bottom up. Not yet in use.
20084 *****************************************************************************/
20085 /* called for bottom up */
20086 osGLOBAL bit32 satSubTM(
20088 tiDeviceHandle_t *tiDeviceHandle,
20091 tiIORequest_t *taskTag,
20092 tiIORequest_t *currentTaskTag,
20097 tdIORequestBody_t *TMtdIORequestBody;
20100 bit32 memAllocStatus;
20101 agsaIORequest_t *agIORequest = agNULL;
20103 TI_DBG6(("satSubTM: start\n"));
20105 /* allocation tdIORequestBody and pass it to satTM() */
20106 memAllocStatus = ostiAllocMemory(
20109 (void **)&TMtdIORequestBody,
20113 sizeof(tdIORequestBody_t),
20117 if (memAllocStatus != tiSuccess)
20119 TI_DBG1(("satSubTM: ostiAllocMemory failed... \n"));
20123 if (TMtdIORequestBody == agNULL)
20125 TI_DBG1(("satSubTM: ostiAllocMemory returned NULL TMIORequestBody\n"));
20129 /* setup task management structure */
20130 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
20131 TMtdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = agNULL;
20132 TMtdIORequestBody->IOType.InitiatorTMIO.TaskTag = agNULL;
20134 /* initialize tiDevhandle */
20135 TMtdIORequestBody->tiDevHandle = tiDeviceHandle;
20137 /* initialize tiIORequest */
20138 TMtdIORequestBody->tiIORequest = agNULL;
20140 /* initialize agIORequest */
20141 agIORequest = &(TMtdIORequestBody->agIORequest);
20142 agIORequest->osData = (void *) TMtdIORequestBody;
20143 agIORequest->sdkData = agNULL; /* SA takes care of this */
20146 task, /* TD_INTERNAL_TM_RESET */
20157 /*****************************************************************************/
20158 /*! \brief SAT implementation for satStartResetDevice.
20160 * SAT implementation for sending SRT and send FIS request to LL layer.
20162 * \param tiRoot: Pointer to TISA initiator driver/port instance.
20163 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
20164 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
20165 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
20166 * \param satIOContext_t: Pointer to the SAT IO Context
20168 * \return If command is started successfully
20169 * - \e tiSuccess: I/O request successfully initiated.
20170 * - \e tiBusy: No resources available, try again later.
20171 * - \e tiIONoDevice: Invalid device handle.
20172 * - \e tiError: Other errors.
20173 * \note : triggerred by OS layer or bottom up
20175 /*****************************************************************************/
20176 /* OS triggerred or bottom up */
20178 satStartResetDevice(
20180 tiIORequest_t *tiIORequest, /* currentTaskTag */
20181 tiDeviceHandle_t *tiDeviceHandle,
20182 tiScsiInitiatorRequest_t *tiScsiRequest, /* should be NULL */
20183 satIOContext_t *satIOContext
20186 satInternalIo_t *satIntIo = agNULL;
20187 satDeviceData_t *satDevData = agNULL;
20188 satIOContext_t *satNewIOContext;
20190 tiIORequest_t *currentTaskTag = agNULL;
20192 TI_DBG1(("satStartResetDevice: start\n"));
20194 currentTaskTag = tiIORequest;
20196 satDevData = satIOContext->pSatDevData;
20198 TI_DBG6(("satStartResetDevice: before alloc\n"));
20200 /* allocate any fis for seting SRT bit in device control */
20201 satIntIo = satAllocIntIoResource( tiRoot,
20207 TI_DBG6(("satStartResetDevice: before after\n"));
20209 if (satIntIo == agNULL)
20211 TI_DBG1(("satStartResetDevice: can't alloacate\n"));
20212 if (satIOContext->NotifyOS)
20214 ostiInitiatorEvent( tiRoot,
20217 tiIntrEventTypeTaskManagement,
20224 satNewIOContext = satPrepareNewIO(satIntIo,
20230 TI_DBG6(("satStartResetDevice: OS satIOContext %p \n", satIOContext));
20231 TI_DBG6(("satStartResetDevice: TD satNewIOContext %p \n", satNewIOContext));
20232 TI_DBG6(("satStartResetDevice: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
20233 TI_DBG6(("satStartResetDevice: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
20237 TI_DBG6(("satStartResetDevice: satNewIOContext %p \n", satNewIOContext));
20239 if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
20241 status = satDeviceReset(tiRoot,
20242 &satIntIo->satIntTiIORequest, /* New tiIORequest */
20244 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
20249 status = satResetDevice(tiRoot,
20250 &satIntIo->satIntTiIORequest, /* New tiIORequest */
20252 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
20256 if (status != tiSuccess)
20258 TI_DBG1(("satStartResetDevice: failed in sending\n"));
20260 satFreeIntIoResource( tiRoot,
20263 if (satIOContext->NotifyOS)
20265 ostiInitiatorEvent( tiRoot,
20268 tiIntrEventTypeTaskManagement,
20277 TI_DBG6(("satStartResetDevice: end\n"));
20282 /*****************************************************************************/
20283 /*! \brief SAT implementation for satResetDevice.
20285 * SAT implementation for building SRT FIS and sends the request to LL layer.
20287 * \param tiRoot: Pointer to TISA initiator driver/port instance.
20288 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
20289 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
20290 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
20291 * \param satIOContext_t: Pointer to the SAT IO Context
20293 * \return If command is started successfully
20294 * - \e tiSuccess: I/O request successfully initiated.
20295 * - \e tiBusy: No resources available, try again later.
20296 * - \e tiIONoDevice: Invalid device handle.
20297 * - \e tiError: Other errors.
20299 /*****************************************************************************/
20302 create any fis and set SRST bit in device control
20307 tiIORequest_t *tiIORequest,
20308 tiDeviceHandle_t *tiDeviceHandle,
20309 tiScsiInitiatorRequest_t *tiScsiRequest,
20310 satIOContext_t *satIOContext
20314 bit32 agRequestType;
20315 agsaFisRegHostToDevice_t *fis;
20316 #ifdef TD_DEBUG_ENABLE
20317 tdIORequestBody_t *tdIORequestBody;
20318 satInternalIo_t *satIntIoContext;
20321 fis = satIOContext->pFis;
20323 TI_DBG2(("satResetDevice: start\n"));
20325 #ifdef TD_DEBUG_ENABLE
20326 satIntIoContext = satIOContext->satIntIoContext;
20327 tdIORequestBody = satIntIoContext->satIntRequestBody;
20329 TI_DBG5(("satResetDevice: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
20330 /* any fis should work */
20331 fis->h.fisType = 0x27; /* Reg host to device */
20332 fis->h.c_pmPort = 0; /* C Bit is not set */
20333 fis->h.command = 0; /* any command */
20334 fis->h.features = 0; /* FIS reserve */
20335 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
20336 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
20337 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
20338 fis->d.device = 0; /* FIS LBA mode */
20339 fis->d.lbaLowExp = 0;
20340 fis->d.lbaMidExp = 0;
20341 fis->d.lbaHighExp = 0;
20342 fis->d.featuresExp = 0;
20343 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
20344 fis->d.sectorCountExp = 0;
20345 fis->d.reserved4 = 0;
20346 fis->d.control = 0x4; /* SRST bit is set */
20347 fis->d.reserved5 = 0;
20349 agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT;
20351 satIOContext->satCompleteCB = &satResetDeviceCB;
20354 * Prepare SGL and send FIS to LL layer.
20356 satIOContext->reqType = agRequestType; /* Save it */
20358 #ifdef TD_INTERNAL_DEBUG
20359 tdhexdump("satResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
20360 #ifdef TD_DEBUG_ENABLE
20361 tdhexdump("satResetDevice LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
20365 status = sataLLIOStart( tiRoot,
20371 TI_DBG6(("satResetDevice: end status %d\n", status));
20375 /*****************************************************************************
20376 *! \brief satResetDeviceCB
20378 * This routine is a callback function called from ossaSATACompleted().
20379 * This CB routine deals with SRT completion. This function send DSRT
20381 * \param agRoot: Handles for this instance of SAS/SATA hardware
20382 * \param agIORequest: Pointer to the LL I/O request context for this I/O.
20383 * \param agIOStatus: Status of completed I/O.
20384 * \param agFirstDword:Pointer to the four bytes of FIS.
20385 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
20387 * \param agParam: Additional info based on status.
20388 * \param ioContext: Pointer to satIOContext_t.
20392 *****************************************************************************/
20393 GLOBAL void satResetDeviceCB(
20394 agsaRoot_t *agRoot,
20395 agsaIORequest_t *agIORequest,
20397 agsaFisHeader_t *agFirstDword,
20399 agsaFrameHandle_t agFrameHandle,
20403 /* callback for satResetDevice */
20404 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
20405 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
20406 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
20407 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
20408 tdIORequestBody_t *tdIORequestBody;
20409 tdIORequestBody_t *tdOrgIORequestBody;
20410 satIOContext_t *satIOContext;
20411 satIOContext_t *satOrgIOContext;
20412 satIOContext_t *satNewIOContext;
20413 satInternalIo_t *satIntIo;
20414 satInternalIo_t *satNewIntIo = agNULL;
20415 satDeviceData_t *satDevData;
20416 tiIORequest_t *tiOrgIORequest;
20417 #ifdef TD_DEBUG_ENABLE
20418 bit32 ataStatus = 0;
20420 agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL;
20424 TI_DBG1(("satResetDeviceCB: start\n"));
20425 TI_DBG6(("satResetDeviceCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
20427 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
20428 satIOContext = (satIOContext_t *) ioContext;
20429 satIntIo = satIOContext->satIntIoContext;
20430 satDevData = satIOContext->pSatDevData;
20431 if (satIntIo == agNULL)
20433 TI_DBG6(("satResetDeviceCB: External, OS generated\n"));
20434 satOrgIOContext = satIOContext;
20435 tiOrgIORequest = tdIORequestBody->tiIORequest;
20439 TI_DBG6(("satResetDeviceCB: Internal, TD generated\n"));
20440 satOrgIOContext = satIOContext->satOrgIOContext;
20441 if (satOrgIOContext == agNULL)
20443 TI_DBG6(("satResetDeviceCB: satOrgIOContext is NULL, wrong\n"));
20448 TI_DBG6(("satResetDeviceCB: satOrgIOContext is NOT NULL\n"));
20450 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
20451 tiOrgIORequest = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
20454 tdIORequestBody->ioCompleted = agTRUE;
20455 tdIORequestBody->ioStarted = agFALSE;
20457 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
20459 TI_DBG1(("satResetDeviceCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
20460 if (satOrgIOContext->NotifyOS == agTRUE)
20462 ostiInitiatorEvent( tiRoot,
20465 tiIntrEventTypeTaskManagement,
20470 satDevData->satTmTaskTag = agNULL;
20472 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20474 satFreeIntIoResource( tiRoot,
20480 if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
20481 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
20482 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
20483 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
20484 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
20485 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
20486 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
20487 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
20488 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
20491 TI_DBG1(("satResetDeviceCB: OSSA_IO_OPEN_CNX_ERROR\n"));
20493 if (satOrgIOContext->NotifyOS == agTRUE)
20495 ostiInitiatorEvent( tiRoot,
20498 tiIntrEventTypeTaskManagement,
20503 satDevData->satTmTaskTag = agNULL;
20505 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20507 satFreeIntIoResource( tiRoot,
20513 if (agIOStatus != OSSA_IO_SUCCESS)
20515 #ifdef TD_DEBUG_ENABLE
20516 /* only agsaFisPioSetup_t is expected */
20517 satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
20518 ataStatus = satPIOSetupHeader->status; /* ATA Status register */
20519 ataError = satPIOSetupHeader->error; /* ATA Eror register */
20521 TI_DBG1(("satResetDeviceCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
20523 if (satOrgIOContext->NotifyOS == agTRUE)
20525 ostiInitiatorEvent( tiRoot,
20528 tiIntrEventTypeTaskManagement,
20533 satDevData->satTmTaskTag = agNULL;
20535 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20537 satFreeIntIoResource( tiRoot,
20545 satNewIntIo = satAllocIntIoResource( tiRoot,
20550 if (satNewIntIo == agNULL)
20552 satDevData->satTmTaskTag = agNULL;
20554 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20556 /* memory allocation failure */
20557 satFreeIntIoResource( tiRoot,
20561 if (satOrgIOContext->NotifyOS == agTRUE)
20563 ostiInitiatorEvent( tiRoot,
20566 tiIntrEventTypeTaskManagement,
20572 TI_DBG1(("satResetDeviceCB: momory allocation fails\n"));
20574 } /* end of memory allocation failure */
20577 * Need to initialize all the fields within satIOContext
20580 satNewIOContext = satPrepareNewIO(
20591 /* send AGSA_SATA_PROTOCOL_SRST_DEASSERT */
20592 status = satDeResetDevice(tiRoot,
20594 satOrgIOContext->ptiDeviceHandle,
20599 if (status != tiSuccess)
20601 if (satOrgIOContext->NotifyOS == agTRUE)
20603 ostiInitiatorEvent( tiRoot,
20606 tiIntrEventTypeTaskManagement,
20611 /* sending AGSA_SATA_PROTOCOL_SRST_DEASSERT fails */
20613 satDevData->satTmTaskTag = agNULL;
20615 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20617 satFreeIntIoResource( tiRoot,
20624 satDevData->satTmTaskTag = agNULL;
20626 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20628 satFreeIntIoResource( tiRoot,
20631 TI_DBG5(("satResetDeviceCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
20632 TI_DBG6(("satResetDeviceCB: end\n"));
20638 /*****************************************************************************/
20639 /*! \brief SAT implementation for satDeResetDevice.
20641 * SAT implementation for building DSRT FIS and sends the request to LL layer.
20643 * \param tiRoot: Pointer to TISA initiator driver/port instance.
20644 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
20645 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
20646 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
20647 * \param satIOContext_t: Pointer to the SAT IO Context
20649 * \return If command is started successfully
20650 * - \e tiSuccess: I/O request successfully initiated.
20651 * - \e tiBusy: No resources available, try again later.
20652 * - \e tiIONoDevice: Invalid device handle.
20653 * - \e tiError: Other errors.
20655 /*****************************************************************************/
20656 GLOBAL bit32 satDeResetDevice(
20658 tiIORequest_t *tiIORequest,
20659 tiDeviceHandle_t *tiDeviceHandle,
20660 tiScsiInitiatorRequest_t *tiScsiRequest,
20661 satIOContext_t *satIOContext
20665 bit32 agRequestType;
20666 agsaFisRegHostToDevice_t *fis;
20667 #ifdef TD_DEBUG_ENABLE
20668 tdIORequestBody_t *tdIORequestBody;
20669 satInternalIo_t *satIntIoContext;
20671 fis = satIOContext->pFis;
20673 TI_DBG6(("satDeResetDevice: start\n"));
20675 #ifdef TD_DEBUG_ENABLE
20676 satIntIoContext = satIOContext->satIntIoContext;
20677 tdIORequestBody = satIntIoContext->satIntRequestBody;
20678 TI_DBG5(("satDeResetDevice: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
20680 /* any fis should work */
20681 fis->h.fisType = 0x27; /* Reg host to device */
20682 fis->h.c_pmPort = 0; /* C Bit is not set */
20683 fis->h.command = 0; /* any command */
20684 fis->h.features = 0; /* FIS reserve */
20685 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
20686 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
20687 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
20688 fis->d.device = 0; /* FIS LBA mode */
20689 fis->d.lbaLowExp = 0;
20690 fis->d.lbaMidExp = 0;
20691 fis->d.lbaHighExp = 0;
20692 fis->d.featuresExp = 0;
20693 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
20694 fis->d.sectorCountExp = 0;
20695 fis->d.reserved4 = 0;
20696 fis->d.control = 0; /* SRST bit is not set */
20697 fis->d.reserved5 = 0;
20699 agRequestType = AGSA_SATA_PROTOCOL_SRST_DEASSERT;
20701 satIOContext->satCompleteCB = &satDeResetDeviceCB;
20704 * Prepare SGL and send FIS to LL layer.
20706 satIOContext->reqType = agRequestType; /* Save it */
20708 #ifdef TD_INTERNAL_DEBUG
20709 tdhexdump("satDeResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
20710 #ifdef TD_DEBUG_ENABLE
20711 tdhexdump("satDeResetDevice LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
20715 status = sataLLIOStart( tiRoot,
20721 TI_DBG6(("satDeResetDevice: end status %d\n", status));
20726 /*****************************************************************************
20727 *! \brief satDeResetDeviceCB
20729 * This routine is a callback function called from ossaSATACompleted().
20730 * This CB routine deals with DSRT completion.
20732 * \param agRoot: Handles for this instance of SAS/SATA hardware
20733 * \param agIORequest: Pointer to the LL I/O request context for this I/O.
20734 * \param agIOStatus: Status of completed I/O.
20735 * \param agFirstDword:Pointer to the four bytes of FIS.
20736 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
20738 * \param agParam: Additional info based on status.
20739 * \param ioContext: Pointer to satIOContext_t.
20743 *****************************************************************************/
20744 GLOBAL void satDeResetDeviceCB(
20745 agsaRoot_t *agRoot,
20746 agsaIORequest_t *agIORequest,
20748 agsaFisHeader_t *agFirstDword,
20750 agsaFrameHandle_t agFrameHandle,
20754 /* callback for satDeResetDevice */
20755 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
20756 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
20757 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
20758 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
20759 tdIORequestBody_t *tdIORequestBody;
20760 tdIORequestBody_t *tdOrgIORequestBody = agNULL;
20761 satIOContext_t *satIOContext;
20762 satIOContext_t *satOrgIOContext;
20763 satInternalIo_t *satIntIo;
20764 satDeviceData_t *satDevData;
20765 tiIORequest_t *tiOrgIORequest;
20766 #ifdef TD_DEBUG_ENABLE
20767 bit32 ataStatus = 0;
20769 agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL;
20771 bit32 report = agFALSE;
20772 bit32 AbortTM = agFALSE;
20774 TI_DBG1(("satDeResetDeviceCB: start\n"));
20775 TI_DBG6(("satDeResetDeviceCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
20776 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
20777 satIOContext = (satIOContext_t *) ioContext;
20778 satIntIo = satIOContext->satIntIoContext;
20779 satDevData = satIOContext->pSatDevData;
20780 if (satIntIo == agNULL)
20782 TI_DBG6(("satDeResetDeviceCB: External, OS generated\n"));
20783 satOrgIOContext = satIOContext;
20784 tiOrgIORequest = tdIORequestBody->tiIORequest;
20788 TI_DBG6(("satDeResetDeviceCB: Internal, TD generated\n"));
20789 satOrgIOContext = satIOContext->satOrgIOContext;
20790 if (satOrgIOContext == agNULL)
20792 TI_DBG6(("satDeResetDeviceCB: satOrgIOContext is NULL, wrong\n"));
20797 TI_DBG6(("satDeResetDeviceCB: satOrgIOContext is NOT NULL\n"));
20799 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
20800 tiOrgIORequest = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
20803 tdIORequestBody->ioCompleted = agTRUE;
20804 tdIORequestBody->ioStarted = agFALSE;
20806 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
20808 TI_DBG1(("satDeResetDeviceCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
20809 if (satOrgIOContext->NotifyOS == agTRUE)
20811 ostiInitiatorEvent( tiRoot,
20814 tiIntrEventTypeTaskManagement,
20819 satDevData->satTmTaskTag = agNULL;
20820 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20822 satFreeIntIoResource( tiRoot,
20828 if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
20829 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
20830 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
20831 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
20832 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
20833 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
20834 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
20835 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
20836 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
20839 TI_DBG1(("satDeResetDeviceCB: OSSA_IO_OPEN_CNX_ERROR\n"));
20841 if (satOrgIOContext->NotifyOS == agTRUE)
20843 ostiInitiatorEvent( tiRoot,
20846 tiIntrEventTypeTaskManagement,
20851 satDevData->satTmTaskTag = agNULL;
20853 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20855 satFreeIntIoResource( tiRoot,
20861 if (agIOStatus != OSSA_IO_SUCCESS)
20863 #ifdef TD_DEBUG_ENABLE
20864 /* only agsaFisPioSetup_t is expected */
20865 satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
20866 ataStatus = satPIOSetupHeader->status; /* ATA Status register */
20867 ataError = satPIOSetupHeader->error; /* ATA Eror register */
20869 TI_DBG1(("satDeResetDeviceCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
20871 if (satOrgIOContext->NotifyOS == agTRUE)
20873 ostiInitiatorEvent( tiRoot,
20876 tiIntrEventTypeTaskManagement,
20881 satDevData->satTmTaskTag = agNULL;
20883 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20885 satFreeIntIoResource( tiRoot,
20892 TI_DBG1(("satDeResetDeviceCB: success \n"));
20893 TI_DBG1(("satDeResetDeviceCB: TMF %d\n", satOrgIOContext->TMF));
20895 if (satOrgIOContext->TMF == AG_ABORT_TASK)
20900 if (satOrgIOContext->NotifyOS == agTRUE)
20905 if (AbortTM == agTRUE)
20907 TI_DBG1(("satDeResetDeviceCB: calling satAbort\n"));
20908 satAbort(agRoot, satOrgIOContext->satToBeAbortedIOContext);
20910 satDevData->satTmTaskTag = agNULL;
20912 satDevData->satDriveState = SAT_DEV_STATE_NORMAL;
20914 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20916 TI_DBG1(("satDeResetDeviceCB: satPendingIO %d satNCQMaxIO %d\n", satDevData->satPendingIO, satDevData->satNCQMaxIO ));
20917 TI_DBG1(("satDeResetDeviceCB: satPendingNCQIO %d satPendingNONNCQIO %d\n", satDevData->satPendingNCQIO, satDevData->satPendingNONNCQIO));
20919 satFreeIntIoResource( tiRoot,
20923 /* clean up TD layer's IORequestBody */
20924 if (tdOrgIORequestBody != agNULL)
20928 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
20929 sizeof(tdIORequestBody_t)
20934 TI_DBG1(("satDeResetDeviceCB: tdOrgIORequestBody is NULL, wrong\n"));
20940 ostiInitiatorEvent( tiRoot,
20943 tiIntrEventTypeTaskManagement,
20949 TI_DBG5(("satDeResetDeviceCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
20950 TI_DBG6(("satDeResetDeviceCB: end\n"));
20955 /*****************************************************************************/
20956 /*! \brief SAT implementation for satStartCheckPowerMode.
20958 * SAT implementation for abort task management for non-ncq sata disk.
20959 * This function sends CHECK POWER MODE
20961 * \param tiRoot: Pointer to TISA initiator driver/port instance.
20962 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
20963 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
20964 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
20965 * \param satIOContext_t: Pointer to the SAT IO Context
20967 * \return If command is started successfully
20968 * - \e tiSuccess: I/O request successfully initiated.
20969 * - \e tiBusy: No resources available, try again later.
20970 * - \e tiIONoDevice: Invalid device handle.
20971 * - \e tiError: Other errors.
20973 /*****************************************************************************/
20974 GLOBAL bit32 satStartCheckPowerMode(
20976 tiIORequest_t *tiIORequest,
20977 tiDeviceHandle_t *tiDeviceHandle,
20978 tiScsiInitiatorRequest_t *tiScsiRequest, /* NULL */
20979 satIOContext_t *satIOContext
20982 satInternalIo_t *satIntIo = agNULL;
20983 satDeviceData_t *satDevData = agNULL;
20984 satIOContext_t *satNewIOContext;
20986 tiIORequest_t *currentTaskTag = agNULL;
20988 TI_DBG6(("satStartCheckPowerMode: start\n"));
20990 currentTaskTag = tiIORequest;
20992 satDevData = satIOContext->pSatDevData;
20994 TI_DBG6(("satStartCheckPowerMode: before alloc\n"));
20996 /* allocate any fis for seting SRT bit in device control */
20997 satIntIo = satAllocIntIoResource( tiRoot,
21003 TI_DBG6(("satStartCheckPowerMode: before after\n"));
21005 if (satIntIo == agNULL)
21007 TI_DBG1(("satStartCheckPowerMode: can't alloacate\n"));
21008 if (satIOContext->NotifyOS)
21010 ostiInitiatorEvent( tiRoot,
21013 tiIntrEventTypeTaskManagement,
21020 satNewIOContext = satPrepareNewIO(satIntIo,
21026 TI_DBG6(("satStartCheckPowerMode: OS satIOContext %p \n", satIOContext));
21027 TI_DBG6(("satStartCheckPowerMode: TD satNewIOContext %p \n", satNewIOContext));
21028 TI_DBG6(("satStartCheckPowerMode: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
21029 TI_DBG6(("satStartCheckPowerMode: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
21033 TI_DBG1(("satStartCheckPowerMode: satNewIOContext %p \n", satNewIOContext));
21035 status = satCheckPowerMode(tiRoot,
21036 &satIntIo->satIntTiIORequest, /* New tiIORequest */
21038 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
21041 if (status != tiSuccess)
21043 TI_DBG1(("satStartCheckPowerMode: failed in sending\n"));
21045 satFreeIntIoResource( tiRoot,
21048 if (satIOContext->NotifyOS)
21050 ostiInitiatorEvent( tiRoot,
21053 tiIntrEventTypeTaskManagement,
21062 TI_DBG6(("satStartCheckPowerMode: end\n"));
21067 /*****************************************************************************/
21068 /*! \brief SAT implementation for satCheckPowerMode.
21070 * This function creates CHECK POWER MODE fis and sends the request to LL layer
21072 * \param tiRoot: Pointer to TISA initiator driver/port instance.
21073 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
21074 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
21075 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
21076 * \param satIOContext_t: Pointer to the SAT IO Context
21078 * \return If command is started successfully
21079 * - \e tiSuccess: I/O request successfully initiated.
21080 * - \e tiBusy: No resources available, try again later.
21081 * - \e tiIONoDevice: Invalid device handle.
21082 * - \e tiError: Other errors.
21084 /*****************************************************************************/
21085 GLOBAL bit32 satCheckPowerMode(
21087 tiIORequest_t *tiIORequest,
21088 tiDeviceHandle_t *tiDeviceHandle,
21089 tiScsiInitiatorRequest_t *tiScsiRequest,
21090 satIOContext_t *satIOContext
21094 sends SAT_CHECK_POWER_MODE as a part of ABORT TASKMANGEMENT for NCQ commands
21095 internally generated - no directly corresponding scsi
21098 bit32 agRequestType;
21099 agsaFisRegHostToDevice_t *fis;
21101 fis = satIOContext->pFis;
21102 TI_DBG5(("satCheckPowerMode: start\n"));
21104 * Send the ATA CHECK POWER MODE command.
21106 fis->h.fisType = 0x27; /* Reg host to device */
21107 fis->h.c_pmPort = 0x80; /* C Bit is set */
21108 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */
21109 fis->h.features = 0;
21112 fis->d.lbaHigh = 0;
21114 fis->d.lbaLowExp = 0;
21115 fis->d.lbaMidExp = 0;
21116 fis->d.lbaHighExp = 0;
21117 fis->d.featuresExp = 0;
21118 fis->d.sectorCount = 0;
21119 fis->d.sectorCountExp = 0;
21120 fis->d.reserved4 = 0;
21121 fis->d.control = 0; /* FIS HOB bit clear */
21122 fis->d.reserved5 = 0;
21124 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
21126 /* Initialize CB for SATA completion.
21128 satIOContext->satCompleteCB = &satCheckPowerModeCB;
21131 * Prepare SGL and send FIS to LL layer.
21133 satIOContext->reqType = agRequestType; /* Save it */
21135 status = sataLLIOStart( tiRoot,
21141 TI_DBG5(("satCheckPowerMode: return\n"));
21146 /*****************************************************************************
21147 *! \brief satCheckPowerModeCB
21149 * This routine is a callback function called from ossaSATACompleted().
21150 * This CB routine deals with CHECK POWER MODE completion as abort task
21153 * \param agRoot: Handles for this instance of SAS/SATA hardware
21154 * \param agIORequest: Pointer to the LL I/O request context for this I/O.
21155 * \param agIOStatus: Status of completed I/O.
21156 * \param agFirstDword:Pointer to the four bytes of FIS.
21157 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
21159 * \param agParam: Additional info based on status.
21160 * \param ioContext: Pointer to satIOContext_t.
21164 *****************************************************************************/
21165 GLOBAL void satCheckPowerModeCB(
21166 agsaRoot_t *agRoot,
21167 agsaIORequest_t *agIORequest,
21169 agsaFisHeader_t *agFirstDword,
21171 agsaFrameHandle_t agFrameHandle,
21175 /* callback for satDeResetDevice */
21176 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
21177 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
21178 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
21179 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
21180 tdIORequestBody_t *tdIORequestBody;
21181 tdIORequestBody_t *tdOrgIORequestBody = agNULL;
21182 satIOContext_t *satIOContext;
21183 satIOContext_t *satOrgIOContext;
21184 satInternalIo_t *satIntIo;
21185 satDeviceData_t *satDevData;
21187 tiIORequest_t *tiOrgIORequest;
21188 #ifdef TD_DEBUG_ENABLE
21189 bit32 ataStatus = 0;
21191 agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL;
21193 bit32 report = agFALSE;
21194 bit32 AbortTM = agFALSE;
21197 TI_DBG1(("satCheckPowerModeCB: start\n"));
21199 TI_DBG1(("satCheckPowerModeCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
21201 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
21202 satIOContext = (satIOContext_t *) ioContext;
21203 satIntIo = satIOContext->satIntIoContext;
21204 satDevData = satIOContext->pSatDevData;
21205 if (satIntIo == agNULL)
21207 TI_DBG6(("satCheckPowerModeCB: External, OS generated\n"));
21208 satOrgIOContext = satIOContext;
21209 tiOrgIORequest = tdIORequestBody->tiIORequest;
21213 TI_DBG6(("satCheckPowerModeCB: Internal, TD generated\n"));
21214 satOrgIOContext = satIOContext->satOrgIOContext;
21215 if (satOrgIOContext == agNULL)
21217 TI_DBG6(("satCheckPowerModeCB: satOrgIOContext is NULL, wrong\n"));
21222 TI_DBG6(("satCheckPowerModeCB: satOrgIOContext is NOT NULL\n"));
21224 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
21225 tiOrgIORequest = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
21229 tdIORequestBody->ioCompleted = agTRUE;
21230 tdIORequestBody->ioStarted = agFALSE;
21232 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
21234 TI_DBG1(("satCheckPowerModeCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
21236 if (satOrgIOContext->NotifyOS == agTRUE)
21238 ostiInitiatorEvent( tiRoot,
21241 tiIntrEventTypeTaskManagement,
21246 satDevData->satTmTaskTag = agNULL;
21248 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21250 satFreeIntIoResource( tiRoot,
21256 if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
21257 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
21258 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
21259 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
21260 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
21261 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
21262 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
21263 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
21264 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
21267 TI_DBG1(("satCheckPowerModeCB: OSSA_IO_OPEN_CNX_ERROR\n"));
21269 if (satOrgIOContext->NotifyOS == agTRUE)
21271 ostiInitiatorEvent( tiRoot,
21274 tiIntrEventTypeTaskManagement,
21279 satDevData->satTmTaskTag = agNULL;
21281 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21283 satFreeIntIoResource( tiRoot,
21289 if (agIOStatus != OSSA_IO_SUCCESS)
21291 #ifdef TD_DEBUG_ENABLE
21292 /* only agsaFisPioSetup_t is expected */
21293 satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
21294 ataStatus = satPIOSetupHeader->status; /* ATA Status register */
21295 ataError = satPIOSetupHeader->error; /* ATA Eror register */
21297 TI_DBG1(("satCheckPowerModeCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
21299 if (satOrgIOContext->NotifyOS == agTRUE)
21301 ostiInitiatorEvent( tiRoot,
21304 tiIntrEventTypeTaskManagement,
21309 satDevData->satTmTaskTag = agNULL;
21311 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21313 satFreeIntIoResource( tiRoot,
21320 TI_DBG1(("satCheckPowerModeCB: success\n"));
21321 TI_DBG1(("satCheckPowerModeCB: TMF %d\n", satOrgIOContext->TMF));
21323 if (satOrgIOContext->TMF == AG_ABORT_TASK)
21328 if (satOrgIOContext->NotifyOS == agTRUE)
21332 if (AbortTM == agTRUE)
21334 TI_DBG1(("satCheckPowerModeCB: calling satAbort\n"));
21335 satAbort(agRoot, satOrgIOContext->satToBeAbortedIOContext);
21337 satDevData->satTmTaskTag = agNULL;
21339 satDevData->satDriveState = SAT_DEV_STATE_NORMAL;
21341 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21343 TI_DBG1(("satCheckPowerModeCB: satPendingIO %d satNCQMaxIO %d\n", satDevData->satPendingIO, satDevData->satNCQMaxIO ));
21344 TI_DBG1(("satCheckPowerModeCB: satPendingNCQIO %d satPendingNONNCQIO %d\n", satDevData->satPendingNCQIO, satDevData->satPendingNONNCQIO));
21346 satFreeIntIoResource( tiRoot,
21350 /* clean up TD layer's IORequestBody */
21351 if (tdOrgIORequestBody != agNULL)
21355 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21356 sizeof(tdIORequestBody_t)
21361 TI_DBG1(("satCheckPowerModeCB: tdOrgIORequestBody is NULL, wrong\n"));
21365 ostiInitiatorEvent( tiRoot,
21368 tiIntrEventTypeTaskManagement,
21373 TI_DBG5(("satCheckPowerModeCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
21374 TI_DBG2(("satCheckPowerModeCB: end\n"));
21379 /*****************************************************************************/
21380 /*! \brief SAT implementation for satAddSATAStartIDDev.
21382 * This function sends identify device data to find out the uniqueness
21385 * \param tiRoot: Pointer to TISA initiator driver/port instance.
21386 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
21387 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
21388 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
21389 * \param satIOContext_t: Pointer to the SAT IO Context
21391 * \return If command is started successfully
21392 * - \e tiSuccess: I/O request successfully initiated.
21393 * - \e tiBusy: No resources available, try again later.
21394 * - \e tiIONoDevice: Invalid device handle.
21395 * - \e tiError: Other errors.
21397 /*****************************************************************************/
21398 GLOBAL bit32 satAddSATAStartIDDev(
21400 tiIORequest_t *tiIORequest,
21401 tiDeviceHandle_t *tiDeviceHandle,
21402 tiScsiInitiatorRequest_t *tiScsiRequest, // NULL
21403 satIOContext_t *satIOContext
21406 satInternalIo_t *satIntIo = agNULL;
21407 satDeviceData_t *satDevData = agNULL;
21408 tdIORequestBody_t *tdIORequestBody;
21409 satIOContext_t *satNewIOContext;
21412 TI_DBG2(("satAddSATAStartIDDev: start\n"));
21414 satDevData = satIOContext->pSatDevData;
21416 TI_DBG2(("satAddSATAStartIDDev: before alloc\n"));
21418 /* allocate identify device command */
21419 satIntIo = satAllocIntIoResource( tiRoot,
21422 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
21425 TI_DBG2(("satAddSATAStartIDDev: after alloc\n"));
21427 if (satIntIo == agNULL)
21429 TI_DBG1(("satAddSATAStartIDDev: can't alloacate\n"));
21434 /* fill in fields */
21435 /* real ttttttthe one worked and the same; 5/21/07/ */
21436 satIntIo->satOrgTiIORequest = tiIORequest; /* changed */
21437 tdIORequestBody = satIntIo->satIntRequestBody;
21438 satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
21440 satNewIOContext->pSatDevData = satDevData;
21441 satNewIOContext->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
21442 satNewIOContext->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
21443 satNewIOContext->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
21444 satNewIOContext->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
21445 satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */
21446 satNewIOContext->interruptContext = tiInterruptContext;
21447 satNewIOContext->satIntIoContext = satIntIo;
21449 satNewIOContext->ptiDeviceHandle = agNULL;
21450 satNewIOContext->satOrgIOContext = satIOContext; /* changed */
21452 /* this is valid only for TD layer generated (not triggered by OS at all) IO */
21453 satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
21456 TI_DBG6(("satAddSATAStartIDDev: OS satIOContext %p \n", satIOContext));
21457 TI_DBG6(("satAddSATAStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
21458 TI_DBG6(("satAddSATAStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
21459 TI_DBG6(("satAddSATAStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
21463 TI_DBG2(("satAddSATAStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
21465 status = satAddSATASendIDDev( tiRoot,
21466 &satIntIo->satIntTiIORequest, /* New tiIORequest */
21468 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
21471 if (status != tiSuccess)
21473 TI_DBG1(("satAddSATAStartIDDev: failed in sending\n"));
21475 satFreeIntIoResource( tiRoot,
21483 TI_DBG6(("satAddSATAStartIDDev: end\n"));
21490 /*****************************************************************************/
21491 /*! \brief SAT implementation for satAddSATASendIDDev.
21493 * This function creates identify device data fis and send it to LL
21495 * \param tiRoot: Pointer to TISA initiator driver/port instance.
21496 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
21497 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
21498 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
21499 * \param satIOContext_t: Pointer to the SAT IO Context
21501 * \return If command is started successfully
21502 * - \e tiSuccess: I/O request successfully initiated.
21503 * - \e tiBusy: No resources available, try again later.
21504 * - \e tiIONoDevice: Invalid device handle.
21505 * - \e tiError: Other errors.
21507 /*****************************************************************************/
21508 GLOBAL bit32 satAddSATASendIDDev(
21510 tiIORequest_t *tiIORequest,
21511 tiDeviceHandle_t *tiDeviceHandle,
21512 tiScsiInitiatorRequest_t *tiScsiRequest,
21513 satIOContext_t *satIOContext)
21516 bit32 agRequestType;
21517 satDeviceData_t *pSatDevData;
21518 agsaFisRegHostToDevice_t *fis;
21519 #ifdef TD_DEBUG_ENABLE
21520 tdIORequestBody_t *tdIORequestBody;
21521 satInternalIo_t *satIntIoContext;
21524 pSatDevData = satIOContext->pSatDevData;
21525 fis = satIOContext->pFis;
21526 TI_DBG2(("satAddSATASendIDDev: start\n"));
21527 #ifdef TD_DEBUG_ENABLE
21528 satIntIoContext = satIOContext->satIntIoContext;
21529 tdIORequestBody = satIntIoContext->satIntRequestBody;
21531 TI_DBG5(("satAddSATASendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
21533 fis->h.fisType = 0x27; /* Reg host to device */
21534 fis->h.c_pmPort = 0x80; /* C Bit is set */
21535 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
21536 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0x40 */
21538 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */
21539 fis->h.features = 0; /* FIS reserve */
21540 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
21541 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
21542 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
21543 fis->d.device = 0; /* FIS LBA mode */
21544 fis->d.lbaLowExp = 0;
21545 fis->d.lbaMidExp = 0;
21546 fis->d.lbaHighExp = 0;
21547 fis->d.featuresExp = 0;
21548 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
21549 fis->d.sectorCountExp = 0;
21550 fis->d.reserved4 = 0;
21551 fis->d.control = 0; /* FIS HOB bit clear */
21552 fis->d.reserved5 = 0;
21554 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
21556 /* Initialize CB for SATA completion.
21558 satIOContext->satCompleteCB = &satAddSATAIDDevCB;
21561 * Prepare SGL and send FIS to LL layer.
21563 satIOContext->reqType = agRequestType; /* Save it */
21565 #ifdef TD_INTERNAL_DEBUG
21566 tdhexdump("satAddSATASendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
21567 #ifdef TD_DEBUG_ENABLE
21568 tdhexdump("satAddSATASendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
21572 status = sataLLIOStart( tiRoot,
21578 TI_DBG2(("satAddSATASendIDDev: end status %d\n", status));
21582 /*****************************************************************************
21583 *! \brief satAddSATAIDDevCB
21585 * This routine is a callback function for satAddSATASendIDDev()
21586 * Using Identify Device Data, this function finds whether devicedata is
21587 * new or old. If new, add it to the devicelist.
21589 * \param agRoot: Handles for this instance of SAS/SATA hardware
21590 * \param agIORequest: Pointer to the LL I/O request context for this I/O.
21591 * \param agIOStatus: Status of completed I/O.
21592 * \param agFirstDword:Pointer to the four bytes of FIS.
21593 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
21595 * \param agParam: Additional info based on status.
21596 * \param ioContext: Pointer to satIOContext_t.
21600 *****************************************************************************/
21601 void satAddSATAIDDevCB(
21602 agsaRoot_t *agRoot,
21603 agsaIORequest_t *agIORequest,
21605 agsaFisHeader_t *agFirstDword,
21613 In the process of Inquiry
21614 Process SAT_IDENTIFY_DEVICE
21616 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
21617 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
21618 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
21619 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
21620 tdIORequestBody_t *tdIORequestBody;
21621 tdIORequestBody_t *tdOrgIORequestBody;
21622 satIOContext_t *satIOContext;
21623 satIOContext_t *satOrgIOContext;
21624 satIOContext_t *satNewIOContext;
21625 satInternalIo_t *satIntIo;
21626 satInternalIo_t *satNewIntIo = agNULL;
21627 satDeviceData_t *satDevData;
21628 tiIORequest_t *tiOrgIORequest = agNULL;
21629 agsaSATAIdentifyData_t *pSATAIdData;
21630 bit16 *tmpptr, tmpptr_tmp;
21632 tdsaDeviceData_t *NewOneDeviceData = agNULL;
21633 tdsaDeviceData_t *oneDeviceData = agNULL;
21634 tdList_t *DeviceListList;
21635 int new_device = agTRUE;
21637 void *sglVirtualAddr;
21638 bit32 retry_status;
21639 agsaContext_t *agContext;
21640 tdsaPortContext_t *onePortContext;
21643 TI_DBG2(("satAddSATAIDDevCB: start\n"));
21644 TI_DBG6(("satAddSATAIDDevCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
21645 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
21646 satIOContext = (satIOContext_t *) ioContext;
21647 satIntIo = satIOContext->satIntIoContext;
21648 satDevData = satIOContext->pSatDevData;
21650 NewOneDeviceData = (tdsaDeviceData_t *)tdIORequestBody->tiDevHandle->tdData;
21651 TI_DBG2(("satAddSATAIDDevCB: NewOneDeviceData %p did %d\n", NewOneDeviceData, NewOneDeviceData->id));
21652 PhyID = NewOneDeviceData->phyID;
21653 TI_DBG2(("satAddSATAIDDevCB: phyID %d\n", PhyID));
21654 agContext = &(NewOneDeviceData->agDeviceResetContext);
21655 agContext->osData = agNULL;
21656 if (satIntIo == agNULL)
21658 TI_DBG1(("satAddSATAIDDevCB: External, OS generated\n"));
21659 TI_DBG1(("satAddSATAIDDevCB: Not possible case\n"));
21660 satOrgIOContext = satIOContext;
21661 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
21662 tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData);
21664 /* put onedevicedata back to free list */
21665 osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
21666 TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
21667 TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
21669 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21671 satFreeIntIoResource( tiRoot,
21674 /* clean up TD layer's IORequestBody */
21677 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21678 sizeof(tdIORequestBody_t)
21681 /* notifying link up */
21686 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
21688 #ifdef INITIATOR_DRIVER
21689 /* triggers discovery */
21692 tiPortDiscoveryReady,
21694 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
21701 TI_DBG1(("satAddSATAIDDevCB: Internal, TD generated\n"));
21702 satOrgIOContext = satIOContext->satOrgIOContext;
21703 if (satOrgIOContext == agNULL)
21705 TI_DBG6(("satAddSATAIDDevCB: satOrgIOContext is NULL\n"));
21710 TI_DBG6(("satAddSATAIDDevCB: satOrgIOContext is NOT NULL\n"));
21711 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
21712 sglVirtualAddr = satIntIo->satIntTiScsiXchg.sglVirtualAddr;
21715 tiOrgIORequest = tdIORequestBody->tiIORequest;
21717 tdIORequestBody->ioCompleted = agTRUE;
21718 tdIORequestBody->ioStarted = agFALSE;
21719 TI_DBG2(("satAddSATAIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
21720 /* protect against double completion for old port */
21721 if (satOrgIOContext->pid != tdsaAllShared->Ports[PhyID].portContext->id)
21723 TI_DBG2(("satAddSATAIDDevCB: incorrect pid\n"));
21724 TI_DBG2(("satAddSATAIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
21725 TI_DBG2(("satAddSATAIDDevCB: tiPortalContext pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
21726 tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData);
21727 /* put onedevicedata back to free list */
21728 osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
21729 TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
21730 TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
21731 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21733 satFreeIntIoResource( tiRoot,
21736 /* clean up TD layer's IORequestBody */
21739 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21740 sizeof(tdIORequestBody_t)
21742 /* no notification to OS layer */
21745 /* completion after portcontext is invalidated */
21746 onePortContext = NewOneDeviceData->tdPortContext;
21747 if (onePortContext != agNULL)
21749 if (onePortContext->valid == agFALSE)
21751 TI_DBG1(("satAddSATAIDDevCB: portcontext is invalid\n"));
21752 TI_DBG1(("satAddSATAIDDevCB: onePortContext->id pid %d\n", onePortContext->id));
21753 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21755 satFreeIntIoResource( tiRoot,
21758 /* clean up TD layer's IORequestBody */
21761 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21762 sizeof(tdIORequestBody_t)
21764 /* no notification to OS layer */
21770 TI_DBG1(("satAddSATAIDDevCB: onePortContext is NULL!!!\n"));
21773 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
21775 TI_DBG1(("satAddSATAIDDevCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
21776 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
21778 satDevData->satPendingNONNCQIO--;
21779 satDevData->satPendingIO--;
21780 retry_status = sataLLIOStart(tiRoot,
21781 &satIntIo->satIntTiIORequest,
21782 &(NewOneDeviceData->tiDeviceHandle),
21783 satIOContext->tiScsiXchg,
21785 if (retry_status != tiSuccess)
21787 /* simply give up */
21788 satDevData->ID_Retries = 0;
21789 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21792 satDevData->ID_Retries++;
21793 tdIORequestBody->ioCompleted = agFALSE;
21794 tdIORequestBody->ioStarted = agTRUE;
21799 if (tdsaAllShared->ResetInDiscovery == 0)
21801 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21803 else /* ResetInDiscovery in on */
21805 /* RESET only one after ID retries */
21806 if (satDevData->NumOfIDRetries <= 0)
21808 satDevData->NumOfIDRetries++;
21809 satDevData->ID_Retries = 0;
21810 satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21811 /* send link reset */
21812 saLocalPhyControl(agRoot,
21814 tdsaRotateQnumber(tiRoot, NewOneDeviceData),
21816 AGSA_PHY_HARD_RESET,
21821 satDevData->ID_Retries = 0;
21822 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21828 if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
21829 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
21830 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
21831 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
21832 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
21833 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
21834 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
21835 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
21836 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
21839 TI_DBG1(("satAddSATAIDDevCB: OSSA_IO_OPEN_CNX_ERROR\n"));
21840 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
21842 satDevData->satPendingNONNCQIO--;
21843 satDevData->satPendingIO--;
21844 retry_status = sataLLIOStart(tiRoot,
21845 &satIntIo->satIntTiIORequest,
21846 &(NewOneDeviceData->tiDeviceHandle),
21847 satIOContext->tiScsiXchg,
21849 if (retry_status != tiSuccess)
21851 /* simply give up */
21852 satDevData->ID_Retries = 0;
21853 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21856 satDevData->ID_Retries++;
21857 tdIORequestBody->ioCompleted = agFALSE;
21858 tdIORequestBody->ioStarted = agTRUE;
21863 if (tdsaAllShared->ResetInDiscovery == 0)
21865 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21867 else /* ResetInDiscovery in on */
21869 /* RESET only one after ID retries */
21870 if (satDevData->NumOfIDRetries <= 0)
21872 satDevData->NumOfIDRetries++;
21873 satDevData->ID_Retries = 0;
21874 satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21875 /* send link reset */
21876 saLocalPhyControl(agRoot,
21878 tdsaRotateQnumber(tiRoot, NewOneDeviceData),
21880 AGSA_PHY_HARD_RESET,
21885 satDevData->ID_Retries = 0;
21886 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21893 if ( agIOStatus != OSSA_IO_SUCCESS ||
21894 (agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0)
21897 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
21899 satIOContext->pSatDevData->satPendingNONNCQIO--;
21900 satIOContext->pSatDevData->satPendingIO--;
21901 retry_status = sataLLIOStart(tiRoot,
21902 &satIntIo->satIntTiIORequest,
21903 &(NewOneDeviceData->tiDeviceHandle),
21904 satIOContext->tiScsiXchg,
21906 if (retry_status != tiSuccess)
21908 /* simply give up */
21909 satDevData->ID_Retries = 0;
21910 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21913 satDevData->ID_Retries++;
21914 tdIORequestBody->ioCompleted = agFALSE;
21915 tdIORequestBody->ioStarted = agTRUE;
21920 if (tdsaAllShared->ResetInDiscovery == 0)
21922 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21924 else /* ResetInDiscovery in on */
21926 /* RESET only one after ID retries */
21927 if (satDevData->NumOfIDRetries <= 0)
21929 satDevData->NumOfIDRetries++;
21930 satDevData->ID_Retries = 0;
21931 satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21932 /* send link reset */
21933 saLocalPhyControl(agRoot,
21935 tdsaRotateQnumber(tiRoot, NewOneDeviceData),
21937 AGSA_PHY_HARD_RESET,
21942 satDevData->ID_Retries = 0;
21943 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21951 TI_DBG2(("satAddSATAIDDevCB: Success\n"));
21952 /* Convert to host endian */
21953 tmpptr = (bit16*)sglVirtualAddr;
21954 //tdhexdump("satAddSATAIDDevCB before", (bit8 *)sglVirtualAddr, sizeof(agsaSATAIdentifyData_t));
21955 for (x=0; x < sizeof(agsaSATAIdentifyData_t)/sizeof(bit16); x++)
21957 OSSA_READ_LE_16(AGROOT, &tmpptr_tmp, tmpptr, 0);
21958 *tmpptr = tmpptr_tmp;
21960 /*Print tmpptr_tmp here for debugging purpose*/
21963 pSATAIdData = (agsaSATAIdentifyData_t *)sglVirtualAddr;
21964 //tdhexdump("satAddSATAIDDevCB after", (bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
21966 TI_DBG5(("satAddSATAIDDevCB: OS satOrgIOContext %p \n", satOrgIOContext));
21967 TI_DBG5(("satAddSATAIDDevCB: TD satIOContext %p \n", satIOContext));
21968 TI_DBG5(("satAddSATAIDDevCB: OS tiScsiXchg %p \n", satOrgIOContext->tiScsiXchg));
21969 TI_DBG5(("satAddSATAIDDevCB: TD tiScsiXchg %p \n", satIOContext->tiScsiXchg));
21972 /* compare idenitfy device data to the exiting list */
21973 DeviceListList = tdsaAllShared->MainDeviceList.flink;
21974 while (DeviceListList != &(tdsaAllShared->MainDeviceList))
21976 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
21977 TI_DBG1(("satAddSATAIDDevCB: LOOP oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
21978 //tdhexdump("satAddSATAIDDevCB LOOP", (bit8 *)&oneDeviceData->satDevData.satIdentifyData, sizeof(agsaSATAIdentifyData_t));
21980 /* what is unique ID for sata device -> response of identify devicedata; not really
21981 Let's compare serial number, firmware version, model number
21983 if ( oneDeviceData->DeviceType == TD_SATA_DEVICE &&
21984 (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.serialNumber,
21985 pSATAIdData->serialNumber,
21987 (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.firmwareVersion,
21988 pSATAIdData->firmwareVersion,
21990 (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.modelNumber,
21991 pSATAIdData->modelNumber,
21995 TI_DBG2(("satAddSATAIDDevCB: did %d\n", oneDeviceData->id));
21996 new_device = agFALSE;
21999 DeviceListList = DeviceListList->flink;
22002 if (new_device == agFALSE)
22004 TI_DBG2(("satAddSATAIDDevCB: old device data\n"));
22005 oneDeviceData->valid = agTRUE;
22006 oneDeviceData->valid2 = agTRUE;
22007 /* save data field from new device data */
22008 oneDeviceData->agRoot = agRoot;
22009 oneDeviceData->agDevHandle = NewOneDeviceData->agDevHandle;
22010 oneDeviceData->agDevHandle->osData = oneDeviceData; /* TD layer */
22011 oneDeviceData->tdPortContext = NewOneDeviceData->tdPortContext;
22012 oneDeviceData->phyID = NewOneDeviceData->phyID;
22015 one SATA directly attached device per phy;
22016 Therefore, deregister then register
22018 saDeregisterDeviceHandle(agRoot, agNULL, NewOneDeviceData->agDevHandle, 0);
22020 if (oneDeviceData->registered == agFALSE)
22022 TI_DBG2(("satAddSATAIDDevCB: re-registering old device data\n"));
22023 /* already has old information; just register it again */
22024 saRegisterNewDevice( /* satAddSATAIDDevCB */
22026 &oneDeviceData->agContext,
22027 tdsaRotateQnumber(tiRoot, oneDeviceData),
22028 &oneDeviceData->agDeviceInfo,
22029 oneDeviceData->tdPortContext->agPortContext,
22034 // tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData);
22035 /* put onedevicedata back to free list */
22036 osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
22037 TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
22038 TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
22039 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22041 satFreeIntIoResource( tiRoot,
22045 if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
22047 /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/
22048 satNewIntIo = satAllocIntIoResource( tiRoot,
22054 if (satNewIntIo == agNULL)
22056 TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
22057 /* clean up TD layer's IORequestBody */
22060 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22061 sizeof(tdIORequestBody_t)
22064 } /* end memory allocation */
22066 satNewIOContext = satPrepareNewIO(satNewIntIo,
22072 /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/
22073 status = satSetFeatures(tiRoot,
22074 &satNewIntIo->satIntTiIORequest,
22075 satNewIOContext->ptiDeviceHandle,
22076 &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */
22079 if (status != tiSuccess)
22081 satFreeIntIoResource( tiRoot,
22084 /* clean up TD layer's IORequestBody */
22087 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22088 sizeof(tdIORequestBody_t)
22094 /* clean up TD layer's IORequestBody */
22097 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22098 sizeof(tdIORequestBody_t)
22100 TI_DBG2(("satAddSATAIDDevCB: pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
22101 /* notifying link up */
22106 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
22110 #ifdef INITIATOR_DRIVER
22111 /* triggers discovery */
22114 tiPortDiscoveryReady,
22116 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
22123 TI_DBG2(("satAddSATAIDDevCB: new device data\n"));
22124 /* copy ID Dev data to satDevData */
22125 satDevData->satIdentifyData = *pSATAIdData;
22128 satDevData->IDDeviceValid = agTRUE;
22129 #ifdef TD_INTERNAL_DEBUG
22130 tdhexdump("satAddSATAIDDevCB ID Dev data",(bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
22131 tdhexdump("satAddSATAIDDevCB Device ID Dev data",(bit8 *)&satDevData->satIdentifyData, sizeof(agsaSATAIdentifyData_t));
22134 /* set satDevData fields from IndentifyData */
22135 satSetDevInfo(satDevData,pSATAIdData);
22136 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22138 satFreeIntIoResource( tiRoot,
22142 if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
22144 /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/
22145 satNewIntIo = satAllocIntIoResource( tiRoot,
22151 if (satNewIntIo == agNULL)
22153 TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
22154 /* clean up TD layer's IORequestBody */
22157 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22158 sizeof(tdIORequestBody_t)
22161 } /* end memory allocation */
22163 satNewIOContext = satPrepareNewIO(satNewIntIo,
22169 /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/
22170 status = satSetFeatures(tiRoot,
22171 &satNewIntIo->satIntTiIORequest,
22172 satNewIOContext->ptiDeviceHandle,
22173 &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */
22176 if (status != tiSuccess)
22178 satFreeIntIoResource( tiRoot,
22181 /* clean up TD layer's IORequestBody */
22184 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22185 sizeof(tdIORequestBody_t)
22192 /* clean up TD layer's IORequestBody */
22195 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22196 sizeof(tdIORequestBody_t)
22199 TI_DBG2(("satAddSATAIDDevCB: pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
22200 /* notifying link up */
22205 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
22207 #ifdef INITIATOR_DRIVER
22208 /* triggers discovery */
22211 tiPortDiscoveryReady,
22213 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
22218 TI_DBG2(("satAddSATAIDDevCB: end\n"));
22223 /*****************************************************************************
22224 *! \brief satAddSATAIDDevCBReset
22226 * This routine cleans up IOs for failed Identify device data
22228 * \param agRoot: Handles for this instance of SAS/SATA hardware
22229 * \param oneDeviceData: Pointer to the device data.
22230 * \param ioContext: Pointer to satIOContext_t.
22231 * \param tdIORequestBody: Pointer to the request body
22232 * \param flag: Decrement pending io or not
22236 *****************************************************************************/
22237 void satAddSATAIDDevCBReset(
22238 agsaRoot_t *agRoot,
22239 tdsaDeviceData_t *oneDeviceData,
22240 satIOContext_t *satIOContext,
22241 tdIORequestBody_t *tdIORequestBody
22244 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
22245 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
22246 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
22247 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
22248 satInternalIo_t *satIntIo;
22249 satDeviceData_t *satDevData;
22251 TI_DBG2(("satAddSATAIDDevCBReset: start\n"));
22252 satIntIo = satIOContext->satIntIoContext;
22253 satDevData = satIOContext->pSatDevData;
22254 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22256 satFreeIntIoResource( tiRoot,
22259 /* clean up TD layer's IORequestBody */
22262 tdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22263 sizeof(tdIORequestBody_t)
22269 /*****************************************************************************
22270 *! \brief satAddSATAIDDevCBCleanup
22272 * This routine cleans up IOs for failed Identify device data
22274 * \param agRoot: Handles for this instance of SAS/SATA hardware
22275 * \param oneDeviceData: Pointer to the device data.
22276 * \param ioContext: Pointer to satIOContext_t.
22277 * \param tdIORequestBody: Pointer to the request body
22281 *****************************************************************************/
22282 void satAddSATAIDDevCBCleanup(
22283 agsaRoot_t *agRoot,
22284 tdsaDeviceData_t *oneDeviceData,
22285 satIOContext_t *satIOContext,
22286 tdIORequestBody_t *tdIORequestBody
22289 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
22290 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
22291 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
22292 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
22293 satInternalIo_t *satIntIo;
22294 satDeviceData_t *satDevData;
22297 TI_DBG2(("satAddSATAIDDevCBCleanup: start\n"));
22298 satIntIo = satIOContext->satIntIoContext;
22299 satDevData = satIOContext->pSatDevData;
22300 PhyID = oneDeviceData->phyID;
22301 tdsaAbortAll(tiRoot, agRoot, oneDeviceData);
22302 /* put onedevicedata back to free list */
22303 osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
22304 TDLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink));
22305 TDLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
22307 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22310 satFreeIntIoResource( tiRoot,
22314 /* clean up TD layer's IORequestBody */
22317 tdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22318 sizeof(tdIORequestBody_t)
22321 /* notifying link up */
22326 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
22328 #ifdef INITIATOR_DRIVER
22329 /* triggers discovery */
22332 tiPortDiscoveryReady,
22334 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
22341 /*****************************************************************************/
22342 /*! \brief SAT implementation for tdsaDiscoveryStartIDDev.
22344 * This function sends identify device data to SATA device in discovery
22347 * \param tiRoot: Pointer to TISA initiator driver/port instance.
22348 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
22349 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
22350 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
22351 * \param oneDeviceData : Pointer to the device data.
22353 * \return If command is started successfully
22354 * - \e tiSuccess: I/O request successfully initiated.
22355 * - \e tiBusy: No resources available, try again later.
22356 * - \e tiIONoDevice: Invalid device handle.
22357 * - \e tiError: Other errors.
22359 /*****************************************************************************/
22361 tdsaDiscoveryStartIDDev(tiRoot_t *tiRoot,
22362 tiIORequest_t *tiIORequest, /* agNULL */
22363 tiDeviceHandle_t *tiDeviceHandle,
22364 tiScsiInitiatorRequest_t *tiScsiRequest, /* agNULL */
22365 tdsaDeviceData_t *oneDeviceData
22369 tdIORequestBody_t *tdIORequestBody;
22372 bit32 memAllocStatus;
22373 agsaIORequest_t *agIORequest = agNULL; /* identify device data itself */
22374 satIOContext_t *satIOContext = agNULL;
22377 /* allocate tdiorequestbody and call tdsaDiscoveryIntStartIDDev
22378 tdsaDiscoveryIntStartIDDev(tiRoot, agNULL, tiDeviceHandle, satIOContext);
22382 TI_DBG3(("tdsaDiscoveryStartIDDev: start\n"));
22383 TI_DBG3(("tdsaDiscoveryStartIDDev: did %d\n", oneDeviceData->id));
22385 /* allocation tdIORequestBody and pass it to satTM() */
22386 memAllocStatus = ostiAllocMemory(
22389 (void **)&tdIORequestBody,
22393 sizeof(tdIORequestBody_t),
22397 if (memAllocStatus != tiSuccess)
22399 TI_DBG1(("tdsaDiscoveryStartIDDev: ostiAllocMemory failed... loc 1\n"));
22402 if (tdIORequestBody == agNULL)
22404 TI_DBG1(("tdsaDiscoveryStartIDDev: ostiAllocMemory returned NULL tdIORequestBody loc 2\n"));
22408 /* setup identify device data IO structure */
22409 tdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
22410 tdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = agNULL;
22411 tdIORequestBody->IOType.InitiatorTMIO.TaskTag = agNULL;
22413 /* initialize tiDevhandle */
22414 tdIORequestBody->tiDevHandle = &(oneDeviceData->tiDeviceHandle);
22415 tdIORequestBody->tiDevHandle->tdData = oneDeviceData;
22417 /* initialize tiIORequest */
22418 tdIORequestBody->tiIORequest = agNULL;
22420 /* initialize agIORequest */
22421 agIORequest = &(tdIORequestBody->agIORequest);
22422 agIORequest->osData = (void *) tdIORequestBody;
22423 agIORequest->sdkData = agNULL; /* SA takes care of this */
22425 /* set up satIOContext */
22426 satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
22427 satIOContext->pSatDevData = &(oneDeviceData->satDevData);
22428 satIOContext->pFis =
22429 &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
22431 satIOContext->tiRequestBody = tdIORequestBody;
22432 satIOContext->ptiDeviceHandle = &(oneDeviceData->tiDeviceHandle);
22433 satIOContext->tiScsiXchg = agNULL;
22434 satIOContext->satIntIoContext = agNULL;
22435 satIOContext->satOrgIOContext = agNULL;
22436 /* followings are used only for internal IO */
22437 satIOContext->currentLBA = 0;
22438 satIOContext->OrgTL = 0;
22439 satIOContext->satToBeAbortedIOContext = agNULL;
22440 satIOContext->NotifyOS = agFALSE;
22442 /* saving port ID just in case of full discovery to full discovery transition */
22443 satIOContext->pid = oneDeviceData->tdPortContext->id;
22444 osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0x0, sizeof(agsaSATAIdentifyData_t));
22445 status = tdsaDiscoveryIntStartIDDev(tiRoot,
22446 tiIORequest, /* agNULL */
22447 tiDeviceHandle, /* &(oneDeviceData->tiDeviceHandle)*/
22451 if (status != tiSuccess)
22453 TI_DBG1(("tdsaDiscoveryStartIDDev: failed in sending %d\n", status));
22454 ostiFreeMemory(tiRoot, osMemHandle, sizeof(tdIORequestBody_t));
22459 /*****************************************************************************/
22460 /*! \brief SAT implementation for tdsaDiscoveryIntStartIDDev.
22462 * This function sends identify device data to SATA device.
22464 * \param tiRoot: Pointer to TISA initiator driver/port instance.
22465 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
22466 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
22467 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
22468 * \param satIOContext_t: Pointer to the SAT IO Context
22470 * \return If command is started successfully
22471 * - \e tiSuccess: I/O request successfully initiated.
22472 * - \e tiBusy: No resources available, try again later.
22473 * - \e tiIONoDevice: Invalid device handle.
22474 * - \e tiError: Other errors.
22476 /*****************************************************************************/
22478 tdsaDiscoveryIntStartIDDev(tiRoot_t *tiRoot,
22479 tiIORequest_t *tiIORequest, /* agNULL */
22480 tiDeviceHandle_t *tiDeviceHandle,
22481 tiScsiInitiatorRequest_t *tiScsiRequest, /* agNULL */
22482 satIOContext_t *satIOContext
22485 satInternalIo_t *satIntIo = agNULL;
22486 satDeviceData_t *satDevData = agNULL;
22487 tdIORequestBody_t *tdIORequestBody;
22488 satIOContext_t *satNewIOContext;
22491 TI_DBG3(("tdsaDiscoveryIntStartIDDev: start\n"));
22493 satDevData = satIOContext->pSatDevData;
22495 /* allocate identify device command */
22496 satIntIo = satAllocIntIoResource( tiRoot,
22499 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
22502 if (satIntIo == agNULL)
22504 TI_DBG2(("tdsaDiscoveryIntStartIDDev: can't alloacate\n"));
22509 /* fill in fields */
22510 /* real ttttttthe one worked and the same; 5/21/07/ */
22511 satIntIo->satOrgTiIORequest = tiIORequest; /* changed */
22512 tdIORequestBody = satIntIo->satIntRequestBody;
22513 satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
22515 satNewIOContext->pSatDevData = satDevData;
22516 satNewIOContext->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
22517 satNewIOContext->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
22518 satNewIOContext->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
22519 satNewIOContext->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
22520 satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */
22521 satNewIOContext->interruptContext = tiInterruptContext;
22522 satNewIOContext->satIntIoContext = satIntIo;
22524 satNewIOContext->ptiDeviceHandle = agNULL;
22525 satNewIOContext->satOrgIOContext = satIOContext; /* changed */
22527 /* this is valid only for TD layer generated (not triggered by OS at all) IO */
22528 satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
22531 TI_DBG6(("tdsaDiscoveryIntStartIDDev: OS satIOContext %p \n", satIOContext));
22532 TI_DBG6(("tdsaDiscoveryIntStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
22533 TI_DBG6(("tdsaDiscoveryIntStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
22534 TI_DBG6(("tdsaDiscoveryIntStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
22538 TI_DBG3(("tdsaDiscoveryIntStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
22540 status = tdsaDiscoverySendIDDev(tiRoot,
22541 &satIntIo->satIntTiIORequest, /* New tiIORequest */
22543 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
22546 if (status != tiSuccess)
22548 TI_DBG1(("tdsaDiscoveryIntStartIDDev: failed in sending %d\n", status));
22550 satFreeIntIoResource( tiRoot,
22558 TI_DBG6(("tdsaDiscoveryIntStartIDDev: end\n"));
22564 /*****************************************************************************/
22565 /*! \brief SAT implementation for tdsaDiscoverySendIDDev.
22567 * This function prepares identify device data FIS and sends it to SATA device.
22569 * \param tiRoot: Pointer to TISA initiator driver/port instance.
22570 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
22571 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
22572 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
22573 * \param satIOContext_t: Pointer to the SAT IO Context
22575 * \return If command is started successfully
22576 * - \e tiSuccess: I/O request successfully initiated.
22577 * - \e tiBusy: No resources available, try again later.
22578 * - \e tiIONoDevice: Invalid device handle.
22579 * - \e tiError: Other errors.
22581 /*****************************************************************************/
22583 tdsaDiscoverySendIDDev(tiRoot_t *tiRoot,
22584 tiIORequest_t *tiIORequest,
22585 tiDeviceHandle_t *tiDeviceHandle,
22586 tiScsiInitiatorRequest_t *tiScsiRequest,
22587 satIOContext_t *satIOContext
22591 bit32 agRequestType;
22592 satDeviceData_t *pSatDevData;
22593 agsaFisRegHostToDevice_t *fis;
22594 #ifdef TD_DEBUG_ENABLE
22595 tdIORequestBody_t *tdIORequestBody;
22596 satInternalIo_t *satIntIoContext;
22599 pSatDevData = satIOContext->pSatDevData;
22600 fis = satIOContext->pFis;
22601 TI_DBG3(("tdsaDiscoverySendIDDev: start\n"));
22602 #ifdef TD_DEBUG_ENABLE
22603 satIntIoContext = satIOContext->satIntIoContext;
22604 tdIORequestBody = satIntIoContext->satIntRequestBody;
22606 TI_DBG5(("tdsaDiscoverySendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
22608 fis->h.fisType = 0x27; /* Reg host to device */
22609 fis->h.c_pmPort = 0x80; /* C Bit is set */
22610 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
22611 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0xA1 */
22613 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */
22614 fis->h.features = 0; /* FIS reserve */
22615 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
22616 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
22617 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
22618 fis->d.device = 0; /* FIS LBA mode */
22619 fis->d.lbaLowExp = 0;
22620 fis->d.lbaMidExp = 0;
22621 fis->d.lbaHighExp = 0;
22622 fis->d.featuresExp = 0;
22623 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
22624 fis->d.sectorCountExp = 0;
22625 fis->d.reserved4 = 0;
22626 fis->d.control = 0; /* FIS HOB bit clear */
22627 fis->d.reserved5 = 0;
22629 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
22631 /* Initialize CB for SATA completion.
22633 satIOContext->satCompleteCB = &tdsaDiscoveryStartIDDevCB;
22636 * Prepare SGL and send FIS to LL layer.
22638 satIOContext->reqType = agRequestType; /* Save it */
22640 #ifdef TD_INTERNAL_DEBUG
22641 tdhexdump("tdsaDiscoverySendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
22642 #ifdef TD_DEBUG_ENABLE
22643 tdhexdump("tdsaDiscoverySendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
22646 status = sataLLIOStart( tiRoot,
22651 TI_DBG3(("tdsaDiscoverySendIDDev: end status %d\n", status));
22656 /*****************************************************************************
22657 *! \brief tdsaDiscoveryStartIDDevCB
22659 * This routine is a callback function for tdsaDiscoverySendIDDev()
22660 * Using Identify Device Data, this function finds whether devicedata is
22661 * new or old. If new, add it to the devicelist. This is done as a part
22664 * \param agRoot: Handles for this instance of SAS/SATA hardware
22665 * \param agIORequest: Pointer to the LL I/O request context for this I/O.
22666 * \param agIOStatus: Status of completed I/O.
22667 * \param agFirstDword:Pointer to the four bytes of FIS.
22668 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
22670 * \param agParam: Additional info based on status.
22671 * \param ioContext: Pointer to satIOContext_t.
22675 *****************************************************************************/
22676 void tdsaDiscoveryStartIDDevCB(
22677 agsaRoot_t *agRoot,
22678 agsaIORequest_t *agIORequest,
22680 agsaFisHeader_t *agFirstDword,
22687 In the process of SAT_IDENTIFY_DEVICE during discovery
22689 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
22690 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
22691 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
22692 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
22693 tdIORequestBody_t *tdIORequestBody;
22694 tdIORequestBody_t *tdOrgIORequestBody;
22695 satIOContext_t *satIOContext;
22696 satIOContext_t *satOrgIOContext;
22697 satIOContext_t *satNewIOContext;
22698 satInternalIo_t *satIntIo;
22699 satInternalIo_t *satNewIntIo = agNULL;
22700 satDeviceData_t *satDevData;
22701 tiIORequest_t *tiOrgIORequest = agNULL;
22703 #ifdef TD_DEBUG_ENABLE
22704 bit32 ataStatus = 0;
22706 agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL;
22708 agsaSATAIdentifyData_t *pSATAIdData;
22709 bit16 *tmpptr, tmpptr_tmp;
22711 tdsaDeviceData_t *oneDeviceData = agNULL;
22712 void *sglVirtualAddr;
22713 tdsaPortContext_t *onePortContext = agNULL;
22714 tiPortalContext_t *tiPortalContext = agNULL;
22715 bit32 retry_status;
22717 TI_DBG3(("tdsaDiscoveryStartIDDevCB: start\n"));
22719 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
22720 satIOContext = (satIOContext_t *) ioContext;
22721 satIntIo = satIOContext->satIntIoContext;
22722 satDevData = satIOContext->pSatDevData;
22723 oneDeviceData = (tdsaDeviceData_t *)tdIORequestBody->tiDevHandle->tdData;
22724 TI_DBG3(("tdsaDiscoveryStartIDDevCB: did %d\n", oneDeviceData->id));
22725 onePortContext = oneDeviceData->tdPortContext;
22726 if (onePortContext == agNULL)
22728 TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext is NULL\n"));
22731 tiPortalContext= onePortContext->tiPortalContext;
22733 satDevData->IDDeviceValid = agFALSE;
22735 if (satIntIo == agNULL)
22737 TI_DBG1(("tdsaDiscoveryStartIDDevCB: External, OS generated\n"));
22738 TI_DBG1(("tdsaDiscoveryStartIDDevCB: Not possible case\n"));
22739 satOrgIOContext = satIOContext;
22740 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
22742 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22744 satFreeIntIoResource( tiRoot,
22748 /* clean up TD layer's IORequestBody */
22751 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22752 sizeof(tdIORequestBody_t)
22758 TI_DBG3(("tdsaDiscoveryStartIDDevCB: Internal, TD generated\n"));
22759 satOrgIOContext = satIOContext->satOrgIOContext;
22760 if (satOrgIOContext == agNULL)
22762 TI_DBG6(("tdsaDiscoveryStartIDDevCB: satOrgIOContext is NULL\n"));
22767 TI_DBG6(("tdsaDiscoveryStartIDDevCB: satOrgIOContext is NOT NULL\n"));
22768 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
22769 sglVirtualAddr = satIntIo->satIntTiScsiXchg.sglVirtualAddr;
22773 tiOrgIORequest = tdIORequestBody->tiIORequest;
22774 tdIORequestBody->ioCompleted = agTRUE;
22775 tdIORequestBody->ioStarted = agFALSE;
22777 TI_DBG3(("tdsaDiscoveryStartIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
22779 /* protect against double completion for old port */
22780 if (satOrgIOContext->pid != oneDeviceData->tdPortContext->id)
22782 TI_DBG3(("tdsaDiscoveryStartIDDevCB: incorrect pid\n"));
22783 TI_DBG3(("tdsaDiscoveryStartIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
22784 TI_DBG3(("tdsaDiscoveryStartIDDevCB: tiPortalContext pid %d\n", oneDeviceData->tdPortContext->id));
22786 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22788 satFreeIntIoResource( tiRoot,
22792 /* clean up TD layer's IORequestBody */
22795 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22796 sizeof(tdIORequestBody_t)
22802 /* completion after portcontext is invalidated */
22803 if (onePortContext != agNULL)
22805 if (onePortContext->valid == agFALSE)
22807 TI_DBG1(("tdsaDiscoveryStartIDDevCB: portcontext is invalid\n"));
22808 TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext->id pid %d\n", onePortContext->id));
22809 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22811 satFreeIntIoResource( tiRoot,
22815 /* clean up TD layer's IORequestBody */
22818 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22819 sizeof(tdIORequestBody_t)
22822 /* no notification to OS layer */
22827 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
22829 TI_DBG1(("tdsaDiscoveryStartIDDevCB: agFirstDword is NULL when error, status %d\n", agIOStatus));
22830 TI_DBG1(("tdsaDiscoveryStartIDDevCB: did %d\n", oneDeviceData->id));
22832 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
22834 satIOContext->pSatDevData->satPendingNONNCQIO--;
22835 satIOContext->pSatDevData->satPendingIO--;
22836 retry_status = sataLLIOStart(tiRoot,
22837 &satIntIo->satIntTiIORequest,
22838 &(oneDeviceData->tiDeviceHandle),
22839 satIOContext->tiScsiXchg,
22841 if (retry_status != tiSuccess)
22843 /* simply give up */
22844 satDevData->ID_Retries = 0;
22845 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22847 satFreeIntIoResource( tiRoot,
22851 /* clean up TD layer's IORequestBody */
22854 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22855 sizeof(tdIORequestBody_t)
22859 satDevData->ID_Retries++;
22860 tdIORequestBody->ioCompleted = agFALSE;
22861 tdIORequestBody->ioStarted = agTRUE;
22866 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22867 satFreeIntIoResource( tiRoot,
22871 /* clean up TD layer's IORequestBody */
22874 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22875 sizeof(tdIORequestBody_t)
22877 if (tdsaAllShared->ResetInDiscovery != 0)
22879 /* ResetInDiscovery in on */
22880 if (satDevData->NumOfIDRetries <= 0)
22882 satDevData->NumOfIDRetries++;
22883 satDevData->ID_Retries = 0;
22884 /* send link reset */
22885 tdsaPhyControlSend(tiRoot,
22887 SMP_PHY_CONTROL_HARD_RESET,
22889 tdsaRotateQnumber(tiRoot, oneDeviceData)
22897 if (agIOStatus == OSSA_IO_ABORTED ||
22898 agIOStatus == OSSA_IO_UNDERFLOW ||
22899 agIOStatus == OSSA_IO_XFER_ERROR_BREAK ||
22900 agIOStatus == OSSA_IO_XFER_ERROR_PHY_NOT_READY ||
22901 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
22902 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
22903 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
22904 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
22905 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
22906 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY ||
22907 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
22908 agIOStatus == OSSA_IO_XFER_ERROR_NAK_RECEIVED ||
22909 agIOStatus == OSSA_IO_XFER_ERROR_DMA ||
22910 agIOStatus == OSSA_IO_XFER_ERROR_SATA_LINK_TIMEOUT ||
22911 agIOStatus == OSSA_IO_XFER_ERROR_REJECTED_NCQ_MODE ||
22912 agIOStatus == OSSA_IO_XFER_OPEN_RETRY_TIMEOUT ||
22913 agIOStatus == OSSA_IO_NO_DEVICE ||
22914 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
22915 agIOStatus == OSSA_IO_PORT_IN_RESET ||
22916 agIOStatus == OSSA_IO_DS_NON_OPERATIONAL ||
22917 agIOStatus == OSSA_IO_DS_IN_RECOVERY ||
22918 agIOStatus == OSSA_IO_DS_IN_ERROR
22921 TI_DBG1(("tdsaDiscoveryStartIDDevCB: OSSA_IO_OPEN_CNX_ERROR 0x%x\n", agIOStatus));
22922 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
22924 satIOContext->pSatDevData->satPendingNONNCQIO--;
22925 satIOContext->pSatDevData->satPendingIO--;
22926 retry_status = sataLLIOStart(tiRoot,
22927 &satIntIo->satIntTiIORequest,
22928 &(oneDeviceData->tiDeviceHandle),
22929 satIOContext->tiScsiXchg,
22931 if (retry_status != tiSuccess)
22933 /* simply give up */
22934 satDevData->ID_Retries = 0;
22935 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22937 satFreeIntIoResource( tiRoot,
22941 /* clean up TD layer's IORequestBody */
22944 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22945 sizeof(tdIORequestBody_t)
22949 satDevData->ID_Retries++;
22950 tdIORequestBody->ioCompleted = agFALSE;
22951 tdIORequestBody->ioStarted = agTRUE;
22956 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22957 satFreeIntIoResource( tiRoot,
22961 /* clean up TD layer's IORequestBody */
22964 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22965 sizeof(tdIORequestBody_t)
22967 if (tdsaAllShared->ResetInDiscovery != 0)
22969 /* ResetInDiscovery in on */
22970 if (satDevData->NumOfIDRetries <= 0)
22972 satDevData->NumOfIDRetries++;
22973 satDevData->ID_Retries = 0;
22974 /* send link reset */
22975 tdsaPhyControlSend(tiRoot,
22977 SMP_PHY_CONTROL_HARD_RESET,
22979 tdsaRotateQnumber(tiRoot, oneDeviceData)
22987 if ( agIOStatus != OSSA_IO_SUCCESS ||
22988 (agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0)
22991 #ifdef TD_DEBUG_ENABLE
22992 /* only agsaFisPioSetup_t is expected */
22993 satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
22994 ataStatus = satPIOSetupHeader->status; /* ATA Status register */
22995 ataError = satPIOSetupHeader->error; /* ATA Eror register */
22997 TI_DBG1(("tdsaDiscoveryStartIDDevCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
22999 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
23001 satIOContext->pSatDevData->satPendingNONNCQIO--;
23002 satIOContext->pSatDevData->satPendingIO--;
23003 retry_status = sataLLIOStart(tiRoot,
23004 &satIntIo->satIntTiIORequest,
23005 &(oneDeviceData->tiDeviceHandle),
23006 satIOContext->tiScsiXchg,
23008 if (retry_status != tiSuccess)
23010 /* simply give up */
23011 satDevData->ID_Retries = 0;
23012 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
23014 satFreeIntIoResource( tiRoot,
23018 /* clean up TD layer's IORequestBody */
23021 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23022 sizeof(tdIORequestBody_t)
23026 satDevData->ID_Retries++;
23027 tdIORequestBody->ioCompleted = agFALSE;
23028 tdIORequestBody->ioStarted = agTRUE;
23033 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
23034 satFreeIntIoResource( tiRoot,
23038 /* clean up TD layer's IORequestBody */
23041 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23042 sizeof(tdIORequestBody_t)
23044 if (tdsaAllShared->ResetInDiscovery != 0)
23046 /* ResetInDiscovery in on */
23047 if (satDevData->NumOfIDRetries <= 0)
23049 satDevData->NumOfIDRetries++;
23050 satDevData->ID_Retries = 0;
23051 /* send link reset */
23052 tdsaPhyControlSend(tiRoot,
23054 SMP_PHY_CONTROL_HARD_RESET,
23056 tdsaRotateQnumber(tiRoot, oneDeviceData)
23066 TI_DBG3(("tdsaDiscoveryStartIDDevCB: Success\n"));
23067 TI_DBG3(("tdsaDiscoveryStartIDDevCB: Success did %d\n", oneDeviceData->id));
23069 /* Convert to host endian */
23070 tmpptr = (bit16*)sglVirtualAddr;
23071 for (x=0; x < sizeof(agsaSATAIdentifyData_t)/sizeof(bit16); x++)
23073 OSSA_READ_LE_16(AGROOT, &tmpptr_tmp, tmpptr, 0);
23074 *tmpptr = tmpptr_tmp;
23078 pSATAIdData = (agsaSATAIdentifyData_t *)sglVirtualAddr;
23079 //tdhexdump("satAddSATAIDDevCB before", (bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
23081 TI_DBG5(("tdsaDiscoveryStartIDDevCB: OS satOrgIOContext %p \n", satOrgIOContext));
23082 TI_DBG5(("tdsaDiscoveryStartIDDevCB: TD satIOContext %p \n", satIOContext));
23083 TI_DBG5(("tdsaDiscoveryStartIDDevCB: OS tiScsiXchg %p \n", satOrgIOContext->tiScsiXchg));
23084 TI_DBG5(("tdsaDiscoveryStartIDDevCB: TD tiScsiXchg %p \n", satIOContext->tiScsiXchg));
23087 /* copy ID Dev data to satDevData */
23088 satDevData->satIdentifyData = *pSATAIdData;
23089 satDevData->IDDeviceValid = agTRUE;
23091 #ifdef TD_INTERNAL_DEBUG
23092 tdhexdump("tdsaDiscoveryStartIDDevCB ID Dev data",(bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
23093 tdhexdump("tdsaDiscoveryStartIDDevCB Device ID Dev data",(bit8 *)&satDevData->satIdentifyData, sizeof(agsaSATAIdentifyData_t));
23096 /* set satDevData fields from IndentifyData */
23097 satSetDevInfo(satDevData,pSATAIdData);
23098 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
23100 satFreeIntIoResource( tiRoot,
23104 if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
23106 /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/
23107 satNewIntIo = satAllocIntIoResource( tiRoot,
23113 if (satNewIntIo == agNULL)
23115 TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
23116 /* clean up TD layer's IORequestBody */
23119 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23120 sizeof(tdIORequestBody_t)
23123 } /* end memory allocation */
23125 satNewIOContext = satPrepareNewIO(satNewIntIo,
23131 /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/
23132 retry_status = satSetFeatures(tiRoot,
23133 &satNewIntIo->satIntTiIORequest,
23134 satNewIOContext->ptiDeviceHandle,
23135 &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */
23138 if (retry_status != tiSuccess)
23140 satFreeIntIoResource(tiRoot, satDevData, satIntIo);
23141 /* clean up TD layer's IORequestBody */
23144 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23145 sizeof(tdIORequestBody_t)
23151 /* clean up TD layer's IORequestBody */
23154 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23155 sizeof(tdIORequestBody_t)
23157 if (onePortContext != agNULL)
23159 if (onePortContext->DiscoveryState == ITD_DSTATE_COMPLETED)
23161 TI_DBG1(("tdsaDiscoveryStartIDDevCB: ID completed after discovery is done; tiDeviceArrival\n"));
23162 /* in case registration is finished after discovery is finished */
23163 ostiInitiatorEvent(
23167 tiIntrEventTypeDeviceChange,
23175 TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext is NULL, wrong\n"));
23178 TI_DBG3(("tdsaDiscoveryStartIDDevCB: end\n"));
23181 /*****************************************************************************
23184 * This routine does local abort for outstanding FIS.
23186 * \param agRoot: Handles for this instance of SAS/SATA hardware
23187 * \param satIOContext: Pointer to satIOContext_t.
23191 *****************************************************************************/
23192 GLOBAL void satAbort(agsaRoot_t *agRoot,
23193 satIOContext_t *satIOContext)
23195 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
23196 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
23197 tdIORequestBody_t *tdIORequestBody; /* io to be aborted */
23198 tdIORequestBody_t *tdAbortIORequestBody; /* abort io itself */
23199 agsaIORequest_t *agToBeAbortedIORequest; /* io to be aborted */
23200 agsaIORequest_t *agAbortIORequest; /* abort io itself */
23203 bit32 memAllocStatus;
23206 TI_DBG1(("satAbort: start\n"));
23208 if (satIOContext == agNULL)
23210 TI_DBG1(("satAbort: satIOContext is NULL, wrong\n"));
23213 tdIORequestBody = (tdIORequestBody_t *)satIOContext->tiRequestBody;
23214 agToBeAbortedIORequest = (agsaIORequest_t *)&(tdIORequestBody->agIORequest);
23215 /* allocating agIORequest for abort itself */
23216 memAllocStatus = ostiAllocMemory(
23219 (void **)&tdAbortIORequestBody,
23223 sizeof(tdIORequestBody_t),
23227 if (memAllocStatus != tiSuccess)
23229 /* let os process IO */
23230 TI_DBG1(("satAbort: ostiAllocMemory failed...\n"));
23234 if (tdAbortIORequestBody == agNULL)
23236 /* let os process IO */
23237 TI_DBG1(("satAbort: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
23240 /* setup task management structure */
23241 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
23242 tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle;
23244 /* initialize agIORequest */
23245 agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
23246 agAbortIORequest->osData = (void *) tdAbortIORequestBody;
23247 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
23253 saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agToBeAbortedIORequest, agNULL );
23256 TI_DBG1(("satAbort: end\n"));
23260 /*****************************************************************************
23261 *! \brief satSATADeviceReset
23263 * This routine is called to reset all phys of port which a device belongs to
23265 * \param tiRoot: Pointer to TISA initiator driver/port instance.
23266 * \param oneDeviceData: Pointer to the device data.
23267 * \param flag: reset flag
23273 *****************************************************************************/
23275 satSATADeviceReset( tiRoot_t *tiRoot,
23276 tdsaDeviceData_t *oneDeviceData,
23279 agsaRoot_t *agRoot;
23280 tdsaPortContext_t *onePortContext;
23283 TI_DBG1(("satSATADeviceReset: start\n"));
23284 agRoot = oneDeviceData->agRoot;
23285 onePortContext = oneDeviceData->tdPortContext;
23287 if (agRoot == agNULL)
23289 TI_DBG1(("satSATADeviceReset: Error!!! agRoot is NULL\n"));
23292 if (onePortContext == agNULL)
23294 TI_DBG1(("satSATADeviceReset: Error!!! onePortContext is NULL\n"));
23298 for(i=0;i<TD_MAX_NUM_PHYS;i++)
23300 if (onePortContext->PhyIDList[i] == agTRUE)
23302 saLocalPhyControl(agRoot, agNULL, tdsaRotateQnumber(tiRoot, agNULL), i, flag, agNULL);
23309 #endif /* #ifdef SATA_ENABLE */