1 /******************************************************************************* 2 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 3 * 4 *Redistribution and use in source and binary forms, with or without modification, are permitted provided 5 *that the following conditions are met: 6 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 7 *following disclaimer. 8 *2. Redistributions in binary form must reproduce the above copyright notice, 9 *this list of conditions and the following disclaimer in the documentation and/or other materials provided 10 *with the distribution. 11 * 12 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 13 *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 14 *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 15 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 16 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 17 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 18 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 19 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 20 21 ********************************************************************************/ 22 /*****************************************************************************/ 23 /** \file 24 * 25 * The file implementing SCSI/ATA Translation (SAT). 26 * The routines in this file are independent from HW LL API. 27 * 28 */ 29 /*****************************************************************************/ 30 #include <sys/cdefs.h> 31 #include <dev/pms/config.h> 32 33 #include <dev/pms/freebsd/driver/common/osenv.h> 34 #include <dev/pms/freebsd/driver/common/ostypes.h> 35 #include <dev/pms/freebsd/driver/common/osdebug.h> 36 37 #ifdef SATA_ENABLE 38 39 #include <dev/pms/RefTisa/sallsdk/api/sa.h> 40 #include <dev/pms/RefTisa/sallsdk/api/saapi.h> 41 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h> 42 43 #include <dev/pms/RefTisa/tisa/api/titypes.h> 44 #include <dev/pms/RefTisa/tisa/api/ostiapi.h> 45 #include <dev/pms/RefTisa/tisa/api/tiapi.h> 46 #include <dev/pms/RefTisa/tisa/api/tiglobal.h> 47 48 #ifdef FDS_SM 49 #include <dev/pms/RefTisa/sat/api/sm.h> 50 #include <dev/pms/RefTisa/sat/api/smapi.h> 51 #include <dev/pms/RefTisa/sat/api/tdsmapi.h> 52 #endif 53 54 #ifdef FDS_DM 55 #include <dev/pms/RefTisa/discovery/api/dm.h> 56 #include <dev/pms/RefTisa/discovery/api/dmapi.h> 57 #include <dev/pms/RefTisa/discovery/api/tddmapi.h> 58 #endif 59 60 #include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h> 61 #include <dev/pms/freebsd/driver/common/osstring.h> 62 #include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h> 63 64 #ifdef INITIATOR_DRIVER 65 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h> 66 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h> 67 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h> 68 #endif 69 70 #ifdef TARGET_DRIVER 71 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h> 72 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h> 73 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h> 74 #endif 75 76 #include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h> 77 #include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h> 78 79 #include <dev/pms/RefTisa/tisa/sassata/sata/host/sat.h> 80 #include <dev/pms/RefTisa/tisa/sassata/sata/host/satproto.h> 81 82 /***************************************************************************** 83 *! \brief satIOStart 84 * 85 * This routine is called to initiate a new SCSI request to SATL. 86 * 87 * \param tiRoot: Pointer to TISA initiator driver/port instance. 88 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 89 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 90 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 91 * \param satIOContext_t: Pointer to the SAT IO Context 92 * 93 * \return: 94 * 95 * \e tiSuccess: I/O request successfully initiated. 96 * \e tiBusy: No resources available, try again later. 97 * \e tiIONoDevice: Invalid device handle. 98 * \e tiError: Other errors that prevent the I/O request to be started. 99 * 100 * 101 *****************************************************************************/ 102 GLOBAL bit32 satIOStart( 103 tiRoot_t *tiRoot, 104 tiIORequest_t *tiIORequest, 105 tiDeviceHandle_t *tiDeviceHandle, 106 tiScsiInitiatorRequest_t *tiScsiRequest, 107 satIOContext_t *satIOContext 108 ) 109 { 110 111 bit32 retVal = tiSuccess; 112 satDeviceData_t *pSatDevData; 113 scsiRspSense_t *pSense; 114 tiIniScsiCmnd_t *scsiCmnd; 115 tiLUN_t *pLun; 116 satInternalIo_t *pSatIntIo; 117 #ifdef TD_DEBUG_ENABLE 118 tdsaDeviceData_t *oneDeviceData; 119 #endif 120 121 pSense = satIOContext->pSense; 122 pSatDevData = satIOContext->pSatDevData; 123 scsiCmnd = &tiScsiRequest->scsiCmnd; 124 pLun = &scsiCmnd->lun; 125 126 /* 127 * Reject all other LUN other than LUN 0. 128 */ 129 if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] | 130 pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) && 131 (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY) 132 ) 133 { 134 TI_DBG1(("satIOStart: *** REJECT *** LUN not zero, cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n", 135 scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle)); 136 satSetSensePayload( pSense, 137 SCSI_SNSKEY_ILLEGAL_REQUEST, 138 0, 139 SCSI_SNSCODE_LOGICAL_NOT_SUPPORTED, 140 satIOContext); 141 142 ostiInitiatorIOCompleted( tiRoot, 143 tiIORequest, 144 tiIOSuccess, 145 SCSI_STAT_CHECK_CONDITION, 146 satIOContext->pTiSenseData, 147 satIOContext->interruptContext ); 148 retVal = tiSuccess; 149 goto ext; 150 } 151 152 TI_DBG6(("satIOStart: satPendingIO %d satNCQMaxIO %d\n",pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO )); 153 154 /* this may happen after tiCOMReset until OS sends inquiry */ 155 if (pSatDevData->IDDeviceValid == agFALSE && (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY)) 156 { 157 #ifdef TD_DEBUG_ENABLE 158 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 159 #endif 160 TI_DBG1(("satIOStart: invalid identify device data did %d\n", oneDeviceData->id)); 161 retVal = tiIONoDevice; 162 goto ext; 163 } 164 /* 165 * Check if we need to return BUSY, i.e. recovery in progress 166 */ 167 if (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY) 168 { 169 #ifdef TD_DEBUG_ENABLE 170 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 171 #endif 172 TI_DBG1(("satIOStart: IN RECOVERY STATE cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n", 173 scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle)); 174 TI_DBG1(("satIOStart: IN RECOVERY STATE did %d\n", oneDeviceData->id)); 175 176 TI_DBG1(("satIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO )); 177 TI_DBG1(("satIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO)); 178 retVal = tiError; 179 goto ext; 180 // return tiBusy; 181 } 182 183 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE) 184 { 185 if (scsiCmnd->cdb[0] == SCSIOPC_REPORT_LUN) 186 { 187 return satReportLun(tiRoot, tiIORequest, tiDeviceHandle, tiScsiRequest, satIOContext); 188 } 189 else 190 { 191 return satPacket(tiRoot, tiIORequest, tiDeviceHandle, tiScsiRequest, satIOContext); 192 } 193 } 194 else /* pSatDevData->satDeviceType != SATA_ATAPI_DEVICE */ 195 { 196 /* Parse CDB */ 197 switch(scsiCmnd->cdb[0]) 198 { 199 case SCSIOPC_READ_6: 200 retVal = satRead6( tiRoot, 201 tiIORequest, 202 tiDeviceHandle, 203 tiScsiRequest, 204 satIOContext); 205 break; 206 207 case SCSIOPC_READ_10: 208 retVal = satRead10( tiRoot, 209 tiIORequest, 210 tiDeviceHandle, 211 tiScsiRequest, 212 satIOContext); 213 break; 214 215 case SCSIOPC_READ_12: 216 TI_DBG5(("satIOStart: SCSIOPC_READ_12\n")); 217 retVal = satRead12( tiRoot, 218 tiIORequest, 219 tiDeviceHandle, 220 tiScsiRequest, 221 satIOContext); 222 break; 223 224 case SCSIOPC_READ_16: 225 retVal = satRead16( tiRoot, 226 tiIORequest, 227 tiDeviceHandle, 228 tiScsiRequest, 229 satIOContext); 230 break; 231 232 case SCSIOPC_WRITE_6: 233 retVal = satWrite6( tiRoot, 234 tiIORequest, 235 tiDeviceHandle, 236 tiScsiRequest, 237 satIOContext); 238 break; 239 240 case SCSIOPC_WRITE_10: 241 retVal = satWrite10( tiRoot, 242 tiIORequest, 243 tiDeviceHandle, 244 tiScsiRequest, 245 satIOContext); 246 break; 247 248 case SCSIOPC_WRITE_12: 249 TI_DBG5(("satIOStart: SCSIOPC_WRITE_12 \n")); 250 retVal = satWrite12( tiRoot, 251 tiIORequest, 252 tiDeviceHandle, 253 tiScsiRequest, 254 satIOContext); 255 256 break; 257 258 case SCSIOPC_WRITE_16: 259 TI_DBG5(("satIOStart: SCSIOPC_WRITE_16\n")); 260 retVal = satWrite16( tiRoot, 261 tiIORequest, 262 tiDeviceHandle, 263 tiScsiRequest, 264 satIOContext); 265 266 break; 267 268 case SCSIOPC_VERIFY_10: 269 retVal = satVerify10( tiRoot, 270 tiIORequest, 271 tiDeviceHandle, 272 tiScsiRequest, 273 satIOContext); 274 break; 275 276 case SCSIOPC_VERIFY_12: 277 TI_DBG5(("satIOStart: SCSIOPC_VERIFY_12\n")); 278 retVal = satVerify12( tiRoot, 279 tiIORequest, 280 tiDeviceHandle, 281 tiScsiRequest, 282 satIOContext); 283 break; 284 285 case SCSIOPC_VERIFY_16: 286 TI_DBG5(("satIOStart: SCSIOPC_VERIFY_16\n")); 287 retVal = satVerify16( tiRoot, 288 tiIORequest, 289 tiDeviceHandle, 290 tiScsiRequest, 291 satIOContext); 292 break; 293 294 case SCSIOPC_TEST_UNIT_READY: 295 retVal = satTestUnitReady( tiRoot, 296 tiIORequest, 297 tiDeviceHandle, 298 tiScsiRequest, 299 satIOContext); 300 break; 301 302 case SCSIOPC_INQUIRY: 303 retVal = satInquiry( tiRoot, 304 tiIORequest, 305 tiDeviceHandle, 306 tiScsiRequest, 307 satIOContext); 308 break; 309 310 case SCSIOPC_REQUEST_SENSE: 311 retVal = satRequestSense( tiRoot, 312 tiIORequest, 313 tiDeviceHandle, 314 tiScsiRequest, 315 satIOContext); 316 break; 317 318 case SCSIOPC_MODE_SENSE_6: 319 retVal = satModeSense6( tiRoot, 320 tiIORequest, 321 tiDeviceHandle, 322 tiScsiRequest, 323 satIOContext); 324 break; 325 326 case SCSIOPC_MODE_SENSE_10: 327 retVal = satModeSense10( tiRoot, 328 tiIORequest, 329 tiDeviceHandle, 330 tiScsiRequest, 331 satIOContext); 332 break; 333 334 335 case SCSIOPC_READ_CAPACITY_10: 336 retVal = satReadCapacity10( tiRoot, 337 tiIORequest, 338 tiDeviceHandle, 339 tiScsiRequest, 340 satIOContext); 341 break; 342 343 case SCSIOPC_READ_CAPACITY_16: 344 retVal = satReadCapacity16( tiRoot, 345 tiIORequest, 346 tiDeviceHandle, 347 tiScsiRequest, 348 satIOContext); 349 break; 350 351 case SCSIOPC_REPORT_LUN: 352 retVal = satReportLun( tiRoot, 353 tiIORequest, 354 tiDeviceHandle, 355 tiScsiRequest, 356 satIOContext); 357 break; 358 359 case SCSIOPC_FORMAT_UNIT: 360 TI_DBG5(("satIOStart: SCSIOPC_FORMAT_UNIT\n")); 361 retVal = satFormatUnit( tiRoot, 362 tiIORequest, 363 tiDeviceHandle, 364 tiScsiRequest, 365 satIOContext); 366 break; 367 case SCSIOPC_SEND_DIAGNOSTIC: /* Table 28, p40 */ 368 TI_DBG5(("satIOStart: SCSIOPC_SEND_DIAGNOSTIC\n")); 369 retVal = satSendDiagnostic( tiRoot, 370 tiIORequest, 371 tiDeviceHandle, 372 tiScsiRequest, 373 satIOContext); 374 break; 375 376 case SCSIOPC_START_STOP_UNIT: 377 TI_DBG5(("satIOStart: SCSIOPC_START_STOP_UNIT\n")); 378 retVal = satStartStopUnit( tiRoot, 379 tiIORequest, 380 tiDeviceHandle, 381 tiScsiRequest, 382 satIOContext); 383 break; 384 385 case SCSIOPC_WRITE_SAME_10: /* sector and LBA; SAT p64 case 3 accessing payload and very 386 inefficient now */ 387 TI_DBG5(("satIOStart: SCSIOPC_WRITE_SAME_10\n")); 388 retVal = satWriteSame10( tiRoot, 389 tiIORequest, 390 tiDeviceHandle, 391 tiScsiRequest, 392 satIOContext); 393 break; 394 395 case SCSIOPC_WRITE_SAME_16: /* no support due to transfer length(sector count) */ 396 TI_DBG5(("satIOStart: SCSIOPC_WRITE_SAME_16\n")); 397 retVal = satWriteSame16( tiRoot, 398 tiIORequest, 399 tiDeviceHandle, 400 tiScsiRequest, 401 satIOContext); 402 break; 403 404 case SCSIOPC_LOG_SENSE: /* SCT and log parameter(informational exceptions) */ 405 TI_DBG5(("satIOStart: SCSIOPC_LOG_SENSE\n")); 406 retVal = satLogSense( tiRoot, 407 tiIORequest, 408 tiDeviceHandle, 409 tiScsiRequest, 410 satIOContext); 411 break; 412 413 case SCSIOPC_MODE_SELECT_6: /*mode layout and AlloLen check */ 414 TI_DBG5(("satIOStart: SCSIOPC_MODE_SELECT_6\n")); 415 retVal = satModeSelect6( tiRoot, 416 tiIORequest, 417 tiDeviceHandle, 418 tiScsiRequest, 419 satIOContext); 420 break; 421 422 case SCSIOPC_MODE_SELECT_10: /* mode layout and AlloLen check and sharing CB with satModeSelect6*/ 423 TI_DBG5(("satIOStart: SCSIOPC_MODE_SELECT_10\n")); 424 retVal = satModeSelect10( tiRoot, 425 tiIORequest, 426 tiDeviceHandle, 427 tiScsiRequest, 428 satIOContext); 429 break; 430 431 case SCSIOPC_SYNCHRONIZE_CACHE_10: /* on error what to return, sharing CB with 432 satSynchronizeCache16 */ 433 TI_DBG5(("satIOStart: SCSIOPC_SYNCHRONIZE_CACHE_10\n")); 434 retVal = satSynchronizeCache10( tiRoot, 435 tiIORequest, 436 tiDeviceHandle, 437 tiScsiRequest, 438 satIOContext); 439 break; 440 441 case SCSIOPC_SYNCHRONIZE_CACHE_16:/* on error what to return, sharing CB with 442 satSynchronizeCache16 */ 443 444 TI_DBG5(("satIOStart: SCSIOPC_SYNCHRONIZE_CACHE_16\n")); 445 retVal = satSynchronizeCache16( tiRoot, 446 tiIORequest, 447 tiDeviceHandle, 448 tiScsiRequest, 449 satIOContext); 450 break; 451 452 case SCSIOPC_WRITE_AND_VERIFY_10: /* single write and multiple writes */ 453 TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_10\n")); 454 retVal = satWriteAndVerify10( tiRoot, 455 tiIORequest, 456 tiDeviceHandle, 457 tiScsiRequest, 458 satIOContext); 459 break; 460 461 case SCSIOPC_WRITE_AND_VERIFY_12: 462 TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_12\n")); 463 retVal = satWriteAndVerify12( tiRoot, 464 tiIORequest, 465 tiDeviceHandle, 466 tiScsiRequest, 467 satIOContext); 468 break; 469 470 case SCSIOPC_WRITE_AND_VERIFY_16: 471 TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_16\n")); 472 retVal = satWriteAndVerify16( tiRoot, 473 tiIORequest, 474 tiDeviceHandle, 475 tiScsiRequest, 476 satIOContext); 477 478 break; 479 480 case SCSIOPC_READ_MEDIA_SERIAL_NUMBER: 481 TI_DBG5(("satIOStart: SCSIOPC_READ_MEDIA_SERIAL_NUMBER\n")); 482 retVal = satReadMediaSerialNumber( tiRoot, 483 tiIORequest, 484 tiDeviceHandle, 485 tiScsiRequest, 486 satIOContext); 487 488 break; 489 490 case SCSIOPC_READ_BUFFER: 491 TI_DBG5(("satIOStart: SCSIOPC_READ_BUFFER\n")); 492 retVal = satReadBuffer( tiRoot, 493 tiIORequest, 494 tiDeviceHandle, 495 tiScsiRequest, 496 satIOContext); 497 498 break; 499 500 case SCSIOPC_WRITE_BUFFER: 501 TI_DBG5(("satIOStart: SCSIOPC_WRITE_BUFFER\n")); 502 retVal = satWriteBuffer( tiRoot, 503 tiIORequest, 504 tiDeviceHandle, 505 tiScsiRequest, 506 satIOContext); 507 508 break; 509 510 case SCSIOPC_REASSIGN_BLOCKS: 511 TI_DBG5(("satIOStart: SCSIOPC_REASSIGN_BLOCKS\n")); 512 retVal = satReassignBlocks( tiRoot, 513 tiIORequest, 514 tiDeviceHandle, 515 tiScsiRequest, 516 satIOContext); 517 518 break; 519 520 default: 521 /* Not implemented SCSI cmd, set up error response */ 522 TI_DBG1(("satIOStart: unsupported SCSI cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n", 523 scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle)); 524 525 satSetSensePayload( pSense, 526 SCSI_SNSKEY_ILLEGAL_REQUEST, 527 0, 528 SCSI_SNSCODE_INVALID_COMMAND, 529 satIOContext); 530 531 ostiInitiatorIOCompleted( tiRoot, 532 tiIORequest, 533 tiIOSuccess, 534 SCSI_STAT_CHECK_CONDITION, 535 satIOContext->pTiSenseData, 536 satIOContext->interruptContext ); 537 retVal = tiSuccess; 538 539 break; 540 541 } /* end switch */ 542 } 543 if (retVal == tiBusy) 544 { 545 #ifdef TD_DEBUG_ENABLE 546 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 547 #endif 548 TI_DBG1(("satIOStart: BUSY did %d\n", oneDeviceData->id)); 549 TI_DBG3(("satIOStart: LL is busy or target queue is full\n")); 550 TI_DBG3(("satIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO )); 551 TI_DBG3(("satIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO)); 552 pSatIntIo = satIOContext->satIntIoContext; 553 554 /* interal structure free */ 555 satFreeIntIoResource( tiRoot, 556 pSatDevData, 557 pSatIntIo); 558 } 559 560 ext: 561 return retVal; 562 } 563 564 565 /*****************************************************************************/ 566 /*! \brief Setup up the SCSI Sense response. 567 * 568 * This function is used to setup up the Sense Data payload for 569 * CHECK CONDITION status. 570 * 571 * \param pSense: Pointer to the scsiRspSense_t sense data structure. 572 * \param SnsKey: SCSI Sense Key. 573 * \param SnsInfo: SCSI Sense Info. 574 * \param SnsCode: SCSI Sense Code. 575 * 576 * \return: None 577 */ 578 /*****************************************************************************/ 579 void satSetSensePayload( scsiRspSense_t *pSense, 580 bit8 SnsKey, 581 bit32 SnsInfo, 582 bit16 SnsCode, 583 satIOContext_t *satIOContext 584 ) 585 { 586 /* for fixed format sense data, SPC-4, p37 */ 587 bit32 i; 588 bit32 senseLength; 589 590 TI_DBG5(("satSetSensePayload: start\n")); 591 592 senseLength = sizeof(scsiRspSense_t); 593 594 /* zero out the data area */ 595 for (i=0;i< senseLength;i++) 596 { 597 ((bit8*)pSense)[i] = 0; 598 } 599 600 /* 601 * SCSI Sense Data part of response data 602 */ 603 pSense->snsRespCode = 0x70; /* 0xC0 == vendor specific */ 604 /* 0x70 == standard current error */ 605 pSense->senseKey = SnsKey; 606 /* 607 * Put sense info in scsi order format 608 */ 609 pSense->info[0] = (bit8)((SnsInfo >> 24) & 0xff); 610 pSense->info[1] = (bit8)((SnsInfo >> 16) & 0xff); 611 pSense->info[2] = (bit8)((SnsInfo >> 8) & 0xff); 612 pSense->info[3] = (bit8)((SnsInfo) & 0xff); 613 pSense->addSenseLen = 11; /* fixed size of sense data = 18 */ 614 pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF); 615 pSense->senseQual = (bit8)(SnsCode & 0xFF); 616 /* 617 * Set pointer in scsi status 618 */ 619 switch(SnsKey) 620 { 621 /* 622 * set illegal request sense key specific error in cdb, no bit pointer 623 */ 624 case SCSI_SNSKEY_ILLEGAL_REQUEST: 625 pSense->skeySpecific[0] = 0xC8; 626 break; 627 628 default: 629 break; 630 } 631 /* setting sense data length */ 632 if (satIOContext != agNULL) 633 { 634 satIOContext->pTiSenseData->senseLen = 18; 635 } 636 else 637 { 638 TI_DBG1(("satSetSensePayload: satIOContext is NULL\n")); 639 } 640 } 641 642 /*****************************************************************************/ 643 /*! \brief Setup up the SCSI Sense response. 644 * 645 * This function is used to setup up the Sense Data payload for 646 * CHECK CONDITION status. 647 * 648 * \param pSense: Pointer to the scsiRspSense_t sense data structure. 649 * \param SnsKey: SCSI Sense Key. 650 * \param SnsInfo: SCSI Sense Info. 651 * \param SnsCode: SCSI Sense Code. 652 * 653 * \return: None 654 */ 655 /*****************************************************************************/ 656 657 void satSetDeferredSensePayload( scsiRspSense_t *pSense, 658 bit8 SnsKey, 659 bit32 SnsInfo, 660 bit16 SnsCode, 661 satIOContext_t *satIOContext 662 ) 663 { 664 /* for fixed format sense data, SPC-4, p37 */ 665 bit32 i; 666 bit32 senseLength; 667 668 senseLength = sizeof(scsiRspSense_t); 669 670 /* zero out the data area */ 671 for (i=0;i< senseLength;i++) 672 { 673 ((bit8*)pSense)[i] = 0; 674 } 675 676 /* 677 * SCSI Sense Data part of response data 678 */ 679 pSense->snsRespCode = 0x71; /* 0xC0 == vendor specific */ 680 /* 0x70 == standard current error */ 681 pSense->senseKey = SnsKey; 682 /* 683 * Put sense info in scsi order format 684 */ 685 pSense->info[0] = (bit8)((SnsInfo >> 24) & 0xff); 686 pSense->info[1] = (bit8)((SnsInfo >> 16) & 0xff); 687 pSense->info[2] = (bit8)((SnsInfo >> 8) & 0xff); 688 pSense->info[3] = (bit8)((SnsInfo) & 0xff); 689 pSense->addSenseLen = 11; /* fixed size of sense data = 18 */ 690 pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF); 691 pSense->senseQual = (bit8)(SnsCode & 0xFF); 692 /* 693 * Set pointer in scsi status 694 */ 695 switch(SnsKey) 696 { 697 /* 698 * set illegal request sense key specific error in cdb, no bit pointer 699 */ 700 case SCSI_SNSKEY_ILLEGAL_REQUEST: 701 pSense->skeySpecific[0] = 0xC8; 702 break; 703 704 default: 705 break; 706 } 707 708 /* setting sense data length */ 709 if (satIOContext != agNULL) 710 { 711 satIOContext->pTiSenseData->senseLen = 18; 712 } 713 else 714 { 715 TI_DBG1(("satSetDeferredSensePayload: satIOContext is NULL\n")); 716 } 717 718 } 719 /*****************************************************************************/ 720 /*! \brief SAT implementation for ATAPI Packet Command. 721 * 722 * SAT implementation for ATAPI Packet and send FIS request to LL layer. 723 * 724 * \param tiRoot: Pointer to TISA initiator driver/port instance. 725 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 726 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 727 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 728 * \param satIOContext_t: Pointer to the SAT IO Context 729 * 730 * \return If command is started successfully 731 * - \e tiSuccess: I/O request successfully initiated. 732 * - \e tiBusy: No resources available, try again later. 733 * - \e tiIONoDevice: Invalid device handle. 734 * - \e tiError: Other errors. 735 */ 736 /*****************************************************************************/ 737 GLOBAL bit32 satPacket( 738 tiRoot_t *tiRoot, 739 tiIORequest_t *tiIORequest, 740 tiDeviceHandle_t *tiDeviceHandle, 741 tiScsiInitiatorRequest_t *tiScsiRequest, 742 satIOContext_t *satIOContext) 743 { 744 bit32 status; 745 bit32 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT; 746 satDeviceData_t *pSatDevData; 747 tiIniScsiCmnd_t *scsiCmnd; 748 agsaFisRegHostToDevice_t *fis; 749 750 pSatDevData = satIOContext->pSatDevData; 751 scsiCmnd = &tiScsiRequest->scsiCmnd; 752 fis = satIOContext->pFis; 753 754 TI_DBG3(("satPacket: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n", 755 scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3], 756 scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7], 757 scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11])); 758 759 fis->h.fisType = 0x27; /* Reg host to device */ 760 fis->h.c_pmPort = 0x80; /* C Bit is set 1*/ 761 fis->h.command = SAT_PACKET; /* 0xA0 */ 762 if (pSatDevData->satDMADIRSupport) /* DMADIR enabled*/ 763 { 764 fis->h.features = (tiScsiRequest->dataDirection == tiDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */ 765 } 766 else 767 { 768 fis->h.features = 0; /* FIS reserve */ 769 } 770 /* Byte count low and byte count high */ 771 if ( scsiCmnd->expDataLength > 0xFFFF ) 772 { 773 fis->d.lbaMid = 0xFF; /* FIS LBA (7 :0 ) */ 774 fis->d.lbaHigh = 0xFF; /* FIS LBA (15:8 ) */ 775 } 776 else 777 { 778 fis->d.lbaMid = (bit8)scsiCmnd->expDataLength; /* FIS LBA (7 :0 ) */ 779 fis->d.lbaHigh = (bit8)(scsiCmnd->expDataLength>>8); /* FIS LBA (15:8 ) */ 780 } 781 782 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 783 fis->d.device = 0; /* FIS LBA (27:24) and FIS LBA mode */ 784 fis->d.lbaLowExp = 0; 785 fis->d.lbaMidExp = 0; 786 fis->d.lbaHighExp = 0; 787 fis->d.featuresExp = 0; 788 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 789 fis->d.sectorCountExp = 0; 790 fis->d.reserved4 = 0; 791 fis->d.control = 0; /* FIS HOB bit clear */ 792 fis->d.reserved5 = 0; 793 794 satIOContext->ATACmd = SAT_PACKET; 795 796 if (tiScsiRequest->dataDirection == tiDirectionIn) 797 { 798 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT; 799 } 800 else 801 { 802 agRequestType = AGSA_SATA_PROTOCOL_H2D_PKT; 803 } 804 805 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 806 { 807 /*DMA transfer mode*/ 808 fis->h.features |= 0x01; 809 } 810 else 811 { 812 /*PIO transfer mode*/ 813 fis->h.features |= 0x0; 814 } 815 816 satIOContext->satCompleteCB = &satPacketCB; 817 818 /* 819 * Prepare SGL and send FIS to LL layer. 820 */ 821 satIOContext->reqType = agRequestType; /* Save it */ 822 823 status = sataLLIOStart( tiRoot, 824 tiIORequest, 825 tiDeviceHandle, 826 tiScsiRequest, 827 satIOContext); 828 829 TI_DBG5(("satPacket: return\n")); 830 return (status); 831 } 832 833 /*****************************************************************************/ 834 /*! \brief SAT implementation for satSetFeatures. 835 * 836 * This function creates SetFeatures fis and sends the request to LL layer 837 * 838 * \param tiRoot: Pointer to TISA initiator driver/port instance. 839 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 840 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 841 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 842 * \param satIOContext_t: Pointer to the SAT IO Context 843 * 844 * \return If command is started successfully 845 * - \e tiSuccess: I/O request successfully initiated. 846 * - \e tiBusy: No resources available, try again later. 847 * - \e tiIONoDevice: Invalid device handle. 848 * - \e tiError: Other errors. 849 */ 850 /*****************************************************************************/ 851 GLOBAL bit32 satSetFeatures( 852 tiRoot_t *tiRoot, 853 tiIORequest_t *tiIORequest, 854 tiDeviceHandle_t *tiDeviceHandle, 855 tiScsiInitiatorRequest_t *tiScsiRequest, 856 satIOContext_t *satIOContext, 857 bit8 bIsDMAMode 858 ) 859 { 860 bit32 status; 861 bit32 agRequestType; 862 agsaFisRegHostToDevice_t *fis; 863 864 fis = satIOContext->pFis; 865 TI_DBG3(("satSetFeatures: start\n")); 866 867 /* 868 * Send the Set Features command. 869 */ 870 fis->h.fisType = 0x27; /* Reg host to device */ 871 fis->h.c_pmPort = 0x80; /* C Bit is set */ 872 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 873 fis->h.features = 0x03; /* set transfer mode */ 874 fis->d.lbaLow = 0; 875 fis->d.lbaMid = 0; 876 fis->d.lbaHigh = 0; 877 fis->d.device = 0; 878 fis->d.lbaLowExp = 0; 879 fis->d.lbaMidExp = 0; 880 fis->d.lbaHighExp = 0; 881 fis->d.featuresExp = 0; 882 fis->d.sectorCountExp = 0; 883 fis->d.reserved4 = 0; 884 fis->d.control = 0; /* FIS HOB bit clear */ 885 fis->d.reserved5 = 0; 886 887 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 888 889 /* Initialize CB for SATA completion. 890 */ 891 if (bIsDMAMode) 892 { 893 fis->d.sectorCount = 0x45; 894 /*satIOContext->satCompleteCB = &satSetFeaturesDMACB;*/ 895 } 896 else 897 { 898 fis->d.sectorCount = 0x0C; 899 /*satIOContext->satCompleteCB = &satSetFeaturesPIOCB;*/ 900 } 901 satIOContext->satCompleteCB = &satSetFeaturesCB; 902 903 /* 904 * Prepare SGL and send FIS to LL layer. 905 */ 906 satIOContext->reqType = agRequestType; /* Save it */ 907 908 status = sataLLIOStart( tiRoot, 909 tiIORequest, 910 tiDeviceHandle, 911 tiScsiRequest, 912 satIOContext); 913 914 TI_DBG5(("satSetFeatures: return\n")); 915 916 return status; 917 } 918 /*****************************************************************************/ 919 /*! \brief SAT implementation for SCSI REQUEST SENSE to ATAPI device. 920 * 921 * SAT implementation for SCSI REQUEST SENSE. 922 * 923 * \param tiRoot: Pointer to TISA initiator driver/port instance. 924 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 925 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 926 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 927 * \param satIOContext_t: Pointer to the SAT IO Context 928 * 929 * \return If command is started successfully 930 * - \e tiSuccess: I/O request successfully initiated. 931 * - \e tiBusy: No resources available, try again later. 932 * - \e tiIONoDevice: Invalid device handle. 933 * - \e tiError: Other errors. 934 */ 935 /*****************************************************************************/ 936 GLOBAL bit32 satRequestSenseForATAPI( 937 tiRoot_t *tiRoot, 938 tiIORequest_t *tiIORequest, 939 tiDeviceHandle_t *tiDeviceHandle, 940 tiScsiInitiatorRequest_t *tiScsiRequest, 941 satIOContext_t *satIOContext) 942 { 943 bit32 status; 944 bit32 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT; 945 satDeviceData_t *pSatDevData; 946 tiIniScsiCmnd_t *scsiCmnd; 947 agsaFisRegHostToDevice_t *fis; 948 949 pSatDevData = satIOContext->pSatDevData; 950 scsiCmnd = &tiScsiRequest->scsiCmnd; 951 fis = satIOContext->pFis; 952 953 scsiCmnd->cdb[0] = SCSIOPC_REQUEST_SENSE; 954 scsiCmnd->cdb[1] = 0; 955 scsiCmnd->cdb[2] = 0; 956 scsiCmnd->cdb[3] = 0; 957 scsiCmnd->cdb[4] = SENSE_DATA_LENGTH; 958 scsiCmnd->cdb[5] = 0; 959 TI_DBG3(("satRequestSenseForATAPI: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n", 960 scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3], 961 scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7], 962 scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11])); 963 964 fis->h.fisType = 0x27; /* Reg host to device */ 965 fis->h.c_pmPort = 0x80; /* C Bit is set 1*/ 966 fis->h.command = SAT_PACKET; /* 0xA0 */ 967 if (pSatDevData->satDMADIRSupport) /* DMADIR enabled*/ 968 { 969 fis->h.features = (tiScsiRequest->dataDirection == tiDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */ 970 } 971 else 972 { 973 fis->h.features = 0; /* FIS reserve */ 974 } 975 976 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 977 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 978 fis->d.lbaHigh = 0x20; /* FIS LBA (23:16) */ 979 fis->d.device = 0; /* FIS LBA (27:24) and FIS LBA mode */ 980 fis->d.lbaLowExp = 0; 981 fis->d.lbaMidExp = 0; 982 fis->d.lbaHighExp = 0; 983 fis->d.featuresExp = 0; 984 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 985 fis->d.sectorCountExp = 0; 986 fis->d.reserved4 = 0; 987 fis->d.control = 0; /* FIS HOB bit clear */ 988 fis->d.reserved5 = (bit32)(scsiCmnd->cdb[0]|(scsiCmnd->cdb[1]<<8)|(scsiCmnd->cdb[2]<<16)|(scsiCmnd->cdb[3]<<24)); 989 990 satIOContext->ATACmd = SAT_PACKET; 991 992 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT; 993 994 //if (pSatDevData->sat48BitSupport == agTRUE) 995 { 996 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 997 { 998 fis->h.features |= 0x01; 999 } 1000 else 1001 { 1002 fis->h.features |= 0x0; 1003 } 1004 } 1005 1006 satIOContext->satCompleteCB = &satRequestSenseForATAPICB; 1007 1008 /* 1009 * Prepare SGL and send FIS to LL layer. 1010 */ 1011 satIOContext->reqType = agRequestType; /* Save it */ 1012 1013 status = sataLLIOStart( tiRoot, 1014 tiIORequest, 1015 tiDeviceHandle, 1016 tiScsiRequest, 1017 satIOContext); 1018 1019 TI_DBG5(("satRequestSenseForATAPI: return\n")); 1020 return (status); 1021 } 1022 /*****************************************************************************/ 1023 /*! \brief SAT implementation for satDeviceReset. 1024 * 1025 * This function creates DEVICE RESET fis and sends the request to LL layer 1026 * 1027 * \param tiRoot: Pointer to TISA initiator driver/port instance. 1028 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 1029 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 1030 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 1031 * \param satIOContext_t: Pointer to the SAT IO Context 1032 * 1033 * \return If command is started successfully 1034 * - \e tiSuccess: I/O request successfully initiated. 1035 * - \e tiBusy: No resources available, try again later. 1036 * - \e tiIONoDevice: Invalid device handle. 1037 * - \e tiError: Other errors. 1038 */ 1039 /*****************************************************************************/ 1040 GLOBAL bit32 satDeviceReset( 1041 tiRoot_t *tiRoot, 1042 tiIORequest_t *tiIORequest, 1043 tiDeviceHandle_t *tiDeviceHandle, 1044 tiScsiInitiatorRequest_t *tiScsiRequest, 1045 satIOContext_t *satIOContext 1046 ) 1047 { 1048 bit32 status; 1049 bit32 agRequestType; 1050 agsaFisRegHostToDevice_t *fis; 1051 1052 fis = satIOContext->pFis; 1053 1054 TI_DBG3(("satDeviceReset: start\n")); 1055 1056 /* 1057 * Send the Execute Device Diagnostic command. 1058 */ 1059 fis->h.fisType = 0x27; /* Reg host to device */ 1060 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1061 fis->h.command = SAT_DEVICE_RESET; /* 0x90 */ 1062 fis->h.features = 0; 1063 fis->d.lbaLow = 0; 1064 fis->d.lbaMid = 0; 1065 fis->d.lbaHigh = 0; 1066 fis->d.device = 0; 1067 fis->d.lbaLowExp = 0; 1068 fis->d.lbaMidExp = 0; 1069 fis->d.lbaHighExp = 0; 1070 fis->d.featuresExp = 0; 1071 fis->d.sectorCount = 0; 1072 fis->d.sectorCountExp = 0; 1073 fis->d.reserved4 = 0; 1074 fis->d.control = 0; /* FIS HOB bit clear */ 1075 fis->d.reserved5 = 0; 1076 1077 agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET; 1078 1079 /* Initialize CB for SATA completion. 1080 */ 1081 satIOContext->satCompleteCB = &satDeviceResetCB; 1082 1083 /* 1084 * Prepare SGL and send FIS to LL layer. 1085 */ 1086 satIOContext->reqType = agRequestType; /* Save it */ 1087 1088 status = sataLLIOStart( tiRoot, 1089 tiIORequest, 1090 tiDeviceHandle, 1091 tiScsiRequest, 1092 satIOContext); 1093 1094 TI_DBG3(("satDeviceReset: return\n")); 1095 1096 return status; 1097 } 1098 1099 /*****************************************************************************/ 1100 /*! \brief SAT implementation for saExecuteDeviceDiagnostic. 1101 * 1102 * This function creates Execute Device Diagnostic fis and sends the request to LL layer 1103 * 1104 * \param tiRoot: Pointer to TISA initiator driver/port instance. 1105 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 1106 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 1107 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 1108 * \param satIOContext_t: Pointer to the SAT IO Context 1109 * 1110 * \return If command is started successfully 1111 * - \e tiSuccess: I/O request successfully initiated. 1112 * - \e tiBusy: No resources available, try again later. 1113 * - \e tiIONoDevice: Invalid device handle. 1114 * - \e tiError: Other errors. 1115 */ 1116 /*****************************************************************************/ 1117 GLOBAL bit32 satExecuteDeviceDiagnostic( 1118 tiRoot_t *tiRoot, 1119 tiIORequest_t *tiIORequest, 1120 tiDeviceHandle_t *tiDeviceHandle, 1121 tiScsiInitiatorRequest_t *tiScsiRequest, 1122 satIOContext_t *satIOContext 1123 ) 1124 { 1125 bit32 status; 1126 bit32 agRequestType; 1127 agsaFisRegHostToDevice_t *fis; 1128 1129 fis = satIOContext->pFis; 1130 1131 TI_DBG3(("satExecuteDeviceDiagnostic: start\n")); 1132 1133 /* 1134 * Send the Execute Device Diagnostic command. 1135 */ 1136 fis->h.fisType = 0x27; /* Reg host to device */ 1137 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1138 fis->h.command = SAT_EXECUTE_DEVICE_DIAGNOSTIC; /* 0x90 */ 1139 fis->h.features = 0; 1140 fis->d.lbaLow = 0; 1141 fis->d.lbaMid = 0; 1142 fis->d.lbaHigh = 0; 1143 fis->d.device = 0; 1144 fis->d.lbaLowExp = 0; 1145 fis->d.lbaMidExp = 0; 1146 fis->d.lbaHighExp = 0; 1147 fis->d.featuresExp = 0; 1148 fis->d.sectorCount = 0; 1149 fis->d.sectorCountExp = 0; 1150 fis->d.reserved4 = 0; 1151 fis->d.control = 0; /* FIS HOB bit clear */ 1152 fis->d.reserved5 = 0; 1153 1154 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 1155 1156 /* Initialize CB for SATA completion. 1157 */ 1158 satIOContext->satCompleteCB = &satExecuteDeviceDiagnosticCB; 1159 1160 /* 1161 * Prepare SGL and send FIS to LL layer. 1162 */ 1163 satIOContext->reqType = agRequestType; /* Save it */ 1164 1165 status = sataLLIOStart( tiRoot, 1166 tiIORequest, 1167 tiDeviceHandle, 1168 tiScsiRequest, 1169 satIOContext); 1170 1171 TI_DBG5(("satExecuteDeviceDiagnostic: return\n")); 1172 1173 return status; 1174 } 1175 1176 1177 /*****************************************************************************/ 1178 /*! \brief SAT implementation for SCSI READ10. 1179 * 1180 * SAT implementation for SCSI READ10 and send FIS request to LL layer. 1181 * 1182 * \param tiRoot: Pointer to TISA initiator driver/port instance. 1183 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 1184 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 1185 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 1186 * \param satIOContext_t: Pointer to the SAT IO Context 1187 * 1188 * \return If command is started successfully 1189 * - \e tiSuccess: I/O request successfully initiated. 1190 * - \e tiBusy: No resources available, try again later. 1191 * - \e tiIONoDevice: Invalid device handle. 1192 * - \e tiError: Other errors. 1193 */ 1194 /*****************************************************************************/ 1195 GLOBAL bit32 satRead10( 1196 tiRoot_t *tiRoot, 1197 tiIORequest_t *tiIORequest, 1198 tiDeviceHandle_t *tiDeviceHandle, 1199 tiScsiInitiatorRequest_t *tiScsiRequest, 1200 satIOContext_t *satIOContext) 1201 { 1202 1203 bit32 status; 1204 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 1205 satDeviceData_t *pSatDevData; 1206 scsiRspSense_t *pSense; 1207 tiIniScsiCmnd_t *scsiCmnd; 1208 agsaFisRegHostToDevice_t *fis; 1209 bit32 lba = 0; 1210 bit32 tl = 0; 1211 bit32 LoopNum = 1; 1212 bit8 LBA[4]; 1213 bit8 TL[4]; 1214 bit32 rangeChk = agFALSE; /* lba and tl range check */ 1215 1216 pSense = satIOContext->pSense; 1217 pSatDevData = satIOContext->pSatDevData; 1218 scsiCmnd = &tiScsiRequest->scsiCmnd; 1219 fis = satIOContext->pFis; 1220 1221 TI_DBG5(("satRead10: start\n")); 1222 TI_DBG5(("satRead10: pSatDevData=%p\n", pSatDevData)); 1223 // tdhexdump("satRead10", (bit8 *)scsiCmnd->cdb, 10); 1224 1225 /* checking FUA_NV */ 1226 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 1227 { 1228 satSetSensePayload( pSense, 1229 SCSI_SNSKEY_ILLEGAL_REQUEST, 1230 0, 1231 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 1232 satIOContext); 1233 1234 ostiInitiatorIOCompleted( tiRoot, 1235 tiIORequest, 1236 tiIOSuccess, 1237 SCSI_STAT_CHECK_CONDITION, 1238 satIOContext->pTiSenseData, 1239 satIOContext->interruptContext ); 1240 1241 TI_DBG1(("satRead10: return FUA_NV\n")); 1242 return tiSuccess; 1243 1244 } 1245 1246 /* checking CONTROL */ 1247 /* NACA == 1 or LINK == 1*/ 1248 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 1249 { 1250 satSetSensePayload( pSense, 1251 SCSI_SNSKEY_ILLEGAL_REQUEST, 1252 0, 1253 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 1254 satIOContext); 1255 1256 ostiInitiatorIOCompleted( tiRoot, 1257 tiIORequest, 1258 tiIOSuccess, 1259 SCSI_STAT_CHECK_CONDITION, 1260 satIOContext->pTiSenseData, 1261 satIOContext->interruptContext ); 1262 1263 TI_DBG1(("satRead10: return control\n")); 1264 return tiSuccess; 1265 } 1266 1267 osti_memset(LBA, 0, sizeof(LBA)); 1268 osti_memset(TL, 0, sizeof(TL)); 1269 1270 /* do not use memcpy due to indexing in LBA and TL */ 1271 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 1272 LBA[1] = scsiCmnd->cdb[3]; 1273 LBA[2] = scsiCmnd->cdb[4]; 1274 LBA[3] = scsiCmnd->cdb[5]; /* LSB */ 1275 1276 TL[0] = 0; 1277 TL[1] = 0; 1278 TL[2] = scsiCmnd->cdb[7]; /* MSB */ 1279 TL[3] = scsiCmnd->cdb[8]; /* LSB */ 1280 1281 rangeChk = satAddNComparebit32(LBA, TL); 1282 1283 /* cbd10; computing LBA and transfer length */ 1284 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 1285 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 1286 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 1287 1288 1289 TI_DBG5(("satRead10: lba %d functioned lba %d\n", lba, satComputeCDB10LBA(satIOContext))); 1290 TI_DBG5(("satRead10: lba 0x%x functioned lba 0x%x\n", lba, satComputeCDB10LBA(satIOContext))); 1291 TI_DBG5(("satRead10: tl %d functioned tl %d\n", tl, satComputeCDB10TL(satIOContext))); 1292 1293 /* Table 34, 9.1, p 46 */ 1294 /* 1295 note: As of 2/10/2006, no support for DMA QUEUED 1296 */ 1297 1298 /* 1299 Table 34, 9.1, p 46, b 1300 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 1301 return check condition 1302 */ 1303 1304 if (pSatDevData->satNCQ != agTRUE && 1305 pSatDevData->sat48BitSupport != agTRUE 1306 ) 1307 { 1308 if (lba > SAT_TR_LBA_LIMIT - 1) 1309 { 1310 TI_DBG1(("satRead10: return LBA out of range, not EXT\n")); 1311 satSetSensePayload( pSense, 1312 SCSI_SNSKEY_ILLEGAL_REQUEST, 1313 0, 1314 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 1315 satIOContext); 1316 1317 ostiInitiatorIOCompleted( tiRoot, 1318 tiIORequest, 1319 tiIOSuccess, 1320 SCSI_STAT_CHECK_CONDITION, 1321 satIOContext->pTiSenseData, 1322 satIOContext->interruptContext ); 1323 1324 return tiSuccess; 1325 } 1326 1327 1328 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 1329 { 1330 TI_DBG1(("satRead10: return LBA+TL out of range, not EXT\n")); 1331 satSetSensePayload( pSense, 1332 SCSI_SNSKEY_ILLEGAL_REQUEST, 1333 0, 1334 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 1335 satIOContext); 1336 1337 ostiInitiatorIOCompleted( tiRoot, 1338 tiIORequest, 1339 tiIOSuccess, 1340 SCSI_STAT_CHECK_CONDITION, 1341 satIOContext->pTiSenseData, 1342 satIOContext->interruptContext ); 1343 1344 return tiSuccess; 1345 } 1346 } 1347 1348 /* case 1 and 2 */ 1349 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT) 1350 { 1351 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 1352 { 1353 /* case 2 */ 1354 /* READ DMA*/ 1355 /* in case that we can't fit the transfer length, 1356 we need to make it fit by sending multiple ATA cmnds */ 1357 TI_DBG5(("satRead10: case 2\n")); 1358 1359 1360 fis->h.fisType = 0x27; /* Reg host to device */ 1361 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1362 fis->h.command = SAT_READ_DMA; /* 0xC8 */ 1363 fis->h.features = 0; /* FIS reserve */ 1364 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 1365 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 1366 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 1367 fis->d.device = 1368 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 1369 fis->d.lbaLowExp = 0; 1370 fis->d.lbaMidExp = 0; 1371 fis->d.lbaHighExp = 0; 1372 fis->d.featuresExp = 0; 1373 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 1374 fis->d.sectorCountExp = 0; 1375 fis->d.reserved4 = 0; 1376 fis->d.control = 0; /* FIS HOB bit clear */ 1377 fis->d.reserved5 = 0; 1378 1379 1380 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 1381 satIOContext->ATACmd = SAT_READ_DMA; 1382 } 1383 else 1384 { 1385 /* case 1 */ 1386 /* READ MULTIPLE or READ SECTOR(S) */ 1387 /* READ SECTORS for easier implemetation */ 1388 /* in case that we can't fit the transfer length, 1389 we need to make it fit by sending multiple ATA cmnds */ 1390 TI_DBG5(("satRead10: case 1\n")); 1391 1392 fis->h.fisType = 0x27; /* Reg host to device */ 1393 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1394 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 1395 fis->h.features = 0; /* FIS reserve */ 1396 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 1397 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 1398 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 1399 fis->d.device = 1400 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 1401 fis->d.lbaLowExp = 0; 1402 fis->d.lbaMidExp = 0; 1403 fis->d.lbaHighExp = 0; 1404 fis->d.featuresExp = 0; 1405 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 1406 fis->d.sectorCountExp = 0; 1407 fis->d.reserved4 = 0; 1408 fis->d.control = 0; /* FIS HOB bit clear */ 1409 fis->d.reserved5 = 0; 1410 1411 1412 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 1413 satIOContext->ATACmd = SAT_READ_SECTORS; 1414 } 1415 } 1416 1417 /* case 3 and 4 */ 1418 if (pSatDevData->sat48BitSupport == agTRUE) 1419 { 1420 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 1421 { 1422 /* case 3 */ 1423 /* READ DMA EXT */ 1424 TI_DBG5(("satRead10: case 3\n")); 1425 fis->h.fisType = 0x27; /* Reg host to device */ 1426 1427 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1428 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */ 1429 fis->h.features = 0; /* FIS reserve */ 1430 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 1431 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 1432 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 1433 fis->d.device = 0x40; /* FIS LBA mode set */ 1434 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 1435 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 1436 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 1437 fis->d.featuresExp = 0; /* FIS reserve */ 1438 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 1439 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 1440 fis->d.reserved4 = 0; 1441 fis->d.control = 0; /* FIS HOB bit clear */ 1442 fis->d.reserved5 = 0; 1443 1444 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 1445 satIOContext->ATACmd = SAT_READ_DMA_EXT; 1446 1447 } 1448 else 1449 { 1450 /* case 4 */ 1451 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/ 1452 /* READ SECTORS EXT for easier implemetation */ 1453 TI_DBG5(("satRead10: case 4\n")); 1454 fis->h.fisType = 0x27; /* Reg host to device */ 1455 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1456 1457 /* Check FUA bit */ 1458 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK) 1459 { 1460 1461 /* for now, no support for FUA */ 1462 satSetSensePayload( pSense, 1463 SCSI_SNSKEY_ILLEGAL_REQUEST, 1464 0, 1465 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 1466 satIOContext); 1467 1468 ostiInitiatorIOCompleted( tiRoot, 1469 tiIORequest, 1470 tiIOSuccess, 1471 SCSI_STAT_CHECK_CONDITION, 1472 satIOContext->pTiSenseData, 1473 satIOContext->interruptContext ); 1474 return tiSuccess; 1475 } 1476 1477 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 1478 1479 fis->h.features = 0; /* FIS reserve */ 1480 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 1481 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 1482 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 1483 fis->d.device = 0x40; /* FIS LBA mode set */ 1484 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 1485 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 1486 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 1487 fis->d.featuresExp = 0; /* FIS reserve */ 1488 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 1489 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 1490 fis->d.reserved4 = 0; 1491 fis->d.control = 0; /* FIS HOB bit clear */ 1492 fis->d.reserved5 = 0; 1493 1494 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 1495 satIOContext->ATACmd = SAT_READ_SECTORS_EXT; 1496 } 1497 } 1498 1499 /* case 5 */ 1500 if (pSatDevData->satNCQ == agTRUE) 1501 { 1502 /* READ FPDMA QUEUED */ 1503 if (pSatDevData->sat48BitSupport != agTRUE) 1504 { 1505 TI_DBG5(("satRead10: case 5 !!! error NCQ but 28 bit address support \n")); 1506 satSetSensePayload( pSense, 1507 SCSI_SNSKEY_ILLEGAL_REQUEST, 1508 0, 1509 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 1510 satIOContext); 1511 1512 ostiInitiatorIOCompleted( tiRoot, 1513 tiIORequest, 1514 tiIOSuccess, 1515 SCSI_STAT_CHECK_CONDITION, 1516 satIOContext->pTiSenseData, 1517 satIOContext->interruptContext ); 1518 return tiSuccess; 1519 } 1520 1521 TI_DBG6(("satRead10: case 5\n")); 1522 1523 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */ 1524 1525 fis->h.fisType = 0x27; /* Reg host to device */ 1526 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1527 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */ 1528 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 1529 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 1530 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 1531 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 1532 1533 /* Check FUA bit */ 1534 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK) 1535 fis->d.device = 0xC0; /* FIS FUA set */ 1536 else 1537 fis->d.device = 0x40; /* FIS FUA clear */ 1538 1539 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 1540 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 1541 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 1542 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 1543 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 1544 fis->d.sectorCountExp = 0; 1545 fis->d.reserved4 = 0; 1546 fis->d.control = 0; /* FIS HOB bit clear */ 1547 fis->d.reserved5 = 0; 1548 1549 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ; 1550 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED; 1551 } 1552 1553 1554 // tdhexdump("satRead10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t)); 1555 1556 /* saves the current LBA and orginal TL */ 1557 satIOContext->currentLBA = lba; 1558 satIOContext->OrgTL = tl; 1559 1560 /* 1561 computing number of loop and remainder for tl 1562 0xFF in case not ext 1563 0xFFFF in case EXT 1564 */ 1565 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 1566 { 1567 LoopNum = satComputeLoopNum(tl, 0xFF); 1568 } 1569 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 1570 { 1571 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 1572 LoopNum = satComputeLoopNum(tl, 0xFFFF); 1573 } 1574 else 1575 { 1576 /* SAT_READ_FPDMA_QUEUED */ 1577 LoopNum = satComputeLoopNum(tl, 0xFFFF); 1578 } 1579 1580 satIOContext->LoopNum = LoopNum; 1581 1582 /* Initialize CB for SATA completion. 1583 */ 1584 if (LoopNum == 1) 1585 { 1586 TI_DBG5(("satRead10: NON CHAINED data\n")); 1587 satIOContext->satCompleteCB = &satNonChainedDataIOCB; 1588 } 1589 else 1590 { 1591 TI_DBG1(("satRead10: CHAINED data\n")); 1592 /* re-setting tl */ 1593 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 1594 { 1595 fis->d.sectorCount = 0xFF; 1596 } 1597 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 1598 { 1599 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 1600 fis->d.sectorCount = 0xFF; 1601 fis->d.sectorCountExp = 0xFF; 1602 } 1603 else 1604 { 1605 /* SAT_READ_FPDMA_QUEUED */ 1606 fis->h.features = 0xFF; 1607 fis->d.featuresExp = 0xFF; 1608 } 1609 1610 /* chained data */ 1611 satIOContext->satCompleteCB = &satChainedDataIOCB; 1612 1613 } 1614 1615 /* 1616 * Prepare SGL and send FIS to LL layer. 1617 */ 1618 satIOContext->reqType = agRequestType; /* Save it */ 1619 1620 status = sataLLIOStart( tiRoot, 1621 tiIORequest, 1622 tiDeviceHandle, 1623 tiScsiRequest, 1624 satIOContext); 1625 1626 TI_DBG5(("satRead10: return\n")); 1627 return (status); 1628 1629 } 1630 1631 1632 /*****************************************************************************/ 1633 /*! \brief SAT implementation for SCSI satRead_1. 1634 * 1635 * SAT implementation for SCSI satRead_1 1636 * Sub function of satRead10 1637 * 1638 * \param tiRoot: Pointer to TISA initiator driver/port instance. 1639 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 1640 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 1641 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 1642 * \param satIOContext_t: Pointer to the SAT IO Context 1643 * 1644 * \return If command is started successfully 1645 * - \e tiSuccess: I/O request successfully initiated. 1646 * - \e tiBusy: No resources available, try again later. 1647 * - \e tiIONoDevice: Invalid device handle. 1648 * - \e tiError: Other errors. 1649 */ 1650 /*****************************************************************************/ 1651 /* 1652 * as a part of loop for read10 1653 */ 1654 GLOBAL bit32 satRead_1( 1655 tiRoot_t *tiRoot, 1656 tiIORequest_t *tiIORequest, 1657 tiDeviceHandle_t *tiDeviceHandle, 1658 tiScsiInitiatorRequest_t *tiScsiRequest, 1659 satIOContext_t *satIOContext) 1660 { 1661 /* 1662 Assumption: error check on lba and tl has been done in satRead*() 1663 lba = lba + tl; 1664 */ 1665 bit32 status; 1666 satIOContext_t *satOrgIOContext = agNULL; 1667 tiIniScsiCmnd_t *scsiCmnd; 1668 agsaFisRegHostToDevice_t *fis; 1669 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 1670 bit32 lba = 0; 1671 bit32 DenomTL = 0xFF; 1672 bit32 Remainder = 0; 1673 bit8 LBA[4]; /* 0 MSB, 3 LSB */ 1674 1675 TI_DBG2(("satRead_1: start\n")); 1676 1677 fis = satIOContext->pFis; 1678 satOrgIOContext = satIOContext->satOrgIOContext; 1679 scsiCmnd = satOrgIOContext->pScsiCmnd; 1680 1681 osti_memset(LBA,0, sizeof(LBA)); 1682 1683 switch (satOrgIOContext->ATACmd) 1684 { 1685 case SAT_READ_DMA: 1686 DenomTL = 0xFF; 1687 break; 1688 case SAT_READ_SECTORS: 1689 DenomTL = 0xFF; 1690 break; 1691 case SAT_READ_DMA_EXT: 1692 DenomTL = 0xFFFF; 1693 break; 1694 case SAT_READ_SECTORS_EXT: 1695 DenomTL = 0xFFFF; 1696 break; 1697 case SAT_READ_FPDMA_QUEUED: 1698 DenomTL = 0xFFFF; 1699 break; 1700 default: 1701 TI_DBG1(("satRead_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd)); 1702 return tiError; 1703 break; 1704 } 1705 1706 Remainder = satOrgIOContext->OrgTL % DenomTL; 1707 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL; 1708 lba = satOrgIOContext->currentLBA; 1709 1710 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); 1711 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2)); 1712 LBA[2] = (bit8)((lba & 0xF0) >> 8); 1713 LBA[3] = (bit8)(lba & 0xF); 1714 1715 1716 switch (satOrgIOContext->ATACmd) 1717 { 1718 case SAT_READ_DMA: 1719 fis->h.fisType = 0x27; /* Reg host to device */ 1720 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1721 fis->h.command = SAT_READ_DMA; /* 0xC8 */ 1722 fis->h.features = 0; /* FIS reserve */ 1723 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 1724 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 1725 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 1726 fis->d.device = 1727 (bit8)((0x4 << 4) | (LBA[0] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 1728 fis->d.lbaLowExp = 0; 1729 fis->d.lbaMidExp = 0; 1730 fis->d.lbaHighExp = 0; 1731 fis->d.featuresExp = 0; 1732 1733 if (satOrgIOContext->LoopNum == 1) 1734 { 1735 /* last loop */ 1736 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 1737 } 1738 else 1739 { 1740 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 1741 } 1742 1743 fis->d.sectorCountExp = 0; 1744 fis->d.reserved4 = 0; 1745 fis->d.control = 0; /* FIS HOB bit clear */ 1746 fis->d.reserved5 = 0; 1747 1748 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 1749 1750 break; 1751 case SAT_READ_SECTORS: 1752 fis->h.fisType = 0x27; /* Reg host to device */ 1753 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1754 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 1755 fis->h.features = 0; /* FIS reserve */ 1756 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 1757 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 1758 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 1759 fis->d.device = 1760 (bit8)((0x4 << 4) | (LBA[0] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 1761 fis->d.lbaLowExp = 0; 1762 fis->d.lbaMidExp = 0; 1763 fis->d.lbaHighExp = 0; 1764 fis->d.featuresExp = 0; 1765 if (satOrgIOContext->LoopNum == 1) 1766 { 1767 /* last loop */ 1768 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 1769 } 1770 else 1771 { 1772 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 1773 } 1774 fis->d.sectorCountExp = 0; 1775 fis->d.reserved4 = 0; 1776 fis->d.control = 0; /* FIS HOB bit clear */ 1777 fis->d.reserved5 = 0; 1778 1779 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 1780 1781 break; 1782 case SAT_READ_DMA_EXT: 1783 fis->h.fisType = 0x27; /* Reg host to device */ 1784 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1785 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */ 1786 fis->h.features = 0; /* FIS reserve */ 1787 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 1788 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 1789 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 1790 fis->d.device = 0x40; /* FIS LBA mode set */ 1791 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 1792 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 1793 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 1794 fis->d.featuresExp = 0; /* FIS reserve */ 1795 if (satOrgIOContext->LoopNum == 1) 1796 { 1797 /* last loop */ 1798 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 1799 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 1800 1801 } 1802 else 1803 { 1804 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 1805 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 1806 } 1807 fis->d.reserved4 = 0; 1808 fis->d.control = 0; /* FIS HOB bit clear */ 1809 fis->d.reserved5 = 0; 1810 1811 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 1812 1813 break; 1814 case SAT_READ_SECTORS_EXT: 1815 fis->h.fisType = 0x27; /* Reg host to device */ 1816 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1817 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 1818 fis->h.features = 0; /* FIS reserve */ 1819 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 1820 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 1821 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 1822 fis->d.device = 0x40; /* FIS LBA mode set */ 1823 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 1824 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 1825 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 1826 fis->d.featuresExp = 0; /* FIS reserve */ 1827 if (satOrgIOContext->LoopNum == 1) 1828 { 1829 /* last loop */ 1830 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 1831 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 1832 } 1833 else 1834 { 1835 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 1836 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 1837 } 1838 fis->d.reserved4 = 0; 1839 fis->d.control = 0; /* FIS HOB bit clear */ 1840 fis->d.reserved5 = 0; 1841 1842 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 1843 break; 1844 case SAT_READ_FPDMA_QUEUED: 1845 fis->h.fisType = 0x27; /* Reg host to device */ 1846 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1847 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */ 1848 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 1849 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 1850 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 1851 1852 /* Check FUA bit */ 1853 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK) 1854 fis->d.device = 0xC0; /* FIS FUA set */ 1855 else 1856 fis->d.device = 0x40; /* FIS FUA clear */ 1857 1858 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 1859 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 1860 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 1861 if (satOrgIOContext->LoopNum == 1) 1862 { 1863 /* last loop */ 1864 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 1865 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 1866 } 1867 else 1868 { 1869 fis->h.features = 0xFF; /* FIS sector count (7:0) */ 1870 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */ 1871 } 1872 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 1873 fis->d.sectorCountExp = 0; 1874 fis->d.reserved4 = 0; 1875 fis->d.control = 0; /* FIS HOB bit clear */ 1876 fis->d.reserved5 = 0; 1877 1878 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ; 1879 break; 1880 default: 1881 TI_DBG1(("satRead_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd)); 1882 return tiError; 1883 break; 1884 } 1885 1886 /* Initialize CB for SATA completion. 1887 */ 1888 /* chained data */ 1889 satIOContext->satCompleteCB = &satChainedDataIOCB; 1890 1891 1892 /* 1893 * Prepare SGL and send FIS to LL layer. 1894 */ 1895 satIOContext->reqType = agRequestType; /* Save it */ 1896 1897 status = sataLLIOStart( tiRoot, 1898 tiIORequest, 1899 tiDeviceHandle, 1900 tiScsiRequest, 1901 satIOContext); 1902 1903 TI_DBG5(("satRead_1: return\n")); 1904 return (status); 1905 } 1906 /*****************************************************************************/ 1907 /*! \brief SAT implementation for SCSI READ12. 1908 * 1909 * SAT implementation for SCSI READ12 and send FIS request to LL layer. 1910 * 1911 * \param tiRoot: Pointer to TISA initiator driver/port instance. 1912 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 1913 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 1914 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 1915 * \param satIOContext_t: Pointer to the SAT IO Context 1916 * 1917 * \return If command is started successfully 1918 * - \e tiSuccess: I/O request successfully initiated. 1919 * - \e tiBusy: No resources available, try again later. 1920 * - \e tiIONoDevice: Invalid device handle. 1921 * - \e tiError: Other errors. 1922 */ 1923 /*****************************************************************************/ 1924 GLOBAL bit32 satRead12( 1925 tiRoot_t *tiRoot, 1926 tiIORequest_t *tiIORequest, 1927 tiDeviceHandle_t *tiDeviceHandle, 1928 tiScsiInitiatorRequest_t *tiScsiRequest, 1929 satIOContext_t *satIOContext) 1930 { 1931 bit32 status; 1932 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 1933 satDeviceData_t *pSatDevData; 1934 scsiRspSense_t *pSense; 1935 tiIniScsiCmnd_t *scsiCmnd; 1936 agsaFisRegHostToDevice_t *fis; 1937 bit32 lba = 0; 1938 bit32 tl = 0; 1939 bit32 LoopNum = 1; 1940 bit8 LBA[4]; 1941 bit8 TL[4]; 1942 bit32 rangeChk = agFALSE; /* lba and tl range check */ 1943 1944 pSense = satIOContext->pSense; 1945 pSatDevData = satIOContext->pSatDevData; 1946 scsiCmnd = &tiScsiRequest->scsiCmnd; 1947 fis = satIOContext->pFis; 1948 1949 TI_DBG5(("satRead12: start\n")); 1950 1951 /* checking FUA_NV */ 1952 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 1953 { 1954 satSetSensePayload( pSense, 1955 SCSI_SNSKEY_ILLEGAL_REQUEST, 1956 0, 1957 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 1958 satIOContext); 1959 1960 ostiInitiatorIOCompleted( tiRoot, 1961 tiIORequest, 1962 tiIOSuccess, 1963 SCSI_STAT_CHECK_CONDITION, 1964 satIOContext->pTiSenseData, 1965 satIOContext->interruptContext ); 1966 1967 TI_DBG1(("satRead12: return FUA_NV\n")); 1968 return tiSuccess; 1969 1970 } 1971 1972 /* checking CONTROL */ 1973 /* NACA == 1 or LINK == 1*/ 1974 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) ) 1975 { 1976 satSetSensePayload( pSense, 1977 SCSI_SNSKEY_ILLEGAL_REQUEST, 1978 0, 1979 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 1980 satIOContext); 1981 1982 ostiInitiatorIOCompleted( tiRoot, 1983 tiIORequest, 1984 tiIOSuccess, 1985 SCSI_STAT_CHECK_CONDITION, 1986 satIOContext->pTiSenseData, 1987 satIOContext->interruptContext ); 1988 1989 TI_DBG2(("satRead12: return control\n")); 1990 return tiSuccess; 1991 } 1992 1993 osti_memset(LBA, 0, sizeof(LBA)); 1994 osti_memset(TL, 0, sizeof(TL)); 1995 1996 /* do not use memcpy due to indexing in LBA and TL */ 1997 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 1998 LBA[1] = scsiCmnd->cdb[3]; 1999 LBA[2] = scsiCmnd->cdb[4]; 2000 LBA[3] = scsiCmnd->cdb[5]; /* LSB */ 2001 2002 TL[0] = scsiCmnd->cdb[6]; /* MSB */ 2003 TL[1] = scsiCmnd->cdb[7]; 2004 TL[2] = scsiCmnd->cdb[8]; 2005 TL[3] = scsiCmnd->cdb[9]; /* LSB */ 2006 2007 rangeChk = satAddNComparebit32(LBA, TL); 2008 2009 lba = satComputeCDB12LBA(satIOContext); 2010 tl = satComputeCDB12TL(satIOContext); 2011 2012 /* Table 34, 9.1, p 46 */ 2013 /* 2014 note: As of 2/10/2006, no support for DMA QUEUED 2015 */ 2016 2017 /* 2018 Table 34, 9.1, p 46, b 2019 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 2020 return check condition 2021 */ 2022 if (pSatDevData->satNCQ != agTRUE && 2023 pSatDevData->sat48BitSupport != agTRUE 2024 ) 2025 { 2026 if (lba > SAT_TR_LBA_LIMIT - 1) 2027 { 2028 TI_DBG1(("satRead12: return LBA out of range, not EXT\n")); 2029 satSetSensePayload( pSense, 2030 SCSI_SNSKEY_ILLEGAL_REQUEST, 2031 0, 2032 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 2033 satIOContext); 2034 2035 ostiInitiatorIOCompleted( tiRoot, 2036 tiIORequest, 2037 tiIOSuccess, 2038 SCSI_STAT_CHECK_CONDITION, 2039 satIOContext->pTiSenseData, 2040 satIOContext->interruptContext ); 2041 2042 return tiSuccess; 2043 } 2044 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 2045 { 2046 TI_DBG1(("satRead12: return LBA+TL out of range, not EXT\n")); 2047 satSetSensePayload( pSense, 2048 SCSI_SNSKEY_ILLEGAL_REQUEST, 2049 0, 2050 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 2051 satIOContext); 2052 2053 ostiInitiatorIOCompleted( tiRoot, 2054 tiIORequest, 2055 tiIOSuccess, 2056 SCSI_STAT_CHECK_CONDITION, 2057 satIOContext->pTiSenseData, 2058 satIOContext->interruptContext ); 2059 2060 return tiSuccess; 2061 } 2062 } 2063 2064 /* case 1 and 2 */ 2065 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT) 2066 { 2067 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 2068 { 2069 /* case 2 */ 2070 /* READ DMA*/ 2071 /* in case that we can't fit the transfer length, 2072 we need to make it fit by sending multiple ATA cmnds */ 2073 TI_DBG5(("satRead12: case 2\n")); 2074 2075 2076 fis->h.fisType = 0x27; /* Reg host to device */ 2077 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2078 fis->h.command = SAT_READ_DMA; /* 0xC8 */ 2079 fis->h.features = 0; /* FIS reserve */ 2080 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 2081 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 2082 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 2083 fis->d.device = 2084 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 2085 fis->d.lbaLowExp = 0; 2086 fis->d.lbaMidExp = 0; 2087 fis->d.lbaHighExp = 0; 2088 fis->d.featuresExp = 0; 2089 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 2090 fis->d.sectorCountExp = 0; 2091 fis->d.reserved4 = 0; 2092 fis->d.control = 0; /* FIS HOB bit clear */ 2093 fis->d.reserved5 = 0; 2094 2095 2096 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 2097 satIOContext->ATACmd = SAT_READ_DMA; 2098 } 2099 else 2100 { 2101 /* case 1 */ 2102 /* READ MULTIPLE or READ SECTOR(S) */ 2103 /* READ SECTORS for easier implemetation */ 2104 /* can't fit the transfer length but need to make it fit by sending multiple*/ 2105 TI_DBG5(("satRead12: case 1\n")); 2106 2107 fis->h.fisType = 0x27; /* Reg host to device */ 2108 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2109 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 2110 fis->h.features = 0; /* FIS reserve */ 2111 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 2112 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 2113 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 2114 fis->d.device = 2115 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 2116 fis->d.lbaLowExp = 0; 2117 fis->d.lbaMidExp = 0; 2118 fis->d.lbaHighExp = 0; 2119 fis->d.featuresExp = 0; 2120 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 2121 fis->d.sectorCountExp = 0; 2122 fis->d.reserved4 = 0; 2123 fis->d.control = 0; /* FIS HOB bit clear */ 2124 fis->d.reserved5 = 0; 2125 2126 2127 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 2128 satIOContext->ATACmd = SAT_READ_SECTORS; 2129 } 2130 } 2131 2132 /* case 3 and 4 */ 2133 if (pSatDevData->sat48BitSupport == agTRUE) 2134 { 2135 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 2136 { 2137 /* case 3 */ 2138 /* READ DMA EXT */ 2139 TI_DBG5(("satRead12: case 3\n")); 2140 fis->h.fisType = 0x27; /* Reg host to device */ 2141 2142 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2143 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */ 2144 fis->h.features = 0; /* FIS reserve */ 2145 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 2146 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 2147 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 2148 fis->d.device = 0x40; /* FIS LBA mode set */ 2149 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 2150 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 2151 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 2152 fis->d.featuresExp = 0; /* FIS reserve */ 2153 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 2154 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 2155 fis->d.reserved4 = 0; 2156 fis->d.control = 0; /* FIS HOB bit clear */ 2157 fis->d.reserved5 = 0; 2158 2159 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 2160 satIOContext->ATACmd = SAT_READ_DMA_EXT; 2161 2162 } 2163 else 2164 { 2165 /* case 4 */ 2166 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/ 2167 /* READ SECTORS EXT for easier implemetation */ 2168 TI_DBG5(("satRead12: case 4\n")); 2169 fis->h.fisType = 0x27; /* Reg host to device */ 2170 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2171 2172 /* Check FUA bit */ 2173 if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK) 2174 { 2175 /* for now, no support for FUA */ 2176 satSetSensePayload( pSense, 2177 SCSI_SNSKEY_ILLEGAL_REQUEST, 2178 0, 2179 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 2180 satIOContext); 2181 2182 ostiInitiatorIOCompleted( tiRoot, 2183 tiIORequest, 2184 tiIOSuccess, 2185 SCSI_STAT_CHECK_CONDITION, 2186 satIOContext->pTiSenseData, 2187 satIOContext->interruptContext ); 2188 return tiSuccess; 2189 } 2190 2191 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 2192 2193 fis->h.features = 0; /* FIS reserve */ 2194 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 2195 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 2196 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 2197 fis->d.device = 0x40; /* FIS LBA mode set */ 2198 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 2199 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 2200 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 2201 fis->d.featuresExp = 0; /* FIS reserve */ 2202 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 2203 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 2204 fis->d.reserved4 = 0; 2205 fis->d.control = 0; /* FIS HOB bit clear */ 2206 fis->d.reserved5 = 0; 2207 2208 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 2209 satIOContext->ATACmd = SAT_READ_SECTORS_EXT; 2210 } 2211 } 2212 2213 /* case 5 */ 2214 if (pSatDevData->satNCQ == agTRUE) 2215 { 2216 /* READ FPDMA QUEUED */ 2217 if (pSatDevData->sat48BitSupport != agTRUE) 2218 { 2219 TI_DBG5(("satRead12: case 5 !!! error NCQ but 28 bit address support \n")); 2220 satSetSensePayload( pSense, 2221 SCSI_SNSKEY_ILLEGAL_REQUEST, 2222 0, 2223 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 2224 satIOContext); 2225 2226 ostiInitiatorIOCompleted( tiRoot, 2227 tiIORequest, 2228 tiIOSuccess, 2229 SCSI_STAT_CHECK_CONDITION, 2230 satIOContext->pTiSenseData, 2231 satIOContext->interruptContext ); 2232 return tiSuccess; 2233 } 2234 2235 TI_DBG6(("satRead12: case 5\n")); 2236 2237 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */ 2238 2239 fis->h.fisType = 0x27; /* Reg host to device */ 2240 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2241 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */ 2242 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 2243 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 2244 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 2245 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 2246 2247 /* Check FUA bit */ 2248 if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK) 2249 fis->d.device = 0xC0; /* FIS FUA set */ 2250 else 2251 fis->d.device = 0x40; /* FIS FUA clear */ 2252 2253 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 2254 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 2255 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 2256 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 2257 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 2258 fis->d.sectorCountExp = 0; 2259 fis->d.reserved4 = 0; 2260 fis->d.control = 0; /* FIS HOB bit clear */ 2261 fis->d.reserved5 = 0; 2262 2263 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ; 2264 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED; 2265 } 2266 2267 /* saves the current LBA and orginal TL */ 2268 satIOContext->currentLBA = lba; 2269 satIOContext->OrgTL = tl; 2270 2271 /* 2272 computing number of loop and remainder for tl 2273 0xFF in case not ext 2274 0xFFFF in case EXT 2275 */ 2276 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 2277 { 2278 LoopNum = satComputeLoopNum(tl, 0xFF); 2279 } 2280 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 2281 { 2282 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 2283 LoopNum = satComputeLoopNum(tl, 0xFFFF); 2284 } 2285 else 2286 { 2287 /* SAT_READ_FPDMA_QUEUEDK */ 2288 LoopNum = satComputeLoopNum(tl, 0xFFFF); 2289 } 2290 2291 satIOContext->LoopNum = LoopNum; 2292 2293 if (LoopNum == 1) 2294 { 2295 TI_DBG5(("satRead12: NON CHAINED data\n")); 2296 satIOContext->satCompleteCB = &satNonChainedDataIOCB; 2297 } 2298 else 2299 { 2300 TI_DBG1(("satRead12: CHAINED data\n")); 2301 /* re-setting tl */ 2302 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 2303 { 2304 fis->d.sectorCount = 0xFF; 2305 } 2306 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 2307 { 2308 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 2309 fis->d.sectorCount = 0xFF; 2310 fis->d.sectorCountExp = 0xFF; 2311 } 2312 else 2313 { 2314 /* SAT_READ_FPDMA_QUEUED */ 2315 fis->h.features = 0xFF; 2316 fis->d.featuresExp = 0xFF; 2317 } 2318 2319 /* chained data */ 2320 satIOContext->satCompleteCB = &satChainedDataIOCB; 2321 } 2322 2323 /* 2324 * Prepare SGL and send FIS to LL layer. 2325 */ 2326 satIOContext->reqType = agRequestType; /* Save it */ 2327 2328 status = sataLLIOStart( tiRoot, 2329 tiIORequest, 2330 tiDeviceHandle, 2331 tiScsiRequest, 2332 satIOContext); 2333 2334 TI_DBG5(("satRead12: return\n")); 2335 return (status); 2336 } 2337 /*****************************************************************************/ 2338 /*! \brief SAT implementation for SCSI READ16. 2339 * 2340 * SAT implementation for SCSI READ16 and send FIS request to LL layer. 2341 * 2342 * \param tiRoot: Pointer to TISA initiator driver/port instance. 2343 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 2344 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 2345 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 2346 * \param satIOContext_t: Pointer to the SAT IO Context 2347 * 2348 * \return If command is started successfully 2349 * - \e tiSuccess: I/O request successfully initiated. 2350 * - \e tiBusy: No resources available, try again later. 2351 * - \e tiIONoDevice: Invalid device handle. 2352 * - \e tiError: Other errors. 2353 */ 2354 /*****************************************************************************/ 2355 GLOBAL bit32 satRead16( 2356 tiRoot_t *tiRoot, 2357 tiIORequest_t *tiIORequest, 2358 tiDeviceHandle_t *tiDeviceHandle, 2359 tiScsiInitiatorRequest_t *tiScsiRequest, 2360 satIOContext_t *satIOContext) 2361 { 2362 bit32 status; 2363 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 2364 satDeviceData_t *pSatDevData; 2365 scsiRspSense_t *pSense; 2366 tiIniScsiCmnd_t *scsiCmnd; 2367 agsaFisRegHostToDevice_t *fis; 2368 bit32 lba = 0; 2369 bit32 tl = 0; 2370 bit32 LoopNum = 1; 2371 bit8 LBA[8]; 2372 bit8 TL[8]; 2373 bit32 rangeChk = agFALSE; /* lba and tl range check */ 2374 bit32 limitChk = agFALSE; /* lba and tl range check */ 2375 2376 pSense = satIOContext->pSense; 2377 pSatDevData = satIOContext->pSatDevData; 2378 scsiCmnd = &tiScsiRequest->scsiCmnd; 2379 fis = satIOContext->pFis; 2380 2381 TI_DBG5(("satRead16: start\n")); 2382 2383 /* checking FUA_NV */ 2384 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 2385 { 2386 satSetSensePayload( pSense, 2387 SCSI_SNSKEY_ILLEGAL_REQUEST, 2388 0, 2389 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 2390 satIOContext); 2391 2392 ostiInitiatorIOCompleted( tiRoot, 2393 tiIORequest, 2394 tiIOSuccess, 2395 SCSI_STAT_CHECK_CONDITION, 2396 satIOContext->pTiSenseData, 2397 satIOContext->interruptContext ); 2398 2399 TI_DBG1(("satRead16: return FUA_NV\n")); 2400 return tiSuccess; 2401 2402 } 2403 2404 /* checking CONTROL */ 2405 /* NACA == 1 or LINK == 1*/ 2406 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 2407 { 2408 satSetSensePayload( pSense, 2409 SCSI_SNSKEY_ILLEGAL_REQUEST, 2410 0, 2411 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 2412 satIOContext); 2413 2414 ostiInitiatorIOCompleted( tiRoot, 2415 tiIORequest, 2416 tiIOSuccess, 2417 SCSI_STAT_CHECK_CONDITION, 2418 satIOContext->pTiSenseData, 2419 satIOContext->interruptContext ); 2420 2421 TI_DBG1(("satRead16: return control\n")); 2422 return tiSuccess; 2423 } 2424 2425 2426 osti_memset(LBA, 0, sizeof(LBA)); 2427 osti_memset(TL, 0, sizeof(TL)); 2428 2429 2430 /* do not use memcpy due to indexing in LBA and TL */ 2431 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 2432 LBA[1] = scsiCmnd->cdb[3]; 2433 LBA[2] = scsiCmnd->cdb[4]; 2434 LBA[3] = scsiCmnd->cdb[5]; 2435 LBA[4] = scsiCmnd->cdb[6]; 2436 LBA[5] = scsiCmnd->cdb[7]; 2437 LBA[6] = scsiCmnd->cdb[8]; 2438 LBA[7] = scsiCmnd->cdb[9]; /* LSB */ 2439 2440 TL[0] = 0; 2441 TL[1] = 0; 2442 TL[2] = 0; 2443 TL[3] = 0; 2444 TL[4] = scsiCmnd->cdb[10]; /* MSB */ 2445 TL[5] = scsiCmnd->cdb[11]; 2446 TL[6] = scsiCmnd->cdb[12]; 2447 TL[7] = scsiCmnd->cdb[13]; /* LSB */ 2448 2449 rangeChk = satAddNComparebit64(LBA, TL); 2450 2451 limitChk = satCompareLBALimitbit(LBA); 2452 2453 lba = satComputeCDB16LBA(satIOContext); 2454 tl = satComputeCDB16TL(satIOContext); 2455 2456 2457 /* Table 34, 9.1, p 46 */ 2458 /* 2459 note: As of 2/10/2006, no support for DMA QUEUED 2460 */ 2461 2462 /* 2463 Table 34, 9.1, p 46, b 2464 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 2465 return check condition 2466 */ 2467 if (pSatDevData->satNCQ != agTRUE && 2468 pSatDevData->sat48BitSupport != agTRUE 2469 ) 2470 { 2471 if (limitChk) 2472 { 2473 TI_DBG1(("satRead16: return LBA out of range, not EXT\n")); 2474 satSetSensePayload( pSense, 2475 SCSI_SNSKEY_ILLEGAL_REQUEST, 2476 0, 2477 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 2478 satIOContext); 2479 2480 ostiInitiatorIOCompleted( tiRoot, 2481 tiIORequest, 2482 tiIOSuccess, 2483 SCSI_STAT_CHECK_CONDITION, 2484 satIOContext->pTiSenseData, 2485 satIOContext->interruptContext ); 2486 2487 return tiSuccess; 2488 } 2489 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 2490 { 2491 TI_DBG1(("satRead16: return LBA+TL out of range, not EXT\n")); 2492 satSetSensePayload( pSense, 2493 SCSI_SNSKEY_ILLEGAL_REQUEST, 2494 0, 2495 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 2496 satIOContext); 2497 2498 ostiInitiatorIOCompleted( tiRoot, 2499 tiIORequest, 2500 tiIOSuccess, 2501 SCSI_STAT_CHECK_CONDITION, 2502 satIOContext->pTiSenseData, 2503 satIOContext->interruptContext ); 2504 2505 return tiSuccess; 2506 } 2507 } 2508 2509 /* case 1 and 2 */ 2510 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT) 2511 { 2512 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 2513 { 2514 /* case 2 */ 2515 /* READ DMA*/ 2516 /* in case that we can't fit the transfer length, 2517 we need to make it fit by sending multiple ATA cmnds */ 2518 TI_DBG5(("satRead16: case 2\n")); 2519 2520 2521 fis->h.fisType = 0x27; /* Reg host to device */ 2522 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2523 fis->h.command = SAT_READ_DMA; /* 0xC8 */ 2524 fis->h.features = 0; /* FIS reserve */ 2525 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 2526 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 2527 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 2528 fis->d.device = 2529 (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 2530 fis->d.lbaLowExp = 0; 2531 fis->d.lbaMidExp = 0; 2532 fis->d.lbaHighExp = 0; 2533 fis->d.featuresExp = 0; 2534 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 2535 fis->d.sectorCountExp = 0; 2536 fis->d.reserved4 = 0; 2537 fis->d.control = 0; /* FIS HOB bit clear */ 2538 fis->d.reserved5 = 0; 2539 2540 2541 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 2542 satIOContext->ATACmd = SAT_READ_DMA; 2543 } 2544 else 2545 { 2546 /* case 1 */ 2547 /* READ MULTIPLE or READ SECTOR(S) */ 2548 /* READ SECTORS for easier implemetation */ 2549 /* can't fit the transfer length but need to make it fit by sending multiple*/ 2550 TI_DBG5(("satRead16: case 1\n")); 2551 2552 fis->h.fisType = 0x27; /* Reg host to device */ 2553 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2554 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 2555 fis->h.features = 0; /* FIS reserve */ 2556 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 2557 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 2558 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 2559 fis->d.device = 2560 (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 2561 fis->d.lbaLowExp = 0; 2562 fis->d.lbaMidExp = 0; 2563 fis->d.lbaHighExp = 0; 2564 fis->d.featuresExp = 0; 2565 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 2566 fis->d.sectorCountExp = 0; 2567 fis->d.reserved4 = 0; 2568 fis->d.control = 0; /* FIS HOB bit clear */ 2569 fis->d.reserved5 = 0; 2570 2571 2572 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 2573 satIOContext->ATACmd = SAT_READ_SECTORS; 2574 } 2575 } 2576 2577 /* case 3 and 4 */ 2578 if (pSatDevData->sat48BitSupport == agTRUE) 2579 { 2580 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 2581 { 2582 /* case 3 */ 2583 /* READ DMA EXT */ 2584 TI_DBG5(("satRead16: case 3\n")); 2585 fis->h.fisType = 0x27; /* Reg host to device */ 2586 2587 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2588 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */ 2589 fis->h.features = 0; /* FIS reserve */ 2590 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 2591 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 2592 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 2593 fis->d.device = 0x40; /* FIS LBA mode set */ 2594 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 2595 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 2596 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 2597 fis->d.featuresExp = 0; /* FIS reserve */ 2598 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 2599 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 2600 fis->d.reserved4 = 0; 2601 fis->d.control = 0; /* FIS HOB bit clear */ 2602 fis->d.reserved5 = 0; 2603 2604 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 2605 satIOContext->ATACmd = SAT_READ_DMA_EXT; 2606 2607 } 2608 else 2609 { 2610 /* case 4 */ 2611 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/ 2612 /* READ SECTORS EXT for easier implemetation */ 2613 TI_DBG5(("satRead16: case 4\n")); 2614 fis->h.fisType = 0x27; /* Reg host to device */ 2615 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2616 2617 /* Check FUA bit */ 2618 if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK) 2619 { 2620 2621 /* for now, no support for FUA */ 2622 satSetSensePayload( pSense, 2623 SCSI_SNSKEY_ILLEGAL_REQUEST, 2624 0, 2625 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 2626 satIOContext); 2627 2628 ostiInitiatorIOCompleted( tiRoot, 2629 tiIORequest, 2630 tiIOSuccess, 2631 SCSI_STAT_CHECK_CONDITION, 2632 satIOContext->pTiSenseData, 2633 satIOContext->interruptContext ); 2634 return tiSuccess; 2635 } 2636 2637 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 2638 2639 fis->h.features = 0; /* FIS reserve */ 2640 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 2641 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 2642 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 2643 fis->d.device = 0x40; /* FIS LBA mode set */ 2644 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 2645 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 2646 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 2647 fis->d.featuresExp = 0; /* FIS reserve */ 2648 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 2649 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 2650 fis->d.reserved4 = 0; 2651 fis->d.control = 0; /* FIS HOB bit clear */ 2652 fis->d.reserved5 = 0; 2653 2654 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 2655 satIOContext->ATACmd = SAT_READ_SECTORS_EXT; 2656 } 2657 } 2658 2659 2660 /* case 5 */ 2661 if (pSatDevData->satNCQ == agTRUE) 2662 { 2663 /* READ FPDMA QUEUED */ 2664 if (pSatDevData->sat48BitSupport != agTRUE) 2665 { 2666 TI_DBG5(("satRead16: case 5 !!! error NCQ but 28 bit address support \n")); 2667 satSetSensePayload( pSense, 2668 SCSI_SNSKEY_ILLEGAL_REQUEST, 2669 0, 2670 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 2671 satIOContext); 2672 2673 ostiInitiatorIOCompleted( tiRoot, 2674 tiIORequest, 2675 tiIOSuccess, 2676 SCSI_STAT_CHECK_CONDITION, 2677 satIOContext->pTiSenseData, 2678 satIOContext->interruptContext ); 2679 return tiSuccess; 2680 } 2681 2682 TI_DBG6(("satRead16: case 5\n")); 2683 2684 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */ 2685 2686 fis->h.fisType = 0x27; /* Reg host to device */ 2687 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2688 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */ 2689 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 2690 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 2691 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 2692 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 2693 2694 /* Check FUA bit */ 2695 if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK) 2696 fis->d.device = 0xC0; /* FIS FUA set */ 2697 else 2698 fis->d.device = 0x40; /* FIS FUA clear */ 2699 2700 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 2701 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 2702 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 2703 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 2704 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 2705 fis->d.sectorCountExp = 0; 2706 fis->d.reserved4 = 0; 2707 fis->d.control = 0; /* FIS HOB bit clear */ 2708 fis->d.reserved5 = 0; 2709 2710 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ; 2711 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED; 2712 } 2713 2714 /* saves the current LBA and orginal TL */ 2715 satIOContext->currentLBA = lba; 2716 satIOContext->OrgTL = tl; 2717 2718 /* 2719 computing number of loop and remainder for tl 2720 0xFF in case not ext 2721 0xFFFF in case EXT 2722 */ 2723 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 2724 { 2725 LoopNum = satComputeLoopNum(tl, 0xFF); 2726 } 2727 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 2728 { 2729 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 2730 LoopNum = satComputeLoopNum(tl, 0xFFFF); 2731 } 2732 else 2733 { 2734 /* SAT_READ_FPDMA_QUEUEDK */ 2735 LoopNum = satComputeLoopNum(tl, 0xFFFF); 2736 } 2737 satIOContext->LoopNum = LoopNum; 2738 2739 if (LoopNum == 1) 2740 { 2741 TI_DBG5(("satRead16: NON CHAINED data\n")); 2742 satIOContext->satCompleteCB = &satNonChainedDataIOCB; 2743 } 2744 else 2745 { 2746 TI_DBG1(("satRead16: CHAINED data\n")); 2747 /* re-setting tl */ 2748 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 2749 { 2750 fis->d.sectorCount = 0xFF; 2751 } 2752 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 2753 { 2754 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 2755 fis->d.sectorCount = 0xFF; 2756 fis->d.sectorCountExp = 0xFF; 2757 } 2758 else 2759 { 2760 /* SAT_READ_FPDMA_QUEUED */ 2761 fis->h.features = 0xFF; 2762 fis->d.featuresExp = 0xFF; 2763 } 2764 2765 /* chained data */ 2766 satIOContext->satCompleteCB = &satChainedDataIOCB; 2767 } 2768 2769 /* 2770 * Prepare SGL and send FIS to LL layer. 2771 */ 2772 satIOContext->reqType = agRequestType; /* Save it */ 2773 2774 status = sataLLIOStart( tiRoot, 2775 tiIORequest, 2776 tiDeviceHandle, 2777 tiScsiRequest, 2778 satIOContext); 2779 2780 TI_DBG5(("satRead16: return\n")); 2781 return (status); 2782 2783 } 2784 2785 /*****************************************************************************/ 2786 /*! \brief SAT implementation for SCSI READ6. 2787 * 2788 * SAT implementation for SCSI READ6 and send FIS request to LL layer. 2789 * 2790 * \param tiRoot: Pointer to TISA initiator driver/port instance. 2791 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 2792 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 2793 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 2794 * \param satIOContext_t: Pointer to the SAT IO Context 2795 * 2796 * \return If command is started successfully 2797 * - \e tiSuccess: I/O request successfully initiated. 2798 * - \e tiBusy: No resources available, try again later. 2799 * - \e tiIONoDevice: Invalid device handle. 2800 * - \e tiError: Other errors. 2801 */ 2802 /*****************************************************************************/ 2803 GLOBAL bit32 satRead6( 2804 tiRoot_t *tiRoot, 2805 tiIORequest_t *tiIORequest, 2806 tiDeviceHandle_t *tiDeviceHandle, 2807 tiScsiInitiatorRequest_t *tiScsiRequest, 2808 satIOContext_t *satIOContext) 2809 { 2810 2811 bit32 status; 2812 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 2813 satDeviceData_t *pSatDevData; 2814 scsiRspSense_t *pSense; 2815 tiIniScsiCmnd_t *scsiCmnd; 2816 agsaFisRegHostToDevice_t *fis; 2817 bit32 lba = 0; 2818 bit16 tl = 0; 2819 2820 pSense = satIOContext->pSense; 2821 pSatDevData = satIOContext->pSatDevData; 2822 scsiCmnd = &tiScsiRequest->scsiCmnd; 2823 fis = satIOContext->pFis; 2824 2825 2826 TI_DBG5(("satRead6: start\n")); 2827 2828 /* no FUA checking since read6 */ 2829 2830 2831 /* checking CONTROL */ 2832 /* NACA == 1 or LINK == 1*/ 2833 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 2834 { 2835 satSetSensePayload( pSense, 2836 SCSI_SNSKEY_ILLEGAL_REQUEST, 2837 0, 2838 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 2839 satIOContext); 2840 2841 ostiInitiatorIOCompleted( tiRoot, 2842 tiIORequest, 2843 tiIOSuccess, 2844 SCSI_STAT_CHECK_CONDITION, 2845 satIOContext->pTiSenseData, 2846 satIOContext->interruptContext ); 2847 2848 TI_DBG2(("satRead6: return control\n")); 2849 return tiSuccess; 2850 } 2851 2852 /* cbd6; computing LBA and transfer length */ 2853 lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2)) 2854 + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3]; 2855 tl = scsiCmnd->cdb[4]; 2856 2857 2858 /* Table 34, 9.1, p 46 */ 2859 /* 2860 note: As of 2/10/2006, no support for DMA QUEUED 2861 */ 2862 2863 /* 2864 Table 34, 9.1, p 46, b 2865 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 2866 return check condition 2867 */ 2868 if (pSatDevData->satNCQ != agTRUE && 2869 pSatDevData->sat48BitSupport != agTRUE 2870 ) 2871 { 2872 if (lba > SAT_TR_LBA_LIMIT - 1) 2873 { 2874 satSetSensePayload( pSense, 2875 SCSI_SNSKEY_ILLEGAL_REQUEST, 2876 0, 2877 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 2878 satIOContext); 2879 2880 ostiInitiatorIOCompleted( tiRoot, 2881 tiIORequest, 2882 tiIOSuccess, 2883 SCSI_STAT_CHECK_CONDITION, 2884 satIOContext->pTiSenseData, 2885 satIOContext->interruptContext ); 2886 2887 TI_DBG1(("satRead6: return LBA out of range\n")); 2888 return tiSuccess; 2889 } 2890 } 2891 2892 /* case 1 and 2 */ 2893 if (lba + tl <= SAT_TR_LBA_LIMIT) 2894 { 2895 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 2896 { 2897 /* case 2 */ 2898 /* READ DMA*/ 2899 TI_DBG5(("satRead6: case 2\n")); 2900 2901 2902 fis->h.fisType = 0x27; /* Reg host to device */ 2903 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2904 fis->h.command = SAT_READ_DMA; /* 0xC8 */ 2905 fis->h.features = 0; /* FIS reserve */ 2906 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 2907 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 2908 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 2909 fis->d.device = 0x40; /* FIS LBA mode */ 2910 fis->d.lbaLowExp = 0; 2911 fis->d.lbaMidExp = 0; 2912 fis->d.lbaHighExp = 0; 2913 fis->d.featuresExp = 0; 2914 if (tl == 0) 2915 { 2916 /* temporary fix */ 2917 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */ 2918 } 2919 else 2920 { 2921 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 2922 } 2923 fis->d.sectorCountExp = 0; 2924 fis->d.reserved4 = 0; 2925 fis->d.control = 0; /* FIS HOB bit clear */ 2926 fis->d.reserved5 = 0; 2927 2928 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 2929 } 2930 else 2931 { 2932 /* case 1 */ 2933 /* READ SECTORS for easier implemetation */ 2934 TI_DBG5(("satRead6: case 1\n")); 2935 2936 fis->h.fisType = 0x27; /* Reg host to device */ 2937 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2938 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 2939 fis->h.features = 0; /* FIS reserve */ 2940 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 2941 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 2942 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 2943 fis->d.device = 0x40; /* FIS LBA mode */ 2944 fis->d.lbaLowExp = 0; 2945 fis->d.lbaMidExp = 0; 2946 fis->d.lbaHighExp = 0; 2947 fis->d.featuresExp = 0; 2948 if (tl == 0) 2949 { 2950 /* temporary fix */ 2951 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */ 2952 } 2953 else 2954 { 2955 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 2956 } 2957 fis->d.sectorCountExp = 0; 2958 fis->d.reserved4 = 0; 2959 fis->d.control = 0; /* FIS HOB bit clear */ 2960 fis->d.reserved5 = 0; 2961 2962 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 2963 2964 } 2965 } 2966 2967 /* case 3 and 4 */ 2968 if (pSatDevData->sat48BitSupport == agTRUE) 2969 { 2970 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 2971 { 2972 /* case 3 */ 2973 /* READ DMA EXT only */ 2974 TI_DBG5(("satRead6: case 3\n")); 2975 fis->h.fisType = 0x27; /* Reg host to device */ 2976 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2977 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */ 2978 fis->h.features = 0; /* FIS reserve */ 2979 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 2980 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 2981 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 2982 fis->d.device = 0x40; /* FIS LBA mode set */ 2983 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 2984 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 2985 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 2986 fis->d.featuresExp = 0; /* FIS reserve */ 2987 if (tl == 0) 2988 { 2989 /* sector count is 256, 0x100*/ 2990 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 2991 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */ 2992 } 2993 else 2994 { 2995 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 2996 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 2997 } 2998 fis->d.reserved4 = 0; 2999 fis->d.control = 0; /* FIS HOB bit clear */ 3000 fis->d.reserved5 = 0; 3001 3002 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 3003 } 3004 else 3005 { 3006 /* case 4 */ 3007 /* READ SECTORS EXT for easier implemetation */ 3008 TI_DBG5(("satRead6: case 4\n")); 3009 3010 fis->h.fisType = 0x27; /* Reg host to device */ 3011 fis->h.c_pmPort = 0x80; /* C Bit is set */ 3012 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 3013 fis->h.features = 0; /* FIS reserve */ 3014 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 3015 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 3016 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 3017 fis->d.device = 0x40; /* FIS LBA mode set */ 3018 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 3019 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 3020 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 3021 fis->d.featuresExp = 0; /* FIS reserve */ 3022 if (tl == 0) 3023 { 3024 /* sector count is 256, 0x100*/ 3025 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 3026 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */ 3027 } 3028 else 3029 { 3030 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 3031 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 3032 } 3033 fis->d.reserved4 = 0; 3034 fis->d.control = 0; /* FIS HOB bit clear */ 3035 fis->d.reserved5 = 0; 3036 3037 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 3038 } 3039 } 3040 3041 /* case 5 */ 3042 if (pSatDevData->satNCQ == agTRUE) 3043 { 3044 /* READ FPDMA QUEUED */ 3045 if (pSatDevData->sat48BitSupport != agTRUE) 3046 { 3047 /* sanity check */ 3048 TI_DBG5(("satRead6: case 5 !!! error NCQ but 28 bit address support \n")); 3049 satSetSensePayload( pSense, 3050 SCSI_SNSKEY_ILLEGAL_REQUEST, 3051 0, 3052 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 3053 satIOContext); 3054 3055 ostiInitiatorIOCompleted( tiRoot, 3056 tiIORequest, 3057 tiIOSuccess, 3058 SCSI_STAT_CHECK_CONDITION, 3059 satIOContext->pTiSenseData, 3060 satIOContext->interruptContext ); 3061 return tiSuccess; 3062 } 3063 TI_DBG5(("satRead6: case 5\n")); 3064 3065 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */ 3066 3067 fis->h.fisType = 0x27; /* Reg host to device */ 3068 fis->h.c_pmPort = 0x80; /* C Bit is set */ 3069 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */ 3070 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 3071 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 3072 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 3073 fis->d.device = 0x40; /* FIS FUA clear */ 3074 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 3075 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 3076 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 3077 if (tl == 0) 3078 { 3079 /* sector count is 256, 0x100*/ 3080 fis->h.features = 0; /* FIS sector count (7:0) */ 3081 fis->d.featuresExp = 0x01; /* FIS sector count (15:8) */ 3082 } 3083 else 3084 { 3085 fis->h.features = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 3086 fis->d.featuresExp = 0; /* FIS sector count (15:8) */ 3087 } 3088 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 3089 fis->d.sectorCountExp = 0; 3090 fis->d.reserved4 = 0; 3091 fis->d.control = 0; /* FIS HOB bit clear */ 3092 fis->d.reserved5 = 0; 3093 3094 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ; 3095 } 3096 3097 /* Initialize CB for SATA completion. 3098 */ 3099 satIOContext->satCompleteCB = &satNonChainedDataIOCB; 3100 3101 /* 3102 * Prepare SGL and send FIS to LL layer. 3103 */ 3104 satIOContext->reqType = agRequestType; /* Save it */ 3105 3106 status = sataLLIOStart( tiRoot, 3107 tiIORequest, 3108 tiDeviceHandle, 3109 tiScsiRequest, 3110 satIOContext); 3111 return (status); 3112 3113 } 3114 3115 /*****************************************************************************/ 3116 /*! \brief SAT implementation for SCSI WRITE16. 3117 * 3118 * SAT implementation for SCSI WRITE16 and send FIS request to LL layer. 3119 * 3120 * \param tiRoot: Pointer to TISA initiator driver/port instance. 3121 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 3122 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 3123 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 3124 * \param satIOContext_t: Pointer to the SAT IO Context 3125 * 3126 * \return If command is started successfully 3127 * - \e tiSuccess: I/O request successfully initiated. 3128 * - \e tiBusy: No resources available, try again later. 3129 * - \e tiIONoDevice: Invalid device handle. 3130 * - \e tiError: Other errors. 3131 */ 3132 /*****************************************************************************/ 3133 GLOBAL bit32 satWrite16( 3134 tiRoot_t *tiRoot, 3135 tiIORequest_t *tiIORequest, 3136 tiDeviceHandle_t *tiDeviceHandle, 3137 tiScsiInitiatorRequest_t *tiScsiRequest, 3138 satIOContext_t *satIOContext) 3139 { 3140 bit32 status; 3141 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 3142 satDeviceData_t *pSatDevData; 3143 scsiRspSense_t *pSense; 3144 tiIniScsiCmnd_t *scsiCmnd; 3145 agsaFisRegHostToDevice_t *fis; 3146 bit32 lba = 0; 3147 bit32 tl = 0; 3148 bit32 LoopNum = 1; 3149 bit8 LBA[8]; 3150 bit8 TL[8]; 3151 bit32 rangeChk = agFALSE; /* lba and tl range check */ 3152 bit32 limitChk = agFALSE; /* lba and tl range check */ 3153 3154 pSense = satIOContext->pSense; 3155 pSatDevData = satIOContext->pSatDevData; 3156 scsiCmnd = &tiScsiRequest->scsiCmnd; 3157 fis = satIOContext->pFis; 3158 3159 TI_DBG5(("satWrite16: start\n")); 3160 3161 /* checking FUA_NV */ 3162 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 3163 { 3164 satSetSensePayload( pSense, 3165 SCSI_SNSKEY_ILLEGAL_REQUEST, 3166 0, 3167 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 3168 satIOContext); 3169 3170 ostiInitiatorIOCompleted( tiRoot, 3171 tiIORequest, 3172 tiIOSuccess, 3173 SCSI_STAT_CHECK_CONDITION, 3174 satIOContext->pTiSenseData, 3175 satIOContext->interruptContext ); 3176 3177 TI_DBG1(("satWrite16: return FUA_NV\n")); 3178 return tiSuccess; 3179 3180 } 3181 3182 /* checking CONTROL */ 3183 /* NACA == 1 or LINK == 1*/ 3184 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 3185 { 3186 satSetSensePayload( pSense, 3187 SCSI_SNSKEY_ILLEGAL_REQUEST, 3188 0, 3189 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 3190 satIOContext); 3191 3192 ostiInitiatorIOCompleted( tiRoot, 3193 tiIORequest, 3194 tiIOSuccess, 3195 SCSI_STAT_CHECK_CONDITION, 3196 satIOContext->pTiSenseData, 3197 satIOContext->interruptContext ); 3198 3199 TI_DBG1(("satWrite16: return control\n")); 3200 return tiSuccess; 3201 } 3202 3203 3204 osti_memset(LBA, 0, sizeof(LBA)); 3205 osti_memset(TL, 0, sizeof(TL)); 3206 3207 3208 /* do not use memcpy due to indexing in LBA and TL */ 3209 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 3210 LBA[1] = scsiCmnd->cdb[3]; 3211 LBA[2] = scsiCmnd->cdb[4]; 3212 LBA[3] = scsiCmnd->cdb[5]; 3213 LBA[4] = scsiCmnd->cdb[6]; 3214 LBA[5] = scsiCmnd->cdb[7]; 3215 LBA[6] = scsiCmnd->cdb[8]; 3216 LBA[7] = scsiCmnd->cdb[9]; /* LSB */ 3217 3218 TL[0] = 0; 3219 TL[1] = 0; 3220 TL[2] = 0; 3221 TL[3] = 0; 3222 TL[4] = scsiCmnd->cdb[10]; /* MSB */ 3223 TL[5] = scsiCmnd->cdb[11]; 3224 TL[6] = scsiCmnd->cdb[12]; 3225 TL[7] = scsiCmnd->cdb[13]; /* LSB */ 3226 3227 rangeChk = satAddNComparebit64(LBA, TL); 3228 3229 limitChk = satCompareLBALimitbit(LBA); 3230 3231 lba = satComputeCDB16LBA(satIOContext); 3232 tl = satComputeCDB16TL(satIOContext); 3233 3234 3235 3236 /* Table 34, 9.1, p 46 */ 3237 /* 3238 note: As of 2/10/2006, no support for DMA QUEUED 3239 */ 3240 3241 /* 3242 Table 34, 9.1, p 46, b 3243 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 3244 return check condition 3245 */ 3246 if (pSatDevData->satNCQ != agTRUE && 3247 pSatDevData->sat48BitSupport != agTRUE 3248 ) 3249 { 3250 if (limitChk) 3251 { 3252 TI_DBG1(("satWrite16: return LBA out of range, not EXT\n")); 3253 satSetSensePayload( pSense, 3254 SCSI_SNSKEY_ILLEGAL_REQUEST, 3255 0, 3256 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 3257 satIOContext); 3258 3259 ostiInitiatorIOCompleted( tiRoot, 3260 tiIORequest, 3261 tiIOSuccess, 3262 SCSI_STAT_CHECK_CONDITION, 3263 satIOContext->pTiSenseData, 3264 satIOContext->interruptContext ); 3265 3266 return tiSuccess; 3267 } 3268 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 3269 { 3270 TI_DBG1(("satWrite16: return LBA+TL out of range, not EXT\n")); 3271 satSetSensePayload( pSense, 3272 SCSI_SNSKEY_ILLEGAL_REQUEST, 3273 0, 3274 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 3275 satIOContext); 3276 3277 ostiInitiatorIOCompleted( tiRoot, 3278 tiIORequest, 3279 tiIOSuccess, 3280 SCSI_STAT_CHECK_CONDITION, 3281 satIOContext->pTiSenseData, 3282 satIOContext->interruptContext ); 3283 3284 return tiSuccess; 3285 } 3286 } 3287 3288 /* case 1 and 2 */ 3289 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT) 3290 { 3291 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 3292 { 3293 /* case 2 */ 3294 /* WRITE DMA*/ 3295 /* In case that we can't fit the transfer length, we loop */ 3296 TI_DBG5(("satWrite16: case 2\n")); 3297 fis->h.fisType = 0x27; /* Reg host to device */ 3298 fis->h.c_pmPort = 0x80; /* C bit is set */ 3299 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 3300 fis->h.features = 0; /* FIS reserve */ 3301 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 3302 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 3303 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 3304 3305 /* FIS LBA mode set LBA (27:24) */ 3306 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); 3307 3308 fis->d.lbaLowExp = 0; 3309 fis->d.lbaMidExp = 0; 3310 fis->d.lbaHighExp = 0; 3311 fis->d.featuresExp = 0; 3312 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 3313 fis->d.sectorCountExp = 0; 3314 fis->d.reserved4 = 0; 3315 fis->d.control = 0; /* FIS HOB bit clear */ 3316 fis->d.reserved5 = 0; 3317 3318 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 3319 satIOContext->ATACmd = SAT_WRITE_DMA; 3320 } 3321 else 3322 { 3323 /* case 1 */ 3324 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 3325 /* WRITE SECTORS for easier implemetation */ 3326 /* In case that we can't fit the transfer length, we loop */ 3327 TI_DBG5(("satWrite16: case 1\n")); 3328 fis->h.fisType = 0x27; /* Reg host to device */ 3329 fis->h.c_pmPort = 0x80; /* C bit is set */ 3330 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 3331 fis->h.features = 0; /* FIS reserve */ 3332 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 3333 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 3334 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 3335 3336 /* FIS LBA mode set LBA (27:24) */ 3337 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); 3338 3339 fis->d.lbaLowExp = 0; 3340 fis->d.lbaMidExp = 0; 3341 fis->d.lbaHighExp = 0; 3342 fis->d.featuresExp = 0; 3343 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 3344 fis->d.sectorCountExp = 0; 3345 fis->d.reserved4 = 0; 3346 fis->d.control = 0; /* FIS HOB bit clear */ 3347 fis->d.reserved5 = 0; 3348 3349 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 3350 satIOContext->ATACmd = SAT_WRITE_SECTORS; 3351 } 3352 } 3353 3354 /* case 3 and 4 */ 3355 if (pSatDevData->sat48BitSupport == agTRUE) 3356 { 3357 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 3358 { 3359 /* case 3 */ 3360 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 3361 TI_DBG5(("satWrite16: case 3\n")); 3362 fis->h.fisType = 0x27; /* Reg host to device */ 3363 fis->h.c_pmPort = 0x80; /* C Bit is set */ 3364 3365 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 3366 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 3367 3368 fis->h.features = 0; /* FIS reserve */ 3369 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 3370 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 3371 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 3372 fis->d.device = 0x40; /* FIS LBA mode set */ 3373 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 3374 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 3375 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 3376 fis->d.featuresExp = 0; /* FIS reserve */ 3377 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 3378 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 3379 fis->d.reserved4 = 0; 3380 fis->d.control = 0; /* FIS HOB bit clear */ 3381 fis->d.reserved5 = 0; 3382 3383 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 3384 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 3385 } 3386 else 3387 { 3388 /* case 4 */ 3389 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 3390 /* WRITE SECTORS EXT for easier implemetation */ 3391 TI_DBG5(("satWrite16: case 4\n")); 3392 fis->h.fisType = 0x27; /* Reg host to device */ 3393 fis->h.c_pmPort = 0x80; /* C Bit is set */ 3394 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 3395 3396 fis->h.features = 0; /* FIS reserve */ 3397 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 3398 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 3399 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 3400 fis->d.device = 0x40; /* FIS LBA mode set */ 3401 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 3402 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 3403 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 3404 fis->d.featuresExp = 0; /* FIS reserve */ 3405 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 3406 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 3407 fis->d.reserved4 = 0; 3408 fis->d.control = 0; /* FIS HOB bit clear */ 3409 fis->d.reserved5 = 0; 3410 3411 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 3412 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 3413 } 3414 } 3415 3416 /* case 5 */ 3417 if (pSatDevData->satNCQ == agTRUE) 3418 { 3419 /* WRITE FPDMA QUEUED */ 3420 if (pSatDevData->sat48BitSupport != agTRUE) 3421 { 3422 TI_DBG5(("satWrite16: case 5 !!! error NCQ but 28 bit address support \n")); 3423 satSetSensePayload( pSense, 3424 SCSI_SNSKEY_ILLEGAL_REQUEST, 3425 0, 3426 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 3427 satIOContext); 3428 3429 ostiInitiatorIOCompleted( tiRoot, 3430 tiIORequest, 3431 tiIOSuccess, 3432 SCSI_STAT_CHECK_CONDITION, 3433 satIOContext->pTiSenseData, 3434 satIOContext->interruptContext ); 3435 return tiSuccess; 3436 } 3437 TI_DBG6(("satWrite16: case 5\n")); 3438 3439 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 3440 3441 fis->h.fisType = 0x27; /* Reg host to device */ 3442 fis->h.c_pmPort = 0x80; /* C Bit is set */ 3443 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 3444 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 3445 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 3446 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 3447 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 3448 3449 /* Check FUA bit */ 3450 if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK) 3451 fis->d.device = 0xC0; /* FIS FUA set */ 3452 else 3453 fis->d.device = 0x40; /* FIS FUA clear */ 3454 3455 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 3456 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 3457 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 3458 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 3459 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 3460 fis->d.sectorCountExp = 0; 3461 fis->d.reserved4 = 0; 3462 fis->d.control = 0; /* FIS HOB bit clear */ 3463 fis->d.reserved5 = 0; 3464 3465 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 3466 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 3467 } 3468 3469 satIOContext->currentLBA = lba; 3470 satIOContext->OrgTL = tl; 3471 3472 /* 3473 computing number of loop and remainder for tl 3474 0xFF in case not ext 3475 0xFFFF in case EXT 3476 */ 3477 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 3478 { 3479 LoopNum = satComputeLoopNum(tl, 0xFF); 3480 } 3481 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 3482 fis->h.command == SAT_WRITE_DMA_EXT || 3483 fis->h.command == SAT_WRITE_DMA_FUA_EXT 3484 ) 3485 { 3486 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 3487 LoopNum = satComputeLoopNum(tl, 0xFFFF); 3488 } 3489 else 3490 { 3491 /* SAT_WRITE_FPDMA_QUEUEDK */ 3492 LoopNum = satComputeLoopNum(tl, 0xFFFF); 3493 } 3494 3495 satIOContext->LoopNum = LoopNum; 3496 3497 3498 if (LoopNum == 1) 3499 { 3500 TI_DBG5(("satWrite16: NON CHAINED data\n")); 3501 /* Initialize CB for SATA completion. 3502 */ 3503 satIOContext->satCompleteCB = &satNonChainedDataIOCB; 3504 } 3505 else 3506 { 3507 TI_DBG1(("satWrite16: CHAINED data\n")); 3508 /* re-setting tl */ 3509 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 3510 { 3511 fis->d.sectorCount = 0xFF; 3512 } 3513 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 3514 fis->h.command == SAT_WRITE_DMA_EXT || 3515 fis->h.command == SAT_WRITE_DMA_FUA_EXT 3516 ) 3517 { 3518 fis->d.sectorCount = 0xFF; 3519 fis->d.sectorCountExp = 0xFF; 3520 } 3521 else 3522 { 3523 /* SAT_WRITE_FPDMA_QUEUED */ 3524 fis->h.features = 0xFF; 3525 fis->d.featuresExp = 0xFF; 3526 } 3527 3528 /* Initialize CB for SATA completion. 3529 */ 3530 satIOContext->satCompleteCB = &satChainedDataIOCB; 3531 } 3532 3533 3534 /* 3535 * Prepare SGL and send FIS to LL layer. 3536 */ 3537 satIOContext->reqType = agRequestType; /* Save it */ 3538 3539 status = sataLLIOStart( tiRoot, 3540 tiIORequest, 3541 tiDeviceHandle, 3542 tiScsiRequest, 3543 satIOContext); 3544 return (status); 3545 } 3546 3547 /*****************************************************************************/ 3548 /*! \brief SAT implementation for SCSI WRITE12. 3549 * 3550 * SAT implementation for SCSI WRITE12 and send FIS request to LL layer. 3551 * 3552 * \param tiRoot: Pointer to TISA initiator driver/port instance. 3553 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 3554 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 3555 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 3556 * \param satIOContext_t: Pointer to the SAT IO Context 3557 * 3558 * \return If command is started successfully 3559 * - \e tiSuccess: I/O request successfully initiated. 3560 * - \e tiBusy: No resources available, try again later. 3561 * - \e tiIONoDevice: Invalid device handle. 3562 * - \e tiError: Other errors. 3563 */ 3564 /*****************************************************************************/ 3565 GLOBAL bit32 satWrite12( 3566 tiRoot_t *tiRoot, 3567 tiIORequest_t *tiIORequest, 3568 tiDeviceHandle_t *tiDeviceHandle, 3569 tiScsiInitiatorRequest_t *tiScsiRequest, 3570 satIOContext_t *satIOContext) 3571 { 3572 bit32 status; 3573 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 3574 satDeviceData_t *pSatDevData; 3575 scsiRspSense_t *pSense; 3576 tiIniScsiCmnd_t *scsiCmnd; 3577 agsaFisRegHostToDevice_t *fis; 3578 bit32 lba = 0; 3579 bit32 tl = 0; 3580 bit32 LoopNum = 1; 3581 bit8 LBA[4]; 3582 bit8 TL[4]; 3583 bit32 rangeChk = agFALSE; /* lba and tl range check */ 3584 3585 pSense = satIOContext->pSense; 3586 pSatDevData = satIOContext->pSatDevData; 3587 scsiCmnd = &tiScsiRequest->scsiCmnd; 3588 fis = satIOContext->pFis; 3589 3590 TI_DBG5(("satWrite12: start\n")); 3591 3592 /* checking FUA_NV */ 3593 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 3594 { 3595 satSetSensePayload( pSense, 3596 SCSI_SNSKEY_ILLEGAL_REQUEST, 3597 0, 3598 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 3599 satIOContext); 3600 3601 ostiInitiatorIOCompleted( tiRoot, 3602 tiIORequest, 3603 tiIOSuccess, 3604 SCSI_STAT_CHECK_CONDITION, 3605 satIOContext->pTiSenseData, 3606 satIOContext->interruptContext ); 3607 3608 TI_DBG1(("satWrite12: return FUA_NV\n")); 3609 return tiSuccess; 3610 3611 } 3612 3613 3614 /* checking CONTROL */ 3615 /* NACA == 1 or LINK == 1*/ 3616 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) ) 3617 { 3618 satSetSensePayload( pSense, 3619 SCSI_SNSKEY_ILLEGAL_REQUEST, 3620 0, 3621 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 3622 satIOContext); 3623 3624 ostiInitiatorIOCompleted( tiRoot, 3625 tiIORequest, 3626 tiIOSuccess, 3627 SCSI_STAT_CHECK_CONDITION, 3628 satIOContext->pTiSenseData, 3629 satIOContext->interruptContext ); 3630 3631 TI_DBG1(("satWrite12: return control\n")); 3632 return tiSuccess; 3633 } 3634 3635 3636 osti_memset(LBA, 0, sizeof(LBA)); 3637 osti_memset(TL, 0, sizeof(TL)); 3638 3639 /* do not use memcpy due to indexing in LBA and TL */ 3640 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 3641 LBA[1] = scsiCmnd->cdb[3]; 3642 LBA[2] = scsiCmnd->cdb[4]; 3643 LBA[3] = scsiCmnd->cdb[5]; /* LSB */ 3644 3645 TL[0] = scsiCmnd->cdb[6]; /* MSB */ 3646 TL[1] = scsiCmnd->cdb[7]; 3647 TL[2] = scsiCmnd->cdb[8]; 3648 TL[3] = scsiCmnd->cdb[9]; /* LSB */ 3649 3650 rangeChk = satAddNComparebit32(LBA, TL); 3651 3652 lba = satComputeCDB12LBA(satIOContext); 3653 tl = satComputeCDB12TL(satIOContext); 3654 3655 3656 /* Table 34, 9.1, p 46 */ 3657 /* 3658 note: As of 2/10/2006, no support for DMA QUEUED 3659 */ 3660 3661 /* 3662 Table 34, 9.1, p 46, b 3663 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 3664 return check condition 3665 */ 3666 if (pSatDevData->satNCQ != agTRUE && 3667 pSatDevData->sat48BitSupport != agTRUE 3668 ) 3669 { 3670 if (lba > SAT_TR_LBA_LIMIT - 1) 3671 { 3672 satSetSensePayload( pSense, 3673 SCSI_SNSKEY_ILLEGAL_REQUEST, 3674 0, 3675 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 3676 satIOContext); 3677 3678 ostiInitiatorIOCompleted( tiRoot, 3679 tiIORequest, 3680 tiIOSuccess, 3681 SCSI_STAT_CHECK_CONDITION, 3682 satIOContext->pTiSenseData, 3683 satIOContext->interruptContext ); 3684 3685 TI_DBG1(("satWrite12: return LBA out of range, not EXT\n")); 3686 return tiSuccess; 3687 } 3688 3689 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 3690 { 3691 TI_DBG1(("satWrite12: return LBA+TL out of range, not EXT\n")); 3692 satSetSensePayload( pSense, 3693 SCSI_SNSKEY_ILLEGAL_REQUEST, 3694 0, 3695 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 3696 satIOContext); 3697 3698 ostiInitiatorIOCompleted( tiRoot, 3699 tiIORequest, 3700 tiIOSuccess, 3701 SCSI_STAT_CHECK_CONDITION, 3702 satIOContext->pTiSenseData, 3703 satIOContext->interruptContext ); 3704 3705 return tiSuccess; 3706 } 3707 } 3708 3709 3710 /* case 1 and 2 */ 3711 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT) 3712 { 3713 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 3714 { 3715 /* case 2 */ 3716 /* WRITE DMA*/ 3717 /* In case that we can't fit the transfer length, we loop */ 3718 TI_DBG5(("satWrite12: case 2\n")); 3719 fis->h.fisType = 0x27; /* Reg host to device */ 3720 fis->h.c_pmPort = 0x80; /* C bit is set */ 3721 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 3722 fis->h.features = 0; /* FIS reserve */ 3723 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 3724 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 3725 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 3726 3727 /* FIS LBA mode set LBA (27:24) */ 3728 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 3729 3730 fis->d.lbaLowExp = 0; 3731 fis->d.lbaMidExp = 0; 3732 fis->d.lbaHighExp = 0; 3733 fis->d.featuresExp = 0; 3734 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 3735 fis->d.sectorCountExp = 0; 3736 fis->d.reserved4 = 0; 3737 fis->d.control = 0; /* FIS HOB bit clear */ 3738 fis->d.reserved5 = 0; 3739 3740 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 3741 satIOContext->ATACmd = SAT_WRITE_DMA; 3742 } 3743 else 3744 { 3745 /* case 1 */ 3746 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 3747 /* WRITE SECTORS for easier implemetation */ 3748 /* In case that we can't fit the transfer length, we loop */ 3749 TI_DBG5(("satWrite12: case 1\n")); 3750 fis->h.fisType = 0x27; /* Reg host to device */ 3751 fis->h.c_pmPort = 0x80; /* C bit is set */ 3752 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 3753 fis->h.features = 0; /* FIS reserve */ 3754 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 3755 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 3756 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 3757 3758 /* FIS LBA mode set LBA (27:24) */ 3759 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 3760 3761 fis->d.lbaLowExp = 0; 3762 fis->d.lbaMidExp = 0; 3763 fis->d.lbaHighExp = 0; 3764 fis->d.featuresExp = 0; 3765 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 3766 fis->d.sectorCountExp = 0; 3767 fis->d.reserved4 = 0; 3768 fis->d.control = 0; /* FIS HOB bit clear */ 3769 fis->d.reserved5 = 0; 3770 3771 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 3772 satIOContext->ATACmd = SAT_WRITE_SECTORS; 3773 } 3774 } 3775 3776 /* case 3 and 4 */ 3777 if (pSatDevData->sat48BitSupport == agTRUE) 3778 { 3779 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 3780 { 3781 /* case 3 */ 3782 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 3783 TI_DBG5(("satWrite12: case 3\n")); 3784 fis->h.fisType = 0x27; /* Reg host to device */ 3785 fis->h.c_pmPort = 0x80; /* C Bit is set */ 3786 3787 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 3788 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 3789 3790 fis->h.features = 0; /* FIS reserve */ 3791 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 3792 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 3793 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 3794 fis->d.device = 0x40; /* FIS LBA mode set */ 3795 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 3796 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 3797 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 3798 fis->d.featuresExp = 0; /* FIS reserve */ 3799 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 3800 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 3801 fis->d.reserved4 = 0; 3802 fis->d.control = 0; /* FIS HOB bit clear */ 3803 fis->d.reserved5 = 0; 3804 3805 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 3806 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 3807 } 3808 else 3809 { 3810 /* case 4 */ 3811 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 3812 /* WRITE SECTORS EXT for easier implemetation */ 3813 TI_DBG5(("satWrite12: case 4\n")); 3814 fis->h.fisType = 0x27; /* Reg host to device */ 3815 fis->h.c_pmPort = 0x80; /* C Bit is set */ 3816 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 3817 3818 fis->h.features = 0; /* FIS reserve */ 3819 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 3820 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 3821 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 3822 fis->d.device = 0x40; /* FIS LBA mode set */ 3823 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 3824 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 3825 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 3826 fis->d.featuresExp = 0; /* FIS reserve */ 3827 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 3828 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 3829 fis->d.reserved4 = 0; 3830 fis->d.control = 0; /* FIS HOB bit clear */ 3831 fis->d.reserved5 = 0; 3832 3833 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 3834 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 3835 } 3836 } 3837 3838 /* case 5 */ 3839 if (pSatDevData->satNCQ == agTRUE) 3840 { 3841 /* WRITE FPDMA QUEUED */ 3842 if (pSatDevData->sat48BitSupport != agTRUE) 3843 { 3844 TI_DBG5(("satWrite12: case 5 !!! error NCQ but 28 bit address support \n")); 3845 satSetSensePayload( pSense, 3846 SCSI_SNSKEY_ILLEGAL_REQUEST, 3847 0, 3848 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 3849 satIOContext); 3850 3851 ostiInitiatorIOCompleted( tiRoot, 3852 tiIORequest, 3853 tiIOSuccess, 3854 SCSI_STAT_CHECK_CONDITION, 3855 satIOContext->pTiSenseData, 3856 satIOContext->interruptContext ); 3857 return tiSuccess; 3858 } 3859 TI_DBG6(("satWrite12: case 5\n")); 3860 3861 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 3862 3863 fis->h.fisType = 0x27; /* Reg host to device */ 3864 fis->h.c_pmPort = 0x80; /* C Bit is set */ 3865 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 3866 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 3867 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 3868 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 3869 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 3870 3871 /* Check FUA bit */ 3872 if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK) 3873 fis->d.device = 0xC0; /* FIS FUA set */ 3874 else 3875 fis->d.device = 0x40; /* FIS FUA clear */ 3876 3877 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 3878 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 3879 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 3880 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 3881 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 3882 fis->d.sectorCountExp = 0; 3883 fis->d.reserved4 = 0; 3884 fis->d.control = 0; /* FIS HOB bit clear */ 3885 fis->d.reserved5 = 0; 3886 3887 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 3888 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 3889 } 3890 3891 satIOContext->currentLBA = lba; 3892 satIOContext->OrgTL = tl; 3893 3894 /* 3895 computing number of loop and remainder for tl 3896 0xFF in case not ext 3897 0xFFFF in case EXT 3898 */ 3899 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 3900 { 3901 LoopNum = satComputeLoopNum(tl, 0xFF); 3902 } 3903 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 3904 fis->h.command == SAT_WRITE_DMA_EXT || 3905 fis->h.command == SAT_WRITE_DMA_FUA_EXT 3906 ) 3907 { 3908 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 3909 LoopNum = satComputeLoopNum(tl, 0xFFFF); 3910 } 3911 else 3912 { 3913 /* SAT_WRITE_FPDMA_QUEUEDK */ 3914 LoopNum = satComputeLoopNum(tl, 0xFFFF); 3915 } 3916 3917 satIOContext->LoopNum = LoopNum; 3918 3919 3920 if (LoopNum == 1) 3921 { 3922 TI_DBG5(("satWrite12: NON CHAINED data\n")); 3923 /* Initialize CB for SATA completion. 3924 */ 3925 satIOContext->satCompleteCB = &satNonChainedDataIOCB; 3926 } 3927 else 3928 { 3929 TI_DBG1(("satWrite12: CHAINED data\n")); 3930 /* re-setting tl */ 3931 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 3932 { 3933 fis->d.sectorCount = 0xFF; 3934 } 3935 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 3936 fis->h.command == SAT_WRITE_DMA_EXT || 3937 fis->h.command == SAT_WRITE_DMA_FUA_EXT 3938 ) 3939 { 3940 fis->d.sectorCount = 0xFF; 3941 fis->d.sectorCountExp = 0xFF; 3942 } 3943 else 3944 { 3945 /* SAT_WRITE_FPDMA_QUEUED */ 3946 fis->h.features = 0xFF; 3947 fis->d.featuresExp = 0xFF; 3948 } 3949 3950 /* Initialize CB for SATA completion. 3951 */ 3952 satIOContext->satCompleteCB = &satChainedDataIOCB; 3953 } 3954 3955 3956 /* 3957 * Prepare SGL and send FIS to LL layer. 3958 */ 3959 satIOContext->reqType = agRequestType; /* Save it */ 3960 3961 status = sataLLIOStart( tiRoot, 3962 tiIORequest, 3963 tiDeviceHandle, 3964 tiScsiRequest, 3965 satIOContext); 3966 return (status); 3967 } 3968 3969 /*****************************************************************************/ 3970 /*! \brief SAT implementation for SCSI WRITE10. 3971 * 3972 * SAT implementation for SCSI WRITE10 and send FIS request to LL layer. 3973 * 3974 * \param tiRoot: Pointer to TISA initiator driver/port instance. 3975 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 3976 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 3977 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 3978 * \param satIOContext_t: Pointer to the SAT IO Context 3979 * 3980 * \return If command is started successfully 3981 * - \e tiSuccess: I/O request successfully initiated. 3982 * - \e tiBusy: No resources available, try again later. 3983 * - \e tiIONoDevice: Invalid device handle. 3984 * - \e tiError: Other errors. 3985 */ 3986 /*****************************************************************************/ 3987 GLOBAL bit32 satWrite10( 3988 tiRoot_t *tiRoot, 3989 tiIORequest_t *tiIORequest, 3990 tiDeviceHandle_t *tiDeviceHandle, 3991 tiScsiInitiatorRequest_t *tiScsiRequest, 3992 satIOContext_t *satIOContext) 3993 { 3994 3995 bit32 status; 3996 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 3997 satDeviceData_t *pSatDevData; 3998 scsiRspSense_t *pSense; 3999 tiIniScsiCmnd_t *scsiCmnd; 4000 agsaFisRegHostToDevice_t *fis; 4001 bit32 lba = 0; 4002 bit32 tl = 0; 4003 bit32 LoopNum = 1; 4004 bit8 LBA[4]; 4005 bit8 TL[4]; 4006 bit32 rangeChk = agFALSE; /* lba and tl range check */ 4007 4008 pSense = satIOContext->pSense; 4009 pSatDevData = satIOContext->pSatDevData; 4010 scsiCmnd = &tiScsiRequest->scsiCmnd; 4011 fis = satIOContext->pFis; 4012 4013 TI_DBG5(("satWrite10: start\n")); 4014 4015 /* checking FUA_NV */ 4016 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 4017 { 4018 satSetSensePayload( pSense, 4019 SCSI_SNSKEY_ILLEGAL_REQUEST, 4020 0, 4021 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 4022 satIOContext); 4023 4024 ostiInitiatorIOCompleted( tiRoot, 4025 tiIORequest, 4026 tiIOSuccess, 4027 SCSI_STAT_CHECK_CONDITION, 4028 satIOContext->pTiSenseData, 4029 satIOContext->interruptContext ); 4030 4031 TI_DBG1(("satWrite10: return FUA_NV\n")); 4032 return tiSuccess; 4033 4034 } 4035 4036 /* checking CONTROL */ 4037 /* NACA == 1 or LINK == 1*/ 4038 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 4039 { 4040 satSetSensePayload( pSense, 4041 SCSI_SNSKEY_ILLEGAL_REQUEST, 4042 0, 4043 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 4044 satIOContext); 4045 4046 ostiInitiatorIOCompleted( tiRoot, 4047 tiIORequest, 4048 tiIOSuccess, 4049 SCSI_STAT_CHECK_CONDITION, 4050 satIOContext->pTiSenseData, 4051 satIOContext->interruptContext ); 4052 4053 TI_DBG1(("satWrite10: return control\n")); 4054 return tiSuccess; 4055 } 4056 4057 osti_memset(LBA, 0, sizeof(LBA)); 4058 osti_memset(TL, 0, sizeof(TL)); 4059 4060 /* do not use memcpy due to indexing in LBA and TL */ 4061 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 4062 LBA[1] = scsiCmnd->cdb[3]; 4063 LBA[2] = scsiCmnd->cdb[4]; 4064 LBA[3] = scsiCmnd->cdb[5]; /* LSB */ 4065 4066 TL[0] = 0; 4067 TL[1] = 0; 4068 TL[2] = scsiCmnd->cdb[7]; /* MSB */ 4069 TL[3] = scsiCmnd->cdb[8]; /* LSB */ 4070 4071 rangeChk = satAddNComparebit32(LBA, TL); 4072 4073 4074 /* cbd10; computing LBA and transfer length */ 4075 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 4076 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 4077 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 4078 4079 TI_DBG5(("satWrite10: lba %d functioned lba %d\n", lba, satComputeCDB10LBA(satIOContext))); 4080 TI_DBG5(("satWrite10: tl %d functioned tl %d\n", tl, satComputeCDB10TL(satIOContext))); 4081 4082 /* Table 34, 9.1, p 46 */ 4083 /* 4084 note: As of 2/10/2006, no support for DMA QUEUED 4085 */ 4086 4087 /* 4088 Table 34, 9.1, p 46, b 4089 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 4090 return check condition 4091 */ 4092 if (pSatDevData->satNCQ != agTRUE && 4093 pSatDevData->sat48BitSupport != agTRUE 4094 ) 4095 { 4096 if (lba > SAT_TR_LBA_LIMIT - 1) 4097 { 4098 satSetSensePayload( pSense, 4099 SCSI_SNSKEY_ILLEGAL_REQUEST, 4100 0, 4101 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 4102 satIOContext); 4103 4104 ostiInitiatorIOCompleted( tiRoot, 4105 tiIORequest, 4106 tiIOSuccess, 4107 SCSI_STAT_CHECK_CONDITION, 4108 satIOContext->pTiSenseData, 4109 satIOContext->interruptContext ); 4110 4111 TI_DBG1(("satWrite10: return LBA out of range, not EXT\n")); 4112 TI_DBG1(("satWrite10: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3], 4113 scsiCmnd->cdb[4], scsiCmnd->cdb[5])); 4114 TI_DBG1(("satWrite10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT)); 4115 return tiSuccess; 4116 } 4117 4118 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 4119 { 4120 TI_DBG1(("satWrite10: return LBA+TL out of range, not EXT\n")); 4121 satSetSensePayload( pSense, 4122 SCSI_SNSKEY_ILLEGAL_REQUEST, 4123 0, 4124 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 4125 satIOContext); 4126 4127 ostiInitiatorIOCompleted( tiRoot, 4128 tiIORequest, 4129 tiIOSuccess, 4130 SCSI_STAT_CHECK_CONDITION, 4131 satIOContext->pTiSenseData, 4132 satIOContext->interruptContext ); 4133 4134 return tiSuccess; 4135 } 4136 4137 } 4138 4139 4140 /* case 1 and 2 */ 4141 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT) 4142 { 4143 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 4144 { 4145 /* case 2 */ 4146 /* WRITE DMA*/ 4147 /* can't fit the transfer length */ 4148 TI_DBG5(("satWrite10: case 2\n")); 4149 fis->h.fisType = 0x27; /* Reg host to device */ 4150 fis->h.c_pmPort = 0x80; /* C bit is set */ 4151 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 4152 fis->h.features = 0; /* FIS reserve */ 4153 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 4154 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 4155 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 4156 4157 /* FIS LBA mode set LBA (27:24) */ 4158 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 4159 4160 fis->d.lbaLowExp = 0; 4161 fis->d.lbaMidExp = 0; 4162 fis->d.lbaHighExp = 0; 4163 fis->d.featuresExp = 0; 4164 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 4165 fis->d.sectorCountExp = 0; 4166 fis->d.reserved4 = 0; 4167 fis->d.control = 0; /* FIS HOB bit clear */ 4168 fis->d.reserved5 = 0; 4169 4170 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 4171 satIOContext->ATACmd = SAT_WRITE_DMA; 4172 } 4173 else 4174 { 4175 /* case 1 */ 4176 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 4177 /* WRITE SECTORS for easier implemetation */ 4178 /* can't fit the transfer length */ 4179 TI_DBG5(("satWrite10: case 1\n")); 4180 fis->h.fisType = 0x27; /* Reg host to device */ 4181 fis->h.c_pmPort = 0x80; /* C bit is set */ 4182 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 4183 fis->h.features = 0; /* FIS reserve */ 4184 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 4185 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 4186 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 4187 4188 /* FIS LBA mode set LBA (27:24) */ 4189 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 4190 4191 fis->d.lbaLowExp = 0; 4192 fis->d.lbaMidExp = 0; 4193 fis->d.lbaHighExp = 0; 4194 fis->d.featuresExp = 0; 4195 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 4196 fis->d.sectorCountExp = 0; 4197 fis->d.reserved4 = 0; 4198 fis->d.control = 0; /* FIS HOB bit clear */ 4199 fis->d.reserved5 = 0; 4200 4201 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 4202 satIOContext->ATACmd = SAT_WRITE_SECTORS; 4203 } 4204 } 4205 /* case 3 and 4 */ 4206 if (pSatDevData->sat48BitSupport == agTRUE) 4207 { 4208 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 4209 { 4210 /* case 3 */ 4211 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 4212 TI_DBG5(("satWrite10: case 3\n")); 4213 fis->h.fisType = 0x27; /* Reg host to device */ 4214 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4215 4216 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 4217 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 4218 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 4219 4220 fis->h.features = 0; /* FIS reserve */ 4221 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 4222 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 4223 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 4224 fis->d.device = 0x40; /* FIS LBA mode set */ 4225 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 4226 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4227 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4228 fis->d.featuresExp = 0; /* FIS reserve */ 4229 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 4230 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 4231 fis->d.reserved4 = 0; 4232 fis->d.control = 0; /* FIS HOB bit clear */ 4233 fis->d.reserved5 = 0; 4234 4235 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 4236 } 4237 else 4238 { 4239 /* case 4 */ 4240 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 4241 /* WRITE SECTORS EXT for easier implemetation */ 4242 TI_DBG5(("satWrite10: case 4\n")); 4243 fis->h.fisType = 0x27; /* Reg host to device */ 4244 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4245 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 4246 4247 fis->h.features = 0; /* FIS reserve */ 4248 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 4249 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 4250 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 4251 fis->d.device = 0x40; /* FIS LBA mode set */ 4252 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 4253 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4254 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4255 fis->d.featuresExp = 0; /* FIS reserve */ 4256 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 4257 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 4258 fis->d.reserved4 = 0; 4259 fis->d.control = 0; /* FIS HOB bit clear */ 4260 fis->d.reserved5 = 0; 4261 4262 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 4263 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 4264 } 4265 } 4266 /* case 5 */ 4267 if (pSatDevData->satNCQ == agTRUE) 4268 { 4269 /* WRITE FPDMA QUEUED */ 4270 if (pSatDevData->sat48BitSupport != agTRUE) 4271 { 4272 TI_DBG5(("satWrite10: case 5 !!! error NCQ but 28 bit address support \n")); 4273 satSetSensePayload( pSense, 4274 SCSI_SNSKEY_ILLEGAL_REQUEST, 4275 0, 4276 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 4277 satIOContext); 4278 4279 ostiInitiatorIOCompleted( tiRoot, 4280 tiIORequest, 4281 tiIOSuccess, 4282 SCSI_STAT_CHECK_CONDITION, 4283 satIOContext->pTiSenseData, 4284 satIOContext->interruptContext ); 4285 return tiSuccess; 4286 } 4287 TI_DBG6(("satWrite10: case 5\n")); 4288 4289 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 4290 4291 fis->h.fisType = 0x27; /* Reg host to device */ 4292 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4293 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 4294 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 4295 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 4296 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 4297 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 4298 4299 /* Check FUA bit */ 4300 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK) 4301 fis->d.device = 0xC0; /* FIS FUA set */ 4302 else 4303 fis->d.device = 0x40; /* FIS FUA clear */ 4304 4305 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 4306 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4307 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4308 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 4309 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 4310 fis->d.sectorCountExp = 0; 4311 fis->d.reserved4 = 0; 4312 fis->d.control = 0; /* FIS HOB bit clear */ 4313 fis->d.reserved5 = 0; 4314 4315 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 4316 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 4317 } 4318 4319 // tdhexdump("satWrite10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t)); 4320 4321 satIOContext->currentLBA = lba; 4322 satIOContext->OrgTL = tl; 4323 4324 /* 4325 computing number of loop and remainder for tl 4326 0xFF in case not ext 4327 0xFFFF in case EXT 4328 */ 4329 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 4330 { 4331 LoopNum = satComputeLoopNum(tl, 0xFF); 4332 } 4333 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 4334 fis->h.command == SAT_WRITE_DMA_EXT || 4335 fis->h.command == SAT_WRITE_DMA_FUA_EXT 4336 ) 4337 { 4338 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 4339 LoopNum = satComputeLoopNum(tl, 0xFFFF); 4340 } 4341 else 4342 { 4343 /* SAT_WRITE_FPDMA_QUEUEDK */ 4344 LoopNum = satComputeLoopNum(tl, 0xFFFF); 4345 } 4346 4347 satIOContext->LoopNum = LoopNum; 4348 4349 4350 if (LoopNum == 1) 4351 { 4352 TI_DBG5(("satWrite10: NON CHAINED data\n")); 4353 /* Initialize CB for SATA completion. 4354 */ 4355 satIOContext->satCompleteCB = &satNonChainedDataIOCB; 4356 } 4357 else 4358 { 4359 TI_DBG1(("satWrite10: CHAINED data\n")); 4360 /* re-setting tl */ 4361 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 4362 { 4363 fis->d.sectorCount = 0xFF; 4364 } 4365 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 4366 fis->h.command == SAT_WRITE_DMA_EXT || 4367 fis->h.command == SAT_WRITE_DMA_FUA_EXT 4368 ) 4369 { 4370 fis->d.sectorCount = 0xFF; 4371 fis->d.sectorCountExp = 0xFF; 4372 } 4373 else 4374 { 4375 /* SAT_WRITE_FPDMA_QUEUED */ 4376 fis->h.features = 0xFF; 4377 fis->d.featuresExp = 0xFF; 4378 } 4379 4380 /* Initialize CB for SATA completion. 4381 */ 4382 satIOContext->satCompleteCB = &satChainedDataIOCB; 4383 } 4384 4385 4386 /* 4387 * Prepare SGL and send FIS to LL layer. 4388 */ 4389 satIOContext->reqType = agRequestType; /* Save it */ 4390 4391 status = sataLLIOStart( tiRoot, 4392 tiIORequest, 4393 tiDeviceHandle, 4394 tiScsiRequest, 4395 satIOContext); 4396 return (status); 4397 } 4398 4399 /*****************************************************************************/ 4400 /*! \brief SAT implementation for SCSI satWrite_1. 4401 * 4402 * SAT implementation for SCSI WRITE10 and send FIS request to LL layer. 4403 * This is used when WRITE10 is divided into multiple ATA commands 4404 * 4405 * \param tiRoot: Pointer to TISA initiator driver/port instance. 4406 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 4407 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 4408 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 4409 * \param satIOContext_t: Pointer to the SAT IO Context 4410 * 4411 * \return If command is started successfully 4412 * - \e tiSuccess: I/O request successfully initiated. 4413 * - \e tiBusy: No resources available, try again later. 4414 * - \e tiIONoDevice: Invalid device handle. 4415 * - \e tiError: Other errors. 4416 */ 4417 /*****************************************************************************/ 4418 GLOBAL bit32 satWrite_1( 4419 tiRoot_t *tiRoot, 4420 tiIORequest_t *tiIORequest, 4421 tiDeviceHandle_t *tiDeviceHandle, 4422 tiScsiInitiatorRequest_t *tiScsiRequest, 4423 satIOContext_t *satIOContext) 4424 { 4425 /* 4426 Assumption: error check on lba and tl has been done in satWrite*() 4427 lba = lba + tl; 4428 */ 4429 bit32 status; 4430 satIOContext_t *satOrgIOContext = agNULL; 4431 tiIniScsiCmnd_t *scsiCmnd; 4432 agsaFisRegHostToDevice_t *fis; 4433 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 4434 bit32 lba = 0; 4435 bit32 DenomTL = 0xFF; 4436 bit32 Remainder = 0; 4437 bit8 LBA[4]; /* 0 MSB, 3 LSB */ 4438 4439 TI_DBG2(("satWrite_1: start\n")); 4440 4441 fis = satIOContext->pFis; 4442 satOrgIOContext = satIOContext->satOrgIOContext; 4443 scsiCmnd = satOrgIOContext->pScsiCmnd; 4444 4445 osti_memset(LBA,0, sizeof(LBA)); 4446 4447 switch (satOrgIOContext->ATACmd) 4448 { 4449 case SAT_WRITE_DMA: 4450 DenomTL = 0xFF; 4451 break; 4452 case SAT_WRITE_SECTORS: 4453 DenomTL = 0xFF; 4454 break; 4455 case SAT_WRITE_DMA_EXT: 4456 DenomTL = 0xFFFF; 4457 break; 4458 case SAT_WRITE_DMA_FUA_EXT: 4459 DenomTL = 0xFFFF; 4460 break; 4461 case SAT_WRITE_SECTORS_EXT: 4462 DenomTL = 0xFFFF; 4463 break; 4464 case SAT_WRITE_FPDMA_QUEUED: 4465 DenomTL = 0xFFFF; 4466 break; 4467 default: 4468 TI_DBG1(("satWrite_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd)); 4469 return tiError; 4470 break; 4471 } 4472 4473 Remainder = satOrgIOContext->OrgTL % DenomTL; 4474 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL; 4475 lba = satOrgIOContext->currentLBA; 4476 4477 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */ 4478 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2)); 4479 LBA[2] = (bit8)((lba & 0xF0) >> 8); 4480 LBA[3] = (bit8)(lba & 0xF); /* LSB */ 4481 4482 switch (satOrgIOContext->ATACmd) 4483 { 4484 case SAT_WRITE_DMA: 4485 fis->h.fisType = 0x27; /* Reg host to device */ 4486 fis->h.c_pmPort = 0x80; /* C bit is set */ 4487 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 4488 fis->h.features = 0; /* FIS reserve */ 4489 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 4490 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 4491 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 4492 4493 /* FIS LBA mode set LBA (27:24) */ 4494 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 4495 4496 fis->d.lbaLowExp = 0; 4497 fis->d.lbaMidExp = 0; 4498 fis->d.lbaHighExp = 0; 4499 fis->d.featuresExp = 0; 4500 if (satOrgIOContext->LoopNum == 1) 4501 { 4502 /* last loop */ 4503 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 4504 } 4505 else 4506 { 4507 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 4508 } 4509 fis->d.sectorCountExp = 0; 4510 fis->d.reserved4 = 0; 4511 fis->d.control = 0; /* FIS HOB bit clear */ 4512 fis->d.reserved5 = 0; 4513 4514 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 4515 4516 break; 4517 case SAT_WRITE_SECTORS: 4518 fis->h.fisType = 0x27; /* Reg host to device */ 4519 fis->h.c_pmPort = 0x80; /* C bit is set */ 4520 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 4521 fis->h.features = 0; /* FIS reserve */ 4522 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 4523 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 4524 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 4525 4526 /* FIS LBA mode set LBA (27:24) */ 4527 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 4528 4529 fis->d.lbaLowExp = 0; 4530 fis->d.lbaMidExp = 0; 4531 fis->d.lbaHighExp = 0; 4532 fis->d.featuresExp = 0; 4533 if (satOrgIOContext->LoopNum == 1) 4534 { 4535 /* last loop */ 4536 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 4537 } 4538 else 4539 { 4540 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 4541 } 4542 fis->d.sectorCountExp = 0; 4543 fis->d.reserved4 = 0; 4544 fis->d.control = 0; /* FIS HOB bit clear */ 4545 fis->d.reserved5 = 0; 4546 4547 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 4548 4549 break; 4550 case SAT_WRITE_DMA_EXT: 4551 fis->h.fisType = 0x27; /* Reg host to device */ 4552 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4553 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x3D */ 4554 fis->h.features = 0; /* FIS reserve */ 4555 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 4556 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 4557 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 4558 fis->d.device = 0x40; /* FIS LBA mode set */ 4559 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 4560 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4561 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4562 fis->d.featuresExp = 0; /* FIS reserve */ 4563 if (satOrgIOContext->LoopNum == 1) 4564 { 4565 /* last loop */ 4566 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 4567 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 4568 } 4569 else 4570 { 4571 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 4572 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 4573 } 4574 fis->d.reserved4 = 0; 4575 fis->d.control = 0; /* FIS HOB bit clear */ 4576 fis->d.reserved5 = 0; 4577 4578 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 4579 4580 break; 4581 case SAT_WRITE_SECTORS_EXT: 4582 fis->h.fisType = 0x27; /* Reg host to device */ 4583 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4584 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 4585 4586 fis->h.features = 0; /* FIS reserve */ 4587 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 4588 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 4589 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 4590 fis->d.device = 0x40; /* FIS LBA mode set */ 4591 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 4592 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4593 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4594 fis->d.featuresExp = 0; /* FIS reserve */ 4595 if (satOrgIOContext->LoopNum == 1) 4596 { 4597 /* last loop */ 4598 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 4599 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 4600 } 4601 else 4602 { 4603 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 4604 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 4605 } 4606 fis->d.reserved4 = 0; 4607 fis->d.control = 0; /* FIS HOB bit clear */ 4608 fis->d.reserved5 = 0; 4609 4610 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 4611 4612 break; 4613 case SAT_WRITE_FPDMA_QUEUED: 4614 fis->h.fisType = 0x27; /* Reg host to device */ 4615 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4616 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 4617 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 4618 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 4619 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 4620 4621 /* Check FUA bit */ 4622 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK) 4623 fis->d.device = 0xC0; /* FIS FUA set */ 4624 else 4625 fis->d.device = 0x40; /* FIS FUA clear */ 4626 4627 fis->d.lbaLowExp = LBA[0];; /* FIS LBA (31:24) */ 4628 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4629 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4630 if (satOrgIOContext->LoopNum == 1) 4631 { 4632 /* last loop */ 4633 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 4634 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 4635 } 4636 else 4637 { 4638 fis->h.features = 0xFF; /* FIS sector count (7:0) */ 4639 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */ 4640 } 4641 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 4642 fis->d.sectorCountExp = 0; 4643 fis->d.reserved4 = 0; 4644 fis->d.control = 0; /* FIS HOB bit clear */ 4645 fis->d.reserved5 = 0; 4646 4647 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 4648 break; 4649 4650 default: 4651 TI_DBG1(("satWrite_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd)); 4652 return tiError; 4653 break; 4654 } 4655 4656 /* Initialize CB for SATA completion. 4657 */ 4658 /* chained data */ 4659 satIOContext->satCompleteCB = &satChainedDataIOCB; 4660 4661 4662 /* 4663 * Prepare SGL and send FIS to LL layer. 4664 */ 4665 satIOContext->reqType = agRequestType; /* Save it */ 4666 4667 status = sataLLIOStart( tiRoot, 4668 tiIORequest, 4669 tiDeviceHandle, 4670 tiScsiRequest, 4671 satIOContext); 4672 4673 TI_DBG5(("satWrite_1: return\n")); 4674 return (status); 4675 } 4676 4677 /*****************************************************************************/ 4678 /*! \brief SAT implementation for SCSI WRITE6. 4679 * 4680 * SAT implementation for SCSI WRITE6 and send FIS request to LL layer. 4681 * 4682 * \param tiRoot: Pointer to TISA initiator driver/port instance. 4683 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 4684 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 4685 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 4686 * \param satIOContext_t: Pointer to the SAT IO Context 4687 * 4688 * \return If command is started successfully 4689 * - \e tiSuccess: I/O request successfully initiated. 4690 * - \e tiBusy: No resources available, try again later. 4691 * - \e tiIONoDevice: Invalid device handle. 4692 * - \e tiError: Other errors. 4693 */ 4694 /*****************************************************************************/ 4695 GLOBAL bit32 satWrite6( 4696 tiRoot_t *tiRoot, 4697 tiIORequest_t *tiIORequest, 4698 tiDeviceHandle_t *tiDeviceHandle, 4699 tiScsiInitiatorRequest_t *tiScsiRequest, 4700 satIOContext_t *satIOContext) 4701 { 4702 4703 bit32 status; 4704 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 4705 satDeviceData_t *pSatDevData; 4706 scsiRspSense_t *pSense; 4707 tiIniScsiCmnd_t *scsiCmnd; 4708 agsaFisRegHostToDevice_t *fis; 4709 bit32 lba = 0; 4710 bit16 tl = 0; 4711 4712 pSense = satIOContext->pSense; 4713 pSatDevData = satIOContext->pSatDevData; 4714 scsiCmnd = &tiScsiRequest->scsiCmnd; 4715 fis = satIOContext->pFis; 4716 4717 TI_DBG5(("satWrite6: start\n")); 4718 4719 /* checking CONTROL */ 4720 /* NACA == 1 or LINK == 1*/ 4721 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 4722 { 4723 satSetSensePayload( pSense, 4724 SCSI_SNSKEY_ILLEGAL_REQUEST, 4725 0, 4726 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 4727 satIOContext); 4728 4729 ostiInitiatorIOCompleted( tiRoot, 4730 tiIORequest, 4731 tiIOSuccess, 4732 SCSI_STAT_CHECK_CONDITION, 4733 satIOContext->pTiSenseData, 4734 satIOContext->interruptContext ); 4735 4736 TI_DBG1(("satWrite6: return control\n")); 4737 return tiSuccess; 4738 } 4739 4740 4741 /* cbd6; computing LBA and transfer length */ 4742 lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2)) 4743 + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3]; 4744 tl = scsiCmnd->cdb[4]; 4745 4746 4747 /* Table 34, 9.1, p 46 */ 4748 /* 4749 note: As of 2/10/2006, no support for DMA QUEUED 4750 */ 4751 4752 /* 4753 Table 34, 9.1, p 46, b 4754 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 4755 return check condition 4756 */ 4757 if (pSatDevData->satNCQ != agTRUE && 4758 pSatDevData->sat48BitSupport != agTRUE 4759 ) 4760 { 4761 if (lba > SAT_TR_LBA_LIMIT - 1) 4762 { 4763 satSetSensePayload( pSense, 4764 SCSI_SNSKEY_ILLEGAL_REQUEST, 4765 0, 4766 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 4767 satIOContext); 4768 4769 ostiInitiatorIOCompleted( tiRoot, 4770 tiIORequest, 4771 tiIOSuccess, 4772 SCSI_STAT_CHECK_CONDITION, 4773 satIOContext->pTiSenseData, 4774 satIOContext->interruptContext ); 4775 4776 TI_DBG1(("satWrite6: return LBA out of range\n")); 4777 return tiSuccess; 4778 } 4779 } 4780 4781 /* case 1 and 2 */ 4782 if (lba + tl <= SAT_TR_LBA_LIMIT) 4783 { 4784 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 4785 { 4786 /* case 2 */ 4787 /* WRITE DMA*/ 4788 TI_DBG5(("satWrite6: case 2\n")); 4789 4790 4791 fis->h.fisType = 0x27; /* Reg host to device */ 4792 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4793 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 4794 fis->h.features = 0; /* FIS reserve */ 4795 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 4796 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 4797 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 4798 fis->d.device = 0x40; /* FIS LBA mode */ 4799 fis->d.lbaLowExp = 0; 4800 fis->d.lbaMidExp = 0; 4801 fis->d.lbaHighExp = 0; 4802 fis->d.featuresExp = 0; 4803 if (tl == 0) 4804 { 4805 /* temporary fix */ 4806 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */ 4807 } 4808 else 4809 { 4810 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 4811 } 4812 fis->d.sectorCountExp = 0; 4813 fis->d.reserved4 = 0; 4814 fis->d.control = 0; /* FIS HOB bit clear */ 4815 fis->d.reserved5 = 0; 4816 4817 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 4818 } 4819 else 4820 { 4821 /* case 1 */ 4822 /* WRITE SECTORS for easier implemetation */ 4823 TI_DBG5(("satWrite6: case 1\n")); 4824 4825 fis->h.fisType = 0x27; /* Reg host to device */ 4826 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4827 fis->h.command = SAT_WRITE_SECTORS; /* 0xCA */ 4828 fis->h.features = 0; /* FIS reserve */ 4829 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 4830 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 4831 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 4832 fis->d.device = 0x40; /* FIS LBA mode */ 4833 fis->d.lbaLowExp = 0; 4834 fis->d.lbaMidExp = 0; 4835 fis->d.lbaHighExp = 0; 4836 fis->d.featuresExp = 0; 4837 if (tl == 0) 4838 { 4839 /* temporary fix */ 4840 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */ 4841 } 4842 else 4843 { 4844 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 4845 } 4846 fis->d.sectorCountExp = 0; 4847 fis->d.reserved4 = 0; 4848 fis->d.control = 0; /* FIS HOB bit clear */ 4849 fis->d.reserved5 = 0; 4850 4851 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 4852 4853 } 4854 } 4855 4856 /* case 3 and 4 */ 4857 if (pSatDevData->sat48BitSupport == agTRUE) 4858 { 4859 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 4860 { 4861 /* case 3 */ 4862 /* WRITE DMA EXT only */ 4863 TI_DBG5(("satWrite6: case 3\n")); 4864 fis->h.fisType = 0x27; /* Reg host to device */ 4865 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4866 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 4867 fis->h.features = 0; /* FIS reserve */ 4868 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 4869 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 4870 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 4871 fis->d.device = 0x40; /* FIS LBA mode set */ 4872 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 4873 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4874 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4875 fis->d.featuresExp = 0; /* FIS reserve */ 4876 if (tl == 0) 4877 { 4878 /* sector count is 256, 0x100*/ 4879 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 4880 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */ 4881 } 4882 else 4883 { 4884 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 4885 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 4886 } 4887 fis->d.reserved4 = 0; 4888 fis->d.control = 0; /* FIS HOB bit clear */ 4889 fis->d.reserved5 = 0; 4890 4891 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 4892 } 4893 else 4894 { 4895 /* case 4 */ 4896 /* WRITE SECTORS EXT for easier implemetation */ 4897 TI_DBG5(("satWrite6: case 4\n")); 4898 4899 fis->h.fisType = 0x27; /* Reg host to device */ 4900 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4901 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 4902 fis->h.features = 0; /* FIS reserve */ 4903 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 4904 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 4905 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 4906 fis->d.device = 0x40; /* FIS LBA mode set */ 4907 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 4908 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4909 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4910 fis->d.featuresExp = 0; /* FIS reserve */ 4911 if (tl == 0) 4912 { 4913 /* sector count is 256, 0x100*/ 4914 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 4915 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */ 4916 } 4917 else 4918 { 4919 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 4920 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 4921 } 4922 fis->d.reserved4 = 0; 4923 fis->d.control = 0; /* FIS HOB bit clear */ 4924 fis->d.reserved5 = 0; 4925 4926 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 4927 } 4928 } 4929 4930 /* case 5 */ 4931 if (pSatDevData->satNCQ == agTRUE) 4932 { 4933 /* WRITE FPDMA QUEUED */ 4934 if (pSatDevData->sat48BitSupport != agTRUE) 4935 { 4936 /* sanity check */ 4937 TI_DBG5(("satWrite6: case 5 !!! error NCQ but 28 bit address support \n")); 4938 satSetSensePayload( pSense, 4939 SCSI_SNSKEY_ILLEGAL_REQUEST, 4940 0, 4941 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 4942 satIOContext); 4943 4944 ostiInitiatorIOCompleted( tiRoot, 4945 tiIORequest, 4946 tiIOSuccess, 4947 SCSI_STAT_CHECK_CONDITION, 4948 satIOContext->pTiSenseData, 4949 satIOContext->interruptContext ); 4950 return tiSuccess; 4951 } 4952 TI_DBG5(("satWrite6: case 5\n")); 4953 4954 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 4955 4956 fis->h.fisType = 0x27; /* Reg host to device */ 4957 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4958 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 4959 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 4960 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 4961 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 4962 fis->d.device = 0x40; /* FIS FUA clear */ 4963 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 4964 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4965 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4966 if (tl == 0) 4967 { 4968 /* sector count is 256, 0x100*/ 4969 fis->h.features = 0; /* FIS sector count (7:0) */ 4970 fis->d.featuresExp = 0x01; /* FIS sector count (15:8) */ 4971 } 4972 else 4973 { 4974 fis->h.features = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 4975 fis->d.featuresExp = 0; /* FIS sector count (15:8) */ 4976 } 4977 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 4978 fis->d.sectorCountExp = 0; 4979 fis->d.reserved4 = 0; 4980 fis->d.control = 0; /* FIS HOB bit clear */ 4981 fis->d.reserved5 = 0; 4982 4983 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 4984 } 4985 4986 /* Initialize CB for SATA completion. 4987 */ 4988 satIOContext->satCompleteCB = &satNonChainedDataIOCB; 4989 4990 /* 4991 * Prepare SGL and send FIS to LL layer. 4992 */ 4993 satIOContext->reqType = agRequestType; /* Save it */ 4994 4995 status = sataLLIOStart( tiRoot, 4996 tiIORequest, 4997 tiDeviceHandle, 4998 tiScsiRequest, 4999 satIOContext); 5000 return (status); 5001 } 5002 5003 5004 /*****************************************************************************/ 5005 /*! \brief SAT implementation for SCSI TEST UNIT READY. 5006 * 5007 * SAT implementation for SCSI TUR and send FIS request to LL layer. 5008 * 5009 * \param tiRoot: Pointer to TISA initiator driver/port instance. 5010 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 5011 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 5012 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 5013 * \param satIOContext_t: Pointer to the SAT IO Context 5014 * 5015 * \return If command is started successfully 5016 * - \e tiSuccess: I/O request successfully initiated. 5017 * - \e tiBusy: No resources available, try again later. 5018 * - \e tiIONoDevice: Invalid device handle. 5019 * - \e tiError: Other errors. 5020 */ 5021 /*****************************************************************************/ 5022 GLOBAL bit32 satTestUnitReady( 5023 tiRoot_t *tiRoot, 5024 tiIORequest_t *tiIORequest, 5025 tiDeviceHandle_t *tiDeviceHandle, 5026 tiScsiInitiatorRequest_t *tiScsiRequest, 5027 satIOContext_t *satIOContext) 5028 { 5029 5030 bit32 status; 5031 bit32 agRequestType; 5032 satDeviceData_t *pSatDevData; 5033 scsiRspSense_t *pSense; 5034 tiIniScsiCmnd_t *scsiCmnd; 5035 agsaFisRegHostToDevice_t *fis; 5036 5037 pSense = satIOContext->pSense; 5038 pSatDevData = satIOContext->pSatDevData; 5039 scsiCmnd = &tiScsiRequest->scsiCmnd; 5040 fis = satIOContext->pFis; 5041 5042 TI_DBG6(("satTestUnitReady: entry tiDeviceHandle=%p tiIORequest=%p\n", 5043 tiDeviceHandle, tiIORequest)); 5044 5045 /* checking CONTROL */ 5046 /* NACA == 1 or LINK == 1*/ 5047 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 5048 { 5049 satSetSensePayload( pSense, 5050 SCSI_SNSKEY_ILLEGAL_REQUEST, 5051 0, 5052 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5053 satIOContext); 5054 5055 ostiInitiatorIOCompleted( tiRoot, 5056 tiIORequest, 5057 tiIOSuccess, 5058 SCSI_STAT_CHECK_CONDITION, 5059 satIOContext->pTiSenseData, 5060 satIOContext->interruptContext ); 5061 5062 TI_DBG1(("satTestUnitReady: return control\n")); 5063 return tiSuccess; 5064 } 5065 5066 /* SAT revision 8, 8.11.2, p42*/ 5067 if (pSatDevData->satStopState == agTRUE) 5068 { 5069 satSetSensePayload( pSense, 5070 SCSI_SNSKEY_NOT_READY, 5071 0, 5072 SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED, 5073 satIOContext); 5074 5075 ostiInitiatorIOCompleted( tiRoot, 5076 tiIORequest, 5077 tiIOSuccess, 5078 SCSI_STAT_CHECK_CONDITION, 5079 satIOContext->pTiSenseData, 5080 satIOContext->interruptContext ); 5081 TI_DBG1(("satTestUnitReady: stop state\n")); 5082 return tiSuccess; 5083 } 5084 5085 /* 5086 * Check if format is in progress 5087 */ 5088 5089 if (pSatDevData->satDriveState == SAT_DEV_STATE_FORMAT_IN_PROGRESS) 5090 { 5091 TI_DBG1(("satTestUnitReady() FORMAT_IN_PROGRESS tiDeviceHandle=%p tiIORequest=%p\n", 5092 tiDeviceHandle, tiIORequest)); 5093 5094 satSetSensePayload( pSense, 5095 SCSI_SNSKEY_NOT_READY, 5096 0, 5097 SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_FORMAT_IN_PROGRESS, 5098 satIOContext); 5099 5100 ostiInitiatorIOCompleted( tiRoot, 5101 tiIORequest, 5102 tiIOSuccess, 5103 SCSI_STAT_CHECK_CONDITION, 5104 satIOContext->pTiSenseData, 5105 satIOContext->interruptContext ); 5106 TI_DBG1(("satTestUnitReady: format in progress\n")); 5107 return tiSuccess; 5108 } 5109 5110 /* 5111 check previously issued ATA command 5112 */ 5113 if (pSatDevData->satPendingIO != 0) 5114 { 5115 if (pSatDevData->satDeviceFaultState == agTRUE) 5116 { 5117 satSetSensePayload( pSense, 5118 SCSI_SNSKEY_HARDWARE_ERROR, 5119 0, 5120 SCSI_SNSCODE_LOGICAL_UNIT_FAILURE, 5121 satIOContext); 5122 5123 ostiInitiatorIOCompleted( tiRoot, 5124 tiIORequest, 5125 tiIOSuccess, 5126 SCSI_STAT_CHECK_CONDITION, 5127 satIOContext->pTiSenseData, 5128 satIOContext->interruptContext ); 5129 TI_DBG1(("satTestUnitReady: previous command ended in error\n")); 5130 return tiSuccess; 5131 } 5132 } 5133 /* 5134 check removalbe media feature set 5135 */ 5136 if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled) 5137 { 5138 TI_DBG5(("satTestUnitReady: sending get media status cmnd\n")); 5139 /* send GET MEDIA STATUS command */ 5140 fis->h.fisType = 0x27; /* Reg host to device */ 5141 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5142 fis->h.command = SAT_GET_MEDIA_STATUS; /* 0xDA */ 5143 fis->h.features = 0; /* FIS features NA */ 5144 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 5145 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 5146 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 5147 fis->d.device = 0; /* FIS DEV is discared in SATA */ 5148 fis->d.lbaLowExp = 0; 5149 fis->d.lbaMidExp = 0; 5150 fis->d.lbaHighExp = 0; 5151 fis->d.featuresExp = 0; 5152 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 5153 fis->d.sectorCountExp = 0; 5154 fis->d.reserved4 = 0; 5155 fis->d.control = 0; /* FIS HOB bit clear */ 5156 fis->d.reserved5 = 0; 5157 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 5158 5159 /* Initialize CB for SATA completion. 5160 */ 5161 satIOContext->satCompleteCB = &satTestUnitReadyCB; 5162 5163 /* 5164 * Prepare SGL and send FIS to LL layer. 5165 */ 5166 satIOContext->reqType = agRequestType; /* Save it */ 5167 5168 status = sataLLIOStart( tiRoot, 5169 tiIORequest, 5170 tiDeviceHandle, 5171 tiScsiRequest, 5172 satIOContext); 5173 5174 return (status); 5175 } 5176 /* 5177 number 6) in SAT p42 5178 send ATA CHECK POWER MODE 5179 */ 5180 TI_DBG5(("satTestUnitReady: sending check power mode cmnd\n")); 5181 status = satTestUnitReady_1( tiRoot, 5182 tiIORequest, 5183 tiDeviceHandle, 5184 tiScsiRequest, 5185 satIOContext); 5186 return (status); 5187 } 5188 5189 5190 /*****************************************************************************/ 5191 /*! \brief SAT implementation for SCSI satTestUnitReady_1. 5192 * 5193 * SAT implementation for SCSI satTestUnitReady_1. 5194 * 5195 * \param tiRoot: Pointer to TISA initiator driver/port instance. 5196 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 5197 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 5198 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 5199 * \param satIOContext_t: Pointer to the SAT IO Context 5200 * 5201 * \return If command is started successfully 5202 * - \e tiSuccess: I/O request successfully initiated. 5203 * - \e tiBusy: No resources available, try again later. 5204 * - \e tiIONoDevice: Invalid device handle. 5205 * - \e tiError: Other errors. 5206 */ 5207 /*****************************************************************************/ 5208 GLOBAL bit32 satTestUnitReady_1( 5209 tiRoot_t *tiRoot, 5210 tiIORequest_t *tiIORequest, 5211 tiDeviceHandle_t *tiDeviceHandle, 5212 tiScsiInitiatorRequest_t *tiScsiRequest, 5213 satIOContext_t *satIOContext) 5214 { 5215 /* 5216 sends SAT_CHECK_POWER_MODE as a part of TESTUNITREADY 5217 internally generated - no directly corresponding scsi 5218 called in satIOCompleted as a part of satTestUnitReady(), SAT, revision8, 8.11.2, p42 5219 */ 5220 bit32 status; 5221 bit32 agRequestType; 5222 agsaFisRegHostToDevice_t *fis; 5223 5224 fis = satIOContext->pFis; 5225 5226 TI_DBG5(("satTestUnitReady_1: start\n")); 5227 5228 /* 5229 * Send the ATA CHECK POWER MODE command. 5230 */ 5231 fis->h.fisType = 0x27; /* Reg host to device */ 5232 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5233 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */ 5234 fis->h.features = 0; 5235 fis->d.lbaLow = 0; 5236 fis->d.lbaMid = 0; 5237 fis->d.lbaHigh = 0; 5238 fis->d.device = 0; 5239 fis->d.lbaLowExp = 0; 5240 fis->d.lbaMidExp = 0; 5241 fis->d.lbaHighExp = 0; 5242 fis->d.featuresExp = 0; 5243 fis->d.sectorCount = 0; 5244 fis->d.sectorCountExp = 0; 5245 fis->d.reserved4 = 0; 5246 fis->d.control = 0; /* FIS HOB bit clear */ 5247 fis->d.reserved5 = 0; 5248 5249 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 5250 5251 /* Initialize CB for SATA completion. 5252 */ 5253 satIOContext->satCompleteCB = &satTestUnitReadyCB; 5254 5255 /* 5256 * Prepare SGL and send FIS to LL layer. 5257 */ 5258 satIOContext->reqType = agRequestType; /* Save it */ 5259 5260 status = sataLLIOStart( tiRoot, 5261 tiIORequest, 5262 tiDeviceHandle, 5263 tiScsiRequest, 5264 satIOContext); 5265 5266 TI_DBG5(("satTestUnitReady_1: return\n")); 5267 5268 return status; 5269 } 5270 5271 5272 /*****************************************************************************/ 5273 /*! \brief SAT implementation for SCSI satReportLun. 5274 * 5275 * SAT implementation for SCSI satReportLun. Only LUN0 is reported. 5276 * 5277 * \param tiRoot: Pointer to TISA initiator driver/port instance. 5278 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 5279 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 5280 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 5281 * \param satIOContext_t: Pointer to the SAT IO Context 5282 * 5283 * \return If command is started successfully 5284 * - \e tiSuccess: I/O request successfully initiated. 5285 * - \e tiBusy: No resources available, try again later. 5286 * - \e tiIONoDevice: Invalid device handle. 5287 * - \e tiError: Other errors. 5288 */ 5289 /*****************************************************************************/ 5290 GLOBAL bit32 satReportLun( 5291 tiRoot_t *tiRoot, 5292 tiIORequest_t *tiIORequest, 5293 tiDeviceHandle_t *tiDeviceHandle, 5294 tiScsiInitiatorRequest_t *tiScsiRequest, 5295 satIOContext_t *satIOContext) 5296 { 5297 scsiRspSense_t *pSense; 5298 bit32 allocationLen; 5299 bit32 reportLunLen; 5300 scsiReportLun_t *pReportLun; 5301 tiIniScsiCmnd_t *scsiCmnd; 5302 5303 TI_DBG5(("satReportLun entry: tiDeviceHandle=%p tiIORequest=%p\n", 5304 tiDeviceHandle, tiIORequest)); 5305 5306 pSense = satIOContext->pSense; 5307 pReportLun = (scsiReportLun_t *) tiScsiRequest->sglVirtualAddr; 5308 scsiCmnd = &tiScsiRequest->scsiCmnd; 5309 5310 // tdhexdump("satReportLun cdb", (bit8 *)scsiCmnd, 16); 5311 5312 /* Find the buffer size allocated by Initiator */ 5313 allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) | 5314 (((bit32)scsiCmnd->cdb[7]) << 16) | 5315 (((bit32)scsiCmnd->cdb[8]) << 8 ) | 5316 (((bit32)scsiCmnd->cdb[9]) ); 5317 5318 reportLunLen = 16; /* 8 byte header and 8 bytes of LUN0 */ 5319 5320 if (allocationLen < reportLunLen) 5321 { 5322 TI_DBG1(("satReportLun *** ERROR *** insufficient len=0x%x tiDeviceHandle=%p tiIORequest=%p\n", 5323 reportLunLen, tiDeviceHandle, tiIORequest)); 5324 5325 satSetSensePayload( pSense, 5326 SCSI_SNSKEY_ILLEGAL_REQUEST, 5327 0, 5328 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5329 satIOContext); 5330 5331 ostiInitiatorIOCompleted( tiRoot, 5332 tiIORequest, 5333 tiIOSuccess, 5334 SCSI_STAT_CHECK_CONDITION, 5335 satIOContext->pTiSenseData, 5336 satIOContext->interruptContext ); 5337 return tiSuccess; 5338 5339 } 5340 5341 /* Set length to one entry */ 5342 pReportLun->len[0] = 0; 5343 pReportLun->len[1] = 0; 5344 pReportLun->len[2] = 0; 5345 pReportLun->len[3] = sizeof (tiLUN_t); 5346 5347 pReportLun->reserved = 0; 5348 5349 /* Set to LUN 0: 5350 * - address method to 0x00: Peripheral device addressing method, 5351 * - bus identifier to 0 5352 */ 5353 pReportLun->lunList[0].lun[0] = 0; 5354 pReportLun->lunList[0].lun[1] = 0; 5355 pReportLun->lunList[0].lun[2] = 0; 5356 pReportLun->lunList[0].lun[3] = 0; 5357 pReportLun->lunList[0].lun[4] = 0; 5358 pReportLun->lunList[0].lun[5] = 0; 5359 pReportLun->lunList[0].lun[6] = 0; 5360 pReportLun->lunList[0].lun[7] = 0; 5361 5362 if (allocationLen > reportLunLen) 5363 { 5364 /* underrun */ 5365 TI_DBG1(("satReportLun reporting underrun reportLunLen=0x%x allocationLen=0x%x \n", reportLunLen, allocationLen)); 5366 5367 ostiInitiatorIOCompleted( tiRoot, 5368 tiIORequest, 5369 tiIOUnderRun, 5370 allocationLen - reportLunLen, 5371 agNULL, 5372 satIOContext->interruptContext ); 5373 5374 5375 } 5376 else 5377 { 5378 ostiInitiatorIOCompleted( tiRoot, 5379 tiIORequest, 5380 tiIOSuccess, 5381 SCSI_STAT_GOOD, 5382 agNULL, 5383 satIOContext->interruptContext); 5384 } 5385 return tiSuccess; 5386 } 5387 5388 5389 /*****************************************************************************/ 5390 /*! \brief SAT implementation for SCSI REQUEST SENSE. 5391 * 5392 * SAT implementation for SCSI REQUEST SENSE. 5393 * 5394 * \param tiRoot: Pointer to TISA initiator driver/port instance. 5395 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 5396 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 5397 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 5398 * \param satIOContext_t: Pointer to the SAT IO Context 5399 * 5400 * \return If command is started successfully 5401 * - \e tiSuccess: I/O request successfully initiated. 5402 * - \e tiBusy: No resources available, try again later. 5403 * - \e tiIONoDevice: Invalid device handle. 5404 * - \e tiError: Other errors. 5405 */ 5406 /*****************************************************************************/ 5407 GLOBAL bit32 satRequestSense( 5408 tiRoot_t *tiRoot, 5409 tiIORequest_t *tiIORequest, 5410 tiDeviceHandle_t *tiDeviceHandle, 5411 tiScsiInitiatorRequest_t *tiScsiRequest, 5412 satIOContext_t *satIOContext) 5413 { 5414 /* 5415 SAT Rev 8 p38, Table25 5416 sending SMART RETURN STATUS 5417 Checking SMART Treshold Exceeded Condition is done in satRequestSenseCB() 5418 Only fixed format sense data is support. In other words, we don't support DESC bit is set 5419 in Request Sense 5420 */ 5421 bit32 status; 5422 bit32 agRequestType; 5423 scsiRspSense_t *pSense; 5424 satDeviceData_t *pSatDevData; 5425 tiIniScsiCmnd_t *scsiCmnd; 5426 agsaFisRegHostToDevice_t *fis; 5427 tdIORequestBody_t *tdIORequestBody; 5428 satInternalIo_t *satIntIo = agNULL; 5429 satIOContext_t *satIOContext2; 5430 5431 TI_DBG4(("satRequestSense entry: tiDeviceHandle=%p tiIORequest=%p\n", 5432 tiDeviceHandle, tiIORequest)); 5433 5434 pSense = (scsiRspSense_t *) tiScsiRequest->sglVirtualAddr; 5435 pSatDevData = satIOContext->pSatDevData; 5436 scsiCmnd = &tiScsiRequest->scsiCmnd; 5437 fis = satIOContext->pFis; 5438 5439 TI_DBG4(("satRequestSense: pSatDevData=%p\n", pSatDevData)); 5440 5441 /* checking CONTROL */ 5442 /* NACA == 1 or LINK == 1*/ 5443 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 5444 { 5445 satSetSensePayload( pSense, 5446 SCSI_SNSKEY_ILLEGAL_REQUEST, 5447 0, 5448 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5449 satIOContext); 5450 5451 ostiInitiatorIOCompleted( tiRoot, 5452 tiIORequest, 5453 tiIOSuccess, 5454 SCSI_STAT_CHECK_CONDITION, 5455 satIOContext->pTiSenseData, 5456 satIOContext->interruptContext ); 5457 5458 TI_DBG1(("satRequestSense: return control\n")); 5459 return tiSuccess; 5460 } 5461 5462 /* 5463 Only fixed format sense data is support. In other words, we don't support DESC bit is set 5464 in Request Sense 5465 */ 5466 if ( scsiCmnd->cdb[1] & ATA_REMOVABLE_MEDIA_DEVICE_MASK ) 5467 { 5468 satSetSensePayload( pSense, 5469 SCSI_SNSKEY_ILLEGAL_REQUEST, 5470 0, 5471 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5472 satIOContext); 5473 5474 ostiInitiatorIOCompleted( tiRoot, 5475 tiIORequest, 5476 tiIOSuccess, 5477 SCSI_STAT_CHECK_CONDITION, 5478 satIOContext->pTiSenseData, 5479 satIOContext->interruptContext ); 5480 5481 TI_DBG1(("satRequestSense: DESC bit is set, which we don't support\n")); 5482 return tiSuccess; 5483 } 5484 5485 5486 if (pSatDevData->satSMARTEnabled == agTRUE) 5487 { 5488 /* sends SMART RETURN STATUS */ 5489 fis->h.fisType = 0x27; /* Reg host to device */ 5490 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5491 5492 fis->h.command = SAT_SMART_RETURN_STATUS; /* 0xB0 */ 5493 fis->h.features = 0xDA; /* FIS features */ 5494 fis->d.featuresExp = 0; /* FIS reserve */ 5495 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 5496 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 5497 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 5498 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 5499 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 5500 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 5501 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 5502 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 5503 fis->d.device = 0; /* FIS DEV is discared in SATA */ 5504 fis->d.control = 0; /* FIS HOB bit clear */ 5505 fis->d.reserved4 = 0; 5506 fis->d.reserved5 = 0; 5507 5508 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 5509 /* Initialize CB for SATA completion. 5510 */ 5511 satIOContext->satCompleteCB = &satRequestSenseCB; 5512 5513 /* 5514 * Prepare SGL and send FIS to LL layer. 5515 */ 5516 satIOContext->reqType = agRequestType; /* Save it */ 5517 5518 status = sataLLIOStart( tiRoot, 5519 tiIORequest, 5520 tiDeviceHandle, 5521 tiScsiRequest, 5522 satIOContext); 5523 5524 TI_DBG4(("satRequestSense: if return, status %d\n", status)); 5525 return (status); 5526 } 5527 else 5528 { 5529 /*allocate iocontext for xmitting xmit SAT_CHECK_POWER_MODE 5530 then call satRequestSense2 */ 5531 5532 TI_DBG4(("satRequestSense: before satIntIo %p\n", satIntIo)); 5533 /* allocate iocontext */ 5534 satIntIo = satAllocIntIoResource( tiRoot, 5535 tiIORequest, /* original request */ 5536 pSatDevData, 5537 tiScsiRequest->scsiCmnd.expDataLength, 5538 satIntIo); 5539 5540 TI_DBG4(("satRequestSense: after satIntIo %p\n", satIntIo)); 5541 5542 if (satIntIo == agNULL) 5543 { 5544 /* memory allocation failure */ 5545 satFreeIntIoResource( tiRoot, 5546 pSatDevData, 5547 satIntIo); 5548 5549 /* failed during sending SMART RETURN STATUS */ 5550 satSetSensePayload( pSense, 5551 SCSI_SNSKEY_NO_SENSE, 5552 0, 5553 SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE, 5554 satIOContext); 5555 5556 ostiInitiatorIOCompleted( tiRoot, 5557 tiIORequest, 5558 tiIOSuccess, 5559 SCSI_STAT_GOOD, 5560 agNULL, 5561 satIOContext->interruptContext ); 5562 5563 TI_DBG4(("satRequestSense: else fail 1\n")); 5564 return tiSuccess; 5565 } /* end of memory allocation failure */ 5566 5567 5568 /* 5569 * Need to initialize all the fields within satIOContext except 5570 * reqType and satCompleteCB which will be set depending on cmd. 5571 */ 5572 5573 if (satIntIo == agNULL) 5574 { 5575 TI_DBG4(("satRequestSense: satIntIo is NULL\n")); 5576 } 5577 else 5578 { 5579 TI_DBG4(("satRequestSense: satIntIo is NOT NULL\n")); 5580 } 5581 /* use this --- tttttthe one the same */ 5582 5583 5584 satIntIo->satOrgTiIORequest = tiIORequest; 5585 tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody; 5586 satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext); 5587 5588 satIOContext2->pSatDevData = pSatDevData; 5589 satIOContext2->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 5590 satIOContext2->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd); 5591 satIOContext2->pSense = &(tdIORequestBody->transport.SATA.sensePayload); 5592 satIOContext2->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData); 5593 satIOContext2->pTiSenseData->senseData = satIOContext2->pSense; 5594 satIOContext2->tiRequestBody = satIntIo->satIntRequestBody; 5595 satIOContext2->interruptContext = satIOContext->interruptContext; 5596 satIOContext2->satIntIoContext = satIntIo; 5597 satIOContext2->ptiDeviceHandle = tiDeviceHandle; 5598 satIOContext2->satOrgIOContext = satIOContext; 5599 5600 TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.len %d\n", satIntIo->satIntTiScsiXchg.agSgl1.len)); 5601 5602 TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.upper %d\n", satIntIo->satIntTiScsiXchg.agSgl1.upper)); 5603 5604 TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.lower %d\n", satIntIo->satIntTiScsiXchg.agSgl1.lower)); 5605 5606 TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.type %d\n", satIntIo->satIntTiScsiXchg.agSgl1.type)); 5607 5608 status = satRequestSense_1( tiRoot, 5609 &(satIntIo->satIntTiIORequest), 5610 tiDeviceHandle, 5611 &(satIntIo->satIntTiScsiXchg), 5612 satIOContext2); 5613 5614 if (status != tiSuccess) 5615 { 5616 satFreeIntIoResource( tiRoot, 5617 pSatDevData, 5618 satIntIo); 5619 5620 /* failed during sending SMART RETURN STATUS */ 5621 satSetSensePayload( pSense, 5622 SCSI_SNSKEY_NO_SENSE, 5623 0, 5624 SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE, 5625 satIOContext); 5626 5627 ostiInitiatorIOCompleted( tiRoot, 5628 tiIORequest, 5629 tiIOSuccess, 5630 SCSI_STAT_CHECK_CONDITION, 5631 agNULL, 5632 satIOContext->interruptContext ); 5633 5634 TI_DBG1(("satRequestSense: else fail 2\n")); 5635 return tiSuccess; 5636 } 5637 TI_DBG4(("satRequestSense: else return success\n")); 5638 return tiSuccess; 5639 } 5640 } 5641 5642 5643 /*****************************************************************************/ 5644 /*! \brief SAT implementation for SCSI REQUEST SENSE. 5645 * 5646 * SAT implementation for SCSI REQUEST SENSE. 5647 * Sub function of satRequestSense 5648 * 5649 * \param tiRoot: Pointer to TISA initiator driver/port instance. 5650 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 5651 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 5652 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 5653 * \param satIOContext_t: Pointer to the SAT IO Context 5654 * 5655 * \return If command is started successfully 5656 * - \e tiSuccess: I/O request successfully initiated. 5657 * - \e tiBusy: No resources available, try again later. 5658 * - \e tiIONoDevice: Invalid device handle. 5659 * - \e tiError: Other errors. 5660 */ 5661 /*****************************************************************************/ 5662 GLOBAL bit32 satRequestSense_1( 5663 tiRoot_t *tiRoot, 5664 tiIORequest_t *tiIORequest, 5665 tiDeviceHandle_t *tiDeviceHandle, 5666 tiScsiInitiatorRequest_t *tiScsiRequest, 5667 satIOContext_t *satIOContext) 5668 { 5669 /* 5670 sends SAT_CHECK_POWER_MODE 5671 */ 5672 bit32 status; 5673 bit32 agRequestType; 5674 agsaFisRegHostToDevice_t *fis; 5675 5676 TI_DBG4(("satRequestSense_1 entry: tiDeviceHandle=%p tiIORequest=%p\n", 5677 tiDeviceHandle, tiIORequest)); 5678 5679 fis = satIOContext->pFis; 5680 /* 5681 * Send the ATA CHECK POWER MODE command. 5682 */ 5683 fis->h.fisType = 0x27; /* Reg host to device */ 5684 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5685 5686 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */ 5687 fis->h.features = 0; 5688 fis->d.lbaLow = 0; 5689 fis->d.lbaMid = 0; 5690 fis->d.lbaHigh = 0; 5691 fis->d.device = 0; 5692 fis->d.lbaLowExp = 0; 5693 fis->d.lbaMidExp = 0; 5694 fis->d.lbaHighExp = 0; 5695 fis->d.featuresExp = 0; 5696 fis->d.sectorCount = 0; 5697 fis->d.sectorCountExp = 0; 5698 fis->d.reserved4 = 0; 5699 fis->d.control = 0; /* FIS HOB bit clear */ 5700 fis->d.reserved5 = 0; 5701 5702 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 5703 5704 /* Initialize CB for SATA completion. 5705 */ 5706 satIOContext->satCompleteCB = &satRequestSenseCB; 5707 5708 /* 5709 * Prepare SGL and send FIS to LL layer. 5710 */ 5711 satIOContext->reqType = agRequestType; /* Save it */ 5712 5713 5714 TI_DBG4(("satRequestSense_1: agSgl1.len %d\n", tiScsiRequest->agSgl1.len)); 5715 5716 TI_DBG4(("satRequestSense_1: agSgl1.upper %d\n", tiScsiRequest->agSgl1.upper)); 5717 5718 TI_DBG4(("satRequestSense_1: agSgl1.lower %d\n", tiScsiRequest->agSgl1.lower)); 5719 5720 TI_DBG4(("satRequestSense_1: agSgl1.type %d\n", tiScsiRequest->agSgl1.type)); 5721 5722 // tdhexdump("satRequestSense_1", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t)); 5723 5724 status = sataLLIOStart( tiRoot, 5725 tiIORequest, 5726 tiDeviceHandle, 5727 tiScsiRequest, 5728 satIOContext); 5729 5730 5731 5732 return status; 5733 } 5734 5735 5736 /*****************************************************************************/ 5737 /*! \brief SAT implementation for SCSI INQUIRY. 5738 * 5739 * SAT implementation for SCSI INQUIRY. 5740 * 5741 * \param tiRoot: Pointer to TISA initiator driver/port instance. 5742 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 5743 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 5744 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 5745 * \param satIOContext_t: Pointer to the SAT IO Context 5746 * 5747 * \return If command is started successfully 5748 * - \e tiSuccess: I/O request successfully initiated. 5749 * - \e tiBusy: No resources available, try again later. 5750 * - \e tiIONoDevice: Invalid device handle. 5751 * - \e tiError: Other errors. 5752 */ 5753 /*****************************************************************************/ 5754 GLOBAL bit32 satInquiry( 5755 tiRoot_t *tiRoot, 5756 tiIORequest_t *tiIORequest, 5757 tiDeviceHandle_t *tiDeviceHandle, 5758 tiScsiInitiatorRequest_t *tiScsiRequest, 5759 satIOContext_t *satIOContext) 5760 { 5761 /* 5762 CMDDT bit is obsolete in SPC-3 and this is assumed in SAT revision 8 5763 */ 5764 scsiRspSense_t *pSense; 5765 tiIniScsiCmnd_t *scsiCmnd; 5766 satDeviceData_t *pSatDevData; 5767 bit32 status; 5768 5769 TI_DBG5(("satInquiry: start\n")); 5770 TI_DBG5(("satInquiry entry: tiDeviceHandle=%p tiIORequest=%p\n", 5771 tiDeviceHandle, tiIORequest)); 5772 pSense = satIOContext->pSense; 5773 scsiCmnd = &tiScsiRequest->scsiCmnd; 5774 pSatDevData = satIOContext->pSatDevData; 5775 TI_DBG5(("satInquiry: pSatDevData=%p\n", pSatDevData)); 5776 //tdhexdump("satInquiry", (bit8 *)scsiCmnd->cdb, 6); 5777 /* checking CONTROL */ 5778 /* NACA == 1 or LINK == 1*/ 5779 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 5780 { 5781 satSetSensePayload( pSense, 5782 SCSI_SNSKEY_ILLEGAL_REQUEST, 5783 0, 5784 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5785 satIOContext); 5786 ostiInitiatorIOCompleted( tiRoot, 5787 tiIORequest, 5788 tiIOSuccess, 5789 SCSI_STAT_CHECK_CONDITION, 5790 satIOContext->pTiSenseData, 5791 satIOContext->interruptContext ); 5792 TI_DBG2(("satInquiry: return control\n")); 5793 return tiSuccess; 5794 } 5795 5796 /* checking EVPD and Allocation Length */ 5797 /* SPC-4 spec 6.4 p141 */ 5798 /* EVPD bit == 0 && PAGE CODE != 0 */ 5799 if ( !(scsiCmnd->cdb[1] & SCSI_EVPD_MASK) && 5800 (scsiCmnd->cdb[2] != 0) 5801 ) 5802 { 5803 satSetSensePayload( pSense, 5804 SCSI_SNSKEY_ILLEGAL_REQUEST, 5805 0, 5806 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5807 satIOContext); 5808 ostiInitiatorIOCompleted( tiRoot, 5809 tiIORequest, 5810 tiIOSuccess, 5811 SCSI_STAT_CHECK_CONDITION, 5812 satIOContext->pTiSenseData, 5813 satIOContext->interruptContext ); 5814 TI_DBG1(("satInquiry: return EVPD and PAGE CODE\n")); 5815 return tiSuccess; 5816 } 5817 TI_DBG6(("satInquiry: allocation length 0x%x %d\n", ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4], ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4])); 5818 5819 /* convert OS IO to TD internal IO */ 5820 if ( pSatDevData->IDDeviceValid == agFALSE) 5821 { 5822 status = satStartIDDev( 5823 tiRoot, 5824 tiIORequest, 5825 tiDeviceHandle, 5826 tiScsiRequest, 5827 satIOContext 5828 ); 5829 TI_DBG6(("satInquiry: end status %d\n", status)); 5830 return status; 5831 } 5832 else 5833 { 5834 TI_DBG6(("satInquiry: calling satInquiryIntCB\n")); 5835 satInquiryIntCB( 5836 tiRoot, 5837 tiIORequest, 5838 tiDeviceHandle, 5839 tiScsiRequest, 5840 satIOContext 5841 ); 5842 5843 return tiSuccess; 5844 } 5845 5846 } 5847 5848 5849 /*****************************************************************************/ 5850 /*! \brief SAT implementation for SCSI satReadCapacity10. 5851 * 5852 * SAT implementation for SCSI satReadCapacity10. 5853 * 5854 * \param tiRoot: Pointer to TISA initiator driver/port instance. 5855 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 5856 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 5857 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 5858 * \param satIOContext_t: Pointer to the SAT IO Context 5859 * 5860 * \return If command is started successfully 5861 * - \e tiSuccess: I/O request successfully initiated. 5862 * - \e tiBusy: No resources available, try again later. 5863 * - \e tiIONoDevice: Invalid device handle. 5864 * - \e tiError: Other errors. 5865 */ 5866 /*****************************************************************************/ 5867 GLOBAL bit32 satReadCapacity10( 5868 tiRoot_t *tiRoot, 5869 tiIORequest_t *tiIORequest, 5870 tiDeviceHandle_t *tiDeviceHandle, 5871 tiScsiInitiatorRequest_t *tiScsiRequest, 5872 satIOContext_t *satIOContext) 5873 { 5874 scsiRspSense_t *pSense; 5875 tiIniScsiCmnd_t *scsiCmnd; 5876 bit8 *pVirtAddr; 5877 satDeviceData_t *pSatDevData; 5878 agsaSATAIdentifyData_t *pSATAIdData; 5879 bit32 lastLba; 5880 bit32 word117_118; 5881 bit32 word117; 5882 bit32 word118; 5883 TI_DBG5(("satReadCapacity10: start: tiDeviceHandle=%p tiIORequest=%p\n", 5884 tiDeviceHandle, tiIORequest)); 5885 5886 pSense = satIOContext->pSense; 5887 pVirtAddr = (bit8 *) tiScsiRequest->sglVirtualAddr; 5888 scsiCmnd = &tiScsiRequest->scsiCmnd; 5889 pSatDevData = satIOContext->pSatDevData; 5890 pSATAIdData = &pSatDevData->satIdentifyData; 5891 5892 5893 /* checking CONTROL */ 5894 /* NACA == 1 or LINK == 1*/ 5895 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 5896 { 5897 satSetSensePayload( pSense, 5898 SCSI_SNSKEY_ILLEGAL_REQUEST, 5899 0, 5900 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5901 satIOContext); 5902 5903 ostiInitiatorIOCompleted( tiRoot, 5904 tiIORequest, 5905 tiIOSuccess, 5906 SCSI_STAT_CHECK_CONDITION, 5907 satIOContext->pTiSenseData, 5908 satIOContext->interruptContext ); 5909 5910 TI_DBG1(("satReadCapacity10: return control\n")); 5911 return tiSuccess; 5912 } 5913 5914 5915 /* 5916 * If Logical block address is not set to zero, return error 5917 */ 5918 if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5])) 5919 { 5920 TI_DBG1(("satReadCapacity10 *** ERROR *** logical address non zero, tiDeviceHandle=%p tiIORequest=%p\n", 5921 tiDeviceHandle, tiIORequest)); 5922 5923 satSetSensePayload( pSense, 5924 SCSI_SNSKEY_ILLEGAL_REQUEST, 5925 0, 5926 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5927 satIOContext); 5928 5929 ostiInitiatorIOCompleted( tiRoot, 5930 tiIORequest, 5931 tiIOSuccess, 5932 SCSI_STAT_CHECK_CONDITION, 5933 satIOContext->pTiSenseData, 5934 satIOContext->interruptContext ); 5935 return tiSuccess; 5936 5937 } 5938 5939 /* 5940 * If PMI bit is not zero, return error 5941 */ 5942 if ( ((scsiCmnd->cdb[8]) & SCSI_READ_CAPACITY10_PMI_MASK) != 0 ) 5943 { 5944 TI_DBG1(("satReadCapacity10 *** ERROR *** PMI is not zero, tiDeviceHandle=%p tiIORequest=%p\n", 5945 tiDeviceHandle, tiIORequest)); 5946 5947 satSetSensePayload( pSense, 5948 SCSI_SNSKEY_ILLEGAL_REQUEST, 5949 0, 5950 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5951 satIOContext); 5952 5953 ostiInitiatorIOCompleted( tiRoot, 5954 tiIORequest, 5955 tiIOSuccess, 5956 SCSI_STAT_CHECK_CONDITION, 5957 satIOContext->pTiSenseData, 5958 satIOContext->interruptContext ); 5959 return tiSuccess; 5960 5961 } 5962 5963 /* 5964 filling in Read Capacity parameter data 5965 saved identify device has been already flipped 5966 See ATA spec p125 and p136 and SBC spec p54 5967 */ 5968 /* 5969 * If 48-bit addressing is supported, set capacity information from Identify 5970 * Device Word 100-103. 5971 */ 5972 if (pSatDevData->sat48BitSupport == agTRUE) 5973 { 5974 /* 5975 * Setting RETURNED LOGICAL BLOCK ADDRESS in READ CAPACITY(10) response data: 5976 * SBC-2 specifies that if the capacity exceeded the 4-byte RETURNED LOGICAL 5977 * BLOCK ADDRESS in READ CAPACITY(10) parameter data, the RETURNED LOGICAL 5978 * BLOCK ADDRESS should be set to 0xFFFFFFFF so the application client would 5979 * then issue a READ CAPACITY(16) command. 5980 */ 5981 /* ATA Identify Device information word 100 - 103 */ 5982 if ( (pSATAIdData->maxLBA32_47 != 0 ) || (pSATAIdData->maxLBA48_63 != 0)) 5983 { 5984 pVirtAddr[0] = 0xFF; /* MSB number of block */ 5985 pVirtAddr[1] = 0xFF; 5986 pVirtAddr[2] = 0xFF; 5987 pVirtAddr[3] = 0xFF; /* LSB number of block */ 5988 TI_DBG1(("satReadCapacity10: returns 0xFFFFFFFF\n")); 5989 } 5990 else /* Fit the Readcapacity10 4-bytes response length */ 5991 { 5992 lastLba = (((pSATAIdData->maxLBA16_31) << 16) ) | 5993 (pSATAIdData->maxLBA0_15); 5994 lastLba = lastLba - 1; /* LBA starts from zero */ 5995 5996 /* 5997 for testing 5998 lastLba = lastLba - (512*10) - 1; 5999 */ 6000 6001 6002 pVirtAddr[0] = (bit8)((lastLba >> 24) & 0xFF); /* MSB */ 6003 pVirtAddr[1] = (bit8)((lastLba >> 16) & 0xFF); 6004 pVirtAddr[2] = (bit8)((lastLba >> 8) & 0xFF); 6005 pVirtAddr[3] = (bit8)((lastLba ) & 0xFF); /* LSB */ 6006 6007 TI_DBG3(("satReadCapacity10: lastLba is 0x%x %d\n", lastLba, lastLba)); 6008 TI_DBG3(("satReadCapacity10: LBA 0 is 0x%x %d\n", pVirtAddr[0], pVirtAddr[0])); 6009 TI_DBG3(("satReadCapacity10: LBA 1 is 0x%x %d\n", pVirtAddr[1], pVirtAddr[1])); 6010 TI_DBG3(("satReadCapacity10: LBA 2 is 0x%x %d\n", pVirtAddr[2], pVirtAddr[2])); 6011 TI_DBG3(("satReadCapacity10: LBA 3 is 0x%x %d\n", pVirtAddr[3], pVirtAddr[3])); 6012 6013 } 6014 } 6015 6016 /* 6017 * For 28-bit addressing, set capacity information from Identify 6018 * Device Word 60-61. 6019 */ 6020 else 6021 { 6022 /* ATA Identify Device information word 60 - 61 */ 6023 lastLba = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) | 6024 (pSATAIdData->numOfUserAddressableSectorsLo); 6025 lastLba = lastLba - 1; /* LBA starts from zero */ 6026 6027 pVirtAddr[0] = (bit8)((lastLba >> 24) & 0xFF); /* MSB */ 6028 pVirtAddr[1] = (bit8)((lastLba >> 16) & 0xFF); 6029 pVirtAddr[2] = (bit8)((lastLba >> 8) & 0xFF); 6030 pVirtAddr[3] = (bit8)((lastLba ) & 0xFF); /* LSB */ 6031 } 6032 /* SAT Rev 8d */ 6033 if (((pSATAIdData->word104_107[2]) & 0x1000) == 0) 6034 { 6035 TI_DBG5(("satReadCapacity10: Default Block Length is 512\n")); 6036 /* 6037 * Set the block size, fixed at 512 bytes. 6038 */ 6039 pVirtAddr[4] = 0x00; /* MSB block size in bytes */ 6040 pVirtAddr[5] = 0x00; 6041 pVirtAddr[6] = 0x02; 6042 pVirtAddr[7] = 0x00; /* LSB block size in bytes */ 6043 } 6044 else 6045 { 6046 word118 = pSATAIdData->word112_126[6]; 6047 word117 = pSATAIdData->word112_126[5]; 6048 6049 word117_118 = (word118 << 16) + word117; 6050 word117_118 = word117_118 * 2; 6051 pVirtAddr[4] = (bit8)((word117_118 >> 24) & 0xFF); /* MSB block size in bytes */ 6052 pVirtAddr[5] = (bit8)((word117_118 >> 16) & 0xFF); 6053 pVirtAddr[6] = (bit8)((word117_118 >> 8) & 0xFF); 6054 pVirtAddr[7] = (bit8)(word117_118 & 0xFF); /* LSB block size in bytes */ 6055 6056 TI_DBG1(("satReadCapacity10: Nondefault word118 %d 0x%x \n", word118, word118)); 6057 TI_DBG1(("satReadCapacity10: Nondefault word117 %d 0x%x \n", word117, word117)); 6058 TI_DBG1(("satReadCapacity10: Nondefault Block Length is %d 0x%x \n",word117_118, word117_118)); 6059 6060 } 6061 6062 /* fill in MAX LBA, which is used in satSendDiagnostic_1() */ 6063 pSatDevData->satMaxLBA[0] = 0; /* MSB */ 6064 pSatDevData->satMaxLBA[1] = 0; 6065 pSatDevData->satMaxLBA[2] = 0; 6066 pSatDevData->satMaxLBA[3] = 0; 6067 pSatDevData->satMaxLBA[4] = pVirtAddr[0]; 6068 pSatDevData->satMaxLBA[5] = pVirtAddr[1]; 6069 pSatDevData->satMaxLBA[6] = pVirtAddr[2]; 6070 pSatDevData->satMaxLBA[7] = pVirtAddr[3]; /* LSB */ 6071 6072 6073 TI_DBG4(("satReadCapacity10 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , tiDeviceHandle=%p tiIORequest=%p\n", 6074 pVirtAddr[0], pVirtAddr[1], pVirtAddr[2], pVirtAddr[3], 6075 pVirtAddr[4], pVirtAddr[5], pVirtAddr[6], pVirtAddr[7], 6076 tiDeviceHandle, tiIORequest)); 6077 6078 6079 /* 6080 * Send the completion response now. 6081 */ 6082 ostiInitiatorIOCompleted( tiRoot, 6083 tiIORequest, 6084 tiIOSuccess, 6085 SCSI_STAT_GOOD, 6086 agNULL, 6087 satIOContext->interruptContext); 6088 return tiSuccess; 6089 } 6090 6091 6092 /*****************************************************************************/ 6093 /*! \brief SAT implementation for SCSI satReadCapacity16. 6094 * 6095 * SAT implementation for SCSI satReadCapacity16. 6096 * 6097 * \param tiRoot: Pointer to TISA initiator driver/port instance. 6098 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 6099 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 6100 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 6101 * \param satIOContext_t: Pointer to the SAT IO Context 6102 * 6103 * \return If command is started successfully 6104 * - \e tiSuccess: I/O request successfully initiated. 6105 * - \e tiBusy: No resources available, try again later. 6106 * - \e tiIONoDevice: Invalid device handle. 6107 * - \e tiError: Other errors. 6108 */ 6109 /*****************************************************************************/ 6110 GLOBAL bit32 satReadCapacity16( 6111 tiRoot_t *tiRoot, 6112 tiIORequest_t *tiIORequest, 6113 tiDeviceHandle_t *tiDeviceHandle, 6114 tiScsiInitiatorRequest_t *tiScsiRequest, 6115 satIOContext_t *satIOContext) 6116 { 6117 6118 scsiRspSense_t *pSense; 6119 tiIniScsiCmnd_t *scsiCmnd; 6120 bit8 *pVirtAddr; 6121 satDeviceData_t *pSatDevData; 6122 agsaSATAIdentifyData_t *pSATAIdData; 6123 bit32 lastLbaLo; 6124 bit32 allocationLen; 6125 bit32 readCapacityLen = 32; 6126 bit32 i = 0; 6127 TI_DBG5(("satReadCapacity16 start: tiDeviceHandle=%p tiIORequest=%p\n", 6128 tiDeviceHandle, tiIORequest)); 6129 6130 pSense = satIOContext->pSense; 6131 pVirtAddr = (bit8 *) tiScsiRequest->sglVirtualAddr; 6132 scsiCmnd = &tiScsiRequest->scsiCmnd; 6133 pSatDevData = satIOContext->pSatDevData; 6134 pSATAIdData = &pSatDevData->satIdentifyData; 6135 6136 /* Find the buffer size allocated by Initiator */ 6137 allocationLen = (((bit32)scsiCmnd->cdb[10]) << 24) | 6138 (((bit32)scsiCmnd->cdb[11]) << 16) | 6139 (((bit32)scsiCmnd->cdb[12]) << 8 ) | 6140 (((bit32)scsiCmnd->cdb[13]) ); 6141 6142 6143 if (allocationLen < readCapacityLen) 6144 { 6145 TI_DBG1(("satReadCapacity16 *** ERROR *** insufficient len=0x%x readCapacityLen=0x%x\n", allocationLen, readCapacityLen)); 6146 6147 satSetSensePayload( pSense, 6148 SCSI_SNSKEY_ILLEGAL_REQUEST, 6149 0, 6150 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6151 satIOContext); 6152 6153 ostiInitiatorIOCompleted( tiRoot, 6154 tiIORequest, 6155 tiIOSuccess, 6156 SCSI_STAT_CHECK_CONDITION, 6157 satIOContext->pTiSenseData, 6158 satIOContext->interruptContext ); 6159 return tiSuccess; 6160 6161 } 6162 6163 /* checking CONTROL */ 6164 /* NACA == 1 or LINK == 1*/ 6165 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 6166 { 6167 satSetSensePayload( pSense, 6168 SCSI_SNSKEY_ILLEGAL_REQUEST, 6169 0, 6170 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6171 satIOContext); 6172 6173 ostiInitiatorIOCompleted( tiRoot, 6174 tiIORequest, 6175 tiIOSuccess, 6176 SCSI_STAT_CHECK_CONDITION, 6177 satIOContext->pTiSenseData, 6178 satIOContext->interruptContext ); 6179 6180 TI_DBG1(("satReadCapacity16: return control\n")); 6181 return tiSuccess; 6182 } 6183 6184 /* 6185 * If Logical blcok address is not set to zero, return error 6186 */ 6187 if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]) || 6188 (scsiCmnd->cdb[6] || scsiCmnd->cdb[7] || scsiCmnd->cdb[8] || scsiCmnd->cdb[9]) ) 6189 { 6190 TI_DBG1(("satReadCapacity16 *** ERROR *** logical address non zero, tiDeviceHandle=%p tiIORequest=%p\n", 6191 tiDeviceHandle, tiIORequest)); 6192 6193 satSetSensePayload( pSense, 6194 SCSI_SNSKEY_ILLEGAL_REQUEST, 6195 0, 6196 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6197 satIOContext); 6198 6199 ostiInitiatorIOCompleted( tiRoot, 6200 tiIORequest, 6201 tiIOSuccess, 6202 SCSI_STAT_CHECK_CONDITION, 6203 satIOContext->pTiSenseData, 6204 satIOContext->interruptContext ); 6205 return tiSuccess; 6206 6207 } 6208 6209 /* 6210 * If PMI bit is not zero, return error 6211 */ 6212 if ( ((scsiCmnd->cdb[14]) & SCSI_READ_CAPACITY16_PMI_MASK) != 0 ) 6213 { 6214 TI_DBG1(("satReadCapacity16 *** ERROR *** PMI is not zero, tiDeviceHandle=%p tiIORequest=%p\n", 6215 tiDeviceHandle, tiIORequest)); 6216 6217 satSetSensePayload( pSense, 6218 SCSI_SNSKEY_ILLEGAL_REQUEST, 6219 0, 6220 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6221 satIOContext); 6222 6223 ostiInitiatorIOCompleted( tiRoot, 6224 tiIORequest, 6225 tiIOSuccess, 6226 SCSI_STAT_CHECK_CONDITION, 6227 satIOContext->pTiSenseData, 6228 satIOContext->interruptContext ); 6229 return tiSuccess; 6230 6231 } 6232 6233 /* 6234 filling in Read Capacity parameter data 6235 */ 6236 6237 /* 6238 * If 48-bit addressing is supported, set capacity information from Identify 6239 * Device Word 100-103. 6240 */ 6241 if (pSatDevData->sat48BitSupport == agTRUE) 6242 { 6243 pVirtAddr[0] = (bit8)(((pSATAIdData->maxLBA48_63) >> 8) & 0xff); /* MSB */ 6244 pVirtAddr[1] = (bit8)((pSATAIdData->maxLBA48_63) & 0xff); 6245 pVirtAddr[2] = (bit8)(((pSATAIdData->maxLBA32_47) >> 8) & 0xff); 6246 pVirtAddr[3] = (bit8)((pSATAIdData->maxLBA32_47) & 0xff); 6247 6248 lastLbaLo = (((pSATAIdData->maxLBA16_31) << 16) ) | (pSATAIdData->maxLBA0_15); 6249 lastLbaLo = lastLbaLo - 1; /* LBA starts from zero */ 6250 6251 pVirtAddr[4] = (bit8)((lastLbaLo >> 24) & 0xFF); 6252 pVirtAddr[5] = (bit8)((lastLbaLo >> 16) & 0xFF); 6253 pVirtAddr[6] = (bit8)((lastLbaLo >> 8) & 0xFF); 6254 pVirtAddr[7] = (bit8)((lastLbaLo ) & 0xFF); /* LSB */ 6255 6256 } 6257 6258 /* 6259 * For 28-bit addressing, set capacity information from Identify 6260 * Device Word 60-61. 6261 */ 6262 else 6263 { 6264 pVirtAddr[0] = 0; /* MSB */ 6265 pVirtAddr[1] = 0; 6266 pVirtAddr[2] = 0; 6267 pVirtAddr[3] = 0; 6268 6269 lastLbaLo = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) | 6270 (pSATAIdData->numOfUserAddressableSectorsLo); 6271 lastLbaLo = lastLbaLo - 1; /* LBA starts from zero */ 6272 6273 pVirtAddr[4] = (bit8)((lastLbaLo >> 24) & 0xFF); 6274 pVirtAddr[5] = (bit8)((lastLbaLo >> 16) & 0xFF); 6275 pVirtAddr[6] = (bit8)((lastLbaLo >> 8) & 0xFF); 6276 pVirtAddr[7] = (bit8)((lastLbaLo ) & 0xFF); /* LSB */ 6277 6278 } 6279 6280 /* 6281 * Set the block size, fixed at 512 bytes. 6282 */ 6283 pVirtAddr[8] = 0x00; /* MSB block size in bytes */ 6284 pVirtAddr[9] = 0x00; 6285 pVirtAddr[10] = 0x02; 6286 pVirtAddr[11] = 0x00; /* LSB block size in bytes */ 6287 6288 6289 /* fill in MAX LBA, which is used in satSendDiagnostic_1() */ 6290 pSatDevData->satMaxLBA[0] = pVirtAddr[0]; /* MSB */ 6291 pSatDevData->satMaxLBA[1] = pVirtAddr[1]; 6292 pSatDevData->satMaxLBA[2] = pVirtAddr[2]; 6293 pSatDevData->satMaxLBA[3] = pVirtAddr[3]; 6294 pSatDevData->satMaxLBA[4] = pVirtAddr[4]; 6295 pSatDevData->satMaxLBA[5] = pVirtAddr[5]; 6296 pSatDevData->satMaxLBA[6] = pVirtAddr[6]; 6297 pSatDevData->satMaxLBA[7] = pVirtAddr[7]; /* LSB */ 6298 6299 TI_DBG5(("satReadCapacity16 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , tiDeviceHandle=%p tiIORequest=%p\n", 6300 pVirtAddr[0], pVirtAddr[1], pVirtAddr[2], pVirtAddr[3], 6301 pVirtAddr[4], pVirtAddr[5], pVirtAddr[6], pVirtAddr[7], 6302 pVirtAddr[8], pVirtAddr[9], pVirtAddr[10], pVirtAddr[11], 6303 tiDeviceHandle, tiIORequest)); 6304 6305 for(i=12;i<=31;i++) 6306 { 6307 pVirtAddr[i] = 0x00; 6308 } 6309 6310 /* 6311 * Send the completion response now. 6312 */ 6313 if (allocationLen > readCapacityLen) 6314 { 6315 /* underrun */ 6316 TI_DBG1(("satReadCapacity16 reporting underrun readCapacityLen=0x%x allocationLen=0x%x \n", readCapacityLen, allocationLen)); 6317 6318 ostiInitiatorIOCompleted( tiRoot, 6319 tiIORequest, 6320 tiIOUnderRun, 6321 allocationLen - readCapacityLen, 6322 agNULL, 6323 satIOContext->interruptContext ); 6324 6325 6326 } 6327 else 6328 { 6329 ostiInitiatorIOCompleted( tiRoot, 6330 tiIORequest, 6331 tiIOSuccess, 6332 SCSI_STAT_GOOD, 6333 agNULL, 6334 satIOContext->interruptContext); 6335 } 6336 return tiSuccess; 6337 6338 } 6339 6340 6341 /*****************************************************************************/ 6342 /*! \brief SAT implementation for SCSI MODE SENSE (6). 6343 * 6344 * SAT implementation for SCSI MODE SENSE (6). 6345 * 6346 * \param tiRoot: Pointer to TISA initiator driver/port instance. 6347 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 6348 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 6349 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 6350 * \param satIOContext_t: Pointer to the SAT IO Context 6351 * 6352 * \return If command is started successfully 6353 * - \e tiSuccess: I/O request successfully initiated. 6354 * - \e tiBusy: No resources available, try again later. 6355 * - \e tiIONoDevice: Invalid device handle. 6356 * - \e tiError: Other errors. 6357 */ 6358 /*****************************************************************************/ 6359 GLOBAL bit32 satModeSense6( 6360 tiRoot_t *tiRoot, 6361 tiIORequest_t *tiIORequest, 6362 tiDeviceHandle_t *tiDeviceHandle, 6363 tiScsiInitiatorRequest_t *tiScsiRequest, 6364 satIOContext_t *satIOContext) 6365 { 6366 6367 scsiRspSense_t *pSense; 6368 bit32 requestLen; 6369 tiIniScsiCmnd_t *scsiCmnd; 6370 bit32 pageSupported; 6371 bit8 page; 6372 bit8 *pModeSense; /* Mode Sense data buffer */ 6373 satDeviceData_t *pSatDevData; 6374 bit8 PC; 6375 bit8 AllPages[MODE_SENSE6_RETURN_ALL_PAGES_LEN]; 6376 bit8 Control[MODE_SENSE6_CONTROL_PAGE_LEN]; 6377 bit8 RWErrorRecovery[MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN]; 6378 bit8 Caching[MODE_SENSE6_CACHING_LEN]; 6379 bit8 InfoExceptionCtrl[MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN]; 6380 bit8 lenRead = 0; 6381 6382 6383 TI_DBG5(("satModeSense6 entry: tiDeviceHandle=%p tiIORequest=%p\n", 6384 tiDeviceHandle, tiIORequest)); 6385 6386 pSense = satIOContext->pSense; 6387 scsiCmnd = &tiScsiRequest->scsiCmnd; 6388 pModeSense = (bit8 *) tiScsiRequest->sglVirtualAddr; 6389 pSatDevData = satIOContext->pSatDevData; 6390 6391 //tdhexdump("satModeSense6", (bit8 *)scsiCmnd->cdb, 6); 6392 /* checking CONTROL */ 6393 /* NACA == 1 or LINK == 1*/ 6394 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 6395 { 6396 satSetSensePayload( pSense, 6397 SCSI_SNSKEY_ILLEGAL_REQUEST, 6398 0, 6399 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6400 satIOContext); 6401 6402 ostiInitiatorIOCompleted( tiRoot, 6403 tiIORequest, 6404 tiIOSuccess, 6405 SCSI_STAT_CHECK_CONDITION, 6406 satIOContext->pTiSenseData, 6407 satIOContext->interruptContext ); 6408 6409 TI_DBG2(("satModeSense6: return control\n")); 6410 return tiSuccess; 6411 } 6412 6413 /* checking PC(Page Control) 6414 SAT revion 8, 8.5.3 p33 and 10.1.2, p66 6415 */ 6416 PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PC_MASK); 6417 if (PC != 0) 6418 { 6419 satSetSensePayload( pSense, 6420 SCSI_SNSKEY_ILLEGAL_REQUEST, 6421 0, 6422 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6423 satIOContext); 6424 6425 ostiInitiatorIOCompleted( tiRoot, 6426 tiIORequest, 6427 tiIOSuccess, 6428 SCSI_STAT_CHECK_CONDITION, 6429 satIOContext->pTiSenseData, 6430 satIOContext->interruptContext ); 6431 6432 TI_DBG1(("satModeSense6: return due to PC value pc 0x%x\n", PC >> 6)); 6433 return tiSuccess; 6434 } 6435 6436 /* reading PAGE CODE */ 6437 page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PAGE_CODE_MASK); 6438 6439 6440 TI_DBG5(("satModeSense6: page=0x%x, tiDeviceHandle=%p tiIORequest=%p\n", 6441 page, tiDeviceHandle, tiIORequest)); 6442 6443 requestLen = scsiCmnd->cdb[4]; 6444 6445 /* 6446 Based on page code value, returns a corresponding mode page 6447 note: no support for subpage 6448 */ 6449 6450 switch(page) 6451 { 6452 case MODESENSE_RETURN_ALL_PAGES: 6453 case MODESENSE_CONTROL_PAGE: /* control */ 6454 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */ 6455 case MODESENSE_CACHING: /* caching */ 6456 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/ 6457 pageSupported = agTRUE; 6458 break; 6459 case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */ 6460 default: 6461 pageSupported = agFALSE; 6462 break; 6463 } 6464 6465 if (pageSupported == agFALSE) 6466 { 6467 6468 TI_DBG1(("satModeSense6 *** ERROR *** not supported page 0x%x tiDeviceHandle=%p tiIORequest=%p\n", 6469 page, tiDeviceHandle, tiIORequest)); 6470 6471 satSetSensePayload( pSense, 6472 SCSI_SNSKEY_ILLEGAL_REQUEST, 6473 0, 6474 SCSI_SNSCODE_INVALID_COMMAND, 6475 satIOContext); 6476 6477 ostiInitiatorIOCompleted( tiRoot, 6478 tiIORequest, 6479 tiIOSuccess, 6480 SCSI_STAT_CHECK_CONDITION, 6481 satIOContext->pTiSenseData, 6482 satIOContext->interruptContext ); 6483 return tiSuccess; 6484 } 6485 6486 switch(page) 6487 { 6488 case MODESENSE_RETURN_ALL_PAGES: 6489 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_RETURN_ALL_PAGES_LEN); 6490 break; 6491 case MODESENSE_CONTROL_PAGE: /* control */ 6492 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_CONTROL_PAGE_LEN); 6493 break; 6494 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */ 6495 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN); 6496 break; 6497 case MODESENSE_CACHING: /* caching */ 6498 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_CACHING_LEN); 6499 break; 6500 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/ 6501 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN); 6502 break; 6503 default: 6504 TI_DBG1(("satModeSense6: default error page %d\n", page)); 6505 break; 6506 } 6507 6508 if (page == MODESENSE_RETURN_ALL_PAGES) 6509 { 6510 TI_DBG5(("satModeSense6: MODESENSE_RETURN_ALL_PAGES\n")); 6511 AllPages[0] = (bit8)(lenRead - 1); 6512 AllPages[1] = 0x00; /* default medium type (currently mounted medium type) */ 6513 AllPages[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 6514 AllPages[3] = 0x08; /* block descriptor length */ 6515 6516 /* 6517 * Fill-up direct-access device block-descriptor, SAT, Table 19 6518 */ 6519 6520 /* density code */ 6521 AllPages[4] = 0x04; /* density-code : reserved for direct-access */ 6522 /* number of blocks */ 6523 AllPages[5] = 0x00; /* unspecified */ 6524 AllPages[6] = 0x00; /* unspecified */ 6525 AllPages[7] = 0x00; /* unspecified */ 6526 /* reserved */ 6527 AllPages[8] = 0x00; /* reserved */ 6528 /* Block size */ 6529 AllPages[9] = 0x00; 6530 AllPages[10] = 0x02; /* Block size is always 512 bytes */ 6531 AllPages[11] = 0x00; 6532 6533 /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */ 6534 AllPages[12] = 0x01; /* page code */ 6535 AllPages[13] = 0x0A; /* page length */ 6536 AllPages[14] = 0x40; /* ARRE is set */ 6537 AllPages[15] = 0x00; 6538 AllPages[16] = 0x00; 6539 AllPages[17] = 0x00; 6540 AllPages[18] = 0x00; 6541 AllPages[19] = 0x00; 6542 AllPages[20] = 0x00; 6543 AllPages[21] = 0x00; 6544 AllPages[22] = 0x00; 6545 AllPages[23] = 0x00; 6546 /* MODESENSE_CACHING */ 6547 AllPages[24] = 0x08; /* page code */ 6548 AllPages[25] = 0x12; /* page length */ 6549 #ifdef NOT_YET 6550 if (pSatDevData->satWriteCacheEnabled == agTRUE) 6551 { 6552 AllPages[26] = 0x04;/* WCE bit is set */ 6553 } 6554 else 6555 { 6556 AllPages[26] = 0x00;/* WCE bit is NOT set */ 6557 } 6558 #endif 6559 AllPages[26] = 0x00;/* WCE bit is NOT set */ 6560 6561 AllPages[27] = 0x00; 6562 AllPages[28] = 0x00; 6563 AllPages[29] = 0x00; 6564 AllPages[30] = 0x00; 6565 AllPages[31] = 0x00; 6566 AllPages[32] = 0x00; 6567 AllPages[33] = 0x00; 6568 AllPages[34] = 0x00; 6569 AllPages[35] = 0x00; 6570 if (pSatDevData->satLookAheadEnabled == agTRUE) 6571 { 6572 AllPages[36] = 0x00;/* DRA bit is NOT set */ 6573 } 6574 else 6575 { 6576 AllPages[36] = 0x20;/* DRA bit is set */ 6577 } 6578 AllPages[37] = 0x00; 6579 AllPages[38] = 0x00; 6580 AllPages[39] = 0x00; 6581 AllPages[40] = 0x00; 6582 AllPages[41] = 0x00; 6583 AllPages[42] = 0x00; 6584 AllPages[43] = 0x00; 6585 /* MODESENSE_CONTROL_PAGE */ 6586 AllPages[44] = 0x0A; /* page code */ 6587 AllPages[45] = 0x0A; /* page length */ 6588 AllPages[46] = 0x02; /* only GLTSD bit is set */ 6589 if (pSatDevData->satNCQ == agTRUE) 6590 { 6591 AllPages[47] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/ 6592 } 6593 else 6594 { 6595 AllPages[47] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */ 6596 } 6597 AllPages[48] = 0x00; 6598 AllPages[49] = 0x00; 6599 AllPages[50] = 0x00; /* obsolete */ 6600 AllPages[51] = 0x00; /* obsolete */ 6601 AllPages[52] = 0xFF; /* Busy Timeout Period */ 6602 AllPages[53] = 0xFF; /* Busy Timeout Period */ 6603 AllPages[54] = 0x00; /* we don't support non-000b value for the self-test code */ 6604 AllPages[55] = 0x00; /* we don't support non-000b value for the self-test code */ 6605 /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */ 6606 AllPages[56] = 0x1C; /* page code */ 6607 AllPages[57] = 0x0A; /* page length */ 6608 if (pSatDevData->satSMARTEnabled == agTRUE) 6609 { 6610 AllPages[58] = 0x00;/* DEXCPT bit is NOT set */ 6611 } 6612 else 6613 { 6614 AllPages[58] = 0x08;/* DEXCPT bit is set */ 6615 } 6616 AllPages[59] = 0x00; /* We don't support MRIE */ 6617 AllPages[60] = 0x00; /* Interval timer vendor-specific */ 6618 AllPages[61] = 0x00; 6619 AllPages[62] = 0x00; 6620 AllPages[63] = 0x00; 6621 AllPages[64] = 0x00; /* REPORT-COUNT */ 6622 AllPages[65] = 0x00; 6623 AllPages[66] = 0x00; 6624 AllPages[67] = 0x00; 6625 6626 osti_memcpy(pModeSense, &AllPages, lenRead); 6627 } 6628 else if (page == MODESENSE_CONTROL_PAGE) 6629 { 6630 TI_DBG5(("satModeSense6: MODESENSE_CONTROL_PAGE\n")); 6631 Control[0] = MODE_SENSE6_CONTROL_PAGE_LEN - 1; 6632 Control[1] = 0x00; /* default medium type (currently mounted medium type) */ 6633 Control[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 6634 Control[3] = 0x08; /* block descriptor length */ 6635 /* 6636 * Fill-up direct-access device block-descriptor, SAT, Table 19 6637 */ 6638 6639 /* density code */ 6640 Control[4] = 0x04; /* density-code : reserved for direct-access */ 6641 /* number of blocks */ 6642 Control[5] = 0x00; /* unspecified */ 6643 Control[6] = 0x00; /* unspecified */ 6644 Control[7] = 0x00; /* unspecified */ 6645 /* reserved */ 6646 Control[8] = 0x00; /* reserved */ 6647 /* Block size */ 6648 Control[9] = 0x00; 6649 Control[10] = 0x02; /* Block size is always 512 bytes */ 6650 Control[11] = 0x00; 6651 /* 6652 * Fill-up control mode page, SAT, Table 65 6653 */ 6654 Control[12] = 0x0A; /* page code */ 6655 Control[13] = 0x0A; /* page length */ 6656 Control[14] = 0x02; /* only GLTSD bit is set */ 6657 if (pSatDevData->satNCQ == agTRUE) 6658 { 6659 Control[15] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/ 6660 } 6661 else 6662 { 6663 Control[15] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */ 6664 } 6665 Control[16] = 0x00; 6666 Control[17] = 0x00; 6667 Control[18] = 0x00; /* obsolete */ 6668 Control[19] = 0x00; /* obsolete */ 6669 Control[20] = 0xFF; /* Busy Timeout Period */ 6670 Control[21] = 0xFF; /* Busy Timeout Period */ 6671 Control[22] = 0x00; /* we don't support non-000b value for the self-test code */ 6672 Control[23] = 0x00; /* we don't support non-000b value for the self-test code */ 6673 6674 osti_memcpy(pModeSense, &Control, lenRead); 6675 6676 } 6677 else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE) 6678 { 6679 TI_DBG5(("satModeSense6: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n")); 6680 RWErrorRecovery[0] = MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN - 1; 6681 RWErrorRecovery[1] = 0x00; /* default medium type (currently mounted medium type) */ 6682 RWErrorRecovery[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 6683 RWErrorRecovery[3] = 0x08; /* block descriptor length */ 6684 /* 6685 * Fill-up direct-access device block-descriptor, SAT, Table 19 6686 */ 6687 6688 /* density code */ 6689 RWErrorRecovery[4] = 0x04; /* density-code : reserved for direct-access */ 6690 /* number of blocks */ 6691 RWErrorRecovery[5] = 0x00; /* unspecified */ 6692 RWErrorRecovery[6] = 0x00; /* unspecified */ 6693 RWErrorRecovery[7] = 0x00; /* unspecified */ 6694 /* reserved */ 6695 RWErrorRecovery[8] = 0x00; /* reserved */ 6696 /* Block size */ 6697 RWErrorRecovery[9] = 0x00; 6698 RWErrorRecovery[10] = 0x02; /* Block size is always 512 bytes */ 6699 RWErrorRecovery[11] = 0x00; 6700 /* 6701 * Fill-up Read-Write Error Recovery mode page, SAT, Table 66 6702 */ 6703 RWErrorRecovery[12] = 0x01; /* page code */ 6704 RWErrorRecovery[13] = 0x0A; /* page length */ 6705 RWErrorRecovery[14] = 0x40; /* ARRE is set */ 6706 RWErrorRecovery[15] = 0x00; 6707 RWErrorRecovery[16] = 0x00; 6708 RWErrorRecovery[17] = 0x00; 6709 RWErrorRecovery[18] = 0x00; 6710 RWErrorRecovery[19] = 0x00; 6711 RWErrorRecovery[20] = 0x00; 6712 RWErrorRecovery[21] = 0x00; 6713 RWErrorRecovery[22] = 0x00; 6714 RWErrorRecovery[23] = 0x00; 6715 6716 osti_memcpy(pModeSense, &RWErrorRecovery, lenRead); 6717 6718 } 6719 else if (page == MODESENSE_CACHING) 6720 { 6721 TI_DBG5(("satModeSense6: MODESENSE_CACHING\n")); 6722 /* special case */ 6723 if (requestLen == 4 && page == MODESENSE_CACHING) 6724 { 6725 TI_DBG5(("satModeSense6: linux 2.6.8.24 support\n")); 6726 6727 pModeSense[0] = 0x20 - 1; /* 32 - 1 */ 6728 pModeSense[1] = 0x00; /* default medium type (currently mounted medium type) */ 6729 pModeSense[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 6730 pModeSense[3] = 0x08; /* block descriptor length */ 6731 ostiInitiatorIOCompleted( tiRoot, 6732 tiIORequest, 6733 tiIOSuccess, 6734 SCSI_STAT_GOOD, 6735 agNULL, 6736 satIOContext->interruptContext); 6737 return tiSuccess; 6738 } 6739 Caching[0] = MODE_SENSE6_CACHING_LEN - 1; 6740 Caching[1] = 0x00; /* default medium type (currently mounted medium type) */ 6741 Caching[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 6742 Caching[3] = 0x08; /* block descriptor length */ 6743 /* 6744 * Fill-up direct-access device block-descriptor, SAT, Table 19 6745 */ 6746 6747 /* density code */ 6748 Caching[4] = 0x04; /* density-code : reserved for direct-access */ 6749 /* number of blocks */ 6750 Caching[5] = 0x00; /* unspecified */ 6751 Caching[6] = 0x00; /* unspecified */ 6752 Caching[7] = 0x00; /* unspecified */ 6753 /* reserved */ 6754 Caching[8] = 0x00; /* reserved */ 6755 /* Block size */ 6756 Caching[9] = 0x00; 6757 Caching[10] = 0x02; /* Block size is always 512 bytes */ 6758 Caching[11] = 0x00; 6759 /* 6760 * Fill-up Caching mode page, SAT, Table 67 6761 */ 6762 /* length 20 */ 6763 Caching[12] = 0x08; /* page code */ 6764 Caching[13] = 0x12; /* page length */ 6765 #ifdef NOT_YET 6766 if (pSatDevData->satWriteCacheEnabled == agTRUE) 6767 { 6768 Caching[14] = 0x04;/* WCE bit is set */ 6769 } 6770 else 6771 { 6772 Caching[14] = 0x00;/* WCE bit is NOT set */ 6773 } 6774 #endif 6775 Caching[14] = 0x00;/* WCE bit is NOT set */ 6776 6777 Caching[15] = 0x00; 6778 Caching[16] = 0x00; 6779 Caching[17] = 0x00; 6780 Caching[18] = 0x00; 6781 Caching[19] = 0x00; 6782 Caching[20] = 0x00; 6783 Caching[21] = 0x00; 6784 Caching[22] = 0x00; 6785 Caching[23] = 0x00; 6786 if (pSatDevData->satLookAheadEnabled == agTRUE) 6787 { 6788 Caching[24] = 0x00;/* DRA bit is NOT set */ 6789 } 6790 else 6791 { 6792 Caching[24] = 0x20;/* DRA bit is set */ 6793 } 6794 Caching[25] = 0x00; 6795 Caching[26] = 0x00; 6796 Caching[27] = 0x00; 6797 Caching[28] = 0x00; 6798 Caching[29] = 0x00; 6799 Caching[30] = 0x00; 6800 Caching[31] = 0x00; 6801 6802 osti_memcpy(pModeSense, &Caching, lenRead); 6803 6804 } 6805 else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE) 6806 { 6807 TI_DBG5(("satModeSense6: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n")); 6808 InfoExceptionCtrl[0] = MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN - 1; 6809 InfoExceptionCtrl[1] = 0x00; /* default medium type (currently mounted medium type) */ 6810 InfoExceptionCtrl[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 6811 InfoExceptionCtrl[3] = 0x08; /* block descriptor length */ 6812 /* 6813 * Fill-up direct-access device block-descriptor, SAT, Table 19 6814 */ 6815 6816 /* density code */ 6817 InfoExceptionCtrl[4] = 0x04; /* density-code : reserved for direct-access */ 6818 /* number of blocks */ 6819 InfoExceptionCtrl[5] = 0x00; /* unspecified */ 6820 InfoExceptionCtrl[6] = 0x00; /* unspecified */ 6821 InfoExceptionCtrl[7] = 0x00; /* unspecified */ 6822 /* reserved */ 6823 InfoExceptionCtrl[8] = 0x00; /* reserved */ 6824 /* Block size */ 6825 InfoExceptionCtrl[9] = 0x00; 6826 InfoExceptionCtrl[10] = 0x02; /* Block size is always 512 bytes */ 6827 InfoExceptionCtrl[11] = 0x00; 6828 /* 6829 * Fill-up informational-exceptions control mode page, SAT, Table 68 6830 */ 6831 InfoExceptionCtrl[12] = 0x1C; /* page code */ 6832 InfoExceptionCtrl[13] = 0x0A; /* page length */ 6833 if (pSatDevData->satSMARTEnabled == agTRUE) 6834 { 6835 InfoExceptionCtrl[14] = 0x00;/* DEXCPT bit is NOT set */ 6836 } 6837 else 6838 { 6839 InfoExceptionCtrl[14] = 0x08;/* DEXCPT bit is set */ 6840 } 6841 InfoExceptionCtrl[15] = 0x00; /* We don't support MRIE */ 6842 InfoExceptionCtrl[16] = 0x00; /* Interval timer vendor-specific */ 6843 InfoExceptionCtrl[17] = 0x00; 6844 InfoExceptionCtrl[18] = 0x00; 6845 InfoExceptionCtrl[19] = 0x00; 6846 InfoExceptionCtrl[20] = 0x00; /* REPORT-COUNT */ 6847 InfoExceptionCtrl[21] = 0x00; 6848 InfoExceptionCtrl[22] = 0x00; 6849 InfoExceptionCtrl[23] = 0x00; 6850 osti_memcpy(pModeSense, &InfoExceptionCtrl, lenRead); 6851 6852 } 6853 else 6854 { 6855 /* Error */ 6856 TI_DBG1(("satModeSense6: Error page %d\n", page)); 6857 satSetSensePayload( pSense, 6858 SCSI_SNSKEY_ILLEGAL_REQUEST, 6859 0, 6860 SCSI_SNSCODE_INVALID_COMMAND, 6861 satIOContext); 6862 6863 ostiInitiatorIOCompleted( tiRoot, 6864 tiIORequest, 6865 tiIOSuccess, 6866 SCSI_STAT_CHECK_CONDITION, 6867 satIOContext->pTiSenseData, 6868 satIOContext->interruptContext ); 6869 return tiSuccess; 6870 } 6871 6872 /* there can be only underrun not overrun in error case */ 6873 if (requestLen > lenRead) 6874 { 6875 TI_DBG6(("satModeSense6 reporting underrun lenRead=0x%x requestLen=0x%x tiIORequest=%p\n", lenRead, requestLen, tiIORequest)); 6876 6877 ostiInitiatorIOCompleted( tiRoot, 6878 tiIORequest, 6879 tiIOUnderRun, 6880 requestLen - lenRead, 6881 agNULL, 6882 satIOContext->interruptContext ); 6883 6884 6885 } 6886 else 6887 { 6888 ostiInitiatorIOCompleted( tiRoot, 6889 tiIORequest, 6890 tiIOSuccess, 6891 SCSI_STAT_GOOD, 6892 agNULL, 6893 satIOContext->interruptContext); 6894 } 6895 6896 return tiSuccess; 6897 6898 } 6899 6900 /*****************************************************************************/ 6901 /*! \brief SAT implementation for SCSI MODE SENSE (10). 6902 * 6903 * SAT implementation for SCSI MODE SENSE (10). 6904 * 6905 * \param tiRoot: Pointer to TISA initiator driver/port instance. 6906 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 6907 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 6908 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 6909 * \param satIOContext_t: Pointer to the SAT IO Context 6910 * 6911 * \return If command is started successfully 6912 * - \e tiSuccess: I/O request successfully initiated. 6913 * - \e tiBusy: No resources available, try again later. 6914 * - \e tiIONoDevice: Invalid device handle. 6915 * - \e tiError: Other errors. 6916 */ 6917 /*****************************************************************************/ 6918 GLOBAL bit32 satModeSense10( 6919 tiRoot_t *tiRoot, 6920 tiIORequest_t *tiIORequest, 6921 tiDeviceHandle_t *tiDeviceHandle, 6922 tiScsiInitiatorRequest_t *tiScsiRequest, 6923 satIOContext_t *satIOContext) 6924 { 6925 6926 scsiRspSense_t *pSense; 6927 bit32 requestLen; 6928 tiIniScsiCmnd_t *scsiCmnd; 6929 bit32 pageSupported; 6930 bit8 page; 6931 bit8 *pModeSense; /* Mode Sense data buffer */ 6932 satDeviceData_t *pSatDevData; 6933 bit8 PC; /* page control */ 6934 bit8 LLBAA; /* Long LBA Accepted */ 6935 bit32 index; 6936 bit8 AllPages[MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN]; 6937 bit8 Control[MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN]; 6938 bit8 RWErrorRecovery[MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN]; 6939 bit8 Caching[MODE_SENSE10_CACHING_LLBAA_LEN]; 6940 bit8 InfoExceptionCtrl[MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN]; 6941 bit8 lenRead = 0; 6942 6943 TI_DBG5(("satModeSense10 entry: tiDeviceHandle=%p tiIORequest=%p\n", 6944 tiDeviceHandle, tiIORequest)); 6945 6946 pSense = satIOContext->pSense; 6947 scsiCmnd = &tiScsiRequest->scsiCmnd; 6948 pModeSense = (bit8 *) tiScsiRequest->sglVirtualAddr; 6949 pSatDevData = satIOContext->pSatDevData; 6950 6951 /* checking CONTROL */ 6952 /* NACA == 1 or LINK == 1*/ 6953 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 6954 { 6955 satSetSensePayload( pSense, 6956 SCSI_SNSKEY_ILLEGAL_REQUEST, 6957 0, 6958 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6959 satIOContext); 6960 6961 ostiInitiatorIOCompleted( tiRoot, 6962 tiIORequest, 6963 tiIOSuccess, 6964 SCSI_STAT_CHECK_CONDITION, 6965 satIOContext->pTiSenseData, 6966 satIOContext->interruptContext ); 6967 6968 TI_DBG2(("satModeSense10: return control\n")); 6969 return tiSuccess; 6970 } 6971 6972 /* checking PC(Page Control) 6973 SAT revion 8, 8.5.3 p33 and 10.1.2, p66 6974 */ 6975 PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PC_MASK); 6976 if (PC != 0) 6977 { 6978 satSetSensePayload( pSense, 6979 SCSI_SNSKEY_ILLEGAL_REQUEST, 6980 0, 6981 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6982 satIOContext); 6983 6984 ostiInitiatorIOCompleted( tiRoot, 6985 tiIORequest, 6986 tiIOSuccess, 6987 SCSI_STAT_CHECK_CONDITION, 6988 satIOContext->pTiSenseData, 6989 satIOContext->interruptContext ); 6990 6991 TI_DBG1(("satModeSense10: return due to PC value pc 0x%x\n", PC)); 6992 return tiSuccess; 6993 } 6994 /* finding LLBAA bit */ 6995 LLBAA = (bit8)((scsiCmnd->cdb[1]) & SCSI_MODE_SENSE10_LLBAA_MASK); 6996 /* reading PAGE CODE */ 6997 page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PAGE_CODE_MASK); 6998 6999 TI_DBG5(("satModeSense10: page=0x%x, tiDeviceHandle=%p tiIORequest=%p\n", 7000 page, tiDeviceHandle, tiIORequest)); 7001 requestLen = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 7002 7003 /* 7004 Based on page code value, returns a corresponding mode page 7005 note: no support for subpage 7006 */ 7007 switch(page) 7008 { 7009 case MODESENSE_RETURN_ALL_PAGES: /* return all pages */ 7010 case MODESENSE_CONTROL_PAGE: /* control */ 7011 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */ 7012 case MODESENSE_CACHING: /* caching */ 7013 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/ 7014 pageSupported = agTRUE; 7015 break; 7016 case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */ 7017 default: 7018 pageSupported = agFALSE; 7019 break; 7020 } 7021 7022 if (pageSupported == agFALSE) 7023 { 7024 7025 TI_DBG1(("satModeSense10 *** ERROR *** not supported page 0x%x tiDeviceHandle=%p tiIORequest=%p\n", 7026 page, tiDeviceHandle, tiIORequest)); 7027 7028 satSetSensePayload( pSense, 7029 SCSI_SNSKEY_ILLEGAL_REQUEST, 7030 0, 7031 SCSI_SNSCODE_INVALID_COMMAND, 7032 satIOContext); 7033 7034 ostiInitiatorIOCompleted( tiRoot, 7035 tiIORequest, 7036 tiIOSuccess, 7037 SCSI_STAT_CHECK_CONDITION, 7038 satIOContext->pTiSenseData, 7039 satIOContext->interruptContext ); 7040 return tiSuccess; 7041 } 7042 7043 switch(page) 7044 { 7045 case MODESENSE_RETURN_ALL_PAGES: 7046 if (LLBAA) 7047 { 7048 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN); 7049 } 7050 else 7051 { 7052 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_RETURN_ALL_PAGES_LEN); 7053 } 7054 break; 7055 case MODESENSE_CONTROL_PAGE: /* control */ 7056 if (LLBAA) 7057 { 7058 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN); 7059 } 7060 else 7061 { 7062 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CONTROL_PAGE_LEN); 7063 } 7064 break; 7065 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */ 7066 if (LLBAA) 7067 { 7068 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN); 7069 } 7070 else 7071 { 7072 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LEN); 7073 } 7074 break; 7075 case MODESENSE_CACHING: /* caching */ 7076 if (LLBAA) 7077 { 7078 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CACHING_LLBAA_LEN); 7079 } 7080 else 7081 { 7082 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CACHING_LEN); 7083 } 7084 break; 7085 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/ 7086 if (LLBAA) 7087 { 7088 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN); 7089 } 7090 else 7091 { 7092 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN); 7093 } 7094 break; 7095 default: 7096 TI_DBG1(("satModeSense10: default error page %d\n", page)); 7097 break; 7098 } 7099 7100 if (page == MODESENSE_RETURN_ALL_PAGES) 7101 { 7102 TI_DBG5(("satModeSense10: MODESENSE_RETURN_ALL_PAGES\n")); 7103 AllPages[0] = 0; 7104 AllPages[1] = (bit8)(lenRead - 2); 7105 AllPages[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */ 7106 AllPages[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */ 7107 if (LLBAA) 7108 { 7109 AllPages[4] = 0x00; /* reserved and LONGLBA */ 7110 AllPages[4] = (bit8)(AllPages[4] | 0x1); /* LONGLBA is set */ 7111 } 7112 else 7113 { 7114 AllPages[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */ 7115 } 7116 AllPages[5] = 0x00; /* reserved */ 7117 AllPages[6] = 0x00; /* block descriptot length */ 7118 if (LLBAA) 7119 { 7120 AllPages[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */ 7121 } 7122 else 7123 { 7124 AllPages[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */ 7125 } 7126 7127 /* 7128 * Fill-up direct-access device block-descriptor, SAT, Table 19 7129 */ 7130 7131 if (LLBAA) 7132 { 7133 /* density code */ 7134 AllPages[8] = 0x04; /* density-code : reserved for direct-access */ 7135 /* number of blocks */ 7136 AllPages[9] = 0x00; /* unspecified */ 7137 AllPages[10] = 0x00; /* unspecified */ 7138 AllPages[11] = 0x00; /* unspecified */ 7139 AllPages[12] = 0x00; /* unspecified */ 7140 AllPages[13] = 0x00; /* unspecified */ 7141 AllPages[14] = 0x00; /* unspecified */ 7142 AllPages[15] = 0x00; /* unspecified */ 7143 /* reserved */ 7144 AllPages[16] = 0x00; /* reserved */ 7145 AllPages[17] = 0x00; /* reserved */ 7146 AllPages[18] = 0x00; /* reserved */ 7147 AllPages[19] = 0x00; /* reserved */ 7148 /* Block size */ 7149 AllPages[20] = 0x00; 7150 AllPages[21] = 0x00; 7151 AllPages[22] = 0x02; /* Block size is always 512 bytes */ 7152 AllPages[23] = 0x00; 7153 } 7154 else 7155 { 7156 /* density code */ 7157 AllPages[8] = 0x04; /* density-code : reserved for direct-access */ 7158 /* number of blocks */ 7159 AllPages[9] = 0x00; /* unspecified */ 7160 AllPages[10] = 0x00; /* unspecified */ 7161 AllPages[11] = 0x00; /* unspecified */ 7162 /* reserved */ 7163 AllPages[12] = 0x00; /* reserved */ 7164 /* Block size */ 7165 AllPages[13] = 0x00; 7166 AllPages[14] = 0x02; /* Block size is always 512 bytes */ 7167 AllPages[15] = 0x00; 7168 } 7169 7170 if (LLBAA) 7171 { 7172 index = 24; 7173 } 7174 else 7175 { 7176 index = 16; 7177 } 7178 /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */ 7179 AllPages[index+0] = 0x01; /* page code */ 7180 AllPages[index+1] = 0x0A; /* page length */ 7181 AllPages[index+2] = 0x40; /* ARRE is set */ 7182 AllPages[index+3] = 0x00; 7183 AllPages[index+4] = 0x00; 7184 AllPages[index+5] = 0x00; 7185 AllPages[index+6] = 0x00; 7186 AllPages[index+7] = 0x00; 7187 AllPages[index+8] = 0x00; 7188 AllPages[index+9] = 0x00; 7189 AllPages[index+10] = 0x00; 7190 AllPages[index+11] = 0x00; 7191 7192 /* MODESENSE_CACHING */ 7193 /* 7194 * Fill-up Caching mode page, SAT, Table 67 7195 */ 7196 /* length 20 */ 7197 AllPages[index+12] = 0x08; /* page code */ 7198 AllPages[index+13] = 0x12; /* page length */ 7199 #ifdef NOT_YET 7200 if (pSatDevData->satWriteCacheEnabled == agTRUE) 7201 { 7202 AllPages[index+14] = 0x04;/* WCE bit is set */ 7203 } 7204 else 7205 { 7206 AllPages[index+14] = 0x00;/* WCE bit is NOT set */ 7207 } 7208 #endif 7209 AllPages[index+14] = 0x00;/* WCE bit is NOT set */ 7210 AllPages[index+15] = 0x00; 7211 AllPages[index+16] = 0x00; 7212 AllPages[index+17] = 0x00; 7213 AllPages[index+18] = 0x00; 7214 AllPages[index+19] = 0x00; 7215 AllPages[index+20] = 0x00; 7216 AllPages[index+21] = 0x00; 7217 AllPages[index+22] = 0x00; 7218 AllPages[index+23] = 0x00; 7219 if (pSatDevData->satLookAheadEnabled == agTRUE) 7220 { 7221 AllPages[index+24] = 0x00;/* DRA bit is NOT set */ 7222 } 7223 else 7224 { 7225 AllPages[index+24] = 0x20;/* DRA bit is set */ 7226 } 7227 AllPages[index+25] = 0x00; 7228 AllPages[index+26] = 0x00; 7229 AllPages[index+27] = 0x00; 7230 AllPages[index+28] = 0x00; 7231 AllPages[index+29] = 0x00; 7232 AllPages[index+30] = 0x00; 7233 AllPages[index+31] = 0x00; 7234 7235 /* MODESENSE_CONTROL_PAGE */ 7236 /* 7237 * Fill-up control mode page, SAT, Table 65 7238 */ 7239 AllPages[index+32] = 0x0A; /* page code */ 7240 AllPages[index+33] = 0x0A; /* page length */ 7241 AllPages[index+34] = 0x02; /* only GLTSD bit is set */ 7242 if (pSatDevData->satNCQ == agTRUE) 7243 { 7244 AllPages[index+35] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/ 7245 } 7246 else 7247 { 7248 AllPages[index+35] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */ 7249 } 7250 AllPages[index+36] = 0x00; 7251 AllPages[index+37] = 0x00; 7252 AllPages[index+38] = 0x00; /* obsolete */ 7253 AllPages[index+39] = 0x00; /* obsolete */ 7254 AllPages[index+40] = 0xFF; /* Busy Timeout Period */ 7255 AllPages[index+41] = 0xFF; /* Busy Timeout Period */ 7256 AllPages[index+42] = 0x00; /* we don't support non-000b value for the self-test code */ 7257 AllPages[index+43] = 0x00; /* we don't support non-000b value for the self-test code */ 7258 7259 /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */ 7260 /* 7261 * Fill-up informational-exceptions control mode page, SAT, Table 68 7262 */ 7263 AllPages[index+44] = 0x1C; /* page code */ 7264 AllPages[index+45] = 0x0A; /* page length */ 7265 if (pSatDevData->satSMARTEnabled == agTRUE) 7266 { 7267 AllPages[index+46] = 0x00;/* DEXCPT bit is NOT set */ 7268 } 7269 else 7270 { 7271 AllPages[index+46] = 0x08;/* DEXCPT bit is set */ 7272 } 7273 AllPages[index+47] = 0x00; /* We don't support MRIE */ 7274 AllPages[index+48] = 0x00; /* Interval timer vendor-specific */ 7275 AllPages[index+49] = 0x00; 7276 AllPages[index+50] = 0x00; 7277 AllPages[index+51] = 0x00; 7278 AllPages[index+52] = 0x00; /* REPORT-COUNT */ 7279 AllPages[index+53] = 0x00; 7280 AllPages[index+54] = 0x00; 7281 AllPages[index+55] = 0x00; 7282 7283 osti_memcpy(pModeSense, &AllPages, lenRead); 7284 } 7285 else if (page == MODESENSE_CONTROL_PAGE) 7286 { 7287 TI_DBG5(("satModeSense10: MODESENSE_CONTROL_PAGE\n")); 7288 Control[0] = 0; 7289 Control[1] = (bit8)(lenRead - 2); 7290 Control[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */ 7291 Control[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */ 7292 if (LLBAA) 7293 { 7294 Control[4] = 0x00; /* reserved and LONGLBA */ 7295 Control[4] = (bit8)(Control[4] | 0x1); /* LONGLBA is set */ 7296 } 7297 else 7298 { 7299 Control[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */ 7300 } 7301 Control[5] = 0x00; /* reserved */ 7302 Control[6] = 0x00; /* block descriptot length */ 7303 if (LLBAA) 7304 { 7305 Control[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */ 7306 } 7307 else 7308 { 7309 Control[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */ 7310 } 7311 7312 /* 7313 * Fill-up direct-access device block-descriptor, SAT, Table 19 7314 */ 7315 7316 if (LLBAA) 7317 { 7318 /* density code */ 7319 Control[8] = 0x04; /* density-code : reserved for direct-access */ 7320 /* number of blocks */ 7321 Control[9] = 0x00; /* unspecified */ 7322 Control[10] = 0x00; /* unspecified */ 7323 Control[11] = 0x00; /* unspecified */ 7324 Control[12] = 0x00; /* unspecified */ 7325 Control[13] = 0x00; /* unspecified */ 7326 Control[14] = 0x00; /* unspecified */ 7327 Control[15] = 0x00; /* unspecified */ 7328 /* reserved */ 7329 Control[16] = 0x00; /* reserved */ 7330 Control[17] = 0x00; /* reserved */ 7331 Control[18] = 0x00; /* reserved */ 7332 Control[19] = 0x00; /* reserved */ 7333 /* Block size */ 7334 Control[20] = 0x00; 7335 Control[21] = 0x00; 7336 Control[22] = 0x02; /* Block size is always 512 bytes */ 7337 Control[23] = 0x00; 7338 } 7339 else 7340 { 7341 /* density code */ 7342 Control[8] = 0x04; /* density-code : reserved for direct-access */ 7343 /* number of blocks */ 7344 Control[9] = 0x00; /* unspecified */ 7345 Control[10] = 0x00; /* unspecified */ 7346 Control[11] = 0x00; /* unspecified */ 7347 /* reserved */ 7348 Control[12] = 0x00; /* reserved */ 7349 /* Block size */ 7350 Control[13] = 0x00; 7351 Control[14] = 0x02; /* Block size is always 512 bytes */ 7352 Control[15] = 0x00; 7353 } 7354 7355 if (LLBAA) 7356 { 7357 index = 24; 7358 } 7359 else 7360 { 7361 index = 16; 7362 } 7363 /* 7364 * Fill-up control mode page, SAT, Table 65 7365 */ 7366 Control[index+0] = 0x0A; /* page code */ 7367 Control[index+1] = 0x0A; /* page length */ 7368 Control[index+2] = 0x02; /* only GLTSD bit is set */ 7369 if (pSatDevData->satNCQ == agTRUE) 7370 { 7371 Control[index+3] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/ 7372 } 7373 else 7374 { 7375 Control[index+3] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */ 7376 } 7377 Control[index+4] = 0x00; 7378 Control[index+5] = 0x00; 7379 Control[index+6] = 0x00; /* obsolete */ 7380 Control[index+7] = 0x00; /* obsolete */ 7381 Control[index+8] = 0xFF; /* Busy Timeout Period */ 7382 Control[index+9] = 0xFF; /* Busy Timeout Period */ 7383 Control[index+10] = 0x00; /* we don't support non-000b value for the self-test code */ 7384 Control[index+11] = 0x00; /* we don't support non-000b value for the self-test code */ 7385 7386 osti_memcpy(pModeSense, &Control, lenRead); 7387 } 7388 else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE) 7389 { 7390 TI_DBG5(("satModeSense10: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n")); 7391 RWErrorRecovery[0] = 0; 7392 RWErrorRecovery[1] = (bit8)(lenRead - 2); 7393 RWErrorRecovery[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */ 7394 RWErrorRecovery[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */ 7395 if (LLBAA) 7396 { 7397 RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA */ 7398 RWErrorRecovery[4] = (bit8)(RWErrorRecovery[4] | 0x1); /* LONGLBA is set */ 7399 } 7400 else 7401 { 7402 RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */ 7403 } 7404 RWErrorRecovery[5] = 0x00; /* reserved */ 7405 RWErrorRecovery[6] = 0x00; /* block descriptot length */ 7406 if (LLBAA) 7407 { 7408 RWErrorRecovery[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */ 7409 } 7410 else 7411 { 7412 RWErrorRecovery[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */ 7413 } 7414 7415 /* 7416 * Fill-up direct-access device block-descriptor, SAT, Table 19 7417 */ 7418 7419 if (LLBAA) 7420 { 7421 /* density code */ 7422 RWErrorRecovery[8] = 0x04; /* density-code : reserved for direct-access */ 7423 /* number of blocks */ 7424 RWErrorRecovery[9] = 0x00; /* unspecified */ 7425 RWErrorRecovery[10] = 0x00; /* unspecified */ 7426 RWErrorRecovery[11] = 0x00; /* unspecified */ 7427 RWErrorRecovery[12] = 0x00; /* unspecified */ 7428 RWErrorRecovery[13] = 0x00; /* unspecified */ 7429 RWErrorRecovery[14] = 0x00; /* unspecified */ 7430 RWErrorRecovery[15] = 0x00; /* unspecified */ 7431 /* reserved */ 7432 RWErrorRecovery[16] = 0x00; /* reserved */ 7433 RWErrorRecovery[17] = 0x00; /* reserved */ 7434 RWErrorRecovery[18] = 0x00; /* reserved */ 7435 RWErrorRecovery[19] = 0x00; /* reserved */ 7436 /* Block size */ 7437 RWErrorRecovery[20] = 0x00; 7438 RWErrorRecovery[21] = 0x00; 7439 RWErrorRecovery[22] = 0x02; /* Block size is always 512 bytes */ 7440 RWErrorRecovery[23] = 0x00; 7441 } 7442 else 7443 { 7444 /* density code */ 7445 RWErrorRecovery[8] = 0x04; /* density-code : reserved for direct-access */ 7446 /* number of blocks */ 7447 RWErrorRecovery[9] = 0x00; /* unspecified */ 7448 RWErrorRecovery[10] = 0x00; /* unspecified */ 7449 RWErrorRecovery[11] = 0x00; /* unspecified */ 7450 /* reserved */ 7451 RWErrorRecovery[12] = 0x00; /* reserved */ 7452 /* Block size */ 7453 RWErrorRecovery[13] = 0x00; 7454 RWErrorRecovery[14] = 0x02; /* Block size is always 512 bytes */ 7455 RWErrorRecovery[15] = 0x00; 7456 } 7457 7458 if (LLBAA) 7459 { 7460 index = 24; 7461 } 7462 else 7463 { 7464 index = 16; 7465 } 7466 /* 7467 * Fill-up Read-Write Error Recovery mode page, SAT, Table 66 7468 */ 7469 RWErrorRecovery[index+0] = 0x01; /* page code */ 7470 RWErrorRecovery[index+1] = 0x0A; /* page length */ 7471 RWErrorRecovery[index+2] = 0x40; /* ARRE is set */ 7472 RWErrorRecovery[index+3] = 0x00; 7473 RWErrorRecovery[index+4] = 0x00; 7474 RWErrorRecovery[index+5] = 0x00; 7475 RWErrorRecovery[index+6] = 0x00; 7476 RWErrorRecovery[index+7] = 0x00; 7477 RWErrorRecovery[index+8] = 0x00; 7478 RWErrorRecovery[index+9] = 0x00; 7479 RWErrorRecovery[index+10] = 0x00; 7480 RWErrorRecovery[index+11] = 0x00; 7481 7482 osti_memcpy(pModeSense, &RWErrorRecovery, lenRead); 7483 } 7484 else if (page == MODESENSE_CACHING) 7485 { 7486 TI_DBG5(("satModeSense10: MODESENSE_CACHING\n")); 7487 Caching[0] = 0; 7488 Caching[1] = (bit8)(lenRead - 2); 7489 Caching[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */ 7490 Caching[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */ 7491 if (LLBAA) 7492 { 7493 Caching[4] = 0x00; /* reserved and LONGLBA */ 7494 Caching[4] = (bit8)(Caching[4] | 0x1); /* LONGLBA is set */ 7495 } 7496 else 7497 { 7498 Caching[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */ 7499 } 7500 Caching[5] = 0x00; /* reserved */ 7501 Caching[6] = 0x00; /* block descriptot length */ 7502 if (LLBAA) 7503 { 7504 Caching[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */ 7505 } 7506 else 7507 { 7508 Caching[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */ 7509 } 7510 7511 /* 7512 * Fill-up direct-access device block-descriptor, SAT, Table 19 7513 */ 7514 7515 if (LLBAA) 7516 { 7517 /* density code */ 7518 Caching[8] = 0x04; /* density-code : reserved for direct-access */ 7519 /* number of blocks */ 7520 Caching[9] = 0x00; /* unspecified */ 7521 Caching[10] = 0x00; /* unspecified */ 7522 Caching[11] = 0x00; /* unspecified */ 7523 Caching[12] = 0x00; /* unspecified */ 7524 Caching[13] = 0x00; /* unspecified */ 7525 Caching[14] = 0x00; /* unspecified */ 7526 Caching[15] = 0x00; /* unspecified */ 7527 /* reserved */ 7528 Caching[16] = 0x00; /* reserved */ 7529 Caching[17] = 0x00; /* reserved */ 7530 Caching[18] = 0x00; /* reserved */ 7531 Caching[19] = 0x00; /* reserved */ 7532 /* Block size */ 7533 Caching[20] = 0x00; 7534 Caching[21] = 0x00; 7535 Caching[22] = 0x02; /* Block size is always 512 bytes */ 7536 Caching[23] = 0x00; 7537 } 7538 else 7539 { 7540 /* density code */ 7541 Caching[8] = 0x04; /* density-code : reserved for direct-access */ 7542 /* number of blocks */ 7543 Caching[9] = 0x00; /* unspecified */ 7544 Caching[10] = 0x00; /* unspecified */ 7545 Caching[11] = 0x00; /* unspecified */ 7546 /* reserved */ 7547 Caching[12] = 0x00; /* reserved */ 7548 /* Block size */ 7549 Caching[13] = 0x00; 7550 Caching[14] = 0x02; /* Block size is always 512 bytes */ 7551 Caching[15] = 0x00; 7552 } 7553 7554 if (LLBAA) 7555 { 7556 index = 24; 7557 } 7558 else 7559 { 7560 index = 16; 7561 } 7562 /* 7563 * Fill-up Caching mode page, SAT, Table 67 7564 */ 7565 /* length 20 */ 7566 Caching[index+0] = 0x08; /* page code */ 7567 Caching[index+1] = 0x12; /* page length */ 7568 #ifdef NOT_YET 7569 if (pSatDevData->satWriteCacheEnabled == agTRUE) 7570 { 7571 Caching[index+2] = 0x04;/* WCE bit is set */ 7572 } 7573 else 7574 { 7575 Caching[index+2] = 0x00;/* WCE bit is NOT set */ 7576 } 7577 #endif 7578 Caching[index+2] = 0x00;/* WCE bit is NOT set */ 7579 Caching[index+3] = 0x00; 7580 Caching[index+4] = 0x00; 7581 Caching[index+5] = 0x00; 7582 Caching[index+6] = 0x00; 7583 Caching[index+7] = 0x00; 7584 Caching[index+8] = 0x00; 7585 Caching[index+9] = 0x00; 7586 Caching[index+10] = 0x00; 7587 Caching[index+11] = 0x00; 7588 if (pSatDevData->satLookAheadEnabled == agTRUE) 7589 { 7590 Caching[index+12] = 0x00;/* DRA bit is NOT set */ 7591 } 7592 else 7593 { 7594 Caching[index+12] = 0x20;/* DRA bit is set */ 7595 } 7596 Caching[index+13] = 0x00; 7597 Caching[index+14] = 0x00; 7598 Caching[index+15] = 0x00; 7599 Caching[index+16] = 0x00; 7600 Caching[index+17] = 0x00; 7601 Caching[index+18] = 0x00; 7602 Caching[index+19] = 0x00; 7603 osti_memcpy(pModeSense, &Caching, lenRead); 7604 7605 } 7606 else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE) 7607 { 7608 TI_DBG5(("satModeSense10: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n")); 7609 InfoExceptionCtrl[0] = 0; 7610 InfoExceptionCtrl[1] = (bit8)(lenRead - 2); 7611 InfoExceptionCtrl[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */ 7612 InfoExceptionCtrl[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */ 7613 if (LLBAA) 7614 { 7615 InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA */ 7616 InfoExceptionCtrl[4] = (bit8)(InfoExceptionCtrl[4] | 0x1); /* LONGLBA is set */ 7617 } 7618 else 7619 { 7620 InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */ 7621 } 7622 InfoExceptionCtrl[5] = 0x00; /* reserved */ 7623 InfoExceptionCtrl[6] = 0x00; /* block descriptot length */ 7624 if (LLBAA) 7625 { 7626 InfoExceptionCtrl[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */ 7627 } 7628 else 7629 { 7630 InfoExceptionCtrl[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */ 7631 } 7632 7633 /* 7634 * Fill-up direct-access device block-descriptor, SAT, Table 19 7635 */ 7636 7637 if (LLBAA) 7638 { 7639 /* density code */ 7640 InfoExceptionCtrl[8] = 0x04; /* density-code : reserved for direct-access */ 7641 /* number of blocks */ 7642 InfoExceptionCtrl[9] = 0x00; /* unspecified */ 7643 InfoExceptionCtrl[10] = 0x00; /* unspecified */ 7644 InfoExceptionCtrl[11] = 0x00; /* unspecified */ 7645 InfoExceptionCtrl[12] = 0x00; /* unspecified */ 7646 InfoExceptionCtrl[13] = 0x00; /* unspecified */ 7647 InfoExceptionCtrl[14] = 0x00; /* unspecified */ 7648 InfoExceptionCtrl[15] = 0x00; /* unspecified */ 7649 /* reserved */ 7650 InfoExceptionCtrl[16] = 0x00; /* reserved */ 7651 InfoExceptionCtrl[17] = 0x00; /* reserved */ 7652 InfoExceptionCtrl[18] = 0x00; /* reserved */ 7653 InfoExceptionCtrl[19] = 0x00; /* reserved */ 7654 /* Block size */ 7655 InfoExceptionCtrl[20] = 0x00; 7656 InfoExceptionCtrl[21] = 0x00; 7657 InfoExceptionCtrl[22] = 0x02; /* Block size is always 512 bytes */ 7658 InfoExceptionCtrl[23] = 0x00; 7659 } 7660 else 7661 { 7662 /* density code */ 7663 InfoExceptionCtrl[8] = 0x04; /* density-code : reserved for direct-access */ 7664 /* number of blocks */ 7665 InfoExceptionCtrl[9] = 0x00; /* unspecified */ 7666 InfoExceptionCtrl[10] = 0x00; /* unspecified */ 7667 InfoExceptionCtrl[11] = 0x00; /* unspecified */ 7668 /* reserved */ 7669 InfoExceptionCtrl[12] = 0x00; /* reserved */ 7670 /* Block size */ 7671 InfoExceptionCtrl[13] = 0x00; 7672 InfoExceptionCtrl[14] = 0x02; /* Block size is always 512 bytes */ 7673 InfoExceptionCtrl[15] = 0x00; 7674 } 7675 7676 if (LLBAA) 7677 { 7678 index = 24; 7679 } 7680 else 7681 { 7682 index = 16; 7683 } 7684 /* 7685 * Fill-up informational-exceptions control mode page, SAT, Table 68 7686 */ 7687 InfoExceptionCtrl[index+0] = 0x1C; /* page code */ 7688 InfoExceptionCtrl[index+1] = 0x0A; /* page length */ 7689 if (pSatDevData->satSMARTEnabled == agTRUE) 7690 { 7691 InfoExceptionCtrl[index+2] = 0x00;/* DEXCPT bit is NOT set */ 7692 } 7693 else 7694 { 7695 InfoExceptionCtrl[index+2] = 0x08;/* DEXCPT bit is set */ 7696 } 7697 InfoExceptionCtrl[index+3] = 0x00; /* We don't support MRIE */ 7698 InfoExceptionCtrl[index+4] = 0x00; /* Interval timer vendor-specific */ 7699 InfoExceptionCtrl[index+5] = 0x00; 7700 InfoExceptionCtrl[index+6] = 0x00; 7701 InfoExceptionCtrl[index+7] = 0x00; 7702 InfoExceptionCtrl[index+8] = 0x00; /* REPORT-COUNT */ 7703 InfoExceptionCtrl[index+9] = 0x00; 7704 InfoExceptionCtrl[index+10] = 0x00; 7705 InfoExceptionCtrl[index+11] = 0x00; 7706 osti_memcpy(pModeSense, &InfoExceptionCtrl, lenRead); 7707 7708 } 7709 else 7710 { 7711 /* Error */ 7712 TI_DBG1(("satModeSense10: Error page %d\n", page)); 7713 satSetSensePayload( pSense, 7714 SCSI_SNSKEY_ILLEGAL_REQUEST, 7715 0, 7716 SCSI_SNSCODE_INVALID_COMMAND, 7717 satIOContext); 7718 7719 ostiInitiatorIOCompleted( tiRoot, 7720 tiIORequest, 7721 tiIOSuccess, 7722 SCSI_STAT_CHECK_CONDITION, 7723 satIOContext->pTiSenseData, 7724 satIOContext->interruptContext ); 7725 return tiSuccess; 7726 } 7727 7728 if (requestLen > lenRead) 7729 { 7730 TI_DBG1(("satModeSense10 reporting underrun lenRead=0x%x requestLen=0x%x tiIORequest=%p\n", lenRead, requestLen, tiIORequest)); 7731 7732 ostiInitiatorIOCompleted( tiRoot, 7733 tiIORequest, 7734 tiIOUnderRun, 7735 requestLen - lenRead, 7736 agNULL, 7737 satIOContext->interruptContext ); 7738 7739 7740 } 7741 else 7742 { 7743 ostiInitiatorIOCompleted( tiRoot, 7744 tiIORequest, 7745 tiIOSuccess, 7746 SCSI_STAT_GOOD, 7747 agNULL, 7748 satIOContext->interruptContext); 7749 } 7750 7751 return tiSuccess; 7752 } 7753 7754 7755 /*****************************************************************************/ 7756 /*! \brief SAT implementation for SCSI VERIFY (10). 7757 * 7758 * SAT implementation for SCSI VERIFY (10). 7759 * 7760 * \param tiRoot: Pointer to TISA initiator driver/port instance. 7761 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 7762 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 7763 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 7764 * \param satIOContext_t: Pointer to the SAT IO Context 7765 * 7766 * \return If command is started successfully 7767 * - \e tiSuccess: I/O request successfully initiated. 7768 * - \e tiBusy: No resources available, try again later. 7769 * - \e tiIONoDevice: Invalid device handle. 7770 * - \e tiError: Other errors. 7771 */ 7772 /*****************************************************************************/ 7773 GLOBAL bit32 satVerify10( 7774 tiRoot_t *tiRoot, 7775 tiIORequest_t *tiIORequest, 7776 tiDeviceHandle_t *tiDeviceHandle, 7777 tiScsiInitiatorRequest_t *tiScsiRequest, 7778 satIOContext_t *satIOContext) 7779 { 7780 /* 7781 For simple implementation, 7782 no byte comparison supported as of 4/5/06 7783 */ 7784 scsiRspSense_t *pSense; 7785 tiIniScsiCmnd_t *scsiCmnd; 7786 satDeviceData_t *pSatDevData; 7787 agsaFisRegHostToDevice_t *fis; 7788 bit32 status; 7789 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 7790 bit32 lba = 0; 7791 bit32 tl = 0; 7792 bit32 LoopNum = 1; 7793 bit8 LBA[4]; 7794 bit8 TL[4]; 7795 bit32 rangeChk = agFALSE; /* lba and tl range check */ 7796 7797 7798 TI_DBG5(("satVerify10 entry: tiDeviceHandle=%p tiIORequest=%p\n", 7799 tiDeviceHandle, tiIORequest)); 7800 7801 pSense = satIOContext->pSense; 7802 scsiCmnd = &tiScsiRequest->scsiCmnd; 7803 pSatDevData = satIOContext->pSatDevData; 7804 fis = satIOContext->pFis; 7805 7806 /* checking BYTCHK */ 7807 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK) 7808 { 7809 /* 7810 should do the byte check 7811 but not supported in this version 7812 */ 7813 satSetSensePayload( pSense, 7814 SCSI_SNSKEY_ILLEGAL_REQUEST, 7815 0, 7816 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 7817 satIOContext); 7818 7819 ostiInitiatorIOCompleted( tiRoot, 7820 tiIORequest, 7821 tiIOSuccess, 7822 SCSI_STAT_CHECK_CONDITION, 7823 satIOContext->pTiSenseData, 7824 satIOContext->interruptContext ); 7825 7826 TI_DBG1(("satVerify10: no byte checking \n")); 7827 return tiSuccess; 7828 } 7829 7830 /* checking CONTROL */ 7831 /* NACA == 1 or LINK == 1*/ 7832 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 7833 { 7834 satSetSensePayload( pSense, 7835 SCSI_SNSKEY_ILLEGAL_REQUEST, 7836 0, 7837 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 7838 satIOContext); 7839 7840 ostiInitiatorIOCompleted( tiRoot, 7841 tiIORequest, 7842 tiIOSuccess, 7843 SCSI_STAT_CHECK_CONDITION, 7844 satIOContext->pTiSenseData, 7845 satIOContext->interruptContext ); 7846 7847 TI_DBG2(("satVerify10: return control\n")); 7848 return tiSuccess; 7849 } 7850 7851 osti_memset(LBA, 0, sizeof(LBA)); 7852 osti_memset(TL, 0, sizeof(TL)); 7853 7854 /* do not use memcpy due to indexing in LBA and TL */ 7855 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 7856 LBA[1] = scsiCmnd->cdb[3]; 7857 LBA[2] = scsiCmnd->cdb[4]; 7858 LBA[3] = scsiCmnd->cdb[5]; /* LSB */ 7859 7860 TL[0] = 0; 7861 TL[1] = 0; 7862 TL[2] = scsiCmnd->cdb[7]; /* MSB */ 7863 TL[3] = scsiCmnd->cdb[8]; /* LSB */ 7864 7865 rangeChk = satAddNComparebit32(LBA, TL); 7866 7867 /* cbd10; computing LBA and transfer length */ 7868 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 7869 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 7870 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 7871 7872 if (pSatDevData->satNCQ != agTRUE && 7873 pSatDevData->sat48BitSupport != agTRUE 7874 ) 7875 { 7876 if (lba > SAT_TR_LBA_LIMIT - 1) 7877 { 7878 satSetSensePayload( pSense, 7879 SCSI_SNSKEY_ILLEGAL_REQUEST, 7880 0, 7881 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 7882 satIOContext); 7883 7884 ostiInitiatorIOCompleted( tiRoot, 7885 tiIORequest, 7886 tiIOSuccess, 7887 SCSI_STAT_CHECK_CONDITION, 7888 satIOContext->pTiSenseData, 7889 satIOContext->interruptContext ); 7890 7891 TI_DBG1(("satVerify10: return LBA out of range, not EXT\n")); 7892 TI_DBG1(("satVerify10: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3], 7893 scsiCmnd->cdb[4], scsiCmnd->cdb[5])); 7894 TI_DBG1(("satVerify10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT)); 7895 return tiSuccess; 7896 } 7897 7898 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 7899 { 7900 TI_DBG1(("satVerify10: return LBA+TL out of range, not EXT\n")); 7901 satSetSensePayload( pSense, 7902 SCSI_SNSKEY_ILLEGAL_REQUEST, 7903 0, 7904 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 7905 satIOContext); 7906 7907 ostiInitiatorIOCompleted( tiRoot, 7908 tiIORequest, 7909 tiIOSuccess, 7910 SCSI_STAT_CHECK_CONDITION, 7911 satIOContext->pTiSenseData, 7912 satIOContext->interruptContext ); 7913 7914 return tiSuccess; 7915 } 7916 } 7917 7918 if (pSatDevData->sat48BitSupport == agTRUE) 7919 { 7920 TI_DBG5(("satVerify10: SAT_READ_VERIFY_SECTORS_EXT\n")); 7921 fis->h.fisType = 0x27; /* Reg host to device */ 7922 fis->h.c_pmPort = 0x80; /* C Bit is set */ 7923 7924 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 7925 fis->h.features = 0; /* FIS reserve */ 7926 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 7927 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 7928 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 7929 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 7930 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 7931 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 7932 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 7933 fis->d.featuresExp = 0; /* FIS reserve */ 7934 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 7935 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 7936 7937 fis->d.reserved4 = 0; 7938 fis->d.control = 0; /* FIS HOB bit clear */ 7939 fis->d.reserved5 = 0; 7940 7941 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 7942 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT; 7943 } 7944 else 7945 { 7946 TI_DBG5(("satVerify10: SAT_READ_VERIFY_SECTORS\n")); 7947 fis->h.fisType = 0x27; /* Reg host to device */ 7948 fis->h.c_pmPort = 0x80; /* C bit is set */ 7949 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 7950 fis->h.features = 0; /* FIS reserve */ 7951 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 7952 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 7953 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 7954 /* FIS LBA mode set LBA (27:24) */ 7955 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 7956 fis->d.lbaLowExp = 0; 7957 fis->d.lbaMidExp = 0; 7958 fis->d.lbaHighExp = 0; 7959 fis->d.featuresExp = 0; 7960 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 7961 fis->d.sectorCountExp = 0; 7962 fis->d.reserved4 = 0; 7963 fis->d.control = 0; /* FIS HOB bit clear */ 7964 fis->d.reserved5 = 0; 7965 7966 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 7967 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS; 7968 7969 } 7970 7971 satIOContext->currentLBA = lba; 7972 satIOContext->OrgTL = tl; 7973 7974 /* 7975 computing number of loop and remainder for tl 7976 0xFF in case not ext 7977 0xFFFF in case EXT 7978 */ 7979 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 7980 { 7981 LoopNum = satComputeLoopNum(tl, 0xFF); 7982 } 7983 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 7984 { 7985 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 7986 LoopNum = satComputeLoopNum(tl, 0xFFFF); 7987 } 7988 else 7989 { 7990 TI_DBG1(("satVerify10: error case 1!!!\n")); 7991 LoopNum = 1; 7992 } 7993 7994 satIOContext->LoopNum = LoopNum; 7995 7996 if (LoopNum == 1) 7997 { 7998 TI_DBG5(("satVerify10: NON CHAINED data\n")); 7999 /* Initialize CB for SATA completion. 8000 */ 8001 satIOContext->satCompleteCB = &satNonChainedVerifyCB; 8002 } 8003 else 8004 { 8005 TI_DBG1(("satVerify10: CHAINED data\n")); 8006 /* re-setting tl */ 8007 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 8008 { 8009 fis->d.sectorCount = 0xFF; 8010 } 8011 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 8012 { 8013 fis->d.sectorCount = 0xFF; 8014 fis->d.sectorCountExp = 0xFF; 8015 } 8016 else 8017 { 8018 TI_DBG1(("satVerify10: error case 2!!!\n")); 8019 } 8020 8021 /* Initialize CB for SATA completion. 8022 */ 8023 satIOContext->satCompleteCB = &satChainedVerifyCB; 8024 } 8025 8026 8027 /* 8028 * Prepare SGL and send FIS to LL layer. 8029 */ 8030 satIOContext->reqType = agRequestType; /* Save it */ 8031 8032 status = sataLLIOStart( tiRoot, 8033 tiIORequest, 8034 tiDeviceHandle, 8035 tiScsiRequest, 8036 satIOContext); 8037 return (status); 8038 } 8039 8040 GLOBAL bit32 satChainedVerify( 8041 tiRoot_t *tiRoot, 8042 tiIORequest_t *tiIORequest, 8043 tiDeviceHandle_t *tiDeviceHandle, 8044 tiScsiInitiatorRequest_t *tiScsiRequest, 8045 satIOContext_t *satIOContext) 8046 { 8047 bit32 status; 8048 satIOContext_t *satOrgIOContext = agNULL; 8049 agsaFisRegHostToDevice_t *fis; 8050 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8051 bit32 lba = 0; 8052 bit32 DenomTL = 0xFF; 8053 bit32 Remainder = 0; 8054 bit8 LBA[4]; /* 0 MSB, 3 LSB */ 8055 8056 TI_DBG2(("satChainedVerify: start\n")); 8057 8058 fis = satIOContext->pFis; 8059 satOrgIOContext = satIOContext->satOrgIOContext; 8060 osti_memset(LBA,0, sizeof(LBA)); 8061 8062 switch (satOrgIOContext->ATACmd) 8063 { 8064 case SAT_READ_VERIFY_SECTORS: 8065 DenomTL = 0xFF; 8066 break; 8067 case SAT_READ_VERIFY_SECTORS_EXT: 8068 DenomTL = 0xFFFF; 8069 break; 8070 default: 8071 TI_DBG1(("satChainedVerify: error incorrect ata command 0x%x\n", satIOContext->ATACmd)); 8072 return tiError; 8073 break; 8074 } 8075 8076 Remainder = satOrgIOContext->OrgTL % DenomTL; 8077 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL; 8078 lba = satOrgIOContext->currentLBA; 8079 8080 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */ 8081 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2)); 8082 LBA[2] = (bit8)((lba & 0xF0) >> 8); 8083 LBA[3] = (bit8)(lba & 0xF); /* LSB */ 8084 8085 switch (satOrgIOContext->ATACmd) 8086 { 8087 case SAT_READ_VERIFY_SECTORS: 8088 fis->h.fisType = 0x27; /* Reg host to device */ 8089 fis->h.c_pmPort = 0x80; /* C bit is set */ 8090 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 8091 fis->h.features = 0; /* FIS reserve */ 8092 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 8093 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 8094 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 8095 8096 /* FIS LBA mode set LBA (27:24) */ 8097 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 8098 8099 fis->d.lbaLowExp = 0; 8100 fis->d.lbaMidExp = 0; 8101 fis->d.lbaHighExp = 0; 8102 fis->d.featuresExp = 0; 8103 if (satOrgIOContext->LoopNum == 1) 8104 { 8105 /* last loop */ 8106 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 8107 } 8108 else 8109 { 8110 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 8111 } 8112 fis->d.sectorCountExp = 0; 8113 fis->d.reserved4 = 0; 8114 fis->d.control = 0; /* FIS HOB bit clear */ 8115 fis->d.reserved5 = 0; 8116 8117 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8118 8119 break; 8120 case SAT_READ_VERIFY_SECTORS_EXT: 8121 fis->h.fisType = 0x27; /* Reg host to device */ 8122 fis->h.c_pmPort = 0x80; /* C Bit is set */ 8123 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT; /* 0x42 */ 8124 fis->h.features = 0; /* FIS reserve */ 8125 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 8126 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 8127 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 8128 fis->d.device = 0x40; /* FIS LBA mode set */ 8129 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 8130 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 8131 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 8132 fis->d.featuresExp = 0; /* FIS reserve */ 8133 if (satOrgIOContext->LoopNum == 1) 8134 { 8135 /* last loop */ 8136 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 8137 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 8138 } 8139 else 8140 { 8141 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 8142 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 8143 } 8144 fis->d.reserved4 = 0; 8145 fis->d.control = 0; /* FIS HOB bit clear */ 8146 fis->d.reserved5 = 0; 8147 8148 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8149 8150 break; 8151 8152 default: 8153 TI_DBG1(("satChainedVerify: error incorrect ata command 0x%x\n", satIOContext->ATACmd)); 8154 return tiError; 8155 break; 8156 } 8157 8158 /* Initialize CB for SATA completion. 8159 */ 8160 /* chained data */ 8161 satIOContext->satCompleteCB = &satChainedVerifyCB; 8162 8163 8164 /* 8165 * Prepare SGL and send FIS to LL layer. 8166 */ 8167 satIOContext->reqType = agRequestType; /* Save it */ 8168 8169 status = sataLLIOStart( tiRoot, 8170 tiIORequest, 8171 tiDeviceHandle, 8172 tiScsiRequest, 8173 satIOContext); 8174 8175 TI_DBG5(("satChainedVerify: return\n")); 8176 return (status); 8177 8178 } 8179 8180 8181 /*****************************************************************************/ 8182 /*! \brief SAT implementation for SCSI VERIFY (12). 8183 * 8184 * SAT implementation for SCSI VERIFY (12). 8185 * 8186 * \param tiRoot: Pointer to TISA initiator driver/port instance. 8187 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 8188 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 8189 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 8190 * \param satIOContext_t: Pointer to the SAT IO Context 8191 * 8192 * \return If command is started successfully 8193 * - \e tiSuccess: I/O request successfully initiated. 8194 * - \e tiBusy: No resources available, try again later. 8195 * - \e tiIONoDevice: Invalid device handle. 8196 * - \e tiError: Other errors. 8197 */ 8198 /*****************************************************************************/ 8199 GLOBAL bit32 satVerify12( 8200 tiRoot_t *tiRoot, 8201 tiIORequest_t *tiIORequest, 8202 tiDeviceHandle_t *tiDeviceHandle, 8203 tiScsiInitiatorRequest_t *tiScsiRequest, 8204 satIOContext_t *satIOContext) 8205 { 8206 /* 8207 For simple implementation, 8208 no byte comparison supported as of 4/5/06 8209 */ 8210 scsiRspSense_t *pSense; 8211 tiIniScsiCmnd_t *scsiCmnd; 8212 satDeviceData_t *pSatDevData; 8213 agsaFisRegHostToDevice_t *fis; 8214 bit32 status; 8215 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8216 bit32 lba = 0; 8217 bit32 tl = 0; 8218 bit32 LoopNum = 1; 8219 bit8 LBA[4]; 8220 bit8 TL[4]; 8221 bit32 rangeChk = agFALSE; /* lba and tl range check */ 8222 8223 TI_DBG5(("satVerify12 entry: tiDeviceHandle=%p tiIORequest=%p\n", 8224 tiDeviceHandle, tiIORequest)); 8225 8226 pSense = satIOContext->pSense; 8227 scsiCmnd = &tiScsiRequest->scsiCmnd; 8228 pSatDevData = satIOContext->pSatDevData; 8229 fis = satIOContext->pFis; 8230 8231 8232 /* checking BYTCHK */ 8233 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK) 8234 { 8235 /* 8236 should do the byte check 8237 but not supported in this version 8238 */ 8239 satSetSensePayload( pSense, 8240 SCSI_SNSKEY_ILLEGAL_REQUEST, 8241 0, 8242 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8243 satIOContext); 8244 8245 ostiInitiatorIOCompleted( tiRoot, 8246 tiIORequest, 8247 tiIOSuccess, 8248 SCSI_STAT_CHECK_CONDITION, 8249 satIOContext->pTiSenseData, 8250 satIOContext->interruptContext ); 8251 8252 TI_DBG1(("satVerify12: no byte checking \n")); 8253 return tiSuccess; 8254 } 8255 8256 /* checking CONTROL */ 8257 /* NACA == 1 or LINK == 1*/ 8258 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) ) 8259 { 8260 satSetSensePayload( pSense, 8261 SCSI_SNSKEY_ILLEGAL_REQUEST, 8262 0, 8263 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8264 satIOContext); 8265 8266 ostiInitiatorIOCompleted( tiRoot, 8267 tiIORequest, 8268 tiIOSuccess, 8269 SCSI_STAT_CHECK_CONDITION, 8270 satIOContext->pTiSenseData, 8271 satIOContext->interruptContext ); 8272 8273 TI_DBG1(("satVerify12: return control\n")); 8274 return tiSuccess; 8275 } 8276 8277 osti_memset(LBA, 0, sizeof(LBA)); 8278 osti_memset(TL, 0, sizeof(TL)); 8279 8280 /* do not use memcpy due to indexing in LBA and TL */ 8281 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 8282 LBA[1] = scsiCmnd->cdb[3]; 8283 LBA[2] = scsiCmnd->cdb[4]; 8284 LBA[3] = scsiCmnd->cdb[5]; /* LSB */ 8285 8286 TL[0] = scsiCmnd->cdb[6]; /* MSB */ 8287 TL[1] = scsiCmnd->cdb[7]; 8288 TL[2] = scsiCmnd->cdb[7]; 8289 TL[3] = scsiCmnd->cdb[8]; /* LSB */ 8290 8291 rangeChk = satAddNComparebit32(LBA, TL); 8292 8293 lba = satComputeCDB12LBA(satIOContext); 8294 tl = satComputeCDB12TL(satIOContext); 8295 8296 if (pSatDevData->satNCQ != agTRUE && 8297 pSatDevData->sat48BitSupport != agTRUE 8298 ) 8299 { 8300 if (lba > SAT_TR_LBA_LIMIT - 1) 8301 { 8302 satSetSensePayload( pSense, 8303 SCSI_SNSKEY_ILLEGAL_REQUEST, 8304 0, 8305 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 8306 satIOContext); 8307 8308 ostiInitiatorIOCompleted( tiRoot, 8309 tiIORequest, 8310 tiIOSuccess, 8311 SCSI_STAT_CHECK_CONDITION, 8312 satIOContext->pTiSenseData, 8313 satIOContext->interruptContext ); 8314 8315 TI_DBG1(("satVerify12: return LBA out of range, not EXT\n")); 8316 TI_DBG1(("satVerify12: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3], 8317 scsiCmnd->cdb[4], scsiCmnd->cdb[5])); 8318 TI_DBG1(("satVerify12: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT)); 8319 return tiSuccess; 8320 } 8321 8322 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 8323 { 8324 TI_DBG1(("satVerify12: return LBA+TL out of range, not EXT\n")); 8325 satSetSensePayload( pSense, 8326 SCSI_SNSKEY_ILLEGAL_REQUEST, 8327 0, 8328 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 8329 satIOContext); 8330 8331 ostiInitiatorIOCompleted( tiRoot, 8332 tiIORequest, 8333 tiIOSuccess, 8334 SCSI_STAT_CHECK_CONDITION, 8335 satIOContext->pTiSenseData, 8336 satIOContext->interruptContext ); 8337 8338 return tiSuccess; 8339 } 8340 } 8341 8342 if (pSatDevData->sat48BitSupport == agTRUE) 8343 { 8344 TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS_EXT\n")); 8345 fis->h.fisType = 0x27; /* Reg host to device */ 8346 fis->h.c_pmPort = 0x80; /* C Bit is set */ 8347 8348 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 8349 fis->h.features = 0; /* FIS reserve */ 8350 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 8351 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 8352 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 8353 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 8354 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 8355 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 8356 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 8357 fis->d.featuresExp = 0; /* FIS reserve */ 8358 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 8359 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 8360 8361 fis->d.reserved4 = 0; 8362 fis->d.control = 0; /* FIS HOB bit clear */ 8363 fis->d.reserved5 = 0; 8364 8365 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8366 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT; 8367 } 8368 else 8369 { 8370 TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS\n")); 8371 fis->h.fisType = 0x27; /* Reg host to device */ 8372 fis->h.c_pmPort = 0x80; /* C bit is set */ 8373 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 8374 fis->h.features = 0; /* FIS reserve */ 8375 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 8376 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 8377 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 8378 /* FIS LBA mode set LBA (27:24) */ 8379 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 8380 fis->d.lbaLowExp = 0; 8381 fis->d.lbaMidExp = 0; 8382 fis->d.lbaHighExp = 0; 8383 fis->d.featuresExp = 0; 8384 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 8385 fis->d.sectorCountExp = 0; 8386 fis->d.reserved4 = 0; 8387 fis->d.control = 0; /* FIS HOB bit clear */ 8388 fis->d.reserved5 = 0; 8389 8390 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8391 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS; 8392 8393 } 8394 8395 satIOContext->currentLBA = lba; 8396 satIOContext->OrgTL = tl; 8397 8398 /* 8399 computing number of loop and remainder for tl 8400 0xFF in case not ext 8401 0xFFFF in case EXT 8402 */ 8403 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 8404 { 8405 LoopNum = satComputeLoopNum(tl, 0xFF); 8406 } 8407 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 8408 { 8409 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 8410 LoopNum = satComputeLoopNum(tl, 0xFFFF); 8411 } 8412 else 8413 { 8414 TI_DBG1(("satVerify12: error case 1!!!\n")); 8415 LoopNum = 1; 8416 } 8417 8418 satIOContext->LoopNum = LoopNum; 8419 8420 if (LoopNum == 1) 8421 { 8422 TI_DBG5(("satVerify12: NON CHAINED data\n")); 8423 /* Initialize CB for SATA completion. 8424 */ 8425 satIOContext->satCompleteCB = &satNonChainedVerifyCB; 8426 } 8427 else 8428 { 8429 TI_DBG1(("satVerify12: CHAINED data\n")); 8430 /* re-setting tl */ 8431 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 8432 { 8433 fis->d.sectorCount = 0xFF; 8434 } 8435 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 8436 { 8437 fis->d.sectorCount = 0xFF; 8438 fis->d.sectorCountExp = 0xFF; 8439 } 8440 else 8441 { 8442 TI_DBG1(("satVerify10: error case 2!!!\n")); 8443 } 8444 8445 /* Initialize CB for SATA completion. 8446 */ 8447 satIOContext->satCompleteCB = &satChainedVerifyCB; 8448 } 8449 8450 8451 /* 8452 * Prepare SGL and send FIS to LL layer. 8453 */ 8454 satIOContext->reqType = agRequestType; /* Save it */ 8455 8456 status = sataLLIOStart( tiRoot, 8457 tiIORequest, 8458 tiDeviceHandle, 8459 tiScsiRequest, 8460 satIOContext); 8461 return (status); 8462 } 8463 /*****************************************************************************/ 8464 /*! \brief SAT implementation for SCSI VERIFY (16). 8465 * 8466 * SAT implementation for SCSI VERIFY (16). 8467 * 8468 * \param tiRoot: Pointer to TISA initiator driver/port instance. 8469 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 8470 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 8471 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 8472 * \param satIOContext_t: Pointer to the SAT IO Context 8473 * 8474 * \return If command is started successfully 8475 * - \e tiSuccess: I/O request successfully initiated. 8476 * - \e tiBusy: No resources available, try again later. 8477 * - \e tiIONoDevice: Invalid device handle. 8478 * - \e tiError: Other errors. 8479 */ 8480 /*****************************************************************************/ 8481 GLOBAL bit32 satVerify16( 8482 tiRoot_t *tiRoot, 8483 tiIORequest_t *tiIORequest, 8484 tiDeviceHandle_t *tiDeviceHandle, 8485 tiScsiInitiatorRequest_t *tiScsiRequest, 8486 satIOContext_t *satIOContext) 8487 { 8488 /* 8489 For simple implementation, 8490 no byte comparison supported as of 4/5/06 8491 */ 8492 scsiRspSense_t *pSense; 8493 tiIniScsiCmnd_t *scsiCmnd; 8494 satDeviceData_t *pSatDevData; 8495 agsaFisRegHostToDevice_t *fis; 8496 bit32 status; 8497 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8498 bit32 lba = 0; 8499 bit32 tl = 0; 8500 bit32 LoopNum = 1; 8501 bit8 LBA[8]; 8502 bit8 TL[8]; 8503 bit32 rangeChk = agFALSE; /* lba and tl range check */ 8504 bit32 limitChk = agFALSE; /* lba and tl range check */ 8505 8506 TI_DBG5(("satVerify16 entry: tiDeviceHandle=%p tiIORequest=%p\n", 8507 tiDeviceHandle, tiIORequest)); 8508 8509 pSense = satIOContext->pSense; 8510 scsiCmnd = &tiScsiRequest->scsiCmnd; 8511 pSatDevData = satIOContext->pSatDevData; 8512 fis = satIOContext->pFis; 8513 8514 /* checking BYTCHK */ 8515 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK) 8516 { 8517 /* 8518 should do the byte check 8519 but not supported in this version 8520 */ 8521 satSetSensePayload( pSense, 8522 SCSI_SNSKEY_ILLEGAL_REQUEST, 8523 0, 8524 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8525 satIOContext); 8526 8527 ostiInitiatorIOCompleted( tiRoot, 8528 tiIORequest, 8529 tiIOSuccess, 8530 SCSI_STAT_CHECK_CONDITION, 8531 satIOContext->pTiSenseData, 8532 satIOContext->interruptContext ); 8533 8534 TI_DBG1(("satVerify16: no byte checking \n")); 8535 return tiSuccess; 8536 } 8537 8538 /* checking CONTROL */ 8539 /* NACA == 1 or LINK == 1*/ 8540 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 8541 { 8542 satSetSensePayload( pSense, 8543 SCSI_SNSKEY_ILLEGAL_REQUEST, 8544 0, 8545 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8546 satIOContext); 8547 8548 ostiInitiatorIOCompleted( tiRoot, 8549 tiIORequest, 8550 tiIOSuccess, 8551 SCSI_STAT_CHECK_CONDITION, 8552 satIOContext->pTiSenseData, 8553 satIOContext->interruptContext ); 8554 8555 TI_DBG2(("satVerify16: return control\n")); 8556 return tiSuccess; 8557 } 8558 8559 osti_memset(LBA, 0, sizeof(LBA)); 8560 osti_memset(TL, 0, sizeof(TL)); 8561 8562 8563 /* do not use memcpy due to indexing in LBA and TL */ 8564 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 8565 LBA[1] = scsiCmnd->cdb[3]; 8566 LBA[2] = scsiCmnd->cdb[4]; 8567 LBA[3] = scsiCmnd->cdb[5]; 8568 LBA[4] = scsiCmnd->cdb[6]; 8569 LBA[5] = scsiCmnd->cdb[7]; 8570 LBA[6] = scsiCmnd->cdb[8]; 8571 LBA[7] = scsiCmnd->cdb[9]; /* LSB */ 8572 8573 TL[0] = 0; 8574 TL[1] = 0; 8575 TL[2] = 0; 8576 TL[3] = 0; 8577 TL[4] = scsiCmnd->cdb[10]; /* MSB */ 8578 TL[5] = scsiCmnd->cdb[11]; 8579 TL[6] = scsiCmnd->cdb[12]; 8580 TL[7] = scsiCmnd->cdb[13]; /* LSB */ 8581 8582 rangeChk = satAddNComparebit64(LBA, TL); 8583 8584 limitChk = satCompareLBALimitbit(LBA); 8585 8586 lba = satComputeCDB16LBA(satIOContext); 8587 tl = satComputeCDB16TL(satIOContext); 8588 8589 if (pSatDevData->satNCQ != agTRUE && 8590 pSatDevData->sat48BitSupport != agTRUE 8591 ) 8592 { 8593 if (limitChk) 8594 { 8595 TI_DBG1(("satVerify16: return LBA out of range, not EXT\n")); 8596 satSetSensePayload( pSense, 8597 SCSI_SNSKEY_ILLEGAL_REQUEST, 8598 0, 8599 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 8600 satIOContext); 8601 8602 ostiInitiatorIOCompleted( tiRoot, 8603 tiIORequest, 8604 tiIOSuccess, 8605 SCSI_STAT_CHECK_CONDITION, 8606 satIOContext->pTiSenseData, 8607 satIOContext->interruptContext ); 8608 8609 return tiSuccess; 8610 } 8611 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 8612 { 8613 TI_DBG1(("satVerify16: return LBA+TL out of range, not EXT\n")); 8614 satSetSensePayload( pSense, 8615 SCSI_SNSKEY_ILLEGAL_REQUEST, 8616 0, 8617 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 8618 satIOContext); 8619 8620 ostiInitiatorIOCompleted( tiRoot, 8621 tiIORequest, 8622 tiIOSuccess, 8623 SCSI_STAT_CHECK_CONDITION, 8624 satIOContext->pTiSenseData, 8625 satIOContext->interruptContext ); 8626 8627 return tiSuccess; 8628 } 8629 } 8630 8631 if (pSatDevData->sat48BitSupport == agTRUE) 8632 { 8633 TI_DBG5(("satVerify16: SAT_READ_VERIFY_SECTORS_EXT\n")); 8634 fis->h.fisType = 0x27; /* Reg host to device */ 8635 fis->h.c_pmPort = 0x80; /* C Bit is set */ 8636 8637 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 8638 fis->h.features = 0; /* FIS reserve */ 8639 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 8640 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 8641 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 8642 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 8643 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 8644 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 8645 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 8646 fis->d.featuresExp = 0; /* FIS reserve */ 8647 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 8648 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 8649 8650 fis->d.reserved4 = 0; 8651 fis->d.control = 0; /* FIS HOB bit clear */ 8652 fis->d.reserved5 = 0; 8653 8654 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8655 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT; 8656 } 8657 else 8658 { 8659 TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS\n")); 8660 fis->h.fisType = 0x27; /* Reg host to device */ 8661 fis->h.c_pmPort = 0x80; /* C bit is set */ 8662 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 8663 fis->h.features = 0; /* FIS reserve */ 8664 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 8665 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 8666 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 8667 /* FIS LBA mode set LBA (27:24) */ 8668 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); 8669 fis->d.lbaLowExp = 0; 8670 fis->d.lbaMidExp = 0; 8671 fis->d.lbaHighExp = 0; 8672 fis->d.featuresExp = 0; 8673 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 8674 fis->d.sectorCountExp = 0; 8675 fis->d.reserved4 = 0; 8676 fis->d.control = 0; /* FIS HOB bit clear */ 8677 fis->d.reserved5 = 0; 8678 8679 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8680 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS; 8681 8682 } 8683 8684 satIOContext->currentLBA = lba; 8685 satIOContext->OrgTL = tl; 8686 8687 /* 8688 computing number of loop and remainder for tl 8689 0xFF in case not ext 8690 0xFFFF in case EXT 8691 */ 8692 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 8693 { 8694 LoopNum = satComputeLoopNum(tl, 0xFF); 8695 } 8696 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 8697 { 8698 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 8699 LoopNum = satComputeLoopNum(tl, 0xFFFF); 8700 } 8701 else 8702 { 8703 TI_DBG1(("satVerify12: error case 1!!!\n")); 8704 LoopNum = 1; 8705 } 8706 8707 satIOContext->LoopNum = LoopNum; 8708 8709 if (LoopNum == 1) 8710 { 8711 TI_DBG5(("satVerify12: NON CHAINED data\n")); 8712 /* Initialize CB for SATA completion. 8713 */ 8714 satIOContext->satCompleteCB = &satNonChainedVerifyCB; 8715 } 8716 else 8717 { 8718 TI_DBG1(("satVerify12: CHAINED data\n")); 8719 /* re-setting tl */ 8720 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 8721 { 8722 fis->d.sectorCount = 0xFF; 8723 } 8724 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 8725 { 8726 fis->d.sectorCount = 0xFF; 8727 fis->d.sectorCountExp = 0xFF; 8728 } 8729 else 8730 { 8731 TI_DBG1(("satVerify10: error case 2!!!\n")); 8732 } 8733 8734 /* Initialize CB for SATA completion. 8735 */ 8736 satIOContext->satCompleteCB = &satChainedVerifyCB; 8737 } 8738 8739 8740 /* 8741 * Prepare SGL and send FIS to LL layer. 8742 */ 8743 satIOContext->reqType = agRequestType; /* Save it */ 8744 8745 status = sataLLIOStart( tiRoot, 8746 tiIORequest, 8747 tiDeviceHandle, 8748 tiScsiRequest, 8749 satIOContext); 8750 return (status); 8751 } 8752 /*****************************************************************************/ 8753 /*! \brief SAT implementation for SCSI satFormatUnit. 8754 * 8755 * SAT implementation for SCSI satFormatUnit. 8756 * 8757 * \param tiRoot: Pointer to TISA initiator driver/port instance. 8758 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 8759 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 8760 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 8761 * \param satIOContext_t: Pointer to the SAT IO Context 8762 * 8763 * \return If command is started successfully 8764 * - \e tiSuccess: I/O request successfully initiated. 8765 * - \e tiBusy: No resources available, try again later. 8766 * - \e tiIONoDevice: Invalid device handle. 8767 * - \e tiError: Other errors. 8768 */ 8769 /*****************************************************************************/ 8770 GLOBAL bit32 satFormatUnit( 8771 tiRoot_t *tiRoot, 8772 tiIORequest_t *tiIORequest, 8773 tiDeviceHandle_t *tiDeviceHandle, 8774 tiScsiInitiatorRequest_t *tiScsiRequest, 8775 satIOContext_t *satIOContext) 8776 { 8777 /* 8778 note: we don't support media certification in this version and IP bit 8779 satDevData->satFormatState will be agFalse since SAT does not actually sends 8780 any ATA command 8781 */ 8782 8783 scsiRspSense_t *pSense; 8784 tiIniScsiCmnd_t *scsiCmnd; 8785 bit32 index = 0; 8786 8787 pSense = satIOContext->pSense; 8788 scsiCmnd = &tiScsiRequest->scsiCmnd; 8789 8790 TI_DBG5(("satFormatUnit:start\n")); 8791 8792 /* 8793 checking opcode 8794 1. FMTDATA bit == 0(no defect list header) 8795 2. FMTDATA bit == 1 and DCRT bit == 1(defect list header is provided 8796 with DCRT bit set) 8797 */ 8798 if ( ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) == 0) || 8799 ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) && 8800 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK)) 8801 ) 8802 { 8803 ostiInitiatorIOCompleted( tiRoot, 8804 tiIORequest, 8805 tiIOSuccess, 8806 SCSI_STAT_GOOD, 8807 agNULL, 8808 satIOContext->interruptContext); 8809 8810 TI_DBG2(("satFormatUnit: return opcode\n")); 8811 return tiSuccess; 8812 } 8813 8814 /* 8815 checking DEFECT LIST FORMAT and defect list length 8816 */ 8817 if ( (((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x00) || 8818 ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x06)) ) 8819 { 8820 /* short parameter header */ 8821 if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x00) 8822 { 8823 index = 8; 8824 } 8825 /* long parameter header */ 8826 if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x01) 8827 { 8828 index = 10; 8829 } 8830 /* defect list length */ 8831 if ((scsiCmnd->cdb[index] != 0) || (scsiCmnd->cdb[index+1] != 0)) 8832 { 8833 satSetSensePayload( pSense, 8834 SCSI_SNSKEY_ILLEGAL_REQUEST, 8835 0, 8836 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8837 satIOContext); 8838 8839 ostiInitiatorIOCompleted( tiRoot, 8840 tiIORequest, 8841 tiIOSuccess, 8842 SCSI_STAT_CHECK_CONDITION, 8843 satIOContext->pTiSenseData, 8844 satIOContext->interruptContext ); 8845 8846 TI_DBG1(("satFormatUnit: return defect list format\n")); 8847 return tiSuccess; 8848 } 8849 } 8850 8851 /* FMTDATA == 1 && CMPLIST == 1*/ 8852 if ( (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) && 8853 (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_CMPLIST_MASK) ) 8854 { 8855 satSetSensePayload( pSense, 8856 SCSI_SNSKEY_ILLEGAL_REQUEST, 8857 0, 8858 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8859 satIOContext); 8860 8861 ostiInitiatorIOCompleted( tiRoot, 8862 tiIORequest, 8863 tiIOSuccess, 8864 SCSI_STAT_CHECK_CONDITION, 8865 satIOContext->pTiSenseData, 8866 satIOContext->interruptContext ); 8867 8868 TI_DBG1(("satFormatUnit: return cmplist\n")); 8869 return tiSuccess; 8870 8871 } 8872 8873 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 8874 { 8875 satSetSensePayload( pSense, 8876 SCSI_SNSKEY_ILLEGAL_REQUEST, 8877 0, 8878 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8879 satIOContext); 8880 8881 ostiInitiatorIOCompleted( tiRoot, 8882 tiIORequest, 8883 tiIOSuccess, 8884 SCSI_STAT_CHECK_CONDITION, 8885 satIOContext->pTiSenseData, 8886 satIOContext->interruptContext ); 8887 8888 TI_DBG1(("satFormatUnit: return control\n")); 8889 return tiSuccess; 8890 } 8891 8892 /* defect list header filed, if exists, SAT rev8, Table 37, p48 */ 8893 if (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) 8894 { 8895 /* case 1,2,3 */ 8896 /* IMMED 1; FOV 0; FOV 1, DCRT 1, IP 0 */ 8897 if ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) || 8898 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK)) || 8899 ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) && 8900 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) && 8901 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK)) 8902 ) 8903 { 8904 ostiInitiatorIOCompleted( tiRoot, 8905 tiIORequest, 8906 tiIOSuccess, 8907 SCSI_STAT_GOOD, 8908 agNULL, 8909 satIOContext->interruptContext); 8910 8911 TI_DBG5(("satFormatUnit: return defect list case 1\n")); 8912 return tiSuccess; 8913 } 8914 /* case 4,5,6 */ 8915 /* 8916 1. IMMED 0, FOV 1, DCRT 0, IP 0 8917 2. IMMED 0, FOV 1, DCRT 0, IP 1 8918 3. IMMED 0, FOV 1, DCRT 1, IP 1 8919 */ 8920 8921 if ( ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) && 8922 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) && 8923 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) && 8924 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) ) 8925 || 8926 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) && 8927 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) && 8928 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) && 8929 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) ) 8930 || 8931 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) && 8932 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) && 8933 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) && 8934 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) ) 8935 ) 8936 { 8937 8938 satSetSensePayload( pSense, 8939 SCSI_SNSKEY_ILLEGAL_REQUEST, 8940 0, 8941 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 8942 satIOContext); 8943 8944 ostiInitiatorIOCompleted( tiRoot, 8945 tiIORequest, 8946 tiIOSuccess, 8947 SCSI_STAT_CHECK_CONDITION, 8948 satIOContext->pTiSenseData, 8949 satIOContext->interruptContext ); 8950 8951 TI_DBG5(("satFormatUnit: return defect list case 2\n")); 8952 return tiSuccess; 8953 8954 } 8955 } 8956 8957 8958 /* 8959 * Send the completion response now. 8960 */ 8961 ostiInitiatorIOCompleted( tiRoot, 8962 tiIORequest, 8963 tiIOSuccess, 8964 SCSI_STAT_GOOD, 8965 agNULL, 8966 satIOContext->interruptContext); 8967 8968 TI_DBG5(("satFormatUnit: return last\n")); 8969 return tiSuccess; 8970 } 8971 8972 8973 /*****************************************************************************/ 8974 /*! \brief SAT implementation for SCSI satSendDiagnostic. 8975 * 8976 * SAT implementation for SCSI satSendDiagnostic. 8977 * 8978 * \param tiRoot: Pointer to TISA initiator driver/port instance. 8979 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 8980 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 8981 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 8982 * \param satIOContext_t: Pointer to the SAT IO Context 8983 * 8984 * \return If command is started successfully 8985 * - \e tiSuccess: I/O request successfully initiated. 8986 * - \e tiBusy: No resources available, try again later. 8987 * - \e tiIONoDevice: Invalid device handle. 8988 * - \e tiError: Other errors. 8989 */ 8990 /*****************************************************************************/ 8991 GLOBAL bit32 satSendDiagnostic( 8992 tiRoot_t *tiRoot, 8993 tiIORequest_t *tiIORequest, 8994 tiDeviceHandle_t *tiDeviceHandle, 8995 tiScsiInitiatorRequest_t *tiScsiRequest, 8996 satIOContext_t *satIOContext) 8997 { 8998 bit32 status; 8999 bit32 agRequestType; 9000 satDeviceData_t *pSatDevData; 9001 scsiRspSense_t *pSense; 9002 tiIniScsiCmnd_t *scsiCmnd; 9003 agsaFisRegHostToDevice_t *fis; 9004 bit32 parmLen; 9005 9006 pSense = satIOContext->pSense; 9007 pSatDevData = satIOContext->pSatDevData; 9008 scsiCmnd = &tiScsiRequest->scsiCmnd; 9009 fis = satIOContext->pFis; 9010 9011 TI_DBG5(("satSendDiagnostic:start\n")); 9012 9013 /* reset satVerifyState */ 9014 pSatDevData->satVerifyState = 0; 9015 /* no pending diagnostic in background */ 9016 pSatDevData->satBGPendingDiag = agFALSE; 9017 9018 /* table 27, 8.10 p39 SAT Rev8 */ 9019 /* 9020 1. checking PF == 1 9021 2. checking DEVOFFL == 1 9022 3. checking UNITOFFL == 1 9023 4. checking PARAMETER LIST LENGTH != 0 9024 9025 */ 9026 if ( (scsiCmnd->cdb[1] & SCSI_PF_MASK) || 9027 (scsiCmnd->cdb[1] & SCSI_DEVOFFL_MASK) || 9028 (scsiCmnd->cdb[1] & SCSI_UNITOFFL_MASK) || 9029 ( (scsiCmnd->cdb[3] != 0) || (scsiCmnd->cdb[4] != 0) ) 9030 ) 9031 { 9032 satSetSensePayload( pSense, 9033 SCSI_SNSKEY_ILLEGAL_REQUEST, 9034 0, 9035 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9036 satIOContext); 9037 9038 ostiInitiatorIOCompleted( tiRoot, 9039 tiIORequest, 9040 tiIOSuccess, 9041 SCSI_STAT_CHECK_CONDITION, 9042 satIOContext->pTiSenseData, 9043 satIOContext->interruptContext ); 9044 9045 TI_DBG1(("satSendDiagnostic: return PF, DEVOFFL, UNITOFFL, PARAM LIST\n")); 9046 return tiSuccess; 9047 } 9048 9049 /* checking CONTROL */ 9050 /* NACA == 1 or LINK == 1*/ 9051 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 9052 { 9053 satSetSensePayload( pSense, 9054 SCSI_SNSKEY_ILLEGAL_REQUEST, 9055 0, 9056 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9057 satIOContext); 9058 9059 ostiInitiatorIOCompleted( tiRoot, 9060 tiIORequest, 9061 tiIOSuccess, 9062 SCSI_STAT_CHECK_CONDITION, 9063 satIOContext->pTiSenseData, 9064 satIOContext->interruptContext ); 9065 9066 TI_DBG2(("satSendDiagnostic: return control\n")); 9067 return tiSuccess; 9068 } 9069 9070 parmLen = (scsiCmnd->cdb[3] << 8) + scsiCmnd->cdb[4]; 9071 9072 /* checking SELFTEST bit*/ 9073 /* table 29, 8.10.3, p41 SAT Rev8 */ 9074 /* case 1 */ 9075 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 9076 (pSatDevData->satSMARTSelfTest == agFALSE) 9077 ) 9078 { 9079 satSetSensePayload( pSense, 9080 SCSI_SNSKEY_ILLEGAL_REQUEST, 9081 0, 9082 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9083 satIOContext); 9084 9085 ostiInitiatorIOCompleted( tiRoot, 9086 tiIORequest, 9087 tiIOSuccess, 9088 SCSI_STAT_CHECK_CONDITION, 9089 satIOContext->pTiSenseData, 9090 satIOContext->interruptContext ); 9091 9092 TI_DBG1(("satSendDiagnostic: return Table 29 case 1\n")); 9093 return tiSuccess; 9094 } 9095 9096 /* case 2 */ 9097 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 9098 (pSatDevData->satSMARTSelfTest == agTRUE) && 9099 (pSatDevData->satSMARTEnabled == agFALSE) 9100 ) 9101 { 9102 satSetSensePayload( pSense, 9103 SCSI_SNSKEY_ABORTED_COMMAND, 9104 0, 9105 SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED, 9106 satIOContext); 9107 9108 ostiInitiatorIOCompleted( tiRoot, 9109 tiIORequest, 9110 tiIOSuccess, 9111 SCSI_STAT_CHECK_CONDITION, 9112 satIOContext->pTiSenseData, 9113 satIOContext->interruptContext ); 9114 9115 TI_DBG5(("satSendDiagnostic: return Table 29 case 2\n")); 9116 return tiSuccess; 9117 } 9118 /* 9119 case 3 9120 see SELF TEST CODE later 9121 */ 9122 9123 9124 9125 /* case 4 */ 9126 9127 /* 9128 sends three ATA verify commands 9129 9130 */ 9131 if ( ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 9132 (pSatDevData->satSMARTSelfTest == agFALSE)) 9133 || 9134 ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 9135 (pSatDevData->satSMARTSelfTest == agTRUE) && 9136 (pSatDevData->satSMARTEnabled == agFALSE)) 9137 ) 9138 { 9139 /* 9140 sector count 1, LBA 0 9141 sector count 1, LBA MAX 9142 sector count 1, LBA random 9143 */ 9144 if (pSatDevData->sat48BitSupport == agTRUE) 9145 { 9146 /* sends READ VERIFY SECTOR(S) EXT*/ 9147 fis->h.fisType = 0x27; /* Reg host to device */ 9148 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9149 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 9150 fis->h.features = 0; /* FIS reserve */ 9151 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 9152 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 9153 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 9154 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 9155 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 9156 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 9157 fis->d.featuresExp = 0; /* FIS reserve */ 9158 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 9159 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 9160 fis->d.reserved4 = 0; 9161 fis->d.device = 0x40; /* 01000000 */ 9162 fis->d.control = 0; /* FIS HOB bit clear */ 9163 fis->d.reserved5 = 0; 9164 9165 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9166 } 9167 else 9168 { 9169 /* READ VERIFY SECTOR(S)*/ 9170 fis->h.fisType = 0x27; /* Reg host to device */ 9171 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9172 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 9173 fis->h.features = 0; /* FIS features NA */ 9174 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 9175 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 9176 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 9177 fis->d.lbaLowExp = 0; 9178 fis->d.lbaMidExp = 0; 9179 fis->d.lbaHighExp = 0; 9180 fis->d.featuresExp = 0; 9181 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 9182 fis->d.sectorCountExp = 0; 9183 fis->d.reserved4 = 0; 9184 fis->d.device = 0x40; /* 01000000 */ 9185 fis->d.control = 0; /* FIS HOB bit clear */ 9186 fis->d.reserved5 = 0; 9187 9188 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9189 } 9190 9191 /* Initialize CB for SATA completion. 9192 */ 9193 satIOContext->satCompleteCB = &satSendDiagnosticCB; 9194 9195 /* 9196 * Prepare SGL and send FIS to LL layer. 9197 */ 9198 satIOContext->reqType = agRequestType; /* Save it */ 9199 9200 status = sataLLIOStart( tiRoot, 9201 tiIORequest, 9202 tiDeviceHandle, 9203 tiScsiRequest, 9204 satIOContext); 9205 9206 9207 TI_DBG5(("satSendDiagnostic: return Table 29 case 4\n")); 9208 return (status); 9209 } 9210 /* case 5 */ 9211 if ( (scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 9212 (pSatDevData->satSMARTSelfTest == agTRUE) && 9213 (pSatDevData->satSMARTEnabled == agTRUE) 9214 ) 9215 { 9216 /* sends SMART EXECUTE OFF-LINE IMMEDIATE */ 9217 fis->h.fisType = 0x27; /* Reg host to device */ 9218 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9219 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0xB0 */ 9220 fis->h.features = 0xD4; /* FIS features NA */ 9221 fis->d.lbaLow = 0x81; /* FIS LBA (7 :0 ) */ 9222 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 9223 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 9224 fis->d.lbaLowExp = 0; 9225 fis->d.lbaMidExp = 0; 9226 fis->d.lbaHighExp = 0; 9227 fis->d.featuresExp = 0; 9228 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 9229 fis->d.sectorCountExp = 0; 9230 fis->d.reserved4 = 0; 9231 fis->d.device = 0; /* FIS DEV is discared in SATA */ 9232 fis->d.control = 0; /* FIS HOB bit clear */ 9233 fis->d.reserved5 = 0; 9234 9235 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9236 9237 /* Initialize CB for SATA completion. 9238 */ 9239 satIOContext->satCompleteCB = &satSendDiagnosticCB; 9240 9241 /* 9242 * Prepare SGL and send FIS to LL layer. 9243 */ 9244 satIOContext->reqType = agRequestType; /* Save it */ 9245 9246 status = sataLLIOStart( tiRoot, 9247 tiIORequest, 9248 tiDeviceHandle, 9249 tiScsiRequest, 9250 satIOContext); 9251 9252 9253 TI_DBG5(("satSendDiagnostic: return Table 29 case 5\n")); 9254 return (status); 9255 } 9256 9257 9258 9259 9260 /* SAT rev8 Table29 p41 case 3*/ 9261 /* checking SELF TEST CODE*/ 9262 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 9263 (pSatDevData->satSMARTSelfTest == agTRUE) && 9264 (pSatDevData->satSMARTEnabled == agTRUE) 9265 ) 9266 { 9267 /* SAT rev8 Table28 p40 */ 9268 /* finding self-test code */ 9269 switch ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_TEST_CODE_MASK) >> 5) 9270 { 9271 case 1: 9272 pSatDevData->satBGPendingDiag = agTRUE; 9273 9274 ostiInitiatorIOCompleted( tiRoot, 9275 tiIORequest, 9276 tiIOSuccess, 9277 SCSI_STAT_GOOD, 9278 agNULL, 9279 satIOContext->interruptContext ); 9280 /* sends SMART EXECUTE OFF-LINE IMMEDIATE */ 9281 fis->h.fisType = 0x27; /* Reg host to device */ 9282 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9283 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */ 9284 fis->h.features = 0xD4; /* FIS features NA */ 9285 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */ 9286 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 9287 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 9288 9289 fis->d.lbaLowExp = 0; 9290 fis->d.lbaMidExp = 0; 9291 fis->d.lbaHighExp = 0; 9292 fis->d.featuresExp = 0; 9293 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 9294 fis->d.sectorCountExp = 0; 9295 fis->d.reserved4 = 0; 9296 fis->d.device = 0; /* FIS DEV is discared in SATA */ 9297 fis->d.control = 0; /* FIS HOB bit clear */ 9298 fis->d.reserved5 = 0; 9299 9300 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9301 9302 /* Initialize CB for SATA completion. 9303 */ 9304 satIOContext->satCompleteCB = &satSendDiagnosticCB; 9305 9306 /* 9307 * Prepare SGL and send FIS to LL layer. 9308 */ 9309 satIOContext->reqType = agRequestType; /* Save it */ 9310 9311 status = sataLLIOStart( tiRoot, 9312 tiIORequest, 9313 tiDeviceHandle, 9314 tiScsiRequest, 9315 satIOContext); 9316 9317 9318 TI_DBG5(("satSendDiagnostic: return Table 28 case 1\n")); 9319 return (status); 9320 case 2: 9321 pSatDevData->satBGPendingDiag = agTRUE; 9322 9323 ostiInitiatorIOCompleted( tiRoot, 9324 tiIORequest, 9325 tiIOSuccess, 9326 SCSI_STAT_GOOD, 9327 agNULL, 9328 satIOContext->interruptContext ); 9329 9330 9331 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */ 9332 fis->h.fisType = 0x27; /* Reg host to device */ 9333 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9334 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */ 9335 fis->h.features = 0xD4; /* FIS features NA */ 9336 fis->d.lbaLow = 0x02; /* FIS LBA (7 :0 ) */ 9337 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 9338 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 9339 fis->d.lbaLowExp = 0; 9340 fis->d.lbaMidExp = 0; 9341 fis->d.lbaHighExp = 0; 9342 fis->d.featuresExp = 0; 9343 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 9344 fis->d.sectorCountExp = 0; 9345 fis->d.reserved4 = 0; 9346 fis->d.device = 0; /* FIS DEV is discared in SATA */ 9347 fis->d.control = 0; /* FIS HOB bit clear */ 9348 fis->d.reserved5 = 0; 9349 9350 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9351 9352 /* Initialize CB for SATA completion. 9353 */ 9354 satIOContext->satCompleteCB = &satSendDiagnosticCB; 9355 9356 /* 9357 * Prepare SGL and send FIS to LL layer. 9358 */ 9359 satIOContext->reqType = agRequestType; /* Save it */ 9360 9361 status = sataLLIOStart( tiRoot, 9362 tiIORequest, 9363 tiDeviceHandle, 9364 tiScsiRequest, 9365 satIOContext); 9366 9367 9368 TI_DBG5(("satSendDiagnostic: return Table 28 case 2\n")); 9369 return (status); 9370 case 4: 9371 /* For simplicity, no abort is supported 9372 Returns good status 9373 need a flag in device data for previously sent background Send Diagnostic 9374 */ 9375 if (parmLen != 0) 9376 { 9377 /* check condition */ 9378 satSetSensePayload( pSense, 9379 SCSI_SNSKEY_ILLEGAL_REQUEST, 9380 0, 9381 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9382 satIOContext); 9383 9384 ostiInitiatorIOCompleted( tiRoot, 9385 tiIORequest, 9386 tiIOSuccess, 9387 SCSI_STAT_CHECK_CONDITION, 9388 satIOContext->pTiSenseData, 9389 satIOContext->interruptContext ); 9390 9391 TI_DBG1(("satSendDiagnostic: case 4, non zero ParmLen %d\n", parmLen)); 9392 return tiSuccess; 9393 } 9394 if (pSatDevData->satBGPendingDiag == agTRUE) 9395 { 9396 /* sends SMART EXECUTE OFF-LINE IMMEDIATE abort */ 9397 fis->h.fisType = 0x27; /* Reg host to device */ 9398 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9399 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */ 9400 fis->h.features = 0xD4; /* FIS features NA */ 9401 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */ 9402 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 9403 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 9404 9405 fis->d.lbaLowExp = 0; 9406 fis->d.lbaMidExp = 0; 9407 fis->d.lbaHighExp = 0; 9408 fis->d.featuresExp = 0; 9409 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 9410 fis->d.sectorCountExp = 0; 9411 fis->d.reserved4 = 0; 9412 fis->d.device = 0; /* FIS DEV is discared in SATA */ 9413 fis->d.control = 0; /* FIS HOB bit clear */ 9414 fis->d.reserved5 = 0; 9415 9416 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9417 9418 /* Initialize CB for SATA completion. 9419 */ 9420 satIOContext->satCompleteCB = &satSendDiagnosticCB; 9421 9422 /* 9423 * Prepare SGL and send FIS to LL layer. 9424 */ 9425 satIOContext->reqType = agRequestType; /* Save it */ 9426 9427 status = sataLLIOStart( tiRoot, 9428 tiIORequest, 9429 tiDeviceHandle, 9430 tiScsiRequest, 9431 satIOContext); 9432 9433 9434 TI_DBG5(("satSendDiagnostic: send SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE case 3\n")); 9435 TI_DBG5(("satSendDiagnostic: Table 28 case 4\n")); 9436 return (status); 9437 } 9438 else 9439 { 9440 /* check condition */ 9441 satSetSensePayload( pSense, 9442 SCSI_SNSKEY_ILLEGAL_REQUEST, 9443 0, 9444 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9445 satIOContext); 9446 9447 ostiInitiatorIOCompleted( tiRoot, 9448 tiIORequest, 9449 tiIOSuccess, 9450 SCSI_STAT_CHECK_CONDITION, 9451 satIOContext->pTiSenseData, 9452 satIOContext->interruptContext ); 9453 9454 TI_DBG1(("satSendDiagnostic: case 4, no pending diagnostic in background\n")); 9455 TI_DBG5(("satSendDiagnostic: Table 28 case 4\n")); 9456 return tiSuccess; 9457 } 9458 break; 9459 case 5: 9460 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */ 9461 fis->h.fisType = 0x27; /* Reg host to device */ 9462 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9463 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */ 9464 fis->h.features = 0xD4; /* FIS features NA */ 9465 fis->d.lbaLow = 0x81; /* FIS LBA (7 :0 ) */ 9466 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 9467 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 9468 fis->d.lbaLowExp = 0; 9469 fis->d.lbaMidExp = 0; 9470 fis->d.lbaHighExp = 0; 9471 fis->d.featuresExp = 0; 9472 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 9473 fis->d.sectorCountExp = 0; 9474 fis->d.reserved4 = 0; 9475 fis->d.device = 0; /* FIS DEV is discared in SATA */ 9476 fis->d.control = 0; /* FIS HOB bit clear */ 9477 fis->d.reserved5 = 0; 9478 9479 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9480 9481 /* Initialize CB for SATA completion. 9482 */ 9483 satIOContext->satCompleteCB = &satSendDiagnosticCB; 9484 9485 /* 9486 * Prepare SGL and send FIS to LL layer. 9487 */ 9488 satIOContext->reqType = agRequestType; /* Save it */ 9489 9490 status = sataLLIOStart( tiRoot, 9491 tiIORequest, 9492 tiDeviceHandle, 9493 tiScsiRequest, 9494 satIOContext); 9495 9496 9497 TI_DBG5(("satSendDiagnostic: return Table 28 case 5\n")); 9498 return (status); 9499 case 6: 9500 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */ 9501 fis->h.fisType = 0x27; /* Reg host to device */ 9502 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9503 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */ 9504 fis->h.features = 0xD4; /* FIS features NA */ 9505 fis->d.lbaLow = 0x82; /* FIS LBA (7 :0 ) */ 9506 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 9507 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 9508 fis->d.lbaLowExp = 0; 9509 fis->d.lbaMidExp = 0; 9510 fis->d.lbaHighExp = 0; 9511 fis->d.featuresExp = 0; 9512 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 9513 fis->d.sectorCountExp = 0; 9514 fis->d.reserved4 = 0; 9515 fis->d.device = 0; /* FIS DEV is discared in SATA */ 9516 fis->d.control = 0; /* FIS HOB bit clear */ 9517 fis->d.reserved5 = 0; 9518 9519 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9520 9521 /* Initialize CB for SATA completion. 9522 */ 9523 satIOContext->satCompleteCB = &satSendDiagnosticCB; 9524 9525 /* 9526 * Prepare SGL and send FIS to LL layer. 9527 */ 9528 satIOContext->reqType = agRequestType; /* Save it */ 9529 9530 status = sataLLIOStart( tiRoot, 9531 tiIORequest, 9532 tiDeviceHandle, 9533 tiScsiRequest, 9534 satIOContext); 9535 9536 9537 TI_DBG5(("satSendDiagnostic: return Table 28 case 6\n")); 9538 return (status); 9539 case 0: 9540 case 3: /* fall through */ 9541 case 7: /* fall through */ 9542 default: 9543 break; 9544 }/* switch */ 9545 9546 /* returns the results of default self-testing, which is good */ 9547 ostiInitiatorIOCompleted( tiRoot, 9548 tiIORequest, 9549 tiIOSuccess, 9550 SCSI_STAT_GOOD, 9551 agNULL, 9552 satIOContext->interruptContext ); 9553 9554 TI_DBG5(("satSendDiagnostic: return Table 28 case 0,3,7 and default\n")); 9555 return tiSuccess; 9556 } 9557 9558 9559 ostiInitiatorIOCompleted( tiRoot, 9560 tiIORequest, 9561 tiIOSuccess, 9562 SCSI_STAT_GOOD, 9563 agNULL, 9564 satIOContext->interruptContext ); 9565 9566 9567 TI_DBG5(("satSendDiagnostic: return last\n")); 9568 return tiSuccess; 9569 } 9570 9571 /*****************************************************************************/ 9572 /*! \brief SAT implementation for SCSI satSendDiagnostic_1. 9573 * 9574 * SAT implementation for SCSI satSendDiagnostic_1. 9575 * Sub function of satSendDiagnostic. 9576 * 9577 * \param tiRoot: Pointer to TISA initiator driver/port instance. 9578 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 9579 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 9580 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 9581 * \param satIOContext_t: Pointer to the SAT IO Context 9582 * 9583 * \return If command is started successfully 9584 * - \e tiSuccess: I/O request successfully initiated. 9585 * - \e tiBusy: No resources available, try again later. 9586 * - \e tiIONoDevice: Invalid device handle. 9587 * - \e tiError: Other errors. 9588 */ 9589 /*****************************************************************************/ 9590 GLOBAL bit32 satSendDiagnostic_1( 9591 tiRoot_t *tiRoot, 9592 tiIORequest_t *tiIORequest, 9593 tiDeviceHandle_t *tiDeviceHandle, 9594 tiScsiInitiatorRequest_t *tiScsiRequest, 9595 satIOContext_t *satIOContext) 9596 { 9597 /* 9598 SAT Rev9, Table29, p41 9599 send 2nd SAT_READ_VERIFY_SECTORS(_EXT) 9600 */ 9601 bit32 status; 9602 bit32 agRequestType; 9603 satDeviceData_t *pSatDevData; 9604 agsaFisRegHostToDevice_t *fis; 9605 9606 TI_DBG5(("satSendDiagnostic_1 entry: tiDeviceHandle=%p tiIORequest=%p\n", 9607 tiDeviceHandle, tiIORequest)); 9608 9609 pSatDevData = satIOContext->pSatDevData; 9610 fis = satIOContext->pFis; 9611 9612 /* 9613 sector count 1, LBA MAX 9614 */ 9615 if (pSatDevData->sat48BitSupport == agTRUE) 9616 { 9617 /* sends READ VERIFY SECTOR(S) EXT*/ 9618 fis->h.fisType = 0x27; /* Reg host to device */ 9619 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9620 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 9621 fis->h.features = 0; /* FIS reserve */ 9622 fis->d.lbaLow = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */ 9623 fis->d.lbaMid = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */ 9624 fis->d.lbaHigh = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */ 9625 fis->d.lbaLowExp = pSatDevData->satMaxLBA[4]; /* FIS LBA (31:24) */ 9626 fis->d.lbaMidExp = pSatDevData->satMaxLBA[3]; /* FIS LBA (39:32) */ 9627 fis->d.lbaHighExp = pSatDevData->satMaxLBA[2]; /* FIS LBA (47:40) */ 9628 fis->d.featuresExp = 0; /* FIS reserve */ 9629 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 9630 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 9631 fis->d.reserved4 = 0; 9632 fis->d.device = 0x40; /* 01000000 */ 9633 fis->d.control = 0; /* FIS HOB bit clear */ 9634 fis->d.reserved5 = 0; 9635 9636 } 9637 else 9638 { 9639 /* READ VERIFY SECTOR(S)*/ 9640 fis->h.fisType = 0x27; /* Reg host to device */ 9641 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9642 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 9643 fis->h.features = 0; /* FIS features NA */ 9644 fis->d.lbaLow = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */ 9645 fis->d.lbaMid = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */ 9646 fis->d.lbaHigh = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */ 9647 fis->d.lbaLowExp = 0; 9648 fis->d.lbaMidExp = 0; 9649 fis->d.lbaHighExp = 0; 9650 fis->d.featuresExp = 0; 9651 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 9652 fis->d.sectorCountExp = 0; 9653 fis->d.reserved4 = 0; 9654 fis->d.device = (bit8)((0x4 << 4) | (pSatDevData->satMaxLBA[4] & 0xF)); 9655 /* DEV and LBA 27:24 */ 9656 fis->d.control = 0; /* FIS HOB bit clear */ 9657 fis->d.reserved5 = 0; 9658 9659 } 9660 9661 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9662 9663 /* Initialize CB for SATA completion. 9664 */ 9665 satIOContext->satCompleteCB = &satSendDiagnosticCB; 9666 9667 /* 9668 * Prepare SGL and send FIS to LL layer. 9669 */ 9670 satIOContext->reqType = agRequestType; /* Save it */ 9671 9672 status = sataLLIOStart( tiRoot, 9673 tiIORequest, 9674 tiDeviceHandle, 9675 tiScsiRequest, 9676 satIOContext); 9677 9678 9679 return status; 9680 } 9681 9682 /*****************************************************************************/ 9683 /*! \brief SAT implementation for SCSI satSendDiagnostic_2. 9684 * 9685 * SAT implementation for SCSI satSendDiagnostic_2. 9686 * Sub function of satSendDiagnostic. 9687 * 9688 * \param tiRoot: Pointer to TISA initiator driver/port instance. 9689 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 9690 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 9691 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 9692 * \param satIOContext_t: Pointer to the SAT IO Context 9693 * 9694 * \return If command is started successfully 9695 * - \e tiSuccess: I/O request successfully initiated. 9696 * - \e tiBusy: No resources available, try again later. 9697 * - \e tiIONoDevice: Invalid device handle. 9698 * - \e tiError: Other errors. 9699 */ 9700 /*****************************************************************************/ 9701 GLOBAL bit32 satSendDiagnostic_2( 9702 tiRoot_t *tiRoot, 9703 tiIORequest_t *tiIORequest, 9704 tiDeviceHandle_t *tiDeviceHandle, 9705 tiScsiInitiatorRequest_t *tiScsiRequest, 9706 satIOContext_t *satIOContext) 9707 { 9708 /* 9709 SAT Rev9, Table29, p41 9710 send 3rd SAT_READ_VERIFY_SECTORS(_EXT) 9711 */ 9712 bit32 status; 9713 bit32 agRequestType; 9714 satDeviceData_t *pSatDevData; 9715 agsaFisRegHostToDevice_t *fis; 9716 9717 TI_DBG5(("satSendDiagnostic_2 entry: tiDeviceHandle=%p tiIORequest=%p\n", 9718 tiDeviceHandle, tiIORequest)); 9719 9720 pSatDevData = satIOContext->pSatDevData; 9721 fis = satIOContext->pFis; 9722 9723 /* 9724 sector count 1, LBA Random 9725 */ 9726 if (pSatDevData->sat48BitSupport == agTRUE) 9727 { 9728 /* sends READ VERIFY SECTOR(S) EXT*/ 9729 fis->h.fisType = 0x27; /* Reg host to device */ 9730 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9731 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 9732 fis->h.features = 0; /* FIS reserve */ 9733 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */ 9734 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 9735 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 9736 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 9737 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 9738 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 9739 fis->d.featuresExp = 0; /* FIS reserve */ 9740 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 9741 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 9742 fis->d.reserved4 = 0; 9743 fis->d.device = 0x40; /* 01000000 */ 9744 fis->d.control = 0; /* FIS HOB bit clear */ 9745 fis->d.reserved5 = 0; 9746 9747 } 9748 else 9749 { 9750 /* READ VERIFY SECTOR(S)*/ 9751 fis->h.fisType = 0x27; /* Reg host to device */ 9752 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9753 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 9754 fis->h.features = 0; /* FIS features NA */ 9755 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */ 9756 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 9757 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 9758 fis->d.lbaLowExp = 0; 9759 fis->d.lbaMidExp = 0; 9760 fis->d.lbaHighExp = 0; 9761 fis->d.featuresExp = 0; 9762 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 9763 fis->d.sectorCountExp = 0; 9764 fis->d.reserved4 = 0; 9765 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 9766 fis->d.control = 0; /* FIS HOB bit clear */ 9767 fis->d.reserved5 = 0; 9768 9769 } 9770 9771 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9772 9773 /* Initialize CB for SATA completion. 9774 */ 9775 satIOContext->satCompleteCB = &satSendDiagnosticCB; 9776 9777 /* 9778 * Prepare SGL and send FIS to LL layer. 9779 */ 9780 satIOContext->reqType = agRequestType; /* Save it */ 9781 9782 status = sataLLIOStart( tiRoot, 9783 tiIORequest, 9784 tiDeviceHandle, 9785 tiScsiRequest, 9786 satIOContext); 9787 9788 9789 return status; 9790 } 9791 /*****************************************************************************/ 9792 /*! \brief SAT implementation for SCSI satStartStopUnit. 9793 * 9794 * SAT implementation for SCSI satStartStopUnit. 9795 * 9796 * \param tiRoot: Pointer to TISA initiator driver/port instance. 9797 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 9798 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 9799 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 9800 * \param satIOContext_t: Pointer to the SAT IO Context 9801 * 9802 * \return If command is started successfully 9803 * - \e tiSuccess: I/O request successfully initiated. 9804 * - \e tiBusy: No resources available, try again later. 9805 * - \e tiIONoDevice: Invalid device handle. 9806 * - \e tiError: Other errors. 9807 */ 9808 /*****************************************************************************/ 9809 GLOBAL bit32 satStartStopUnit( 9810 tiRoot_t *tiRoot, 9811 tiIORequest_t *tiIORequest, 9812 tiDeviceHandle_t *tiDeviceHandle, 9813 tiScsiInitiatorRequest_t *tiScsiRequest, 9814 satIOContext_t *satIOContext) 9815 { 9816 bit32 status; 9817 bit32 agRequestType; 9818 satDeviceData_t *pSatDevData; 9819 scsiRspSense_t *pSense; 9820 tiIniScsiCmnd_t *scsiCmnd; 9821 agsaFisRegHostToDevice_t *fis; 9822 9823 pSense = satIOContext->pSense; 9824 pSatDevData = satIOContext->pSatDevData; 9825 scsiCmnd = &tiScsiRequest->scsiCmnd; 9826 fis = satIOContext->pFis; 9827 9828 TI_DBG5(("satStartStopUnit:start\n")); 9829 9830 /* checking CONTROL */ 9831 /* NACA == 1 or LINK == 1*/ 9832 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 9833 { 9834 satSetSensePayload( pSense, 9835 SCSI_SNSKEY_ILLEGAL_REQUEST, 9836 0, 9837 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9838 satIOContext); 9839 9840 ostiInitiatorIOCompleted( tiRoot, 9841 tiIORequest, 9842 tiIOSuccess, 9843 SCSI_STAT_CHECK_CONDITION, 9844 satIOContext->pTiSenseData, 9845 satIOContext->interruptContext ); 9846 9847 TI_DBG1(("satStartStopUnit: return control\n")); 9848 return tiSuccess; 9849 } 9850 9851 /* Spec p55, Table 48 checking START and LOEJ bit */ 9852 /* case 1 */ 9853 if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) 9854 { 9855 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) ) 9856 { 9857 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/ 9858 ostiInitiatorIOCompleted( tiRoot, 9859 tiIORequest, 9860 tiIOSuccess, 9861 SCSI_STAT_GOOD, 9862 agNULL, 9863 satIOContext->interruptContext ); 9864 TI_DBG5(("satStartStopUnit: return table48 case 1-1\n")); 9865 return tiSuccess; 9866 } 9867 /* sends FLUSH CACHE or FLUSH CACHE EXT */ 9868 if (pSatDevData->sat48BitSupport == agTRUE) 9869 { 9870 /* FLUSH CACHE EXT */ 9871 fis->h.fisType = 0x27; /* Reg host to device */ 9872 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9873 9874 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */ 9875 fis->h.features = 0; /* FIS reserve */ 9876 fis->d.featuresExp = 0; /* FIS reserve */ 9877 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 9878 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 9879 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 9880 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 9881 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 9882 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 9883 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 9884 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 9885 fis->d.device = 0; /* FIS DEV is discared in SATA */ 9886 fis->d.control = 0; /* FIS HOB bit clear */ 9887 fis->d.reserved4 = 0; 9888 fis->d.reserved5 = 0; 9889 9890 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9891 } 9892 else 9893 { 9894 /* FLUSH CACHE */ 9895 fis->h.fisType = 0x27; /* Reg host to device */ 9896 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9897 9898 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */ 9899 fis->h.features = 0; /* FIS features NA */ 9900 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 9901 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 9902 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 9903 fis->d.lbaLowExp = 0; 9904 fis->d.lbaMidExp = 0; 9905 fis->d.lbaHighExp = 0; 9906 fis->d.featuresExp = 0; 9907 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 9908 fis->d.sectorCountExp = 0; 9909 fis->d.device = 0; /* FIS DEV is discared in SATA */ 9910 fis->d.control = 0; /* FIS HOB bit clear */ 9911 fis->d.reserved4 = 0; 9912 fis->d.reserved5 = 0; 9913 9914 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9915 } 9916 9917 /* Initialize CB for SATA completion. 9918 */ 9919 satIOContext->satCompleteCB = &satStartStopUnitCB; 9920 9921 /* 9922 * Prepare SGL and send FIS to LL layer. 9923 */ 9924 satIOContext->reqType = agRequestType; /* Save it */ 9925 9926 status = sataLLIOStart( tiRoot, 9927 tiIORequest, 9928 tiDeviceHandle, 9929 tiScsiRequest, 9930 satIOContext); 9931 9932 9933 TI_DBG5(("satStartStopUnit: return table48 case 1\n")); 9934 return (status); 9935 } 9936 /* case 2 */ 9937 else if ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) 9938 { 9939 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/ 9940 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) ) 9941 { 9942 ostiInitiatorIOCompleted( tiRoot, 9943 tiIORequest, 9944 tiIOSuccess, 9945 SCSI_STAT_GOOD, 9946 agNULL, 9947 satIOContext->interruptContext ); 9948 9949 TI_DBG5(("satStartStopUnit: return table48 case 2 1\n")); 9950 return tiSuccess; 9951 } 9952 /* 9953 sends READ_VERIFY_SECTORS(_EXT) 9954 sector count 1, any LBA between zero to Maximum 9955 */ 9956 if (pSatDevData->sat48BitSupport == agTRUE) 9957 { 9958 /* READ VERIFY SECTOR(S) EXT*/ 9959 fis->h.fisType = 0x27; /* Reg host to device */ 9960 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9961 9962 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 9963 fis->h.features = 0; /* FIS reserve */ 9964 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */ 9965 fis->d.lbaMid = 0x00; /* FIS LBA (15:8 ) */ 9966 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */ 9967 fis->d.lbaLowExp = 0x00; /* FIS LBA (31:24) */ 9968 fis->d.lbaMidExp = 0x00; /* FIS LBA (39:32) */ 9969 fis->d.lbaHighExp = 0x00; /* FIS LBA (47:40) */ 9970 fis->d.featuresExp = 0; /* FIS reserve */ 9971 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 9972 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 9973 fis->d.reserved4 = 0; 9974 fis->d.device = 0x40; /* 01000000 */ 9975 fis->d.control = 0; /* FIS HOB bit clear */ 9976 fis->d.reserved5 = 0; 9977 9978 } 9979 else 9980 { 9981 /* READ VERIFY SECTOR(S)*/ 9982 fis->h.fisType = 0x27; /* Reg host to device */ 9983 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9984 9985 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 9986 fis->h.features = 0; /* FIS features NA */ 9987 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */ 9988 fis->d.lbaMid = 0x00; /* FIS LBA (15:8 ) */ 9989 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */ 9990 fis->d.lbaLowExp = 0; 9991 fis->d.lbaMidExp = 0; 9992 fis->d.lbaHighExp = 0; 9993 fis->d.featuresExp = 0; 9994 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 9995 fis->d.sectorCountExp = 0; 9996 fis->d.reserved4 = 0; 9997 fis->d.device = 0x40; /* 01000000 */ 9998 fis->d.control = 0; /* FIS HOB bit clear */ 9999 fis->d.reserved5 = 0; 10000 10001 } 10002 10003 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 10004 10005 /* Initialize CB for SATA completion. 10006 */ 10007 satIOContext->satCompleteCB = &satStartStopUnitCB; 10008 10009 /* 10010 * Prepare SGL and send FIS to LL layer. 10011 */ 10012 satIOContext->reqType = agRequestType; /* Save it */ 10013 10014 status = sataLLIOStart( tiRoot, 10015 tiIORequest, 10016 tiDeviceHandle, 10017 tiScsiRequest, 10018 satIOContext); 10019 10020 TI_DBG5(("satStartStopUnit: return table48 case 2 2\n")); 10021 return status; 10022 } 10023 /* case 3 */ 10024 else if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) 10025 { 10026 if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled) 10027 { 10028 /* support for removal media */ 10029 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/ 10030 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) ) 10031 { 10032 ostiInitiatorIOCompleted( tiRoot, 10033 tiIORequest, 10034 tiIOSuccess, 10035 SCSI_STAT_GOOD, 10036 agNULL, 10037 satIOContext->interruptContext ); 10038 10039 TI_DBG5(("satStartStopUnit: return table48 case 3 1\n")); 10040 return tiSuccess; 10041 } 10042 /* 10043 sends MEDIA EJECT 10044 */ 10045 /* Media Eject fis */ 10046 fis->h.fisType = 0x27; /* Reg host to device */ 10047 fis->h.c_pmPort = 0x80; /* C Bit is set */ 10048 10049 fis->h.command = SAT_MEDIA_EJECT; /* 0xED */ 10050 fis->h.features = 0; /* FIS features NA */ 10051 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 10052 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 10053 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 10054 fis->d.lbaLowExp = 0; 10055 fis->d.lbaMidExp = 0; 10056 fis->d.lbaHighExp = 0; 10057 fis->d.featuresExp = 0; 10058 /* sector count zero */ 10059 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 10060 fis->d.sectorCountExp = 0; 10061 fis->d.device = 0; /* FIS DEV is discared in SATA */ 10062 fis->d.control = 0; /* FIS HOB bit clear */ 10063 fis->d.reserved4 = 0; 10064 fis->d.reserved5 = 0; 10065 10066 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 10067 10068 /* Initialize CB for SATA completion. 10069 */ 10070 satIOContext->satCompleteCB = &satStartStopUnitCB; 10071 10072 /* 10073 * Prepare SGL and send FIS to LL layer. 10074 */ 10075 satIOContext->reqType = agRequestType; /* Save it */ 10076 10077 status = sataLLIOStart( tiRoot, 10078 tiIORequest, 10079 tiDeviceHandle, 10080 tiScsiRequest, 10081 satIOContext); 10082 10083 return status; 10084 } 10085 else 10086 { 10087 /* no support for removal media */ 10088 satSetSensePayload( pSense, 10089 SCSI_SNSKEY_ILLEGAL_REQUEST, 10090 0, 10091 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10092 satIOContext); 10093 10094 ostiInitiatorIOCompleted( tiRoot, 10095 tiIORequest, 10096 tiIOSuccess, 10097 SCSI_STAT_CHECK_CONDITION, 10098 satIOContext->pTiSenseData, 10099 satIOContext->interruptContext ); 10100 10101 TI_DBG5(("satStartStopUnit: return Table 29 case 3 2\n")); 10102 return tiSuccess; 10103 } 10104 10105 } 10106 /* case 4 */ 10107 else /* ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) */ 10108 { 10109 satSetSensePayload( pSense, 10110 SCSI_SNSKEY_ILLEGAL_REQUEST, 10111 0, 10112 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10113 satIOContext); 10114 10115 ostiInitiatorIOCompleted( tiRoot, 10116 tiIORequest, 10117 tiIOSuccess, 10118 SCSI_STAT_CHECK_CONDITION, 10119 satIOContext->pTiSenseData, 10120 satIOContext->interruptContext ); 10121 10122 TI_DBG5(("satStartStopUnit: return Table 29 case 4\n")); 10123 return tiSuccess; 10124 } 10125 10126 10127 } 10128 10129 10130 /*****************************************************************************/ 10131 /*! \brief SAT implementation for SCSI satStartStopUnit_1. 10132 * 10133 * SAT implementation for SCSI satStartStopUnit_1. 10134 * Sub function of satStartStopUnit 10135 * 10136 * \param tiRoot: Pointer to TISA initiator driver/port instance. 10137 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 10138 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 10139 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 10140 * \param satIOContext_t: Pointer to the SAT IO Context 10141 * 10142 * \return If command is started successfully 10143 * - \e tiSuccess: I/O request successfully initiated. 10144 * - \e tiBusy: No resources available, try again later. 10145 * - \e tiIONoDevice: Invalid device handle. 10146 * - \e tiError: Other errors. 10147 */ 10148 /*****************************************************************************/ 10149 GLOBAL bit32 satStartStopUnit_1( 10150 tiRoot_t *tiRoot, 10151 tiIORequest_t *tiIORequest, 10152 tiDeviceHandle_t *tiDeviceHandle, 10153 tiScsiInitiatorRequest_t *tiScsiRequest, 10154 satIOContext_t *satIOContext) 10155 { 10156 /* 10157 SAT Rev 8, Table 48, 9.11.3 p55 10158 sends STANDBY 10159 */ 10160 bit32 status; 10161 bit32 agRequestType; 10162 agsaFisRegHostToDevice_t *fis; 10163 10164 TI_DBG5(("satStartStopUnit_1 entry: tiDeviceHandle=%p tiIORequest=%p\n", 10165 tiDeviceHandle, tiIORequest)); 10166 10167 fis = satIOContext->pFis; 10168 10169 /* STANDBY */ 10170 fis->h.fisType = 0x27; /* Reg host to device */ 10171 fis->h.c_pmPort = 0x80; /* C Bit is set */ 10172 10173 fis->h.command = SAT_STANDBY; /* 0xE2 */ 10174 fis->h.features = 0; /* FIS features NA */ 10175 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 10176 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 10177 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 10178 fis->d.lbaLowExp = 0; 10179 fis->d.lbaMidExp = 0; 10180 fis->d.lbaHighExp = 0; 10181 fis->d.featuresExp = 0; 10182 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 10183 fis->d.sectorCountExp = 0; 10184 fis->d.reserved4 = 0; 10185 fis->d.device = 0; /* 0 */ 10186 fis->d.control = 0; /* FIS HOB bit clear */ 10187 fis->d.reserved5 = 0; 10188 10189 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 10190 10191 /* Initialize CB for SATA completion. 10192 */ 10193 satIOContext->satCompleteCB = &satStartStopUnitCB; 10194 10195 /* 10196 * Prepare SGL and send FIS to LL layer. 10197 */ 10198 satIOContext->reqType = agRequestType; /* Save it */ 10199 10200 status = sataLLIOStart( tiRoot, 10201 tiIORequest, 10202 tiDeviceHandle, 10203 tiScsiRequest, 10204 satIOContext); 10205 10206 TI_DBG5(("satStartStopUnit_1 return status %d\n", status)); 10207 return status; 10208 } 10209 10210 /*****************************************************************************/ 10211 /*! \brief SAT implementation for SCSI satRead10_2. 10212 * 10213 * SAT implementation for SCSI satRead10_2 10214 * Sub function of satRead10 10215 * 10216 * \param tiRoot: Pointer to TISA initiator driver/port instance. 10217 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 10218 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 10219 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 10220 * \param satIOContext_t: Pointer to the SAT IO Context 10221 * 10222 * \return If command is started successfully 10223 * - \e tiSuccess: I/O request successfully initiated. 10224 * - \e tiBusy: No resources available, try again later. 10225 * - \e tiIONoDevice: Invalid device handle. 10226 * - \e tiError: Other errors. 10227 */ 10228 /*****************************************************************************/ 10229 GLOBAL bit32 satRead10_2( 10230 tiRoot_t *tiRoot, 10231 tiIORequest_t *tiIORequest, 10232 tiDeviceHandle_t *tiDeviceHandle, 10233 tiScsiInitiatorRequest_t *tiScsiRequest, 10234 satIOContext_t *satIOContext) 10235 { 10236 /* 10237 externally generated ATA cmd, there is corresponding scsi cmnd 10238 called by satStartStopUnit() or maybe satRead10() 10239 */ 10240 10241 bit32 status; 10242 bit32 agRequestType; 10243 satDeviceData_t *pSatDevData; 10244 agsaFisRegHostToDevice_t *fis; 10245 10246 pSatDevData = satIOContext->pSatDevData; 10247 fis = satIOContext->pFis; 10248 10249 TI_DBG5(("satReadVerifySectorsNoChain: start\n")); 10250 10251 /* specifying ReadVerifySectors has no chain */ 10252 pSatDevData->satVerifyState = 0xFFFFFFFF; 10253 10254 if (pSatDevData->sat48BitSupport == agTRUE) 10255 { 10256 /* READ VERIFY SECTOR(S) EXT*/ 10257 fis->h.fisType = 0x27; /* Reg host to device */ 10258 fis->h.c_pmPort = 0x80; /* C Bit is set */ 10259 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 10260 fis->h.features = 0; /* FIS reserve */ 10261 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */ 10262 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 10263 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */ 10264 fis->d.lbaLowExp = 0xF1; /* FIS LBA (31:24) */ 10265 fis->d.lbaMidExp = 0x5F; /* FIS LBA (39:32) */ 10266 fis->d.lbaHighExp = 0xFF; /* FIS LBA (47:40) */ 10267 fis->d.featuresExp = 0; /* FIS reserve */ 10268 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 10269 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 10270 fis->d.reserved4 = 0; 10271 fis->d.device = 0x4E; /* 01001110 */ 10272 fis->d.control = 0; /* FIS HOB bit clear */ 10273 fis->d.reserved5 = 0; 10274 10275 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 10276 } 10277 else 10278 { 10279 /* READ VERIFY SECTOR(S)*/ 10280 fis->h.fisType = 0x27; /* Reg host to device */ 10281 fis->h.c_pmPort = 0x80; /* C Bit is set */ 10282 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 10283 fis->h.features = 0; /* FIS features NA */ 10284 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */ 10285 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 10286 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */ 10287 fis->d.lbaLowExp = 0; 10288 fis->d.lbaMidExp = 0; 10289 fis->d.lbaHighExp = 0; 10290 fis->d.featuresExp = 0; 10291 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 10292 fis->d.sectorCountExp = 0; 10293 fis->d.reserved4 = 0; 10294 fis->d.device = 0x4E; /* 01001110 */ 10295 fis->d.control = 0; /* FIS HOB bit clear */ 10296 fis->d.reserved5 = 0; 10297 10298 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 10299 } 10300 10301 /* Initialize CB for SATA completion. 10302 */ 10303 satIOContext->satCompleteCB = &satNonDataIOCB; 10304 10305 /* 10306 * Prepare SGL and send FIS to LL layer. 10307 */ 10308 satIOContext->reqType = agRequestType; /* Save it */ 10309 10310 status = sataLLIOStart( tiRoot, 10311 tiIORequest, 10312 tiDeviceHandle, 10313 tiScsiRequest, 10314 satIOContext); 10315 10316 TI_DBG5(("satReadVerifySectorsNoChain: return last\n")); 10317 10318 return status; 10319 } 10320 10321 10322 /*****************************************************************************/ 10323 /*! \brief SAT implementation for SCSI satWriteSame10. 10324 * 10325 * SAT implementation for SCSI satWriteSame10. 10326 * 10327 * \param tiRoot: Pointer to TISA initiator driver/port instance. 10328 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 10329 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 10330 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 10331 * \param satIOContext_t: Pointer to the SAT IO Context 10332 * 10333 * \return If command is started successfully 10334 * - \e tiSuccess: I/O request successfully initiated. 10335 * - \e tiBusy: No resources available, try again later. 10336 * - \e tiIONoDevice: Invalid device handle. 10337 * - \e tiError: Other errors. 10338 */ 10339 /*****************************************************************************/ 10340 GLOBAL bit32 satWriteSame10( 10341 tiRoot_t *tiRoot, 10342 tiIORequest_t *tiIORequest, 10343 tiDeviceHandle_t *tiDeviceHandle, 10344 tiScsiInitiatorRequest_t *tiScsiRequest, 10345 satIOContext_t *satIOContext) 10346 { 10347 bit32 status; 10348 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 10349 satDeviceData_t *pSatDevData; 10350 scsiRspSense_t *pSense; 10351 tiIniScsiCmnd_t *scsiCmnd; 10352 agsaFisRegHostToDevice_t *fis; 10353 bit32 lba = 0; 10354 bit32 tl = 0; 10355 10356 pSense = satIOContext->pSense; 10357 pSatDevData = satIOContext->pSatDevData; 10358 scsiCmnd = &tiScsiRequest->scsiCmnd; 10359 fis = satIOContext->pFis; 10360 10361 TI_DBG5(("satWriteSame10: start\n")); 10362 10363 /* checking CONTROL */ 10364 /* NACA == 1 or LINK == 1*/ 10365 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 10366 { 10367 satSetSensePayload( pSense, 10368 SCSI_SNSKEY_ILLEGAL_REQUEST, 10369 0, 10370 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10371 satIOContext); 10372 10373 ostiInitiatorIOCompleted( tiRoot, 10374 tiIORequest, 10375 tiIOSuccess, 10376 SCSI_STAT_CHECK_CONDITION, 10377 satIOContext->pTiSenseData, 10378 satIOContext->interruptContext ); 10379 10380 TI_DBG1(("satWriteSame10: return control\n")); 10381 return tiSuccess; 10382 } 10383 10384 10385 /* checking LBDATA and PBDATA */ 10386 /* case 1 */ 10387 if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) && 10388 !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) 10389 { 10390 TI_DBG5(("satWriteSame10: case 1\n")); 10391 /* spec 9.26.2, Table 62, p64, case 1*/ 10392 /* 10393 normal case 10394 just like write in 9.17.1 10395 */ 10396 10397 if ( pSatDevData->sat48BitSupport != agTRUE ) 10398 { 10399 /* 10400 writeSame10 but no support for 48 bit addressing 10401 -> problem in transfer length. Therefore, return check condition 10402 */ 10403 satSetSensePayload( pSense, 10404 SCSI_SNSKEY_ILLEGAL_REQUEST, 10405 0, 10406 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10407 satIOContext); 10408 10409 ostiInitiatorIOCompleted( tiRoot, 10410 tiIORequest, 10411 tiIOSuccess, 10412 SCSI_STAT_CHECK_CONDITION, 10413 satIOContext->pTiSenseData, 10414 satIOContext->interruptContext ); 10415 10416 TI_DBG1(("satWriteSame10: return internal checking\n")); 10417 return tiSuccess; 10418 } 10419 10420 /* cdb10; computing LBA and transfer length */ 10421 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 10422 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 10423 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 10424 10425 10426 /* Table 34, 9.1, p 46 */ 10427 /* 10428 note: As of 2/10/2006, no support for DMA QUEUED 10429 */ 10430 10431 /* 10432 Table 34, 9.1, p 46, b (footnote) 10433 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 10434 return check condition 10435 */ 10436 if (pSatDevData->satNCQ != agTRUE && 10437 pSatDevData->sat48BitSupport != agTRUE 10438 ) 10439 { 10440 if (lba > SAT_TR_LBA_LIMIT - 1) /* SAT_TR_LBA_LIMIT is 2^28, 0x10000000 */ 10441 { 10442 satSetSensePayload( pSense, 10443 SCSI_SNSKEY_ILLEGAL_REQUEST, 10444 0, 10445 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 10446 satIOContext); 10447 10448 ostiInitiatorIOCompleted( tiRoot, 10449 tiIORequest, 10450 tiIOSuccess, 10451 SCSI_STAT_CHECK_CONDITION, 10452 satIOContext->pTiSenseData, 10453 satIOContext->interruptContext ); 10454 10455 TI_DBG1(("satWriteSame10: return LBA out of range\n")); 10456 return tiSuccess; 10457 } 10458 } 10459 10460 if (lba + tl <= SAT_TR_LBA_LIMIT) 10461 { 10462 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 10463 { 10464 /* case 2 */ 10465 /* WRITE DMA */ 10466 /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */ 10467 TI_DBG5(("satWriteSame10: case 1-2 !!! error due to writeSame10\n")); 10468 satSetSensePayload( pSense, 10469 SCSI_SNSKEY_ILLEGAL_REQUEST, 10470 0, 10471 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10472 satIOContext); 10473 10474 ostiInitiatorIOCompleted( tiRoot, 10475 tiIORequest, 10476 tiIOSuccess, 10477 SCSI_STAT_CHECK_CONDITION, 10478 satIOContext->pTiSenseData, 10479 satIOContext->interruptContext ); 10480 return tiSuccess; 10481 } 10482 else 10483 { 10484 /* case 1 */ 10485 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 10486 /* WRITE SECTORS is chosen for easier implemetation */ 10487 /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */ 10488 TI_DBG5(("satWriteSame10: case 1-1 !!! error due to writesame10\n")); 10489 satSetSensePayload( pSense, 10490 SCSI_SNSKEY_ILLEGAL_REQUEST, 10491 0, 10492 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10493 satIOContext); 10494 10495 ostiInitiatorIOCompleted( tiRoot, 10496 tiIORequest, 10497 tiIOSuccess, 10498 SCSI_STAT_CHECK_CONDITION, 10499 satIOContext->pTiSenseData, 10500 satIOContext->interruptContext ); 10501 return tiSuccess; 10502 } 10503 } /* end of case 1 and 2 */ 10504 10505 /* case 3 and 4 */ 10506 if (pSatDevData->sat48BitSupport == agTRUE) 10507 { 10508 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 10509 { 10510 /* case 3 */ 10511 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 10512 /* WRITE DMA EXT is chosen since WRITE SAME does not have FUA bit */ 10513 TI_DBG5(("satWriteSame10: case 1-3\n")); 10514 fis->h.fisType = 0x27; /* Reg host to device */ 10515 fis->h.c_pmPort = 0x80; /* C Bit is set */ 10516 10517 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 10518 10519 fis->h.features = 0; /* FIS reserve */ 10520 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 10521 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 10522 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 10523 fis->d.device = 0x40; /* FIS LBA mode set */ 10524 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 10525 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 10526 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 10527 fis->d.featuresExp = 0; /* FIS reserve */ 10528 if (tl == 0) 10529 { 10530 /* error check 10531 ATA spec, p125, 6.17.29 10532 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF 10533 and allowed value is 0x0FFFFFFF - 1 10534 */ 10535 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF) 10536 { 10537 TI_DBG5(("satWriteSame10: case 3 !!! warning can't fit sectors\n")); 10538 satSetSensePayload( pSense, 10539 SCSI_SNSKEY_ILLEGAL_REQUEST, 10540 0, 10541 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10542 satIOContext); 10543 10544 ostiInitiatorIOCompleted( tiRoot, 10545 tiIORequest, 10546 tiIOSuccess, 10547 SCSI_STAT_CHECK_CONDITION, 10548 satIOContext->pTiSenseData, 10549 satIOContext->interruptContext ); 10550 return tiSuccess; 10551 } 10552 } 10553 /* one sector at a time */ 10554 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 10555 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 10556 fis->d.reserved4 = 0; 10557 fis->d.control = 0; /* FIS HOB bit clear */ 10558 fis->d.reserved5 = 0; 10559 10560 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 10561 } 10562 else 10563 { 10564 /* case 4 */ 10565 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 10566 /* WRITE SECTORS EXT is chosen for easier implemetation */ 10567 TI_DBG5(("satWriteSame10: case 1-4\n")); 10568 fis->h.fisType = 0x27; /* Reg host to device */ 10569 fis->h.c_pmPort = 0x80; /* C Bit is set */ 10570 10571 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 10572 fis->h.features = 0; /* FIS reserve */ 10573 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 10574 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 10575 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 10576 fis->d.device = 0x40; /* FIS LBA mode set */ 10577 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 10578 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 10579 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 10580 fis->d.featuresExp = 0; /* FIS reserve */ 10581 if (tl == 0) 10582 { 10583 /* error check 10584 ATA spec, p125, 6.17.29 10585 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF 10586 and allowed value is 0x0FFFFFFF - 1 10587 */ 10588 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF) 10589 { 10590 TI_DBG5(("satWriteSame10: case 4 !!! warning can't fit sectors\n")); 10591 satSetSensePayload( pSense, 10592 SCSI_SNSKEY_ILLEGAL_REQUEST, 10593 0, 10594 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10595 satIOContext); 10596 10597 ostiInitiatorIOCompleted( tiRoot, 10598 tiIORequest, 10599 tiIOSuccess, 10600 SCSI_STAT_CHECK_CONDITION, 10601 satIOContext->pTiSenseData, 10602 satIOContext->interruptContext ); 10603 return tiSuccess; 10604 } 10605 } 10606 /* one sector at a time */ 10607 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 10608 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 10609 fis->d.reserved4 = 0; 10610 fis->d.control = 0; /* FIS HOB bit clear */ 10611 fis->d.reserved5 = 0; 10612 10613 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 10614 } 10615 } 10616 10617 /* case 5 */ 10618 if (pSatDevData->satNCQ == agTRUE) 10619 { 10620 /* WRITE FPDMA QUEUED */ 10621 if (pSatDevData->sat48BitSupport != agTRUE) 10622 { 10623 TI_DBG5(("satWriteSame10: case 1-5 !!! error NCQ but 28 bit address support \n")); 10624 satSetSensePayload( pSense, 10625 SCSI_SNSKEY_ILLEGAL_REQUEST, 10626 0, 10627 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10628 satIOContext); 10629 10630 ostiInitiatorIOCompleted( tiRoot, 10631 tiIORequest, 10632 tiIOSuccess, 10633 SCSI_STAT_CHECK_CONDITION, 10634 satIOContext->pTiSenseData, 10635 satIOContext->interruptContext ); 10636 return tiSuccess; 10637 } 10638 TI_DBG5(("satWriteSame10: case 1-5\n")); 10639 10640 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 10641 10642 fis->h.fisType = 0x27; /* Reg host to device */ 10643 fis->h.c_pmPort = 0x80; /* C Bit is set */ 10644 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 10645 10646 if (tl == 0) 10647 { 10648 /* error check 10649 ATA spec, p125, 6.17.29 10650 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF 10651 and allowed value is 0x0FFFFFFF - 1 10652 */ 10653 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF) 10654 { 10655 TI_DBG5(("satWriteSame10: case 4 !!! warning can't fit sectors\n")); 10656 satSetSensePayload( pSense, 10657 SCSI_SNSKEY_ILLEGAL_REQUEST, 10658 0, 10659 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10660 satIOContext); 10661 10662 ostiInitiatorIOCompleted( tiRoot, 10663 tiIORequest, 10664 tiIOSuccess, 10665 SCSI_STAT_CHECK_CONDITION, 10666 satIOContext->pTiSenseData, 10667 satIOContext->interruptContext ); 10668 return tiSuccess; 10669 } 10670 } 10671 /* one sector at a time */ 10672 fis->h.features = 1; /* FIS sector count (7:0) */ 10673 fis->d.featuresExp = 0; /* FIS sector count (15:8) */ 10674 10675 10676 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 10677 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 10678 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 10679 10680 /* NO FUA bit in the WRITE SAME 10 */ 10681 fis->d.device = 0x40; /* FIS FUA clear */ 10682 10683 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 10684 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 10685 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 10686 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 10687 fis->d.sectorCountExp = 0; 10688 fis->d.reserved4 = 0; 10689 fis->d.control = 0; /* FIS HOB bit clear */ 10690 fis->d.reserved5 = 0; 10691 10692 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 10693 } 10694 /* Initialize CB for SATA completion. 10695 */ 10696 satIOContext->satCompleteCB = &satWriteSame10CB; 10697 10698 /* 10699 * Prepare SGL and send FIS to LL layer. 10700 */ 10701 satIOContext->reqType = agRequestType; /* Save it */ 10702 10703 status = sataLLIOStart( tiRoot, 10704 tiIORequest, 10705 tiDeviceHandle, 10706 tiScsiRequest, 10707 satIOContext); 10708 return (status); 10709 10710 10711 } /* end of case 1 */ 10712 else if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) && 10713 (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) 10714 { 10715 /* spec 9.26.2, Table 62, p64, case 2*/ 10716 satSetSensePayload( pSense, 10717 SCSI_SNSKEY_ILLEGAL_REQUEST, 10718 0, 10719 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10720 satIOContext); 10721 10722 ostiInitiatorIOCompleted( tiRoot, 10723 tiIORequest, 10724 tiIOSuccess, 10725 SCSI_STAT_CHECK_CONDITION, 10726 satIOContext->pTiSenseData, 10727 satIOContext->interruptContext ); 10728 10729 TI_DBG5(("satWriteSame10: return Table 62 case 2\n")); 10730 return tiSuccess; 10731 } 10732 else if ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) && 10733 !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) 10734 { 10735 TI_DBG5(("satWriteSame10: Table 62 case 3\n")); 10736 10737 } 10738 else /* ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) && 10739 (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) */ 10740 { 10741 10742 /* spec 9.26.2, Table 62, p64, case 4*/ 10743 satSetSensePayload( pSense, 10744 SCSI_SNSKEY_ILLEGAL_REQUEST, 10745 0, 10746 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10747 satIOContext); 10748 10749 ostiInitiatorIOCompleted( tiRoot, 10750 tiIORequest, 10751 tiIOSuccess, 10752 SCSI_STAT_CHECK_CONDITION, 10753 satIOContext->pTiSenseData, 10754 satIOContext->interruptContext ); 10755 10756 TI_DBG5(("satWriteSame10: return Table 62 case 4\n")); 10757 return tiSuccess; 10758 } 10759 10760 10761 return tiSuccess; 10762 } 10763 10764 /*****************************************************************************/ 10765 /*! \brief SAT implementation for SCSI satWriteSame10_1. 10766 * 10767 * SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer. 10768 * This is used when WRITESAME10 is divided into multiple ATA commands 10769 * 10770 * \param tiRoot: Pointer to TISA initiator driver/port instance. 10771 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 10772 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 10773 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 10774 * \param satIOContext_t: Pointer to the SAT IO Context 10775 * \param lba: LBA 10776 * 10777 * \return If command is started successfully 10778 * - \e tiSuccess: I/O request successfully initiated. 10779 * - \e tiBusy: No resources available, try again later. 10780 * - \e tiIONoDevice: Invalid device handle. 10781 * - \e tiError: Other errors. 10782 */ 10783 /*****************************************************************************/ 10784 GLOBAL bit32 satWriteSame10_1( 10785 tiRoot_t *tiRoot, 10786 tiIORequest_t *tiIORequest, 10787 tiDeviceHandle_t *tiDeviceHandle, 10788 tiScsiInitiatorRequest_t *tiScsiRequest, 10789 satIOContext_t *satIOContext, 10790 bit32 lba 10791 ) 10792 { 10793 /* 10794 sends SAT_WRITE_DMA_EXT 10795 */ 10796 10797 bit32 status; 10798 bit32 agRequestType; 10799 agsaFisRegHostToDevice_t *fis; 10800 bit8 lba1, lba2 ,lba3, lba4; 10801 10802 TI_DBG5(("satWriteSame10_1 entry: tiDeviceHandle=%p tiIORequest=%p\n", 10803 tiDeviceHandle, tiIORequest)); 10804 10805 fis = satIOContext->pFis; 10806 10807 /* MSB */ 10808 lba1 = (bit8)((lba & 0xFF000000) >> (8*3)); 10809 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2)); 10810 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1)); 10811 /* LSB */ 10812 lba4 = (bit8)(lba & 0x000000FF); 10813 10814 /* SAT_WRITE_DMA_EXT */ 10815 fis->h.fisType = 0x27; /* Reg host to device */ 10816 fis->h.c_pmPort = 0x80; /* C Bit is set */ 10817 10818 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 10819 10820 fis->h.features = 0; /* FIS reserve */ 10821 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */ 10822 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */ 10823 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */ 10824 fis->d.device = 0x40; /* FIS LBA mode set */ 10825 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */ 10826 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 10827 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 10828 fis->d.featuresExp = 0; /* FIS reserve */ 10829 /* one sector at a time */ 10830 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 10831 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 10832 10833 fis->d.reserved4 = 0; 10834 fis->d.control = 0; /* FIS HOB bit clear */ 10835 fis->d.reserved5 = 0; 10836 10837 10838 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 10839 10840 /* Initialize CB for SATA completion. 10841 */ 10842 satIOContext->satCompleteCB = &satWriteSame10CB; 10843 10844 /* 10845 * Prepare SGL and send FIS to LL layer. 10846 */ 10847 satIOContext->reqType = agRequestType; /* Save it */ 10848 10849 status = sataLLIOStart( tiRoot, 10850 tiIORequest, 10851 tiDeviceHandle, 10852 tiScsiRequest, 10853 satIOContext); 10854 10855 TI_DBG5(("satWriteSame10_1 return status %d\n", status)); 10856 return status; 10857 } 10858 10859 /*****************************************************************************/ 10860 /*! \brief SAT implementation for SCSI satWriteSame10_2. 10861 * 10862 * SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer. 10863 * This is used when WRITESAME10 is divided into multiple ATA commands 10864 * 10865 * \param tiRoot: Pointer to TISA initiator driver/port instance. 10866 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 10867 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 10868 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 10869 * \param satIOContext_t: Pointer to the SAT IO Context 10870 * \param lba: LBA 10871 * 10872 * \return If command is started successfully 10873 * - \e tiSuccess: I/O request successfully initiated. 10874 * - \e tiBusy: No resources available, try again later. 10875 * - \e tiIONoDevice: Invalid device handle. 10876 * - \e tiError: Other errors. 10877 */ 10878 /*****************************************************************************/ 10879 GLOBAL bit32 satWriteSame10_2( 10880 tiRoot_t *tiRoot, 10881 tiIORequest_t *tiIORequest, 10882 tiDeviceHandle_t *tiDeviceHandle, 10883 tiScsiInitiatorRequest_t *tiScsiRequest, 10884 satIOContext_t *satIOContext, 10885 bit32 lba 10886 ) 10887 { 10888 /* 10889 sends SAT_WRITE_SECTORS_EXT 10890 */ 10891 10892 bit32 status; 10893 bit32 agRequestType; 10894 agsaFisRegHostToDevice_t *fis; 10895 bit8 lba1, lba2 ,lba3, lba4; 10896 10897 TI_DBG5(("satWriteSame10_2 entry: tiDeviceHandle=%p tiIORequest=%p\n", 10898 tiDeviceHandle, tiIORequest)); 10899 10900 fis = satIOContext->pFis; 10901 10902 /* MSB */ 10903 lba1 = (bit8)((lba & 0xFF000000) >> (8*3)); 10904 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2)); 10905 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1)); 10906 /* LSB */ 10907 lba4 = (bit8)(lba & 0x000000FF); 10908 10909 10910 /* SAT_WRITE_SECTORS_EXT */ 10911 fis->h.fisType = 0x27; /* Reg host to device */ 10912 fis->h.c_pmPort = 0x80; /* C Bit is set */ 10913 10914 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 10915 fis->h.features = 0; /* FIS reserve */ 10916 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */ 10917 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */ 10918 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */ 10919 fis->d.device = 0x40; /* FIS LBA mode set */ 10920 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */ 10921 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 10922 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 10923 fis->d.featuresExp = 0; /* FIS reserve */ 10924 /* one sector at a time */ 10925 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 10926 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 10927 10928 fis->d.reserved4 = 0; 10929 fis->d.control = 0; /* FIS HOB bit clear */ 10930 fis->d.reserved5 = 0; 10931 10932 10933 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 10934 10935 /* Initialize CB for SATA completion. 10936 */ 10937 satIOContext->satCompleteCB = &satWriteSame10CB; 10938 10939 /* 10940 * Prepare SGL and send FIS to LL layer. 10941 */ 10942 satIOContext->reqType = agRequestType; /* Save it */ 10943 10944 status = sataLLIOStart( tiRoot, 10945 tiIORequest, 10946 tiDeviceHandle, 10947 tiScsiRequest, 10948 satIOContext); 10949 10950 TI_DBG5(("satWriteSame10_2 return status %d\n", status)); 10951 return status; 10952 } 10953 10954 /*****************************************************************************/ 10955 /*! \brief SAT implementation for SCSI satWriteSame10_3. 10956 * 10957 * SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer. 10958 * This is used when WRITESAME10 is divided into multiple ATA commands 10959 * 10960 * \param tiRoot: Pointer to TISA initiator driver/port instance. 10961 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 10962 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 10963 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 10964 * \param satIOContext_t: Pointer to the SAT IO Context 10965 * \param lba: LBA 10966 * 10967 * \return If command is started successfully 10968 * - \e tiSuccess: I/O request successfully initiated. 10969 * - \e tiBusy: No resources available, try again later. 10970 * - \e tiIONoDevice: Invalid device handle. 10971 * - \e tiError: Other errors. 10972 */ 10973 /*****************************************************************************/ 10974 GLOBAL bit32 satWriteSame10_3( 10975 tiRoot_t *tiRoot, 10976 tiIORequest_t *tiIORequest, 10977 tiDeviceHandle_t *tiDeviceHandle, 10978 tiScsiInitiatorRequest_t *tiScsiRequest, 10979 satIOContext_t *satIOContext, 10980 bit32 lba 10981 ) 10982 { 10983 /* 10984 sends SAT_WRITE_FPDMA_QUEUED 10985 */ 10986 10987 bit32 status; 10988 bit32 agRequestType; 10989 agsaFisRegHostToDevice_t *fis; 10990 bit8 lba1, lba2 ,lba3, lba4; 10991 10992 TI_DBG5(("satWriteSame10_3 entry: tiDeviceHandle=%p tiIORequest=%p\n", 10993 tiDeviceHandle, tiIORequest)); 10994 10995 fis = satIOContext->pFis; 10996 10997 /* MSB */ 10998 lba1 = (bit8)((lba & 0xFF000000) >> (8*3)); 10999 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2)); 11000 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1)); 11001 /* LSB */ 11002 lba4 = (bit8)(lba & 0x000000FF); 11003 11004 /* SAT_WRITE_FPDMA_QUEUED */ 11005 fis->h.fisType = 0x27; /* Reg host to device */ 11006 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11007 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 11008 11009 11010 /* one sector at a time */ 11011 fis->h.features = 1; /* FIS sector count (7:0) */ 11012 fis->d.featuresExp = 0; /* FIS sector count (15:8) */ 11013 11014 11015 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */ 11016 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */ 11017 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */ 11018 11019 /* NO FUA bit in the WRITE SAME 10 */ 11020 fis->d.device = 0x40; /* FIS FUA clear */ 11021 11022 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */ 11023 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 11024 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 11025 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 11026 fis->d.sectorCountExp = 0; 11027 fis->d.reserved4 = 0; 11028 fis->d.control = 0; /* FIS HOB bit clear */ 11029 fis->d.reserved5 = 0; 11030 11031 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 11032 11033 /* Initialize CB for SATA completion. 11034 */ 11035 satIOContext->satCompleteCB = &satWriteSame10CB; 11036 11037 /* 11038 * Prepare SGL and send FIS to LL layer. 11039 */ 11040 satIOContext->reqType = agRequestType; /* Save it */ 11041 11042 status = sataLLIOStart( tiRoot, 11043 tiIORequest, 11044 tiDeviceHandle, 11045 tiScsiRequest, 11046 satIOContext); 11047 11048 TI_DBG5(("satWriteSame10_2 return status %d\n", status)); 11049 return status; 11050 } 11051 /*****************************************************************************/ 11052 /*! \brief SAT implementation for SCSI satWriteSame16. 11053 * 11054 * SAT implementation for SCSI satWriteSame16. 11055 * 11056 * \param tiRoot: Pointer to TISA initiator driver/port instance. 11057 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 11058 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 11059 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 11060 * \param satIOContext_t: Pointer to the SAT IO Context 11061 * 11062 * \return If command is started successfully 11063 * - \e tiSuccess: I/O request successfully initiated. 11064 * - \e tiBusy: No resources available, try again later. 11065 * - \e tiIONoDevice: Invalid device handle. 11066 * - \e tiError: Other errors. 11067 */ 11068 /*****************************************************************************/ 11069 GLOBAL bit32 satWriteSame16( 11070 tiRoot_t *tiRoot, 11071 tiIORequest_t *tiIORequest, 11072 tiDeviceHandle_t *tiDeviceHandle, 11073 tiScsiInitiatorRequest_t *tiScsiRequest, 11074 satIOContext_t *satIOContext) 11075 { 11076 scsiRspSense_t *pSense; 11077 11078 pSense = satIOContext->pSense; 11079 11080 TI_DBG5(("satWriteSame16:start\n")); 11081 11082 11083 satSetSensePayload( pSense, 11084 SCSI_SNSKEY_NO_SENSE, 11085 0, 11086 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 11087 satIOContext); 11088 11089 ostiInitiatorIOCompleted( tiRoot, 11090 tiIORequest, /* == &satIntIo->satOrgTiIORequest */ 11091 tiIOSuccess, 11092 SCSI_STAT_CHECK_CONDITION, 11093 satIOContext->pTiSenseData, 11094 satIOContext->interruptContext ); 11095 TI_DBG5(("satWriteSame16: return internal checking\n")); 11096 return tiSuccess; 11097 } 11098 11099 /*****************************************************************************/ 11100 /*! \brief SAT implementation for SCSI satLogSense_1. 11101 * 11102 * Part of SAT implementation for SCSI satLogSense. 11103 * 11104 * \param tiRoot: Pointer to TISA initiator driver/port instance. 11105 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 11106 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 11107 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 11108 * \param satIOContext_t: Pointer to the SAT IO Context 11109 * 11110 * \return If command is started successfully 11111 * - \e tiSuccess: I/O request successfully initiated. 11112 * - \e tiBusy: No resources available, try again later. 11113 * - \e tiIONoDevice: Invalid device handle. 11114 * - \e tiError: Other errors. 11115 */ 11116 /*****************************************************************************/ 11117 GLOBAL bit32 satLogSense_1( 11118 tiRoot_t *tiRoot, 11119 tiIORequest_t *tiIORequest, 11120 tiDeviceHandle_t *tiDeviceHandle, 11121 tiScsiInitiatorRequest_t *tiScsiRequest, 11122 satIOContext_t *satIOContext) 11123 { 11124 bit32 status; 11125 bit32 agRequestType; 11126 satDeviceData_t *pSatDevData; 11127 agsaFisRegHostToDevice_t *fis; 11128 11129 pSatDevData = satIOContext->pSatDevData; 11130 fis = satIOContext->pFis; 11131 11132 TI_DBG5(("satLogSense_1: start\n")); 11133 11134 11135 /* SAT Rev 8, 10.2.4 p74 */ 11136 if ( pSatDevData->sat48BitSupport == agTRUE ) 11137 { 11138 TI_DBG5(("satLogSense_1: case 2-1 sends READ LOG EXT\n")); 11139 /* sends READ LOG EXT */ 11140 fis->h.fisType = 0x27; /* Reg host to device */ 11141 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11142 11143 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */ 11144 fis->h.features = 0; /* FIS reserve */ 11145 fis->d.lbaLow = 0x07; /* 0x07 */ 11146 fis->d.lbaMid = 0; /* */ 11147 fis->d.lbaHigh = 0; /* */ 11148 fis->d.device = 0; /* */ 11149 fis->d.lbaLowExp = 0; /* */ 11150 fis->d.lbaMidExp = 0; /* */ 11151 fis->d.lbaHighExp = 0; /* */ 11152 fis->d.featuresExp = 0; /* FIS reserve */ 11153 fis->d.sectorCount = 0x01; /* 1 sector counts */ 11154 fis->d.sectorCountExp = 0x00; /* 1 sector counts */ 11155 fis->d.reserved4 = 0; 11156 fis->d.control = 0; /* FIS HOB bit clear */ 11157 fis->d.reserved5 = 0; 11158 11159 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 11160 11161 /* Initialize CB for SATA completion. 11162 */ 11163 satIOContext->satCompleteCB = &satLogSenseCB; 11164 11165 /* 11166 * Prepare SGL and send FIS to LL layer. 11167 */ 11168 satIOContext->reqType = agRequestType; /* Save it */ 11169 11170 status = sataLLIOStart( tiRoot, 11171 tiIORequest, 11172 tiDeviceHandle, 11173 tiScsiRequest, 11174 satIOContext); 11175 return status; 11176 11177 } 11178 else 11179 { 11180 TI_DBG5(("satLogSense_1: case 2-2 sends SMART READ LOG\n")); 11181 /* sends SMART READ LOG */ 11182 fis->h.fisType = 0x27; /* Reg host to device */ 11183 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11184 11185 fis->h.command = SAT_SMART_READ_LOG; /* 0x2F */ 11186 fis->h.features = 0x00; /* 0xd5 */ 11187 fis->d.lbaLow = 0x06; /* 0x06 */ 11188 fis->d.lbaMid = 0x00; /* 0x4f */ 11189 fis->d.lbaHigh = 0x00; /* 0xc2 */ 11190 fis->d.device = 0; /* */ 11191 fis->d.lbaLowExp = 0; /* */ 11192 fis->d.lbaMidExp = 0; /* */ 11193 fis->d.lbaHighExp = 0; /* */ 11194 fis->d.featuresExp = 0; /* FIS reserve */ 11195 fis->d.sectorCount = 0x01; /* */ 11196 fis->d.sectorCountExp = 0x00; /* */ 11197 fis->d.reserved4 = 0; 11198 fis->d.control = 0; /* FIS HOB bit clear */ 11199 fis->d.reserved5 = 0; 11200 11201 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 11202 11203 /* Initialize CB for SATA completion. 11204 */ 11205 satIOContext->satCompleteCB = &satLogSenseCB; 11206 11207 /* 11208 * Prepare SGL and send FIS to LL layer. 11209 */ 11210 satIOContext->reqType = agRequestType; /* Save it */ 11211 11212 status = sataLLIOStart( tiRoot, 11213 tiIORequest, 11214 tiDeviceHandle, 11215 tiScsiRequest, 11216 satIOContext); 11217 return status; 11218 11219 } 11220 } 11221 11222 /*****************************************************************************/ 11223 /*! \brief SAT implementation for SCSI satSMARTEnable. 11224 * 11225 * Part of SAT implementation for SCSI satLogSense. 11226 * 11227 * \param tiRoot: Pointer to TISA initiator driver/port instance. 11228 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 11229 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 11230 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 11231 * \param satIOContext_t: Pointer to the SAT IO Context 11232 * 11233 * \return If command is started successfully 11234 * - \e tiSuccess: I/O request successfully initiated. 11235 * - \e tiBusy: No resources available, try again later. 11236 * - \e tiIONoDevice: Invalid device handle. 11237 * - \e tiError: Other errors. 11238 */ 11239 /*****************************************************************************/ 11240 GLOBAL bit32 satSMARTEnable( 11241 tiRoot_t *tiRoot, 11242 tiIORequest_t *tiIORequest, 11243 tiDeviceHandle_t *tiDeviceHandle, 11244 tiScsiInitiatorRequest_t *tiScsiRequest, 11245 satIOContext_t *satIOContext) 11246 { 11247 bit32 status; 11248 bit32 agRequestType; 11249 agsaFisRegHostToDevice_t *fis; 11250 11251 TI_DBG4(("satSMARTEnable entry: tiDeviceHandle=%p tiIORequest=%p\n", 11252 tiDeviceHandle, tiIORequest)); 11253 11254 fis = satIOContext->pFis; 11255 11256 /* 11257 * Send the SAT_SMART_ENABLE_OPERATIONS command. 11258 */ 11259 fis->h.fisType = 0x27; /* Reg host to device */ 11260 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11261 11262 fis->h.command = SAT_SMART_ENABLE_OPERATIONS; /* 0xB0 */ 11263 fis->h.features = 0xD8; 11264 fis->d.lbaLow = 0; 11265 fis->d.lbaMid = 0x4F; 11266 fis->d.lbaHigh = 0xC2; 11267 fis->d.device = 0; 11268 fis->d.lbaLowExp = 0; 11269 fis->d.lbaMidExp = 0; 11270 fis->d.lbaHighExp = 0; 11271 fis->d.featuresExp = 0; 11272 fis->d.sectorCount = 0; 11273 fis->d.sectorCountExp = 0; 11274 fis->d.reserved4 = 0; 11275 fis->d.control = 0; /* FIS HOB bit clear */ 11276 fis->d.reserved5 = 0; 11277 11278 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 11279 11280 /* Initialize CB for SATA completion. 11281 */ 11282 satIOContext->satCompleteCB = &satSMARTEnableCB; 11283 11284 /* 11285 * Prepare SGL and send FIS to LL layer. 11286 */ 11287 satIOContext->reqType = agRequestType; /* Save it */ 11288 11289 status = sataLLIOStart( tiRoot, 11290 tiIORequest, 11291 tiDeviceHandle, 11292 tiScsiRequest, 11293 satIOContext); 11294 11295 11296 return status; 11297 } 11298 11299 /*****************************************************************************/ 11300 /*! \brief SAT implementation for SCSI satLogSense_3. 11301 * 11302 * Part of SAT implementation for SCSI satLogSense. 11303 * 11304 * \param tiRoot: Pointer to TISA initiator driver/port instance. 11305 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 11306 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 11307 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 11308 * \param satIOContext_t: Pointer to the SAT IO Context 11309 * 11310 * \return If command is started successfully 11311 * - \e tiSuccess: I/O request successfully initiated. 11312 * - \e tiBusy: No resources available, try again later. 11313 * - \e tiIONoDevice: Invalid device handle. 11314 * - \e tiError: Other errors. 11315 */ 11316 /*****************************************************************************/ 11317 GLOBAL bit32 satLogSense_3( 11318 tiRoot_t *tiRoot, 11319 tiIORequest_t *tiIORequest, 11320 tiDeviceHandle_t *tiDeviceHandle, 11321 tiScsiInitiatorRequest_t *tiScsiRequest, 11322 satIOContext_t *satIOContext) 11323 { 11324 bit32 status; 11325 bit32 agRequestType; 11326 agsaFisRegHostToDevice_t *fis; 11327 11328 TI_DBG4(("satLogSense_3 entry: tiDeviceHandle=%p tiIORequest=%p\n", 11329 tiDeviceHandle, tiIORequest)); 11330 11331 fis = satIOContext->pFis; 11332 /* sends READ LOG EXT */ 11333 fis->h.fisType = 0x27; /* Reg host to device */ 11334 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11335 11336 fis->h.command = SAT_SMART_READ_LOG; /* 0x2F */ 11337 fis->h.features = 0xD5; /* 0xd5 */ 11338 fis->d.lbaLow = 0x06; /* 0x06 */ 11339 fis->d.lbaMid = 0x4F; /* 0x4f */ 11340 fis->d.lbaHigh = 0xC2; /* 0xc2 */ 11341 fis->d.device = 0; /* */ 11342 fis->d.lbaLowExp = 0; /* */ 11343 fis->d.lbaMidExp = 0; /* */ 11344 fis->d.lbaHighExp = 0; /* */ 11345 fis->d.featuresExp = 0; /* FIS reserve */ 11346 fis->d.sectorCount = 0x01; /* 1 sector counts */ 11347 fis->d.sectorCountExp = 0x00; /* 1 sector counts */ 11348 fis->d.reserved4 = 0; 11349 fis->d.control = 0; /* FIS HOB bit clear */ 11350 fis->d.reserved5 = 0; 11351 11352 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 11353 11354 /* Initialize CB for SATA completion. 11355 */ 11356 satIOContext->satCompleteCB = &satLogSenseCB; 11357 11358 /* 11359 * Prepare SGL and send FIS to LL layer. 11360 */ 11361 satIOContext->reqType = agRequestType; /* Save it */ 11362 11363 status = sataLLIOStart( tiRoot, 11364 tiIORequest, 11365 tiDeviceHandle, 11366 tiScsiRequest, 11367 satIOContext); 11368 return status; 11369 } 11370 11371 /*****************************************************************************/ 11372 /*! \brief SAT implementation for SCSI satLogSense_2. 11373 * 11374 * Part of SAT implementation for SCSI satLogSense. 11375 * 11376 * \param tiRoot: Pointer to TISA initiator driver/port instance. 11377 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 11378 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 11379 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 11380 * \param satIOContext_t: Pointer to the SAT IO Context 11381 * 11382 * \return If command is started successfully 11383 * - \e tiSuccess: I/O request successfully initiated. 11384 * - \e tiBusy: No resources available, try again later. 11385 * - \e tiIONoDevice: Invalid device handle. 11386 * - \e tiError: Other errors. 11387 */ 11388 /*****************************************************************************/ 11389 GLOBAL bit32 satLogSense_2( 11390 tiRoot_t *tiRoot, 11391 tiIORequest_t *tiIORequest, 11392 tiDeviceHandle_t *tiDeviceHandle, 11393 tiScsiInitiatorRequest_t *tiScsiRequest, 11394 satIOContext_t *satIOContext) 11395 { 11396 bit32 status; 11397 bit32 agRequestType; 11398 agsaFisRegHostToDevice_t *fis; 11399 11400 TI_DBG4(("satLogSense_2 entry: tiDeviceHandle=%p tiIORequest=%p\n", 11401 tiDeviceHandle, tiIORequest)); 11402 11403 fis = satIOContext->pFis; 11404 /* sends READ LOG EXT */ 11405 fis->h.fisType = 0x27; /* Reg host to device */ 11406 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11407 11408 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */ 11409 fis->h.features = 0; /* FIS reserve */ 11410 fis->d.lbaLow = 0x07; /* 0x07 */ 11411 fis->d.lbaMid = 0; /* */ 11412 fis->d.lbaHigh = 0; /* */ 11413 fis->d.device = 0; /* */ 11414 fis->d.lbaLowExp = 0; /* */ 11415 fis->d.lbaMidExp = 0; /* */ 11416 fis->d.lbaHighExp = 0; /* */ 11417 fis->d.featuresExp = 0; /* FIS reserve */ 11418 fis->d.sectorCount = 0x01; /* 1 sector counts */ 11419 fis->d.sectorCountExp = 0x00; /* 1 sector counts */ 11420 fis->d.reserved4 = 0; 11421 fis->d.control = 0; /* FIS HOB bit clear */ 11422 fis->d.reserved5 = 0; 11423 11424 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 11425 11426 /* Initialize CB for SATA completion. 11427 */ 11428 satIOContext->satCompleteCB = &satLogSenseCB; 11429 11430 /* 11431 * Prepare SGL and send FIS to LL layer. 11432 */ 11433 satIOContext->reqType = agRequestType; /* Save it */ 11434 11435 status = sataLLIOStart( tiRoot, 11436 tiIORequest, 11437 tiDeviceHandle, 11438 tiScsiRequest, 11439 satIOContext); 11440 return status; 11441 } 11442 11443 /*****************************************************************************/ 11444 /*! \brief SAT implementation for SCSI satLogSenseAllocate. 11445 * 11446 * Part of SAT implementation for SCSI satLogSense. 11447 * 11448 * \param tiRoot: Pointer to TISA initiator driver/port instance. 11449 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 11450 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 11451 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 11452 * \param satIOContext_t: Pointer to the SAT IO Context 11453 * \param payloadSize: size of payload to be allocated. 11454 * \param flag: flag value 11455 * 11456 * \return If command is started successfully 11457 * - \e tiSuccess: I/O request successfully initiated. 11458 * - \e tiBusy: No resources available, try again later. 11459 * - \e tiIONoDevice: Invalid device handle. 11460 * - \e tiError: Other errors. 11461 * \note 11462 * - flag values: LOG_SENSE_0, LOG_SENSE_1, LOG_SENSE_2 11463 */ 11464 /*****************************************************************************/ 11465 GLOBAL bit32 satLogSenseAllocate( 11466 tiRoot_t *tiRoot, 11467 tiIORequest_t *tiIORequest, 11468 tiDeviceHandle_t *tiDeviceHandle, 11469 tiScsiInitiatorRequest_t *tiScsiRequest, 11470 satIOContext_t *satIOContext, 11471 bit32 payloadSize, 11472 bit32 flag 11473 ) 11474 { 11475 satDeviceData_t *pSatDevData; 11476 tdIORequestBody_t *tdIORequestBody; 11477 satInternalIo_t *satIntIo = agNULL; 11478 satIOContext_t *satIOContext2; 11479 bit32 status; 11480 11481 TI_DBG4(("satLogSense_2 entry: tiDeviceHandle=%p tiIORequest=%p\n", 11482 tiDeviceHandle, tiIORequest)); 11483 11484 pSatDevData = satIOContext->pSatDevData; 11485 11486 /* create internal satIOContext */ 11487 satIntIo = satAllocIntIoResource( tiRoot, 11488 tiIORequest, /* original request */ 11489 pSatDevData, 11490 payloadSize, 11491 satIntIo); 11492 11493 if (satIntIo == agNULL) 11494 { 11495 /* memory allocation failure */ 11496 satFreeIntIoResource( tiRoot, 11497 pSatDevData, 11498 satIntIo); 11499 11500 ostiInitiatorIOCompleted( tiRoot, 11501 tiIORequest, 11502 tiIOFailed, 11503 tiDetailOtherError, 11504 agNULL, 11505 satIOContext->interruptContext ); 11506 11507 TI_DBG4(("satLogSense_2: fail in allocation\n")); 11508 return tiSuccess; 11509 } /* end of memory allocation failure */ 11510 11511 satIntIo->satOrgTiIORequest = tiIORequest; 11512 tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody; 11513 satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext); 11514 11515 satIOContext2->pSatDevData = pSatDevData; 11516 satIOContext2->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 11517 satIOContext2->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd); 11518 satIOContext2->pSense = &(tdIORequestBody->transport.SATA.sensePayload); 11519 satIOContext2->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData); 11520 satIOContext2->pTiSenseData->senseData = satIOContext2->pSense; 11521 satIOContext2->tiRequestBody = satIntIo->satIntRequestBody; 11522 satIOContext2->interruptContext = satIOContext->interruptContext; 11523 satIOContext2->satIntIoContext = satIntIo; 11524 satIOContext2->ptiDeviceHandle = tiDeviceHandle; 11525 satIOContext2->satOrgIOContext = satIOContext; 11526 11527 if (flag == LOG_SENSE_0) 11528 { 11529 /* SAT_SMART_ENABLE_OPERATIONS */ 11530 status = satSMARTEnable( tiRoot, 11531 &(satIntIo->satIntTiIORequest), 11532 tiDeviceHandle, 11533 &(satIntIo->satIntTiScsiXchg), 11534 satIOContext2); 11535 } 11536 else if (flag == LOG_SENSE_1) 11537 { 11538 /* SAT_READ_LOG_EXT */ 11539 status = satLogSense_2( tiRoot, 11540 &(satIntIo->satIntTiIORequest), 11541 tiDeviceHandle, 11542 &(satIntIo->satIntTiScsiXchg), 11543 satIOContext2); 11544 } 11545 else 11546 { 11547 /* SAT_SMART_READ_LOG */ 11548 /* SAT_READ_LOG_EXT */ 11549 status = satLogSense_3( tiRoot, 11550 &(satIntIo->satIntTiIORequest), 11551 tiDeviceHandle, 11552 &(satIntIo->satIntTiScsiXchg), 11553 satIOContext2); 11554 11555 } 11556 if (status != tiSuccess) 11557 { 11558 satFreeIntIoResource( tiRoot, 11559 pSatDevData, 11560 satIntIo); 11561 11562 ostiInitiatorIOCompleted( tiRoot, 11563 tiIORequest, 11564 tiIOFailed, 11565 tiDetailOtherError, 11566 agNULL, 11567 satIOContext->interruptContext ); 11568 return tiSuccess; 11569 } 11570 11571 11572 return tiSuccess; 11573 } 11574 11575 11576 /*****************************************************************************/ 11577 /*! \brief SAT implementation for SCSI satLogSense. 11578 * 11579 * SAT implementation for SCSI satLogSense. 11580 * 11581 * \param tiRoot: Pointer to TISA initiator driver/port instance. 11582 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 11583 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 11584 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 11585 * \param satIOContext_t: Pointer to the SAT IO Context 11586 * 11587 * \return If command is started successfully 11588 * - \e tiSuccess: I/O request successfully initiated. 11589 * - \e tiBusy: No resources available, try again later. 11590 * - \e tiIONoDevice: Invalid device handle. 11591 * - \e tiError: Other errors. 11592 */ 11593 /*****************************************************************************/ 11594 GLOBAL bit32 satLogSense( 11595 tiRoot_t *tiRoot, 11596 tiIORequest_t *tiIORequest, 11597 tiDeviceHandle_t *tiDeviceHandle, 11598 tiScsiInitiatorRequest_t *tiScsiRequest, 11599 satIOContext_t *satIOContext) 11600 { 11601 bit32 status; 11602 bit32 agRequestType; 11603 satDeviceData_t *pSatDevData; 11604 scsiRspSense_t *pSense; 11605 tiIniScsiCmnd_t *scsiCmnd; 11606 agsaFisRegHostToDevice_t *fis; 11607 bit8 *pLogPage; /* Log Page data buffer */ 11608 bit32 flag = 0; 11609 bit16 AllocLen = 0; /* allocation length */ 11610 bit8 AllLogPages[8]; 11611 bit16 lenRead = 0; 11612 11613 pSense = satIOContext->pSense; 11614 pSatDevData = satIOContext->pSatDevData; 11615 scsiCmnd = &tiScsiRequest->scsiCmnd; 11616 fis = satIOContext->pFis; 11617 pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr; 11618 11619 TI_DBG5(("satLogSense: start\n")); 11620 11621 osti_memset(&AllLogPages, 0, 8); 11622 /* checking CONTROL */ 11623 /* NACA == 1 or LINK == 1*/ 11624 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 11625 { 11626 satSetSensePayload( pSense, 11627 SCSI_SNSKEY_ILLEGAL_REQUEST, 11628 0, 11629 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11630 satIOContext); 11631 11632 ostiInitiatorIOCompleted( tiRoot, 11633 tiIORequest, 11634 tiIOSuccess, 11635 SCSI_STAT_CHECK_CONDITION, 11636 satIOContext->pTiSenseData, 11637 satIOContext->interruptContext ); 11638 11639 TI_DBG2(("satLogSense: return control\n")); 11640 return tiSuccess; 11641 } 11642 11643 11644 AllocLen = (bit8)((scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]); 11645 11646 /* checking PC (Page Control) */ 11647 /* nothing */ 11648 11649 /* special cases */ 11650 if (AllocLen == 4) 11651 { 11652 TI_DBG1(("satLogSense: AllocLen is 4\n")); 11653 switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK) 11654 { 11655 case LOGSENSE_SUPPORTED_LOG_PAGES: 11656 TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n")); 11657 11658 /* SAT Rev 8, 10.2.5 p76 */ 11659 if (pSatDevData->satSMARTFeatureSet == agTRUE) 11660 { 11661 /* add informational exception log */ 11662 flag = 1; 11663 if (pSatDevData->satSMARTSelfTest == agTRUE) 11664 { 11665 /* add Self-Test results log page */ 11666 flag = 2; 11667 } 11668 } 11669 else 11670 { 11671 /* only supported, no informational exception log, no Self-Test results log page */ 11672 flag = 0; 11673 } 11674 lenRead = 4; 11675 AllLogPages[0] = LOGSENSE_SUPPORTED_LOG_PAGES; /* page code */ 11676 AllLogPages[1] = 0; /* reserved */ 11677 switch (flag) 11678 { 11679 case 0: 11680 /* only supported */ 11681 AllLogPages[2] = 0; /* page length */ 11682 AllLogPages[3] = 1; /* page length */ 11683 break; 11684 case 1: 11685 /* supported and informational exception log */ 11686 AllLogPages[2] = 0; /* page length */ 11687 AllLogPages[3] = 2; /* page length */ 11688 break; 11689 case 2: 11690 /* supported and informational exception log */ 11691 AllLogPages[2] = 0; /* page length */ 11692 AllLogPages[3] = 3; /* page length */ 11693 break; 11694 default: 11695 TI_DBG1(("satLogSense: error unallowed flag value %d\n", flag)); 11696 break; 11697 } 11698 osti_memcpy(pLogPage, &AllLogPages, lenRead); 11699 break; 11700 case LOGSENSE_SELFTEST_RESULTS_PAGE: 11701 TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n")); 11702 lenRead = 4; 11703 AllLogPages[0] = LOGSENSE_SELFTEST_RESULTS_PAGE; /* page code */ 11704 AllLogPages[1] = 0; /* reserved */ 11705 /* page length = SELFTEST_RESULTS_LOG_PAGE_LENGTH - 1 - 3 = 400 = 0x190 */ 11706 AllLogPages[2] = 0x01; 11707 AllLogPages[3] = 0x90; /* page length */ 11708 osti_memcpy(pLogPage, &AllLogPages, lenRead); 11709 11710 break; 11711 case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE: 11712 TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n")); 11713 lenRead = 4; 11714 AllLogPages[0] = LOGSENSE_INFORMATION_EXCEPTIONS_PAGE; /* page code */ 11715 AllLogPages[1] = 0; /* reserved */ 11716 AllLogPages[2] = 0; /* page length */ 11717 AllLogPages[3] = INFORMATION_EXCEPTIONS_LOG_PAGE_LENGTH - 1 - 3; /* page length */ 11718 osti_memcpy(pLogPage, &AllLogPages, lenRead); 11719 break; 11720 default: 11721 TI_DBG1(("satLogSense: default Page Code 0x%x\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)); 11722 satSetSensePayload( pSense, 11723 SCSI_SNSKEY_ILLEGAL_REQUEST, 11724 0, 11725 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11726 satIOContext); 11727 11728 ostiInitiatorIOCompleted( tiRoot, 11729 tiIORequest, 11730 tiIOSuccess, 11731 SCSI_STAT_CHECK_CONDITION, 11732 satIOContext->pTiSenseData, 11733 satIOContext->interruptContext ); 11734 return tiSuccess; 11735 } 11736 ostiInitiatorIOCompleted( tiRoot, 11737 tiIORequest, 11738 tiIOSuccess, 11739 SCSI_STAT_GOOD, 11740 agNULL, 11741 satIOContext->interruptContext); 11742 return tiSuccess; 11743 11744 } /* if */ 11745 11746 /* SAT rev8 Table 11 p30*/ 11747 /* checking Page Code */ 11748 switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK) 11749 { 11750 case LOGSENSE_SUPPORTED_LOG_PAGES: 11751 TI_DBG5(("satLogSense: case 1\n")); 11752 11753 /* SAT Rev 8, 10.2.5 p76 */ 11754 11755 if (pSatDevData->satSMARTFeatureSet == agTRUE) 11756 { 11757 /* add informational exception log */ 11758 flag = 1; 11759 if (pSatDevData->satSMARTSelfTest == agTRUE) 11760 { 11761 /* add Self-Test results log page */ 11762 flag = 2; 11763 } 11764 } 11765 else 11766 { 11767 /* only supported, no informational exception log, no Self-Test results log page */ 11768 flag = 0; 11769 } 11770 AllLogPages[0] = 0; /* page code */ 11771 AllLogPages[1] = 0; /* reserved */ 11772 switch (flag) 11773 { 11774 case 0: 11775 /* only supported */ 11776 AllLogPages[2] = 0; /* page length */ 11777 AllLogPages[3] = 1; /* page length */ 11778 AllLogPages[4] = 0x00; /* supported page list */ 11779 lenRead = (bit8)(MIN(AllocLen, 5)); 11780 break; 11781 case 1: 11782 /* supported and informational exception log */ 11783 AllLogPages[2] = 0; /* page length */ 11784 AllLogPages[3] = 2; /* page length */ 11785 AllLogPages[4] = 0x00; /* supported page list */ 11786 AllLogPages[5] = 0x10; /* supported page list */ 11787 lenRead = (bit8)(MIN(AllocLen, 6)); 11788 break; 11789 case 2: 11790 /* supported and informational exception log */ 11791 AllLogPages[2] = 0; /* page length */ 11792 AllLogPages[3] = 3; /* page length */ 11793 AllLogPages[4] = 0x00; /* supported page list */ 11794 AllLogPages[5] = 0x10; /* supported page list */ 11795 AllLogPages[6] = 0x2F; /* supported page list */ 11796 lenRead = (bit8)(MIN(AllocLen, 7)); 11797 break; 11798 default: 11799 TI_DBG1(("satLogSense: error unallowed flag value %d\n", flag)); 11800 break; 11801 } 11802 11803 osti_memcpy(pLogPage, &AllLogPages, lenRead); 11804 /* comparing allocation length to Log Page byte size */ 11805 /* SPC-4, 4.3.4.6, p28 */ 11806 if (AllocLen > lenRead ) 11807 { 11808 TI_DBG1(("satLogSense reporting underrun lenRead=0x%x AllocLen=0x%x tiIORequest=%p\n", lenRead, AllocLen, tiIORequest)); 11809 ostiInitiatorIOCompleted( tiRoot, 11810 tiIORequest, 11811 tiIOUnderRun, 11812 AllocLen - lenRead, 11813 agNULL, 11814 satIOContext->interruptContext ); 11815 } 11816 else 11817 { 11818 ostiInitiatorIOCompleted( tiRoot, 11819 tiIORequest, 11820 tiIOSuccess, 11821 SCSI_STAT_GOOD, 11822 agNULL, 11823 satIOContext->interruptContext); 11824 } 11825 break; 11826 case LOGSENSE_SELFTEST_RESULTS_PAGE: 11827 TI_DBG5(("satLogSense: case 2\n")); 11828 /* checking SMART self-test */ 11829 if (pSatDevData->satSMARTSelfTest == agFALSE) 11830 { 11831 TI_DBG5(("satLogSense: case 2 no SMART Self Test\n")); 11832 satSetSensePayload( pSense, 11833 SCSI_SNSKEY_ILLEGAL_REQUEST, 11834 0, 11835 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11836 satIOContext); 11837 11838 ostiInitiatorIOCompleted( tiRoot, 11839 tiIORequest, 11840 tiIOSuccess, 11841 SCSI_STAT_CHECK_CONDITION, 11842 satIOContext->pTiSenseData, 11843 satIOContext->interruptContext ); 11844 } 11845 else 11846 { 11847 /* if satSMARTEnabled is false, send SMART_ENABLE_OPERATIONS */ 11848 if (pSatDevData->satSMARTEnabled == agFALSE) 11849 { 11850 TI_DBG5(("satLogSense: case 2 calling satSMARTEnable\n")); 11851 status = satLogSenseAllocate(tiRoot, 11852 tiIORequest, 11853 tiDeviceHandle, 11854 tiScsiRequest, 11855 satIOContext, 11856 0, 11857 LOG_SENSE_0 11858 ); 11859 11860 return status; 11861 11862 } 11863 else 11864 { 11865 /* SAT Rev 8, 10.2.4 p74 */ 11866 if ( pSatDevData->sat48BitSupport == agTRUE ) 11867 { 11868 TI_DBG5(("satLogSense: case 2-1 sends READ LOG EXT\n")); 11869 status = satLogSenseAllocate(tiRoot, 11870 tiIORequest, 11871 tiDeviceHandle, 11872 tiScsiRequest, 11873 satIOContext, 11874 512, 11875 LOG_SENSE_1 11876 ); 11877 11878 return status; 11879 } 11880 else 11881 { 11882 TI_DBG5(("satLogSense: case 2-2 sends SMART READ LOG\n")); 11883 status = satLogSenseAllocate(tiRoot, 11884 tiIORequest, 11885 tiDeviceHandle, 11886 tiScsiRequest, 11887 satIOContext, 11888 512, 11889 LOG_SENSE_2 11890 ); 11891 11892 return status; 11893 } 11894 } 11895 } 11896 break; 11897 case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE: 11898 TI_DBG5(("satLogSense: case 3\n")); 11899 /* checking SMART feature set */ 11900 if (pSatDevData->satSMARTFeatureSet == agFALSE) 11901 { 11902 satSetSensePayload( pSense, 11903 SCSI_SNSKEY_ILLEGAL_REQUEST, 11904 0, 11905 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11906 satIOContext); 11907 11908 ostiInitiatorIOCompleted( tiRoot, 11909 tiIORequest, 11910 tiIOSuccess, 11911 SCSI_STAT_CHECK_CONDITION, 11912 satIOContext->pTiSenseData, 11913 satIOContext->interruptContext ); 11914 } 11915 else 11916 { 11917 /* checking SMART feature enabled */ 11918 if (pSatDevData->satSMARTEnabled == agFALSE) 11919 { 11920 satSetSensePayload( pSense, 11921 SCSI_SNSKEY_ABORTED_COMMAND, 11922 0, 11923 SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED, 11924 satIOContext); 11925 11926 ostiInitiatorIOCompleted( tiRoot, 11927 tiIORequest, 11928 tiIOSuccess, 11929 SCSI_STAT_CHECK_CONDITION, 11930 satIOContext->pTiSenseData, 11931 satIOContext->interruptContext ); 11932 } 11933 else 11934 { 11935 /* SAT Rev 8, 10.2.3 p72 */ 11936 TI_DBG5(("satLogSense: case 3 sends SMART RETURN STATUS\n")); 11937 11938 /* sends SMART RETURN STATUS */ 11939 fis->h.fisType = 0x27; /* Reg host to device */ 11940 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11941 11942 fis->h.command = SAT_SMART_RETURN_STATUS;/* 0xB0 */ 11943 fis->h.features = 0xDA; /* FIS features */ 11944 fis->d.featuresExp = 0; /* FIS reserve */ 11945 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 11946 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 11947 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 11948 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 11949 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 11950 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 11951 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 11952 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 11953 fis->d.device = 0; /* FIS DEV is discared in SATA */ 11954 fis->d.control = 0; /* FIS HOB bit clear */ 11955 fis->d.reserved4 = 0; 11956 fis->d.reserved5 = 0; 11957 11958 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 11959 /* Initialize CB for SATA completion. 11960 */ 11961 satIOContext->satCompleteCB = &satLogSenseCB; 11962 11963 /* 11964 * Prepare SGL and send FIS to LL layer. 11965 */ 11966 satIOContext->reqType = agRequestType; /* Save it */ 11967 11968 status = sataLLIOStart( tiRoot, 11969 tiIORequest, 11970 tiDeviceHandle, 11971 tiScsiRequest, 11972 satIOContext); 11973 11974 11975 return status; 11976 } 11977 } 11978 break; 11979 default: 11980 TI_DBG1(("satLogSense: default Page Code 0x%x\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)); 11981 satSetSensePayload( pSense, 11982 SCSI_SNSKEY_ILLEGAL_REQUEST, 11983 0, 11984 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11985 satIOContext); 11986 11987 ostiInitiatorIOCompleted( tiRoot, 11988 tiIORequest, 11989 tiIOSuccess, 11990 SCSI_STAT_CHECK_CONDITION, 11991 satIOContext->pTiSenseData, 11992 satIOContext->interruptContext ); 11993 11994 break; 11995 } /* end switch */ 11996 11997 return tiSuccess; 11998 11999 12000 } 12001 12002 /*****************************************************************************/ 12003 /*! \brief SAT implementation for SCSI satModeSelect6. 12004 * 12005 * SAT implementation for SCSI satModeSelect6. 12006 * 12007 * \param tiRoot: Pointer to TISA initiator driver/port instance. 12008 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 12009 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 12010 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 12011 * \param satIOContext_t: Pointer to the SAT IO Context 12012 * 12013 * \return If command is started successfully 12014 * - \e tiSuccess: I/O request successfully initiated. 12015 * - \e tiBusy: No resources available, try again later. 12016 * - \e tiIONoDevice: Invalid device handle. 12017 * - \e tiError: Other errors. 12018 */ 12019 /*****************************************************************************/ 12020 GLOBAL bit32 satModeSelect6( 12021 tiRoot_t *tiRoot, 12022 tiIORequest_t *tiIORequest, 12023 tiDeviceHandle_t *tiDeviceHandle, 12024 tiScsiInitiatorRequest_t *tiScsiRequest, 12025 satIOContext_t *satIOContext) 12026 { 12027 bit32 status; 12028 bit32 agRequestType; 12029 satDeviceData_t *pSatDevData; 12030 scsiRspSense_t *pSense; 12031 tiIniScsiCmnd_t *scsiCmnd; 12032 agsaFisRegHostToDevice_t *fis; 12033 bit8 *pLogPage; /* Log Page data buffer */ 12034 bit32 StartingIndex = 0; 12035 bit8 PageCode = 0; 12036 bit32 chkCnd = agFALSE; 12037 12038 pSense = satIOContext->pSense; 12039 pSatDevData = satIOContext->pSatDevData; 12040 scsiCmnd = &tiScsiRequest->scsiCmnd; 12041 fis = satIOContext->pFis; 12042 pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr; 12043 12044 TI_DBG5(("satModeSelect6: start\n")); 12045 12046 /* checking CONTROL */ 12047 /* NACA == 1 or LINK == 1*/ 12048 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 12049 { 12050 satSetSensePayload( pSense, 12051 SCSI_SNSKEY_ILLEGAL_REQUEST, 12052 0, 12053 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12054 satIOContext); 12055 12056 ostiInitiatorIOCompleted( tiRoot, 12057 tiIORequest, 12058 tiIOSuccess, 12059 SCSI_STAT_CHECK_CONDITION, 12060 satIOContext->pTiSenseData, 12061 satIOContext->interruptContext ); 12062 12063 TI_DBG2(("satModeSelect6: return control\n")); 12064 return tiSuccess; 12065 } 12066 12067 /* checking PF bit */ 12068 if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT6_PF_MASK)) 12069 { 12070 satSetSensePayload( pSense, 12071 SCSI_SNSKEY_ILLEGAL_REQUEST, 12072 0, 12073 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12074 satIOContext); 12075 12076 ostiInitiatorIOCompleted( tiRoot, 12077 tiIORequest, 12078 tiIOSuccess, 12079 SCSI_STAT_CHECK_CONDITION, 12080 satIOContext->pTiSenseData, 12081 satIOContext->interruptContext ); 12082 12083 TI_DBG1(("satModeSelect6: PF bit check \n")); 12084 return tiSuccess; 12085 12086 } 12087 12088 /* checking Block Descriptor Length on Mode parameter header(6)*/ 12089 if (pLogPage[3] == 8) 12090 { 12091 /* mode parameter block descriptor exists */ 12092 PageCode = (bit8)(pLogPage[12] & 0x3F); /* page code and index is 4 + 8 */ 12093 StartingIndex = 12; 12094 } 12095 else if (pLogPage[3] == 0) 12096 { 12097 /* mode parameter block descriptor does not exist */ 12098 PageCode = (bit8)(pLogPage[4] & 0x3F); /* page code and index is 4 + 0 */ 12099 StartingIndex = 4; 12100 ostiInitiatorIOCompleted( tiRoot, 12101 tiIORequest, 12102 tiIOSuccess, 12103 SCSI_STAT_GOOD, 12104 agNULL, 12105 satIOContext->interruptContext); 12106 return tiSuccess; 12107 } 12108 else 12109 { 12110 TI_DBG1(("satModeSelect6: return mode parameter block descriptor 0x%x\n", pLogPage[3])); 12111 /* no more than one mode parameter block descriptor shall be supported */ 12112 satSetSensePayload( pSense, 12113 SCSI_SNSKEY_NO_SENSE, 12114 0, 12115 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 12116 satIOContext); 12117 12118 ostiInitiatorIOCompleted( tiRoot, 12119 tiIORequest, 12120 tiIOSuccess, 12121 SCSI_STAT_CHECK_CONDITION, 12122 satIOContext->pTiSenseData, 12123 satIOContext->interruptContext ); 12124 return tiSuccess; 12125 } 12126 12127 12128 12129 switch (PageCode) /* page code */ 12130 { 12131 case MODESELECT_CONTROL_PAGE: 12132 TI_DBG1(("satModeSelect6: Control mode page\n")); 12133 /* 12134 compare pLogPage to expected value (SAT Table 65, p67) 12135 If not match, return check condition 12136 */ 12137 if ( pLogPage[StartingIndex+1] != 0x0A || 12138 pLogPage[StartingIndex+2] != 0x02 || 12139 (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) || 12140 (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) || 12141 (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */ 12142 (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */ 12143 (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */ 12144 12145 (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */ 12146 (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */ 12147 (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */ 12148 (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */ 12149 12150 pLogPage[StartingIndex+8] != 0xFF || 12151 pLogPage[StartingIndex+9] != 0xFF || 12152 pLogPage[StartingIndex+10] != 0x00 || 12153 pLogPage[StartingIndex+11] != 0x00 12154 ) 12155 { 12156 chkCnd = agTRUE; 12157 } 12158 if (chkCnd == agTRUE) 12159 { 12160 satSetSensePayload( pSense, 12161 SCSI_SNSKEY_ILLEGAL_REQUEST, 12162 0, 12163 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12164 satIOContext); 12165 12166 ostiInitiatorIOCompleted( tiRoot, 12167 tiIORequest, 12168 tiIOSuccess, 12169 SCSI_STAT_CHECK_CONDITION, 12170 satIOContext->pTiSenseData, 12171 satIOContext->interruptContext ); 12172 12173 TI_DBG1(("satModeSelect10: unexpected values\n")); 12174 } 12175 else 12176 { 12177 ostiInitiatorIOCompleted( tiRoot, 12178 tiIORequest, 12179 tiIOSuccess, 12180 SCSI_STAT_GOOD, 12181 agNULL, 12182 satIOContext->interruptContext); 12183 } 12184 return tiSuccess; 12185 break; 12186 case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE: 12187 TI_DBG1(("satModeSelect6: Read-Write Error Recovery mode page\n")); 12188 12189 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_AWRE_MASK) || 12190 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_RC_MASK) || 12191 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_EER_MASK) || 12192 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PER_MASK) || 12193 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DTE_MASK) || 12194 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DCR_MASK) || 12195 (pLogPage[StartingIndex + 10]) || 12196 (pLogPage[StartingIndex + 11]) 12197 ) 12198 { 12199 TI_DBG5(("satModeSelect6: return check condition \n")); 12200 12201 satSetSensePayload( pSense, 12202 SCSI_SNSKEY_ILLEGAL_REQUEST, 12203 0, 12204 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 12205 satIOContext); 12206 12207 ostiInitiatorIOCompleted( tiRoot, 12208 tiIORequest, 12209 tiIOSuccess, 12210 SCSI_STAT_CHECK_CONDITION, 12211 satIOContext->pTiSenseData, 12212 satIOContext->interruptContext ); 12213 return tiSuccess; 12214 } 12215 else 12216 { 12217 TI_DBG5(("satModeSelect6: return GOOD \n")); 12218 ostiInitiatorIOCompleted( tiRoot, 12219 tiIORequest, 12220 tiIOSuccess, 12221 SCSI_STAT_GOOD, 12222 agNULL, 12223 satIOContext->interruptContext); 12224 return tiSuccess; 12225 } 12226 12227 break; 12228 case MODESELECT_CACHING: 12229 /* SAT rev8 Table67, p69*/ 12230 TI_DBG5(("satModeSelect6: Caching mode page\n")); 12231 if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */ 12232 (pLogPage[StartingIndex + 3]) || 12233 (pLogPage[StartingIndex + 4]) || 12234 (pLogPage[StartingIndex + 5]) || 12235 (pLogPage[StartingIndex + 6]) || 12236 (pLogPage[StartingIndex + 7]) || 12237 (pLogPage[StartingIndex + 8]) || 12238 (pLogPage[StartingIndex + 9]) || 12239 (pLogPage[StartingIndex + 10]) || 12240 (pLogPage[StartingIndex + 11]) || 12241 12242 (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */ 12243 (pLogPage[StartingIndex + 13]) || 12244 (pLogPage[StartingIndex + 14]) || 12245 (pLogPage[StartingIndex + 15]) 12246 ) 12247 { 12248 TI_DBG1(("satModeSelect6: return check condition \n")); 12249 12250 satSetSensePayload( pSense, 12251 SCSI_SNSKEY_ILLEGAL_REQUEST, 12252 0, 12253 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 12254 satIOContext); 12255 12256 ostiInitiatorIOCompleted( tiRoot, 12257 tiIORequest, 12258 tiIOSuccess, 12259 SCSI_STAT_CHECK_CONDITION, 12260 satIOContext->pTiSenseData, 12261 satIOContext->interruptContext ); 12262 return tiSuccess; 12263 12264 } 12265 else 12266 { 12267 /* sends ATA SET FEATURES based on WCE bit */ 12268 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_WCE_MASK) ) 12269 { 12270 TI_DBG5(("satModeSelect6: disable write cache\n")); 12271 /* sends SET FEATURES */ 12272 fis->h.fisType = 0x27; /* Reg host to device */ 12273 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12274 12275 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 12276 fis->h.features = 0x82; /* disable write cache */ 12277 fis->d.lbaLow = 0; /* */ 12278 fis->d.lbaMid = 0; /* */ 12279 fis->d.lbaHigh = 0; /* */ 12280 fis->d.device = 0; /* */ 12281 fis->d.lbaLowExp = 0; /* */ 12282 fis->d.lbaMidExp = 0; /* */ 12283 fis->d.lbaHighExp = 0; /* */ 12284 fis->d.featuresExp = 0; /* */ 12285 fis->d.sectorCount = 0; /* */ 12286 fis->d.sectorCountExp = 0; /* */ 12287 fis->d.reserved4 = 0; 12288 fis->d.control = 0; /* FIS HOB bit clear */ 12289 fis->d.reserved5 = 0; 12290 12291 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12292 12293 /* Initialize CB for SATA completion. 12294 */ 12295 satIOContext->satCompleteCB = &satModeSelect6n10CB; 12296 12297 /* 12298 * Prepare SGL and send FIS to LL layer. 12299 */ 12300 satIOContext->reqType = agRequestType; /* Save it */ 12301 12302 status = sataLLIOStart( tiRoot, 12303 tiIORequest, 12304 tiDeviceHandle, 12305 tiScsiRequest, 12306 satIOContext); 12307 return status; 12308 } 12309 else 12310 { 12311 TI_DBG5(("satModeSelect6: enable write cache\n")); 12312 /* sends SET FEATURES */ 12313 fis->h.fisType = 0x27; /* Reg host to device */ 12314 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12315 12316 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 12317 fis->h.features = 0x02; /* enable write cache */ 12318 fis->d.lbaLow = 0; /* */ 12319 fis->d.lbaMid = 0; /* */ 12320 fis->d.lbaHigh = 0; /* */ 12321 fis->d.device = 0; /* */ 12322 fis->d.lbaLowExp = 0; /* */ 12323 fis->d.lbaMidExp = 0; /* */ 12324 fis->d.lbaHighExp = 0; /* */ 12325 fis->d.featuresExp = 0; /* */ 12326 fis->d.sectorCount = 0; /* */ 12327 fis->d.sectorCountExp = 0; /* */ 12328 fis->d.reserved4 = 0; 12329 fis->d.control = 0; /* FIS HOB bit clear */ 12330 fis->d.reserved5 = 0; 12331 12332 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12333 12334 /* Initialize CB for SATA completion. 12335 */ 12336 satIOContext->satCompleteCB = &satModeSelect6n10CB; 12337 12338 /* 12339 * Prepare SGL and send FIS to LL layer. 12340 */ 12341 satIOContext->reqType = agRequestType; /* Save it */ 12342 12343 status = sataLLIOStart( tiRoot, 12344 tiIORequest, 12345 tiDeviceHandle, 12346 tiScsiRequest, 12347 satIOContext); 12348 return status; 12349 12350 } 12351 } 12352 break; 12353 case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE: 12354 TI_DBG5(("satModeSelect6: Informational Exception Control mode page\n")); 12355 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PERF_MASK) || 12356 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_TEST_MASK) 12357 ) 12358 { 12359 TI_DBG1(("satModeSelect6: return check condition \n")); 12360 12361 satSetSensePayload( pSense, 12362 SCSI_SNSKEY_ILLEGAL_REQUEST, 12363 0, 12364 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 12365 satIOContext); 12366 12367 ostiInitiatorIOCompleted( tiRoot, 12368 tiIORequest, 12369 tiIOSuccess, 12370 SCSI_STAT_CHECK_CONDITION, 12371 satIOContext->pTiSenseData, 12372 satIOContext->interruptContext ); 12373 return tiSuccess; 12374 } 12375 else 12376 { 12377 /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */ 12378 if ( !(pLogPage[StartingIndex + 2] & 0x08) ) 12379 { 12380 TI_DBG5(("satModeSelect6: enable information exceptions reporting\n")); 12381 /* sends SMART ENABLE OPERATIONS */ 12382 fis->h.fisType = 0x27; /* Reg host to device */ 12383 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12384 12385 fis->h.command = SAT_SMART_ENABLE_OPERATIONS; /* 0xB0 */ 12386 fis->h.features = 0xD8; /* enable */ 12387 fis->d.lbaLow = 0; /* */ 12388 fis->d.lbaMid = 0x4F; /* 0x4F */ 12389 fis->d.lbaHigh = 0xC2; /* 0xC2 */ 12390 fis->d.device = 0; /* */ 12391 fis->d.lbaLowExp = 0; /* */ 12392 fis->d.lbaMidExp = 0; /* */ 12393 fis->d.lbaHighExp = 0; /* */ 12394 fis->d.featuresExp = 0; /* */ 12395 fis->d.sectorCount = 0; /* */ 12396 fis->d.sectorCountExp = 0; /* */ 12397 fis->d.reserved4 = 0; 12398 fis->d.control = 0; /* FIS HOB bit clear */ 12399 fis->d.reserved5 = 0; 12400 12401 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12402 12403 /* Initialize CB for SATA completion. 12404 */ 12405 satIOContext->satCompleteCB = &satModeSelect6n10CB; 12406 12407 /* 12408 * Prepare SGL and send FIS to LL layer. 12409 */ 12410 satIOContext->reqType = agRequestType; /* Save it */ 12411 12412 status = sataLLIOStart( tiRoot, 12413 tiIORequest, 12414 tiDeviceHandle, 12415 tiScsiRequest, 12416 satIOContext); 12417 return status; 12418 } 12419 else 12420 { 12421 TI_DBG5(("satModeSelect6: disable information exceptions reporting\n")); 12422 /* sends SMART DISABLE OPERATIONS */ 12423 fis->h.fisType = 0x27; /* Reg host to device */ 12424 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12425 12426 fis->h.command = SAT_SMART_DISABLE_OPERATIONS; /* 0xB0 */ 12427 fis->h.features = 0xD9; /* disable */ 12428 fis->d.lbaLow = 0; /* */ 12429 fis->d.lbaMid = 0x4F; /* 0x4F */ 12430 fis->d.lbaHigh = 0xC2; /* 0xC2 */ 12431 fis->d.device = 0; /* */ 12432 fis->d.lbaLowExp = 0; /* */ 12433 fis->d.lbaMidExp = 0; /* */ 12434 fis->d.lbaHighExp = 0; /* */ 12435 fis->d.featuresExp = 0; /* */ 12436 fis->d.sectorCount = 0; /* */ 12437 fis->d.sectorCountExp = 0; /* */ 12438 fis->d.reserved4 = 0; 12439 fis->d.control = 0; /* FIS HOB bit clear */ 12440 fis->d.reserved5 = 0; 12441 12442 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12443 12444 /* Initialize CB for SATA completion. 12445 */ 12446 satIOContext->satCompleteCB = &satModeSelect6n10CB; 12447 12448 /* 12449 * Prepare SGL and send FIS to LL layer. 12450 */ 12451 satIOContext->reqType = agRequestType; /* Save it */ 12452 12453 status = sataLLIOStart( tiRoot, 12454 tiIORequest, 12455 tiDeviceHandle, 12456 tiScsiRequest, 12457 satIOContext); 12458 return status; 12459 12460 } 12461 } 12462 break; 12463 default: 12464 TI_DBG1(("satModeSelect6: Error unknown page code 0x%x\n", pLogPage[12])); 12465 satSetSensePayload( pSense, 12466 SCSI_SNSKEY_NO_SENSE, 12467 0, 12468 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 12469 satIOContext); 12470 12471 ostiInitiatorIOCompleted( tiRoot, 12472 tiIORequest, 12473 tiIOSuccess, 12474 SCSI_STAT_CHECK_CONDITION, 12475 satIOContext->pTiSenseData, 12476 satIOContext->interruptContext ); 12477 return tiSuccess; 12478 } 12479 12480 } 12481 12482 /*****************************************************************************/ 12483 /*! \brief SAT implementation for SCSI satModeSelect6n10_1. 12484 * 12485 * This function is part of implementation of ModeSelect6 and ModeSelect10. 12486 * When ModeSelect6 or ModeSelect10 is coverted into multiple ATA commands, 12487 * this function is used. 12488 * 12489 * \param tiRoot: Pointer to TISA initiator driver/port instance. 12490 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 12491 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 12492 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 12493 * \param satIOContext_t: Pointer to the SAT IO Context 12494 * 12495 * \return If command is started successfully 12496 * - \e tiSuccess: I/O request successfully initiated. 12497 * - \e tiBusy: No resources available, try again later. 12498 * - \e tiIONoDevice: Invalid device handle. 12499 * - \e tiError: Other errors. 12500 */ 12501 /*****************************************************************************/ 12502 GLOBAL bit32 satModeSelect6n10_1( 12503 tiRoot_t *tiRoot, 12504 tiIORequest_t *tiIORequest, 12505 tiDeviceHandle_t *tiDeviceHandle, 12506 tiScsiInitiatorRequest_t *tiScsiRequest, 12507 satIOContext_t *satIOContext) 12508 { 12509 /* sends either ATA SET FEATURES based on DRA bit */ 12510 bit32 status; 12511 bit32 agRequestType; 12512 agsaFisRegHostToDevice_t *fis; 12513 bit8 *pLogPage; /* Log Page data buffer */ 12514 bit32 StartingIndex = 0; 12515 12516 fis = satIOContext->pFis; 12517 pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr; 12518 TI_DBG5(("satModeSelect6_1: start\n")); 12519 /* checking Block Descriptor Length on Mode parameter header(6)*/ 12520 if (pLogPage[3] == 8) 12521 { 12522 /* mode parameter block descriptor exists */ 12523 StartingIndex = 12; 12524 } 12525 else 12526 { 12527 /* mode parameter block descriptor does not exist */ 12528 StartingIndex = 4; 12529 } 12530 12531 /* sends ATA SET FEATURES based on DRA bit */ 12532 if ( !(pLogPage[StartingIndex + 12] & SCSI_MODE_SELECT6_DRA_MASK) ) 12533 { 12534 TI_DBG5(("satModeSelect6_1: enable read look-ahead feature\n")); 12535 /* sends SET FEATURES */ 12536 fis->h.fisType = 0x27; /* Reg host to device */ 12537 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12538 12539 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 12540 fis->h.features = 0xAA; /* enable read look-ahead */ 12541 fis->d.lbaLow = 0; /* */ 12542 fis->d.lbaMid = 0; /* */ 12543 fis->d.lbaHigh = 0; /* */ 12544 fis->d.device = 0; /* */ 12545 fis->d.lbaLowExp = 0; /* */ 12546 fis->d.lbaMidExp = 0; /* */ 12547 fis->d.lbaHighExp = 0; /* */ 12548 fis->d.featuresExp = 0; /* */ 12549 fis->d.sectorCount = 0; /* */ 12550 fis->d.sectorCountExp = 0; /* */ 12551 fis->d.reserved4 = 0; 12552 fis->d.control = 0; /* FIS HOB bit clear */ 12553 fis->d.reserved5 = 0; 12554 12555 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12556 12557 /* Initialize CB for SATA completion. 12558 */ 12559 satIOContext->satCompleteCB = &satModeSelect6n10CB; 12560 12561 /* 12562 * Prepare SGL and send FIS to LL layer. 12563 */ 12564 satIOContext->reqType = agRequestType; /* Save it */ 12565 12566 status = sataLLIOStart( tiRoot, 12567 tiIORequest, 12568 tiDeviceHandle, 12569 tiScsiRequest, 12570 satIOContext); 12571 return status; 12572 } 12573 else 12574 { 12575 TI_DBG5(("satModeSelect6_1: disable read look-ahead feature\n")); 12576 /* sends SET FEATURES */ 12577 fis->h.fisType = 0x27; /* Reg host to device */ 12578 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12579 12580 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 12581 fis->h.features = 0x55; /* disable read look-ahead */ 12582 fis->d.lbaLow = 0; /* */ 12583 fis->d.lbaMid = 0; /* */ 12584 fis->d.lbaHigh = 0; /* */ 12585 fis->d.device = 0; /* */ 12586 fis->d.lbaLowExp = 0; /* */ 12587 fis->d.lbaMidExp = 0; /* */ 12588 fis->d.lbaHighExp = 0; /* */ 12589 fis->d.featuresExp = 0; /* */ 12590 fis->d.sectorCount = 0; /* */ 12591 fis->d.sectorCountExp = 0; /* */ 12592 fis->d.reserved4 = 0; 12593 fis->d.control = 0; /* FIS HOB bit clear */ 12594 fis->d.reserved5 = 0; 12595 12596 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12597 12598 /* Initialize CB for SATA completion. 12599 */ 12600 satIOContext->satCompleteCB = &satModeSelect6n10CB; 12601 12602 /* 12603 * Prepare SGL and send FIS to LL layer. 12604 */ 12605 satIOContext->reqType = agRequestType; /* Save it */ 12606 12607 status = sataLLIOStart( tiRoot, 12608 tiIORequest, 12609 tiDeviceHandle, 12610 tiScsiRequest, 12611 satIOContext); 12612 return status; 12613 } 12614 12615 } 12616 12617 12618 /*****************************************************************************/ 12619 /*! \brief SAT implementation for SCSI satModeSelect10. 12620 * 12621 * SAT implementation for SCSI satModeSelect10. 12622 * 12623 * \param tiRoot: Pointer to TISA initiator driver/port instance. 12624 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 12625 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 12626 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 12627 * \param satIOContext_t: Pointer to the SAT IO Context 12628 * 12629 * \return If command is started successfully 12630 * - \e tiSuccess: I/O request successfully initiated. 12631 * - \e tiBusy: No resources available, try again later. 12632 * - \e tiIONoDevice: Invalid device handle. 12633 * - \e tiError: Other errors. 12634 */ 12635 /*****************************************************************************/ 12636 GLOBAL bit32 satModeSelect10( 12637 tiRoot_t *tiRoot, 12638 tiIORequest_t *tiIORequest, 12639 tiDeviceHandle_t *tiDeviceHandle, 12640 tiScsiInitiatorRequest_t *tiScsiRequest, 12641 satIOContext_t *satIOContext) 12642 { 12643 bit32 status; 12644 bit32 agRequestType; 12645 satDeviceData_t *pSatDevData; 12646 scsiRspSense_t *pSense; 12647 tiIniScsiCmnd_t *scsiCmnd; 12648 agsaFisRegHostToDevice_t *fis; 12649 bit8 *pLogPage; /* Log Page data buffer */ 12650 bit16 BlkDescLen = 0; /* Block Descriptor Length */ 12651 bit32 StartingIndex = 0; 12652 bit8 PageCode = 0; 12653 bit32 chkCnd = agFALSE; 12654 12655 pSense = satIOContext->pSense; 12656 pSatDevData = satIOContext->pSatDevData; 12657 scsiCmnd = &tiScsiRequest->scsiCmnd; 12658 fis = satIOContext->pFis; 12659 pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr; 12660 12661 TI_DBG5(("satModeSelect10: start\n")); 12662 12663 /* checking CONTROL */ 12664 /* NACA == 1 or LINK == 1*/ 12665 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 12666 { 12667 satSetSensePayload( pSense, 12668 SCSI_SNSKEY_ILLEGAL_REQUEST, 12669 0, 12670 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12671 satIOContext); 12672 12673 ostiInitiatorIOCompleted( tiRoot, 12674 tiIORequest, 12675 tiIOSuccess, 12676 SCSI_STAT_CHECK_CONDITION, 12677 satIOContext->pTiSenseData, 12678 satIOContext->interruptContext ); 12679 12680 TI_DBG2(("satModeSelect10: return control\n")); 12681 return tiSuccess; 12682 } 12683 12684 /* checking PF bit */ 12685 if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT10_PF_MASK)) 12686 { 12687 satSetSensePayload( pSense, 12688 SCSI_SNSKEY_ILLEGAL_REQUEST, 12689 0, 12690 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12691 satIOContext); 12692 12693 ostiInitiatorIOCompleted( tiRoot, 12694 tiIORequest, 12695 tiIOSuccess, 12696 SCSI_STAT_CHECK_CONDITION, 12697 satIOContext->pTiSenseData, 12698 satIOContext->interruptContext ); 12699 12700 TI_DBG1(("satModeSelect10: PF bit check \n")); 12701 return tiSuccess; 12702 12703 } 12704 12705 BlkDescLen = (bit8)((pLogPage[6] << 8) + pLogPage[7]); 12706 12707 /* checking Block Descriptor Length on Mode parameter header(10) and LONGLBA bit*/ 12708 if ( (BlkDescLen == 8) && !(pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) ) 12709 { 12710 /* mode parameter block descriptor exists and length is 8 byte */ 12711 PageCode = (bit8)(pLogPage[16] & 0x3F); /* page code and index is 8 + 8 */ 12712 StartingIndex = 16; 12713 } 12714 else if ( (BlkDescLen == 16) && (pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) ) 12715 { 12716 /* mode parameter block descriptor exists and length is 16 byte */ 12717 PageCode = (bit8)(pLogPage[24] & 0x3F); /* page code and index is 8 + 16 */ 12718 StartingIndex = 24; 12719 } 12720 else if (BlkDescLen == 0) 12721 { 12722 /* 12723 mode parameter block descriptor does not exist 12724 */ 12725 PageCode = (bit8)(pLogPage[8] & 0x3F); /* page code and index is 8 + 0 */ 12726 StartingIndex = 8; 12727 ostiInitiatorIOCompleted( tiRoot, 12728 tiIORequest, 12729 tiIOSuccess, 12730 SCSI_STAT_GOOD, 12731 agNULL, 12732 satIOContext->interruptContext); 12733 return tiSuccess; 12734 } 12735 else 12736 { 12737 TI_DBG1(("satModeSelect10: return mode parameter block descriptor 0x%x\n", BlkDescLen)); 12738 /* no more than one mode parameter block descriptor shall be supported */ 12739 satSetSensePayload( pSense, 12740 SCSI_SNSKEY_NO_SENSE, 12741 0, 12742 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 12743 satIOContext); 12744 12745 ostiInitiatorIOCompleted( tiRoot, 12746 tiIORequest, 12747 tiIOSuccess, 12748 SCSI_STAT_CHECK_CONDITION, 12749 satIOContext->pTiSenseData, 12750 satIOContext->interruptContext ); 12751 return tiSuccess; 12752 } 12753 /* 12754 for debugging only 12755 */ 12756 if (StartingIndex == 8) 12757 { 12758 tdhexdump("startingindex 8", (bit8 *)pLogPage, 8); 12759 } 12760 else if(StartingIndex == 16) 12761 { 12762 if (PageCode == MODESELECT_CACHING) 12763 { 12764 tdhexdump("startingindex 16", (bit8 *)pLogPage, 16+20); 12765 } 12766 else 12767 { 12768 tdhexdump("startingindex 16", (bit8 *)pLogPage, 16+12); 12769 } 12770 } 12771 else 12772 { 12773 if (PageCode == MODESELECT_CACHING) 12774 { 12775 tdhexdump("startingindex 24", (bit8 *)pLogPage, 24+20); 12776 } 12777 else 12778 { 12779 tdhexdump("startingindex 24", (bit8 *)pLogPage, 24+12); 12780 } 12781 } 12782 switch (PageCode) /* page code */ 12783 { 12784 case MODESELECT_CONTROL_PAGE: 12785 TI_DBG5(("satModeSelect10: Control mode page\n")); 12786 /* 12787 compare pLogPage to expected value (SAT Table 65, p67) 12788 If not match, return check condition 12789 */ 12790 if ( pLogPage[StartingIndex+1] != 0x0A || 12791 pLogPage[StartingIndex+2] != 0x02 || 12792 (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) || 12793 (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) || 12794 (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */ 12795 (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */ 12796 (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */ 12797 12798 (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */ 12799 (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */ 12800 (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */ 12801 (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */ 12802 12803 pLogPage[StartingIndex+8] != 0xFF || 12804 pLogPage[StartingIndex+9] != 0xFF || 12805 pLogPage[StartingIndex+10] != 0x00 || 12806 pLogPage[StartingIndex+11] != 0x00 12807 ) 12808 { 12809 chkCnd = agTRUE; 12810 } 12811 if (chkCnd == agTRUE) 12812 { 12813 satSetSensePayload( pSense, 12814 SCSI_SNSKEY_ILLEGAL_REQUEST, 12815 0, 12816 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12817 satIOContext); 12818 12819 ostiInitiatorIOCompleted( tiRoot, 12820 tiIORequest, 12821 tiIOSuccess, 12822 SCSI_STAT_CHECK_CONDITION, 12823 satIOContext->pTiSenseData, 12824 satIOContext->interruptContext ); 12825 12826 TI_DBG1(("satModeSelect10: unexpected values\n")); 12827 } 12828 else 12829 { 12830 ostiInitiatorIOCompleted( tiRoot, 12831 tiIORequest, 12832 tiIOSuccess, 12833 SCSI_STAT_GOOD, 12834 agNULL, 12835 satIOContext->interruptContext); 12836 } 12837 return tiSuccess; 12838 break; 12839 case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE: 12840 TI_DBG5(("satModeSelect10: Read-Write Error Recovery mode page\n")); 12841 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_AWRE_MASK) || 12842 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_RC_MASK) || 12843 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_EER_MASK) || 12844 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PER_MASK) || 12845 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DTE_MASK) || 12846 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DCR_MASK) || 12847 (pLogPage[StartingIndex + 10]) || 12848 (pLogPage[StartingIndex + 11]) 12849 ) 12850 { 12851 TI_DBG1(("satModeSelect10: return check condition \n")); 12852 12853 satSetSensePayload( pSense, 12854 SCSI_SNSKEY_ILLEGAL_REQUEST, 12855 0, 12856 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 12857 satIOContext); 12858 12859 ostiInitiatorIOCompleted( tiRoot, 12860 tiIORequest, 12861 tiIOSuccess, 12862 SCSI_STAT_CHECK_CONDITION, 12863 satIOContext->pTiSenseData, 12864 satIOContext->interruptContext ); 12865 return tiSuccess; 12866 } 12867 else 12868 { 12869 TI_DBG2(("satModeSelect10: return GOOD \n")); 12870 ostiInitiatorIOCompleted( tiRoot, 12871 tiIORequest, 12872 tiIOSuccess, 12873 SCSI_STAT_GOOD, 12874 agNULL, 12875 satIOContext->interruptContext); 12876 return tiSuccess; 12877 } 12878 12879 break; 12880 case MODESELECT_CACHING: 12881 /* SAT rev8 Table67, p69*/ 12882 TI_DBG5(("satModeSelect10: Caching mode page\n")); 12883 if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */ 12884 (pLogPage[StartingIndex + 3]) || 12885 (pLogPage[StartingIndex + 4]) || 12886 (pLogPage[StartingIndex + 5]) || 12887 (pLogPage[StartingIndex + 6]) || 12888 (pLogPage[StartingIndex + 7]) || 12889 (pLogPage[StartingIndex + 8]) || 12890 (pLogPage[StartingIndex + 9]) || 12891 (pLogPage[StartingIndex + 10]) || 12892 (pLogPage[StartingIndex + 11]) || 12893 12894 (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */ 12895 (pLogPage[StartingIndex + 13]) || 12896 (pLogPage[StartingIndex + 14]) || 12897 (pLogPage[StartingIndex + 15]) 12898 ) 12899 { 12900 TI_DBG1(("satModeSelect10: return check condition \n")); 12901 12902 satSetSensePayload( pSense, 12903 SCSI_SNSKEY_ILLEGAL_REQUEST, 12904 0, 12905 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 12906 satIOContext); 12907 12908 ostiInitiatorIOCompleted( tiRoot, 12909 tiIORequest, 12910 tiIOSuccess, 12911 SCSI_STAT_CHECK_CONDITION, 12912 satIOContext->pTiSenseData, 12913 satIOContext->interruptContext ); 12914 return tiSuccess; 12915 12916 } 12917 else 12918 { 12919 /* sends ATA SET FEATURES based on WCE bit */ 12920 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_WCE_MASK) ) 12921 { 12922 TI_DBG5(("satModeSelect10: disable write cache\n")); 12923 /* sends SET FEATURES */ 12924 fis->h.fisType = 0x27; /* Reg host to device */ 12925 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12926 12927 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 12928 fis->h.features = 0x82; /* disable write cache */ 12929 fis->d.lbaLow = 0; /* */ 12930 fis->d.lbaMid = 0; /* */ 12931 fis->d.lbaHigh = 0; /* */ 12932 fis->d.device = 0; /* */ 12933 fis->d.lbaLowExp = 0; /* */ 12934 fis->d.lbaMidExp = 0; /* */ 12935 fis->d.lbaHighExp = 0; /* */ 12936 fis->d.featuresExp = 0; /* */ 12937 fis->d.sectorCount = 0; /* */ 12938 fis->d.sectorCountExp = 0; /* */ 12939 fis->d.reserved4 = 0; 12940 fis->d.control = 0; /* FIS HOB bit clear */ 12941 fis->d.reserved5 = 0; 12942 12943 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12944 12945 /* Initialize CB for SATA completion. 12946 */ 12947 satIOContext->satCompleteCB = &satModeSelect6n10CB; 12948 12949 /* 12950 * Prepare SGL and send FIS to LL layer. 12951 */ 12952 satIOContext->reqType = agRequestType; /* Save it */ 12953 12954 status = sataLLIOStart( tiRoot, 12955 tiIORequest, 12956 tiDeviceHandle, 12957 tiScsiRequest, 12958 satIOContext); 12959 return status; 12960 } 12961 else 12962 { 12963 TI_DBG5(("satModeSelect10: enable write cache\n")); 12964 /* sends SET FEATURES */ 12965 fis->h.fisType = 0x27; /* Reg host to device */ 12966 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12967 12968 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 12969 fis->h.features = 0x02; /* enable write cache */ 12970 fis->d.lbaLow = 0; /* */ 12971 fis->d.lbaMid = 0; /* */ 12972 fis->d.lbaHigh = 0; /* */ 12973 fis->d.device = 0; /* */ 12974 fis->d.lbaLowExp = 0; /* */ 12975 fis->d.lbaMidExp = 0; /* */ 12976 fis->d.lbaHighExp = 0; /* */ 12977 fis->d.featuresExp = 0; /* */ 12978 fis->d.sectorCount = 0; /* */ 12979 fis->d.sectorCountExp = 0; /* */ 12980 fis->d.reserved4 = 0; 12981 fis->d.control = 0; /* FIS HOB bit clear */ 12982 fis->d.reserved5 = 0; 12983 12984 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12985 12986 /* Initialize CB for SATA completion. 12987 */ 12988 satIOContext->satCompleteCB = &satModeSelect6n10CB; 12989 12990 /* 12991 * Prepare SGL and send FIS to LL layer. 12992 */ 12993 satIOContext->reqType = agRequestType; /* Save it */ 12994 12995 status = sataLLIOStart( tiRoot, 12996 tiIORequest, 12997 tiDeviceHandle, 12998 tiScsiRequest, 12999 satIOContext); 13000 return status; 13001 13002 } 13003 } 13004 break; 13005 case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE: 13006 TI_DBG5(("satModeSelect10: Informational Exception Control mode page\n")); 13007 13008 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PERF_MASK) || 13009 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_TEST_MASK) 13010 ) 13011 { 13012 TI_DBG1(("satModeSelect10: return check condition \n")); 13013 13014 satSetSensePayload( pSense, 13015 SCSI_SNSKEY_ILLEGAL_REQUEST, 13016 0, 13017 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 13018 satIOContext); 13019 13020 ostiInitiatorIOCompleted( tiRoot, 13021 tiIORequest, 13022 tiIOSuccess, 13023 SCSI_STAT_CHECK_CONDITION, 13024 satIOContext->pTiSenseData, 13025 satIOContext->interruptContext ); 13026 return tiSuccess; 13027 } 13028 else 13029 { 13030 /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */ 13031 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DEXCPT_MASK) ) 13032 { 13033 TI_DBG5(("satModeSelect10: enable information exceptions reporting\n")); 13034 /* sends SMART ENABLE OPERATIONS */ 13035 fis->h.fisType = 0x27; /* Reg host to device */ 13036 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13037 13038 fis->h.command = SAT_SMART_ENABLE_OPERATIONS; /* 0xB0 */ 13039 fis->h.features = 0xD8; /* enable */ 13040 fis->d.lbaLow = 0; /* */ 13041 fis->d.lbaMid = 0x4F; /* 0x4F */ 13042 fis->d.lbaHigh = 0xC2; /* 0xC2 */ 13043 fis->d.device = 0; /* */ 13044 fis->d.lbaLowExp = 0; /* */ 13045 fis->d.lbaMidExp = 0; /* */ 13046 fis->d.lbaHighExp = 0; /* */ 13047 fis->d.featuresExp = 0; /* */ 13048 fis->d.sectorCount = 0; /* */ 13049 fis->d.sectorCountExp = 0; /* */ 13050 fis->d.reserved4 = 0; 13051 fis->d.control = 0; /* FIS HOB bit clear */ 13052 fis->d.reserved5 = 0; 13053 13054 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 13055 13056 /* Initialize CB for SATA completion. 13057 */ 13058 satIOContext->satCompleteCB = &satModeSelect6n10CB; 13059 13060 /* 13061 * Prepare SGL and send FIS to LL layer. 13062 */ 13063 satIOContext->reqType = agRequestType; /* Save it */ 13064 13065 status = sataLLIOStart( tiRoot, 13066 tiIORequest, 13067 tiDeviceHandle, 13068 tiScsiRequest, 13069 satIOContext); 13070 return status; 13071 } 13072 else 13073 { 13074 TI_DBG5(("satModeSelect10: disable information exceptions reporting\n")); 13075 /* sends SMART DISABLE OPERATIONS */ 13076 fis->h.fisType = 0x27; /* Reg host to device */ 13077 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13078 13079 fis->h.command = SAT_SMART_DISABLE_OPERATIONS; /* 0xB0 */ 13080 fis->h.features = 0xD9; /* disable */ 13081 fis->d.lbaLow = 0; /* */ 13082 fis->d.lbaMid = 0x4F; /* 0x4F */ 13083 fis->d.lbaHigh = 0xC2; /* 0xC2 */ 13084 fis->d.device = 0; /* */ 13085 fis->d.lbaLowExp = 0; /* */ 13086 fis->d.lbaMidExp = 0; /* */ 13087 fis->d.lbaHighExp = 0; /* */ 13088 fis->d.featuresExp = 0; /* */ 13089 fis->d.sectorCount = 0; /* */ 13090 fis->d.sectorCountExp = 0; /* */ 13091 fis->d.reserved4 = 0; 13092 fis->d.control = 0; /* FIS HOB bit clear */ 13093 fis->d.reserved5 = 0; 13094 13095 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 13096 13097 /* Initialize CB for SATA completion. 13098 */ 13099 satIOContext->satCompleteCB = &satModeSelect6n10CB; 13100 13101 /* 13102 * Prepare SGL and send FIS to LL layer. 13103 */ 13104 satIOContext->reqType = agRequestType; /* Save it */ 13105 13106 status = sataLLIOStart( tiRoot, 13107 tiIORequest, 13108 tiDeviceHandle, 13109 tiScsiRequest, 13110 satIOContext); 13111 return status; 13112 13113 } 13114 } 13115 break; 13116 default: 13117 TI_DBG1(("satModeSelect10: Error unknown page code 0x%x\n", pLogPage[12])); 13118 satSetSensePayload( pSense, 13119 SCSI_SNSKEY_NO_SENSE, 13120 0, 13121 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 13122 satIOContext); 13123 13124 ostiInitiatorIOCompleted( tiRoot, 13125 tiIORequest, 13126 tiIOSuccess, 13127 SCSI_STAT_CHECK_CONDITION, 13128 satIOContext->pTiSenseData, 13129 satIOContext->interruptContext ); 13130 return tiSuccess; 13131 } 13132 13133 } 13134 13135 13136 /*****************************************************************************/ 13137 /*! \brief SAT implementation for SCSI satSynchronizeCache10. 13138 * 13139 * SAT implementation for SCSI satSynchronizeCache10. 13140 * 13141 * \param tiRoot: Pointer to TISA initiator driver/port instance. 13142 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 13143 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 13144 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 13145 * \param satIOContext_t: Pointer to the SAT IO Context 13146 * 13147 * \return If command is started successfully 13148 * - \e tiSuccess: I/O request successfully initiated. 13149 * - \e tiBusy: No resources available, try again later. 13150 * - \e tiIONoDevice: Invalid device handle. 13151 * - \e tiError: Other errors. 13152 */ 13153 /*****************************************************************************/ 13154 GLOBAL bit32 satSynchronizeCache10( 13155 tiRoot_t *tiRoot, 13156 tiIORequest_t *tiIORequest, 13157 tiDeviceHandle_t *tiDeviceHandle, 13158 tiScsiInitiatorRequest_t *tiScsiRequest, 13159 satIOContext_t *satIOContext) 13160 { 13161 bit32 status; 13162 bit32 agRequestType; 13163 satDeviceData_t *pSatDevData; 13164 scsiRspSense_t *pSense; 13165 tiIniScsiCmnd_t *scsiCmnd; 13166 agsaFisRegHostToDevice_t *fis; 13167 13168 pSense = satIOContext->pSense; 13169 pSatDevData = satIOContext->pSatDevData; 13170 scsiCmnd = &tiScsiRequest->scsiCmnd; 13171 fis = satIOContext->pFis; 13172 13173 TI_DBG5(("satSynchronizeCache10: start\n")); 13174 13175 /* checking CONTROL */ 13176 /* NACA == 1 or LINK == 1*/ 13177 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 13178 { 13179 satSetSensePayload( pSense, 13180 SCSI_SNSKEY_ILLEGAL_REQUEST, 13181 0, 13182 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13183 satIOContext); 13184 13185 ostiInitiatorIOCompleted( tiRoot, 13186 tiIORequest, 13187 tiIOSuccess, 13188 SCSI_STAT_CHECK_CONDITION, 13189 satIOContext->pTiSenseData, 13190 satIOContext->interruptContext ); 13191 13192 TI_DBG2(("satSynchronizeCache10: return control\n")); 13193 return tiSuccess; 13194 } 13195 13196 /* checking IMMED bit */ 13197 if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK) 13198 { 13199 TI_DBG1(("satSynchronizeCache10: GOOD status due to IMMED bit\n")); 13200 13201 /* return GOOD status first here */ 13202 ostiInitiatorIOCompleted( tiRoot, 13203 tiIORequest, 13204 tiIOSuccess, 13205 SCSI_STAT_GOOD, 13206 agNULL, 13207 satIOContext->interruptContext); 13208 } 13209 13210 /* sends FLUSH CACHE or FLUSH CACHE EXT */ 13211 if (pSatDevData->sat48BitSupport == agTRUE) 13212 { 13213 TI_DBG5(("satSynchronizeCache10: sends FLUSH CACHE EXT\n")); 13214 /* FLUSH CACHE EXT */ 13215 fis->h.fisType = 0x27; /* Reg host to device */ 13216 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13217 13218 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */ 13219 fis->h.features = 0; /* FIS reserve */ 13220 fis->d.featuresExp = 0; /* FIS reserve */ 13221 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 13222 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 13223 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 13224 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 13225 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 13226 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 13227 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 13228 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 13229 fis->d.device = 0; /* FIS DEV is discared in SATA */ 13230 fis->d.control = 0; /* FIS HOB bit clear */ 13231 fis->d.reserved4 = 0; 13232 fis->d.reserved5 = 0; 13233 13234 } 13235 else 13236 { 13237 TI_DBG5(("satSynchronizeCache10: sends FLUSH CACHE\n")); 13238 /* FLUSH CACHE */ 13239 fis->h.fisType = 0x27; /* Reg host to device */ 13240 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13241 13242 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */ 13243 fis->h.features = 0; /* FIS features NA */ 13244 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 13245 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 13246 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 13247 fis->d.lbaLowExp = 0; 13248 fis->d.lbaMidExp = 0; 13249 fis->d.lbaHighExp = 0; 13250 fis->d.featuresExp = 0; 13251 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 13252 fis->d.sectorCountExp = 0; 13253 fis->d.device = 0; /* FIS DEV is discared in SATA */ 13254 fis->d.control = 0; /* FIS HOB bit clear */ 13255 fis->d.reserved4 = 0; 13256 fis->d.reserved5 = 0; 13257 13258 } 13259 13260 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 13261 13262 /* Initialize CB for SATA completion. 13263 */ 13264 satIOContext->satCompleteCB = &satSynchronizeCache10n16CB; 13265 13266 /* 13267 * Prepare SGL and send FIS to LL layer. 13268 */ 13269 satIOContext->reqType = agRequestType; /* Save it */ 13270 13271 status = sataLLIOStart( tiRoot, 13272 tiIORequest, 13273 tiDeviceHandle, 13274 tiScsiRequest, 13275 satIOContext); 13276 13277 13278 return (status); 13279 } 13280 13281 /*****************************************************************************/ 13282 /*! \brief SAT implementation for SCSI satSynchronizeCache16. 13283 * 13284 * SAT implementation for SCSI satSynchronizeCache16. 13285 * 13286 * \param tiRoot: Pointer to TISA initiator driver/port instance. 13287 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 13288 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 13289 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 13290 * \param satIOContext_t: Pointer to the SAT IO Context 13291 * 13292 * \return If command is started successfully 13293 * - \e tiSuccess: I/O request successfully initiated. 13294 * - \e tiBusy: No resources available, try again later. 13295 * - \e tiIONoDevice: Invalid device handle. 13296 * - \e tiError: Other errors. 13297 */ 13298 /*****************************************************************************/ 13299 GLOBAL bit32 satSynchronizeCache16( 13300 tiRoot_t *tiRoot, 13301 tiIORequest_t *tiIORequest, 13302 tiDeviceHandle_t *tiDeviceHandle, 13303 tiScsiInitiatorRequest_t *tiScsiRequest, 13304 satIOContext_t *satIOContext) 13305 { 13306 bit32 status; 13307 bit32 agRequestType; 13308 satDeviceData_t *pSatDevData; 13309 scsiRspSense_t *pSense; 13310 tiIniScsiCmnd_t *scsiCmnd; 13311 agsaFisRegHostToDevice_t *fis; 13312 13313 pSense = satIOContext->pSense; 13314 pSatDevData = satIOContext->pSatDevData; 13315 scsiCmnd = &tiScsiRequest->scsiCmnd; 13316 fis = satIOContext->pFis; 13317 13318 TI_DBG5(("satSynchronizeCache16: start\n")); 13319 13320 /* checking CONTROL */ 13321 /* NACA == 1 or LINK == 1*/ 13322 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 13323 { 13324 satSetSensePayload( pSense, 13325 SCSI_SNSKEY_ILLEGAL_REQUEST, 13326 0, 13327 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13328 satIOContext); 13329 13330 ostiInitiatorIOCompleted( tiRoot, 13331 tiIORequest, 13332 tiIOSuccess, 13333 SCSI_STAT_CHECK_CONDITION, 13334 satIOContext->pTiSenseData, 13335 satIOContext->interruptContext ); 13336 13337 TI_DBG1(("satSynchronizeCache16: return control\n")); 13338 return tiSuccess; 13339 } 13340 13341 13342 /* checking IMMED bit */ 13343 if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK) 13344 { 13345 TI_DBG1(("satSynchronizeCache16: GOOD status due to IMMED bit\n")); 13346 13347 /* return GOOD status first here */ 13348 ostiInitiatorIOCompleted( tiRoot, 13349 tiIORequest, 13350 tiIOSuccess, 13351 SCSI_STAT_GOOD, 13352 agNULL, 13353 satIOContext->interruptContext); 13354 } 13355 13356 /* sends FLUSH CACHE or FLUSH CACHE EXT */ 13357 if (pSatDevData->sat48BitSupport == agTRUE) 13358 { 13359 TI_DBG5(("satSynchronizeCache16: sends FLUSH CACHE EXT\n")); 13360 /* FLUSH CACHE EXT */ 13361 fis->h.fisType = 0x27; /* Reg host to device */ 13362 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13363 13364 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */ 13365 fis->h.features = 0; /* FIS reserve */ 13366 fis->d.featuresExp = 0; /* FIS reserve */ 13367 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 13368 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 13369 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 13370 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 13371 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 13372 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 13373 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 13374 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 13375 fis->d.device = 0; /* FIS DEV is discared in SATA */ 13376 fis->d.control = 0; /* FIS HOB bit clear */ 13377 fis->d.reserved4 = 0; 13378 fis->d.reserved5 = 0; 13379 13380 } 13381 else 13382 { 13383 TI_DBG5(("satSynchronizeCache16: sends FLUSH CACHE\n")); 13384 /* FLUSH CACHE */ 13385 fis->h.fisType = 0x27; /* Reg host to device */ 13386 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13387 13388 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */ 13389 fis->h.features = 0; /* FIS features NA */ 13390 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 13391 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 13392 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 13393 fis->d.lbaLowExp = 0; 13394 fis->d.lbaMidExp = 0; 13395 fis->d.lbaHighExp = 0; 13396 fis->d.featuresExp = 0; 13397 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 13398 fis->d.sectorCountExp = 0; 13399 fis->d.device = 0; /* FIS DEV is discared in SATA */ 13400 fis->d.control = 0; /* FIS HOB bit clear */ 13401 fis->d.reserved4 = 0; 13402 fis->d.reserved5 = 0; 13403 13404 } 13405 13406 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 13407 13408 /* Initialize CB for SATA completion. 13409 */ 13410 satIOContext->satCompleteCB = &satSynchronizeCache10n16CB; 13411 13412 /* 13413 * Prepare SGL and send FIS to LL layer. 13414 */ 13415 satIOContext->reqType = agRequestType; /* Save it */ 13416 13417 status = sataLLIOStart( tiRoot, 13418 tiIORequest, 13419 tiDeviceHandle, 13420 tiScsiRequest, 13421 satIOContext); 13422 13423 13424 return (status); 13425 } 13426 13427 13428 /*****************************************************************************/ 13429 /*! \brief SAT implementation for SCSI satWriteAndVerify10. 13430 * 13431 * SAT implementation for SCSI satWriteAndVerify10. 13432 * 13433 * \param tiRoot: Pointer to TISA initiator driver/port instance. 13434 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 13435 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 13436 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 13437 * \param satIOContext_t: Pointer to the SAT IO Context 13438 * 13439 * \return If command is started successfully 13440 * - \e tiSuccess: I/O request successfully initiated. 13441 * - \e tiBusy: No resources available, try again later. 13442 * - \e tiIONoDevice: Invalid device handle. 13443 * - \e tiError: Other errors. 13444 */ 13445 /*****************************************************************************/ 13446 GLOBAL bit32 satWriteAndVerify10( 13447 tiRoot_t *tiRoot, 13448 tiIORequest_t *tiIORequest, 13449 tiDeviceHandle_t *tiDeviceHandle, 13450 tiScsiInitiatorRequest_t *tiScsiRequest, 13451 satIOContext_t *satIOContext) 13452 { 13453 /* 13454 combination of write10 and verify10 13455 */ 13456 13457 bit32 status; 13458 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 13459 satDeviceData_t *pSatDevData; 13460 scsiRspSense_t *pSense; 13461 tiIniScsiCmnd_t *scsiCmnd; 13462 agsaFisRegHostToDevice_t *fis; 13463 bit32 lba = 0; 13464 bit32 tl = 0; 13465 bit32 LoopNum = 1; 13466 bit8 LBA[4]; 13467 bit8 TL[4]; 13468 bit32 rangeChk = agFALSE; /* lba and tl range check */ 13469 13470 pSense = satIOContext->pSense; 13471 pSatDevData = satIOContext->pSatDevData; 13472 scsiCmnd = &tiScsiRequest->scsiCmnd; 13473 fis = satIOContext->pFis; 13474 13475 TI_DBG5(("satWriteAndVerify10: start\n")); 13476 13477 13478 /* checking BYTCHK bit */ 13479 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK) 13480 { 13481 satSetSensePayload( pSense, 13482 SCSI_SNSKEY_ILLEGAL_REQUEST, 13483 0, 13484 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13485 satIOContext); 13486 13487 ostiInitiatorIOCompleted( tiRoot, 13488 tiIORequest, 13489 tiIOSuccess, 13490 SCSI_STAT_CHECK_CONDITION, 13491 satIOContext->pTiSenseData, 13492 satIOContext->interruptContext ); 13493 13494 TI_DBG1(("satWriteAndVerify10: BYTCHK bit checking \n")); 13495 return tiSuccess; 13496 } 13497 13498 13499 /* checking CONTROL */ 13500 /* NACA == 1 or LINK == 1*/ 13501 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 13502 { 13503 satSetSensePayload( pSense, 13504 SCSI_SNSKEY_ILLEGAL_REQUEST, 13505 0, 13506 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13507 satIOContext); 13508 13509 ostiInitiatorIOCompleted( tiRoot, 13510 tiIORequest, 13511 tiIOSuccess, 13512 SCSI_STAT_CHECK_CONDITION, 13513 satIOContext->pTiSenseData, 13514 satIOContext->interruptContext ); 13515 13516 TI_DBG1(("satWriteAndVerify10: return control\n")); 13517 return tiSuccess; 13518 } 13519 13520 osti_memset(LBA, 0, sizeof(LBA)); 13521 osti_memset(TL, 0, sizeof(TL)); 13522 13523 /* do not use memcpy due to indexing in LBA and TL */ 13524 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 13525 LBA[1] = scsiCmnd->cdb[3]; 13526 LBA[2] = scsiCmnd->cdb[4]; 13527 LBA[3] = scsiCmnd->cdb[5]; /* LSB */ 13528 13529 TL[0] = 0; 13530 TL[1] = 0; 13531 TL[2] = scsiCmnd->cdb[7]; /* MSB */ 13532 TL[3] = scsiCmnd->cdb[8]; /* LSB */ 13533 13534 rangeChk = satAddNComparebit32(LBA, TL); 13535 13536 /* cbd10; computing LBA and transfer length */ 13537 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 13538 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 13539 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 13540 13541 13542 /* Table 34, 9.1, p 46 */ 13543 /* 13544 note: As of 2/10/2006, no support for DMA QUEUED 13545 */ 13546 13547 /* 13548 Table 34, 9.1, p 46, b 13549 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 13550 return check condition 13551 */ 13552 if (pSatDevData->satNCQ != agTRUE && 13553 pSatDevData->sat48BitSupport != agTRUE 13554 ) 13555 { 13556 if (lba > SAT_TR_LBA_LIMIT - 1) 13557 { 13558 satSetSensePayload( pSense, 13559 SCSI_SNSKEY_ILLEGAL_REQUEST, 13560 0, 13561 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 13562 satIOContext); 13563 13564 ostiInitiatorIOCompleted( tiRoot, 13565 tiIORequest, 13566 tiIOSuccess, 13567 SCSI_STAT_CHECK_CONDITION, 13568 satIOContext->pTiSenseData, 13569 satIOContext->interruptContext ); 13570 13571 TI_DBG1(("satWriteAndVerify10: return LBA out of range\n")); 13572 return tiSuccess; 13573 } 13574 13575 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 13576 { 13577 TI_DBG1(("satWrite10: return LBA+TL out of range, not EXT\n")); 13578 satSetSensePayload( pSense, 13579 SCSI_SNSKEY_ILLEGAL_REQUEST, 13580 0, 13581 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 13582 satIOContext); 13583 13584 ostiInitiatorIOCompleted( tiRoot, 13585 tiIORequest, 13586 tiIOSuccess, 13587 SCSI_STAT_CHECK_CONDITION, 13588 satIOContext->pTiSenseData, 13589 satIOContext->interruptContext ); 13590 13591 return tiSuccess; 13592 } 13593 } 13594 13595 13596 /* case 1 and 2 */ 13597 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT) 13598 { 13599 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 13600 { 13601 /* case 2 */ 13602 /* WRITE DMA*/ 13603 /* can't fit the transfer length */ 13604 TI_DBG5(("satWriteAndVerify10: case 2 !!!\n")); 13605 fis->h.fisType = 0x27; /* Reg host to device */ 13606 fis->h.c_pmPort = 0x80; /* C bit is set */ 13607 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 13608 fis->h.features = 0; /* FIS reserve */ 13609 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 13610 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 13611 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 13612 13613 /* FIS LBA mode set LBA (27:24) */ 13614 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 13615 13616 fis->d.lbaLowExp = 0; 13617 fis->d.lbaMidExp = 0; 13618 fis->d.lbaHighExp = 0; 13619 fis->d.featuresExp = 0; 13620 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 13621 fis->d.sectorCountExp = 0; 13622 fis->d.reserved4 = 0; 13623 fis->d.control = 0; /* FIS HOB bit clear */ 13624 fis->d.reserved5 = 0; 13625 13626 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 13627 satIOContext->ATACmd = SAT_WRITE_DMA; 13628 } 13629 else 13630 { 13631 /* case 1 */ 13632 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 13633 /* WRITE SECTORS for easier implemetation */ 13634 /* can't fit the transfer length */ 13635 TI_DBG5(("satWriteAndVerify10: case 1 !!!\n")); 13636 fis->h.fisType = 0x27; /* Reg host to device */ 13637 fis->h.c_pmPort = 0x80; /* C bit is set */ 13638 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 13639 fis->h.features = 0; /* FIS reserve */ 13640 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 13641 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 13642 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 13643 13644 /* FIS LBA mode set LBA (27:24) */ 13645 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 13646 13647 fis->d.lbaLowExp = 0; 13648 fis->d.lbaMidExp = 0; 13649 fis->d.lbaHighExp = 0; 13650 fis->d.featuresExp = 0; 13651 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 13652 fis->d.sectorCountExp = 0; 13653 fis->d.reserved4 = 0; 13654 fis->d.control = 0; /* FIS HOB bit clear */ 13655 fis->d.reserved5 = 0; 13656 13657 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 13658 satIOContext->ATACmd = SAT_WRITE_SECTORS; 13659 13660 } 13661 } 13662 13663 /* case 3 and 4 */ 13664 if (pSatDevData->sat48BitSupport == agTRUE) 13665 { 13666 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 13667 { 13668 /* case 3 */ 13669 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 13670 TI_DBG5(("satWriteAndVerify10: case 3\n")); 13671 fis->h.fisType = 0x27; /* Reg host to device */ 13672 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13673 13674 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 13675 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 13676 13677 fis->h.features = 0; /* FIS reserve */ 13678 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 13679 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 13680 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 13681 fis->d.device = 0x40; /* FIS LBA mode set */ 13682 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 13683 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 13684 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 13685 fis->d.featuresExp = 0; /* FIS reserve */ 13686 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 13687 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 13688 fis->d.reserved4 = 0; 13689 fis->d.control = 0; /* FIS HOB bit clear */ 13690 fis->d.reserved5 = 0; 13691 13692 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 13693 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 13694 } 13695 else 13696 { 13697 /* case 4 */ 13698 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 13699 /* WRITE SECTORS EXT for easier implemetation */ 13700 TI_DBG5(("satWriteAndVerify10: case 4\n")); 13701 fis->h.fisType = 0x27; /* Reg host to device */ 13702 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13703 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 13704 13705 fis->h.features = 0; /* FIS reserve */ 13706 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 13707 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 13708 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 13709 fis->d.device = 0x40; /* FIS LBA mode set */ 13710 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 13711 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 13712 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 13713 fis->d.featuresExp = 0; /* FIS reserve */ 13714 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 13715 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 13716 fis->d.reserved4 = 0; 13717 fis->d.control = 0; /* FIS HOB bit clear */ 13718 fis->d.reserved5 = 0; 13719 13720 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 13721 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 13722 } 13723 } 13724 /* case 5 */ 13725 if (pSatDevData->satNCQ == agTRUE) 13726 { 13727 /* WRITE FPDMA QUEUED */ 13728 if (pSatDevData->sat48BitSupport != agTRUE) 13729 { 13730 TI_DBG5(("satWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support \n")); 13731 satSetSensePayload( pSense, 13732 SCSI_SNSKEY_ILLEGAL_REQUEST, 13733 0, 13734 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13735 satIOContext); 13736 13737 ostiInitiatorIOCompleted( tiRoot, 13738 tiIORequest, 13739 tiIOSuccess, 13740 SCSI_STAT_CHECK_CONDITION, 13741 satIOContext->pTiSenseData, 13742 satIOContext->interruptContext ); 13743 return tiSuccess; 13744 } 13745 TI_DBG5(("satWriteAndVerify10: case 5\n")); 13746 13747 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 13748 13749 fis->h.fisType = 0x27; /* Reg host to device */ 13750 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13751 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 13752 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 13753 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 13754 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 13755 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 13756 13757 /* Check FUA bit */ 13758 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK) 13759 fis->d.device = 0xC0; /* FIS FUA set */ 13760 else 13761 fis->d.device = 0x40; /* FIS FUA clear */ 13762 13763 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 13764 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 13765 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 13766 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 13767 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 13768 fis->d.sectorCountExp = 0; 13769 fis->d.reserved4 = 0; 13770 fis->d.control = 0; /* FIS HOB bit clear */ 13771 fis->d.reserved5 = 0; 13772 13773 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 13774 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 13775 } 13776 13777 satIOContext->currentLBA = lba; 13778 satIOContext->OrgTL = tl; 13779 13780 /* 13781 computing number of loop and remainder for tl 13782 0xFF in case not ext 13783 0xFFFF in case EXT 13784 */ 13785 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 13786 { 13787 LoopNum = satComputeLoopNum(tl, 0xFF); 13788 } 13789 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 13790 fis->h.command == SAT_WRITE_DMA_EXT || 13791 fis->h.command == SAT_WRITE_DMA_FUA_EXT 13792 ) 13793 { 13794 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 13795 LoopNum = satComputeLoopNum(tl, 0xFFFF); 13796 } 13797 else 13798 { 13799 /* SAT_WRITE_FPDMA_QUEUED */ 13800 LoopNum = satComputeLoopNum(tl, 0xFFFF); 13801 } 13802 13803 satIOContext->LoopNum = LoopNum; 13804 13805 13806 if (LoopNum == 1) 13807 { 13808 TI_DBG5(("satWriteAndVerify10: NON CHAINED data\n")); 13809 /* Initialize CB for SATA completion. 13810 */ 13811 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB; 13812 } 13813 else 13814 { 13815 TI_DBG1(("satWriteAndVerify10: CHAINED data\n")); 13816 /* re-setting tl */ 13817 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 13818 { 13819 fis->d.sectorCount = 0xFF; 13820 } 13821 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 13822 fis->h.command == SAT_WRITE_DMA_EXT || 13823 fis->h.command == SAT_WRITE_DMA_FUA_EXT 13824 ) 13825 { 13826 fis->d.sectorCount = 0xFF; 13827 fis->d.sectorCountExp = 0xFF; 13828 } 13829 else 13830 { 13831 /* SAT_WRITE_FPDMA_QUEUED */ 13832 fis->h.features = 0xFF; 13833 fis->d.featuresExp = 0xFF; 13834 } 13835 13836 /* Initialize CB for SATA completion. 13837 */ 13838 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB; 13839 } 13840 13841 13842 /* 13843 * Prepare SGL and send FIS to LL layer. 13844 */ 13845 satIOContext->reqType = agRequestType; /* Save it */ 13846 13847 status = sataLLIOStart( tiRoot, 13848 tiIORequest, 13849 tiDeviceHandle, 13850 tiScsiRequest, 13851 satIOContext); 13852 return (status); 13853 13854 } 13855 13856 13857 13858 13859 13860 13861 #ifdef REMOVED 13862 GLOBAL bit32 satWriteAndVerify10( 13863 tiRoot_t *tiRoot, 13864 tiIORequest_t *tiIORequest, 13865 tiDeviceHandle_t *tiDeviceHandle, 13866 tiScsiInitiatorRequest_t *tiScsiRequest, 13867 satIOContext_t *satIOContext) 13868 { 13869 /* 13870 combination of write10 and verify10 13871 */ 13872 13873 bit32 status; 13874 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 13875 satDeviceData_t *pSatDevData; 13876 scsiRspSense_t *pSense; 13877 tiIniScsiCmnd_t *scsiCmnd; 13878 agsaFisRegHostToDevice_t *fis; 13879 bit32 lba = 0; 13880 bit32 tl = 0; 13881 13882 pSense = satIOContext->pSense; 13883 pSatDevData = satIOContext->pSatDevData; 13884 scsiCmnd = &tiScsiRequest->scsiCmnd; 13885 fis = satIOContext->pFis; 13886 13887 TI_DBG5(("satWriteAndVerify10: start\n")); 13888 13889 13890 /* checking BYTCHK bit */ 13891 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK) 13892 { 13893 satSetSensePayload( pSense, 13894 SCSI_SNSKEY_ILLEGAL_REQUEST, 13895 0, 13896 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13897 satIOContext); 13898 13899 ostiInitiatorIOCompleted( tiRoot, 13900 tiIORequest, 13901 tiIOSuccess, 13902 SCSI_STAT_CHECK_CONDITION, 13903 satIOContext->pTiSenseData, 13904 satIOContext->interruptContext ); 13905 13906 TI_DBG1(("satWriteAndVerify10: BYTCHK bit checking \n")); 13907 return tiSuccess; 13908 } 13909 13910 13911 /* checking CONTROL */ 13912 /* NACA == 1 or LINK == 1*/ 13913 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 13914 { 13915 satSetSensePayload( pSense, 13916 SCSI_SNSKEY_ILLEGAL_REQUEST, 13917 0, 13918 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13919 satIOContext); 13920 13921 ostiInitiatorIOCompleted( tiRoot, 13922 tiIORequest, 13923 tiIOSuccess, 13924 SCSI_STAT_CHECK_CONDITION, 13925 satIOContext->pTiSenseData, 13926 satIOContext->interruptContext ); 13927 13928 TI_DBG2(("satWriteAndVerify10: return control\n")); 13929 return tiSuccess; 13930 } 13931 13932 /* let's do write10 */ 13933 if ( pSatDevData->sat48BitSupport != agTRUE ) 13934 { 13935 /* 13936 writeandverify10 but no support for 48 bit addressing -> problem in transfer 13937 length(sector count) 13938 */ 13939 satSetSensePayload( pSense, 13940 SCSI_SNSKEY_ILLEGAL_REQUEST, 13941 0, 13942 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13943 satIOContext); 13944 13945 ostiInitiatorIOCompleted( tiRoot, 13946 tiIORequest, 13947 tiIOSuccess, 13948 SCSI_STAT_CHECK_CONDITION, 13949 satIOContext->pTiSenseData, 13950 satIOContext->interruptContext ); 13951 13952 TI_DBG1(("satWriteAndVerify10: return internal checking\n")); 13953 return tiSuccess; 13954 } 13955 13956 /* cbd10; computing LBA and transfer length */ 13957 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 13958 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 13959 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 13960 13961 13962 /* Table 34, 9.1, p 46 */ 13963 /* 13964 note: As of 2/10/2006, no support for DMA QUEUED 13965 */ 13966 13967 /* 13968 Table 34, 9.1, p 46, b 13969 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 13970 return check condition 13971 */ 13972 if (pSatDevData->satNCQ != agTRUE && 13973 pSatDevData->sat48BitSupport != agTRUE 13974 ) 13975 { 13976 if (lba > SAT_TR_LBA_LIMIT - 1) 13977 { 13978 satSetSensePayload( pSense, 13979 SCSI_SNSKEY_ILLEGAL_REQUEST, 13980 0, 13981 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 13982 satIOContext); 13983 13984 ostiInitiatorIOCompleted( tiRoot, 13985 tiIORequest, 13986 tiIOSuccess, 13987 SCSI_STAT_CHECK_CONDITION, 13988 satIOContext->pTiSenseData, 13989 satIOContext->interruptContext ); 13990 13991 TI_DBG1(("satWriteAndVerify10: return LBA out of range\n")); 13992 return tiSuccess; 13993 } 13994 } 13995 13996 13997 /* case 1 and 2 */ 13998 if (lba + tl <= SAT_TR_LBA_LIMIT) 13999 { 14000 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 14001 { 14002 /* case 2 */ 14003 /* WRITE DMA*/ 14004 /* can't fit the transfer length */ 14005 TI_DBG5(("satWriteAndVerify10: case 2 !!!\n")); 14006 fis->h.fisType = 0x27; /* Reg host to device */ 14007 fis->h.c_pmPort = 0x80; /* C bit is set */ 14008 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 14009 fis->h.features = 0; /* FIS reserve */ 14010 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14011 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14012 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14013 14014 /* FIS LBA mode set LBA (27:24) */ 14015 fis->d.device = (0x4 << 4) | (scsiCmnd->cdb[2] & 0xF); 14016 14017 fis->d.lbaLowExp = 0; 14018 fis->d.lbaMidExp = 0; 14019 fis->d.lbaHighExp = 0; 14020 fis->d.featuresExp = 0; 14021 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 14022 fis->d.sectorCountExp = 0; 14023 fis->d.reserved4 = 0; 14024 fis->d.control = 0; /* FIS HOB bit clear */ 14025 fis->d.reserved5 = 0; 14026 14027 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14028 satIOContext->ATACmd = SAT_WRITE_DMA; 14029 } 14030 else 14031 { 14032 /* case 1 */ 14033 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 14034 /* WRITE SECTORS for easier implemetation */ 14035 /* can't fit the transfer length */ 14036 TI_DBG5(("satWriteAndVerify10: case 1 !!!\n")); 14037 fis->h.fisType = 0x27; /* Reg host to device */ 14038 fis->h.c_pmPort = 0x80; /* C bit is set */ 14039 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 14040 fis->h.features = 0; /* FIS reserve */ 14041 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14042 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14043 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14044 14045 /* FIS LBA mode set LBA (27:24) */ 14046 fis->d.device = (0x4 << 4) | (scsiCmnd->cdb[2] & 0xF); 14047 14048 fis->d.lbaLowExp = 0; 14049 fis->d.lbaMidExp = 0; 14050 fis->d.lbaHighExp = 0; 14051 fis->d.featuresExp = 0; 14052 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 14053 fis->d.sectorCountExp = 0; 14054 fis->d.reserved4 = 0; 14055 fis->d.control = 0; /* FIS HOB bit clear */ 14056 fis->d.reserved5 = 0; 14057 14058 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 14059 satIOContext->ATACmd = SAT_WRITE_SECTORS; 14060 14061 } 14062 } 14063 14064 /* case 3 and 4 */ 14065 if (pSatDevData->sat48BitSupport == agTRUE) 14066 { 14067 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 14068 { 14069 /* case 3 */ 14070 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 14071 TI_DBG5(("satWriteAndVerify10: case 3\n")); 14072 fis->h.fisType = 0x27; /* Reg host to device */ 14073 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14074 14075 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 14076 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 14077 14078 fis->h.features = 0; /* FIS reserve */ 14079 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14080 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14081 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14082 fis->d.device = 0x40; /* FIS LBA mode set */ 14083 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 14084 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14085 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14086 fis->d.featuresExp = 0; /* FIS reserve */ 14087 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 14088 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 14089 fis->d.reserved4 = 0; 14090 fis->d.control = 0; /* FIS HOB bit clear */ 14091 fis->d.reserved5 = 0; 14092 14093 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14094 } 14095 else 14096 { 14097 /* case 4 */ 14098 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 14099 /* WRITE SECTORS EXT for easier implemetation */ 14100 TI_DBG5(("satWriteAndVerify10: case 4\n")); 14101 fis->h.fisType = 0x27; /* Reg host to device */ 14102 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14103 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 14104 14105 fis->h.features = 0; /* FIS reserve */ 14106 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14107 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14108 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14109 fis->d.device = 0x40; /* FIS LBA mode set */ 14110 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 14111 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14112 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14113 fis->d.featuresExp = 0; /* FIS reserve */ 14114 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 14115 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 14116 fis->d.reserved4 = 0; 14117 fis->d.control = 0; /* FIS HOB bit clear */ 14118 fis->d.reserved5 = 0; 14119 14120 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 14121 } 14122 } 14123 /* case 5 */ 14124 if (pSatDevData->satNCQ == agTRUE) 14125 { 14126 /* WRITE FPDMA QUEUED */ 14127 if (pSatDevData->sat48BitSupport != agTRUE) 14128 { 14129 TI_DBG5(("satWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support \n")); 14130 satSetSensePayload( pSense, 14131 SCSI_SNSKEY_ILLEGAL_REQUEST, 14132 0, 14133 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 14134 satIOContext); 14135 14136 ostiInitiatorIOCompleted( tiRoot, 14137 tiIORequest, 14138 tiIOSuccess, 14139 SCSI_STAT_CHECK_CONDITION, 14140 satIOContext->pTiSenseData, 14141 satIOContext->interruptContext ); 14142 return tiSuccess; 14143 } 14144 TI_DBG5(("satWriteAndVerify10: case 5\n")); 14145 14146 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 14147 14148 fis->h.fisType = 0x27; /* Reg host to device */ 14149 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14150 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 14151 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 14152 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14153 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14154 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14155 14156 /* Check FUA bit */ 14157 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK) 14158 fis->d.device = 0xC0; /* FIS FUA set */ 14159 else 14160 fis->d.device = 0x40; /* FIS FUA clear */ 14161 14162 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 14163 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14164 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14165 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 14166 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 14167 fis->d.sectorCountExp = 0; 14168 fis->d.reserved4 = 0; 14169 fis->d.control = 0; /* FIS HOB bit clear */ 14170 fis->d.reserved5 = 0; 14171 14172 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 14173 } 14174 14175 /* Initialize CB for SATA completion. 14176 */ 14177 satIOContext->satCompleteCB = &satWriteAndVerify10CB; 14178 14179 /* 14180 * Prepare SGL and send FIS to LL layer. 14181 */ 14182 satIOContext->reqType = agRequestType; /* Save it */ 14183 14184 status = sataLLIOStart( tiRoot, 14185 tiIORequest, 14186 tiDeviceHandle, 14187 tiScsiRequest, 14188 satIOContext); 14189 return (status); 14190 14191 } 14192 #endif /* REMOVED */ 14193 14194 #ifdef REMOVED 14195 /*****************************************************************************/ 14196 /*! \brief SAT implementation for SCSI satWriteAndVerify10_1. 14197 * 14198 * SAT implementation for SCSI satWriteAndVerify10_1. 14199 * Sub function of satWriteAndVerify10 14200 * 14201 * \param tiRoot: Pointer to TISA initiator driver/port instance. 14202 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 14203 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 14204 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 14205 * \param satIOContext_t: Pointer to the SAT IO Context 14206 * 14207 * \return If command is started successfully 14208 * - \e tiSuccess: I/O request successfully initiated. 14209 * - \e tiBusy: No resources available, try again later. 14210 * - \e tiIONoDevice: Invalid device handle. 14211 * - \e tiError: Other errors. 14212 */ 14213 /*****************************************************************************/ 14214 GLOBAL bit32 satWriteAndVerify10_1( 14215 tiRoot_t *tiRoot, 14216 tiIORequest_t *tiIORequest, 14217 tiDeviceHandle_t *tiDeviceHandle, 14218 tiScsiInitiatorRequest_t *tiScsiRequest, 14219 satIOContext_t *satIOContext) 14220 { 14221 bit32 status; 14222 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14223 satDeviceData_t *pSatDevData; 14224 scsiRspSense_t *pSense; 14225 tiIniScsiCmnd_t *scsiCmnd; 14226 agsaFisRegHostToDevice_t *fis; 14227 14228 pSense = satIOContext->pSense; 14229 pSatDevData = satIOContext->pSatDevData; 14230 scsiCmnd = &tiScsiRequest->scsiCmnd; 14231 fis = satIOContext->pFis; 14232 14233 TI_DBG5(("satWriteAndVerify10_1: start\n")); 14234 14235 if (pSatDevData->sat48BitSupport == agTRUE) 14236 { 14237 fis->h.fisType = 0x27; /* Reg host to device */ 14238 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14239 14240 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 14241 fis->h.features = 0; /* FIS reserve */ 14242 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14243 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14244 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14245 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 14246 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 14247 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14248 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14249 fis->d.featuresExp = 0; /* FIS reserve */ 14250 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 14251 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 14252 14253 fis->d.reserved4 = 0; 14254 fis->d.control = 0; /* FIS HOB bit clear */ 14255 fis->d.reserved5 = 0; 14256 14257 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14258 14259 /* Initialize CB for SATA completion. 14260 */ 14261 satIOContext->satCompleteCB = &satWriteAndVerify10CB; 14262 14263 /* 14264 * Prepare SGL and send FIS to LL layer. 14265 */ 14266 satIOContext->reqType = agRequestType; /* Save it */ 14267 14268 status = sataLLIOStart( tiRoot, 14269 tiIORequest, 14270 tiDeviceHandle, 14271 tiScsiRequest, 14272 satIOContext); 14273 14274 14275 TI_DBG1(("satWriteAndVerify10_1: return status %d\n", status)); 14276 return (status); 14277 } 14278 else 14279 { 14280 /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */ 14281 TI_DBG1(("satWriteAndVerify10_1: can't fit in SAT_READ_VERIFY_SECTORS\n")); 14282 return tiError; 14283 } 14284 14285 14286 return tiSuccess; 14287 } 14288 #endif /* REMOVED */ 14289 14290 /*****************************************************************************/ 14291 /*! \brief SAT implementation for SCSI satWriteAndVerify12. 14292 * 14293 * SAT implementation for SCSI satWriteAndVerify12. 14294 * 14295 * \param tiRoot: Pointer to TISA initiator driver/port instance. 14296 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 14297 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 14298 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 14299 * \param satIOContext_t: Pointer to the SAT IO Context 14300 * 14301 * \return If command is started successfully 14302 * - \e tiSuccess: I/O request successfully initiated. 14303 * - \e tiBusy: No resources available, try again later. 14304 * - \e tiIONoDevice: Invalid device handle. 14305 * - \e tiError: Other errors. 14306 */ 14307 /*****************************************************************************/ 14308 GLOBAL bit32 satWriteAndVerify12( 14309 tiRoot_t *tiRoot, 14310 tiIORequest_t *tiIORequest, 14311 tiDeviceHandle_t *tiDeviceHandle, 14312 tiScsiInitiatorRequest_t *tiScsiRequest, 14313 satIOContext_t *satIOContext) 14314 { 14315 /* 14316 combination of write12 and verify12 14317 temp: since write12 is not support (due to internal checking), no support 14318 */ 14319 bit32 status; 14320 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14321 satDeviceData_t *pSatDevData; 14322 scsiRspSense_t *pSense; 14323 tiIniScsiCmnd_t *scsiCmnd; 14324 agsaFisRegHostToDevice_t *fis; 14325 bit32 lba = 0; 14326 bit32 tl = 0; 14327 bit32 LoopNum = 1; 14328 bit8 LBA[4]; 14329 bit8 TL[4]; 14330 bit32 rangeChk = agFALSE; /* lba and tl range check */ 14331 14332 pSense = satIOContext->pSense; 14333 pSatDevData = satIOContext->pSatDevData; 14334 scsiCmnd = &tiScsiRequest->scsiCmnd; 14335 fis = satIOContext->pFis; 14336 14337 TI_DBG5(("satWriteAndVerify12: start\n")); 14338 14339 /* checking BYTCHK bit */ 14340 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK) 14341 { 14342 satSetSensePayload( pSense, 14343 SCSI_SNSKEY_ILLEGAL_REQUEST, 14344 0, 14345 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 14346 satIOContext); 14347 14348 ostiInitiatorIOCompleted( tiRoot, 14349 tiIORequest, 14350 tiIOSuccess, 14351 SCSI_STAT_CHECK_CONDITION, 14352 satIOContext->pTiSenseData, 14353 satIOContext->interruptContext ); 14354 14355 TI_DBG1(("satWriteAndVerify12: BYTCHK bit checking \n")); 14356 return tiSuccess; 14357 } 14358 14359 /* checking CONTROL */ 14360 /* NACA == 1 or LINK == 1*/ 14361 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) ) 14362 { 14363 satSetSensePayload( pSense, 14364 SCSI_SNSKEY_ILLEGAL_REQUEST, 14365 0, 14366 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 14367 satIOContext); 14368 14369 ostiInitiatorIOCompleted( tiRoot, 14370 tiIORequest, 14371 tiIOSuccess, 14372 SCSI_STAT_CHECK_CONDITION, 14373 satIOContext->pTiSenseData, 14374 satIOContext->interruptContext ); 14375 14376 TI_DBG2(("satWriteAndVerify12: return control\n")); 14377 return tiSuccess; 14378 } 14379 14380 osti_memset(LBA, 0, sizeof(LBA)); 14381 osti_memset(TL, 0, sizeof(TL)); 14382 14383 /* do not use memcpy due to indexing in LBA and TL */ 14384 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 14385 LBA[1] = scsiCmnd->cdb[3]; 14386 LBA[2] = scsiCmnd->cdb[4]; 14387 LBA[3] = scsiCmnd->cdb[5]; /* LSB */ 14388 14389 TL[0] = scsiCmnd->cdb[6]; /* MSB */ 14390 TL[1] = scsiCmnd->cdb[7]; 14391 TL[2] = scsiCmnd->cdb[7]; 14392 TL[3] = scsiCmnd->cdb[8]; /* LSB */ 14393 14394 rangeChk = satAddNComparebit32(LBA, TL); 14395 14396 lba = satComputeCDB12LBA(satIOContext); 14397 tl = satComputeCDB12TL(satIOContext); 14398 14399 14400 /* Table 34, 9.1, p 46 */ 14401 /* 14402 note: As of 2/10/2006, no support for DMA QUEUED 14403 */ 14404 14405 /* 14406 Table 34, 9.1, p 46, b 14407 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 14408 return check condition 14409 */ 14410 if (pSatDevData->satNCQ != agTRUE && 14411 pSatDevData->sat48BitSupport != agTRUE 14412 ) 14413 { 14414 if (lba > SAT_TR_LBA_LIMIT - 1) 14415 { 14416 satSetSensePayload( pSense, 14417 SCSI_SNSKEY_ILLEGAL_REQUEST, 14418 0, 14419 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 14420 satIOContext); 14421 14422 ostiInitiatorIOCompleted( tiRoot, 14423 tiIORequest, 14424 tiIOSuccess, 14425 SCSI_STAT_CHECK_CONDITION, 14426 satIOContext->pTiSenseData, 14427 satIOContext->interruptContext ); 14428 14429 TI_DBG1(("satWriteAndVerify12: return LBA out of range, not EXT\n")); 14430 return tiSuccess; 14431 } 14432 14433 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 14434 { 14435 TI_DBG1(("satWriteAndVerify12: return LBA+TL out of range, not EXT\n")); 14436 satSetSensePayload( pSense, 14437 SCSI_SNSKEY_ILLEGAL_REQUEST, 14438 0, 14439 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 14440 satIOContext); 14441 14442 ostiInitiatorIOCompleted( tiRoot, 14443 tiIORequest, 14444 tiIOSuccess, 14445 SCSI_STAT_CHECK_CONDITION, 14446 satIOContext->pTiSenseData, 14447 satIOContext->interruptContext ); 14448 14449 return tiSuccess; 14450 } 14451 } 14452 14453 /* case 1 and 2 */ 14454 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT) 14455 { 14456 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 14457 { 14458 /* case 2 */ 14459 /* WRITE DMA*/ 14460 /* In case that we can't fit the transfer length, we loop */ 14461 TI_DBG5(("satWriteAndVerify12: case 2\n")); 14462 fis->h.fisType = 0x27; /* Reg host to device */ 14463 fis->h.c_pmPort = 0x80; /* C bit is set */ 14464 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 14465 fis->h.features = 0; /* FIS reserve */ 14466 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14467 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14468 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14469 14470 /* FIS LBA mode set LBA (27:24) */ 14471 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 14472 14473 fis->d.lbaLowExp = 0; 14474 fis->d.lbaMidExp = 0; 14475 fis->d.lbaHighExp = 0; 14476 fis->d.featuresExp = 0; 14477 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 14478 fis->d.sectorCountExp = 0; 14479 fis->d.reserved4 = 0; 14480 fis->d.control = 0; /* FIS HOB bit clear */ 14481 fis->d.reserved5 = 0; 14482 14483 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14484 satIOContext->ATACmd = SAT_WRITE_DMA; 14485 } 14486 else 14487 { 14488 /* case 1 */ 14489 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 14490 /* WRITE SECTORS for easier implemetation */ 14491 /* In case that we can't fit the transfer length, we loop */ 14492 TI_DBG5(("satWriteAndVerify12: case 1\n")); 14493 fis->h.fisType = 0x27; /* Reg host to device */ 14494 fis->h.c_pmPort = 0x80; /* C bit is set */ 14495 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 14496 fis->h.features = 0; /* FIS reserve */ 14497 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14498 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14499 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14500 14501 /* FIS LBA mode set LBA (27:24) */ 14502 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 14503 14504 fis->d.lbaLowExp = 0; 14505 fis->d.lbaMidExp = 0; 14506 fis->d.lbaHighExp = 0; 14507 fis->d.featuresExp = 0; 14508 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 14509 fis->d.sectorCountExp = 0; 14510 fis->d.reserved4 = 0; 14511 fis->d.control = 0; /* FIS HOB bit clear */ 14512 fis->d.reserved5 = 0; 14513 14514 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 14515 satIOContext->ATACmd = SAT_WRITE_SECTORS; 14516 } 14517 } 14518 14519 /* case 3 and 4 */ 14520 if (pSatDevData->sat48BitSupport == agTRUE) 14521 { 14522 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 14523 { 14524 /* case 3 */ 14525 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 14526 TI_DBG5(("satWriteAndVerify12: case 3\n")); 14527 fis->h.fisType = 0x27; /* Reg host to device */ 14528 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14529 14530 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 14531 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 14532 14533 fis->h.features = 0; /* FIS reserve */ 14534 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14535 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14536 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14537 fis->d.device = 0x40; /* FIS LBA mode set */ 14538 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 14539 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14540 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14541 fis->d.featuresExp = 0; /* FIS reserve */ 14542 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 14543 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 14544 fis->d.reserved4 = 0; 14545 fis->d.control = 0; /* FIS HOB bit clear */ 14546 fis->d.reserved5 = 0; 14547 14548 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14549 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 14550 } 14551 else 14552 { 14553 /* case 4 */ 14554 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 14555 /* WRITE SECTORS EXT for easier implemetation */ 14556 TI_DBG5(("satWriteAndVerify12: case 4\n")); 14557 fis->h.fisType = 0x27; /* Reg host to device */ 14558 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14559 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 14560 14561 fis->h.features = 0; /* FIS reserve */ 14562 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14563 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14564 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14565 fis->d.device = 0x40; /* FIS LBA mode set */ 14566 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 14567 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14568 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14569 fis->d.featuresExp = 0; /* FIS reserve */ 14570 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 14571 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 14572 fis->d.reserved4 = 0; 14573 fis->d.control = 0; /* FIS HOB bit clear */ 14574 fis->d.reserved5 = 0; 14575 14576 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 14577 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 14578 } 14579 } 14580 14581 /* case 5 */ 14582 if (pSatDevData->satNCQ == agTRUE) 14583 { 14584 /* WRITE FPDMA QUEUED */ 14585 if (pSatDevData->sat48BitSupport != agTRUE) 14586 { 14587 TI_DBG5(("satWriteAndVerify12: case 5 !!! error NCQ but 28 bit address support \n")); 14588 satSetSensePayload( pSense, 14589 SCSI_SNSKEY_ILLEGAL_REQUEST, 14590 0, 14591 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 14592 satIOContext); 14593 14594 ostiInitiatorIOCompleted( tiRoot, 14595 tiIORequest, 14596 tiIOSuccess, 14597 SCSI_STAT_CHECK_CONDITION, 14598 satIOContext->pTiSenseData, 14599 satIOContext->interruptContext ); 14600 return tiSuccess; 14601 } 14602 TI_DBG6(("satWriteAndVerify12: case 5\n")); 14603 14604 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 14605 14606 fis->h.fisType = 0x27; /* Reg host to device */ 14607 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14608 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 14609 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 14610 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14611 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14612 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14613 14614 /* Check FUA bit */ 14615 if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK) 14616 fis->d.device = 0xC0; /* FIS FUA set */ 14617 else 14618 fis->d.device = 0x40; /* FIS FUA clear */ 14619 14620 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 14621 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14622 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14623 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 14624 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 14625 fis->d.sectorCountExp = 0; 14626 fis->d.reserved4 = 0; 14627 fis->d.control = 0; /* FIS HOB bit clear */ 14628 fis->d.reserved5 = 0; 14629 14630 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 14631 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 14632 } 14633 14634 satIOContext->currentLBA = lba; 14635 // satIOContext->OrgLBA = lba; 14636 satIOContext->OrgTL = tl; 14637 14638 /* 14639 computing number of loop and remainder for tl 14640 0xFF in case not ext 14641 0xFFFF in case EXT 14642 */ 14643 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 14644 { 14645 LoopNum = satComputeLoopNum(tl, 0xFF); 14646 } 14647 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 14648 fis->h.command == SAT_WRITE_DMA_EXT || 14649 fis->h.command == SAT_WRITE_DMA_FUA_EXT 14650 ) 14651 { 14652 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 14653 LoopNum = satComputeLoopNum(tl, 0xFFFF); 14654 } 14655 else 14656 { 14657 /* SAT_WRITE_FPDMA_QUEUEDK */ 14658 LoopNum = satComputeLoopNum(tl, 0xFFFF); 14659 } 14660 14661 satIOContext->LoopNum = LoopNum; 14662 satIOContext->LoopNum2 = LoopNum; 14663 14664 14665 if (LoopNum == 1) 14666 { 14667 TI_DBG5(("satWriteAndVerify12: NON CHAINED data\n")); 14668 /* Initialize CB for SATA completion. 14669 */ 14670 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB; 14671 } 14672 else 14673 { 14674 TI_DBG1(("satWriteAndVerify12: CHAINED data\n")); 14675 /* re-setting tl */ 14676 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 14677 { 14678 fis->d.sectorCount = 0xFF; 14679 } 14680 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 14681 fis->h.command == SAT_WRITE_DMA_EXT || 14682 fis->h.command == SAT_WRITE_DMA_FUA_EXT 14683 ) 14684 { 14685 fis->d.sectorCount = 0xFF; 14686 fis->d.sectorCountExp = 0xFF; 14687 } 14688 else 14689 { 14690 /* SAT_WRITE_FPDMA_QUEUED */ 14691 fis->h.features = 0xFF; 14692 fis->d.featuresExp = 0xFF; 14693 } 14694 14695 /* Initialize CB for SATA completion. 14696 */ 14697 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB; 14698 } 14699 14700 14701 /* 14702 * Prepare SGL and send FIS to LL layer. 14703 */ 14704 satIOContext->reqType = agRequestType; /* Save it */ 14705 14706 status = sataLLIOStart( tiRoot, 14707 tiIORequest, 14708 tiDeviceHandle, 14709 tiScsiRequest, 14710 satIOContext); 14711 return (status); 14712 } 14713 14714 GLOBAL bit32 satNonChainedWriteNVerify_Verify( 14715 tiRoot_t *tiRoot, 14716 tiIORequest_t *tiIORequest, 14717 tiDeviceHandle_t *tiDeviceHandle, 14718 tiScsiInitiatorRequest_t *tiScsiRequest, 14719 satIOContext_t *satIOContext) 14720 { 14721 bit32 status; 14722 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14723 satDeviceData_t *pSatDevData; 14724 tiIniScsiCmnd_t *scsiCmnd; 14725 agsaFisRegHostToDevice_t *fis; 14726 14727 pSatDevData = satIOContext->pSatDevData; 14728 scsiCmnd = &tiScsiRequest->scsiCmnd; 14729 fis = satIOContext->pFis; 14730 14731 TI_DBG5(("satNonChainedWriteNVerify_Verify: start\n")); 14732 14733 if (pSatDevData->sat48BitSupport == agTRUE) 14734 { 14735 fis->h.fisType = 0x27; /* Reg host to device */ 14736 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14737 14738 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 14739 fis->h.features = 0; /* FIS reserve */ 14740 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14741 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14742 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14743 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 14744 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 14745 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14746 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14747 fis->d.featuresExp = 0; /* FIS reserve */ 14748 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 14749 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 14750 14751 fis->d.reserved4 = 0; 14752 fis->d.control = 0; /* FIS HOB bit clear */ 14753 fis->d.reserved5 = 0; 14754 14755 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14756 14757 /* Initialize CB for SATA completion. 14758 */ 14759 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB; 14760 14761 /* 14762 * Prepare SGL and send FIS to LL layer. 14763 */ 14764 satIOContext->reqType = agRequestType; /* Save it */ 14765 14766 status = sataLLIOStart( tiRoot, 14767 tiIORequest, 14768 tiDeviceHandle, 14769 tiScsiRequest, 14770 satIOContext); 14771 14772 14773 TI_DBG1(("satNonChainedWriteNVerify_Verify: return status %d\n", status)); 14774 return (status); 14775 } 14776 else 14777 { 14778 /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */ 14779 TI_DBG1(("satNonChainedWriteNVerify_Verify: can't fit in SAT_READ_VERIFY_SECTORS\n")); 14780 return tiError; 14781 } 14782 14783 } 14784 14785 GLOBAL bit32 satChainedWriteNVerify_Write( 14786 tiRoot_t *tiRoot, 14787 tiIORequest_t *tiIORequest, 14788 tiDeviceHandle_t *tiDeviceHandle, 14789 tiScsiInitiatorRequest_t *tiScsiRequest, 14790 satIOContext_t *satIOContext) 14791 { 14792 /* 14793 Assumption: error check on lba and tl has been done in satWrite*() 14794 lba = lba + tl; 14795 */ 14796 bit32 status; 14797 satIOContext_t *satOrgIOContext = agNULL; 14798 tiIniScsiCmnd_t *scsiCmnd; 14799 agsaFisRegHostToDevice_t *fis; 14800 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14801 bit32 lba = 0; 14802 bit32 DenomTL = 0xFF; 14803 bit32 Remainder = 0; 14804 bit8 LBA[4]; /* 0 MSB, 3 LSB */ 14805 14806 TI_DBG1(("satChainedWriteNVerify_Write: start\n")); 14807 14808 fis = satIOContext->pFis; 14809 satOrgIOContext = satIOContext->satOrgIOContext; 14810 scsiCmnd = satOrgIOContext->pScsiCmnd; 14811 14812 osti_memset(LBA,0, sizeof(LBA)); 14813 14814 switch (satOrgIOContext->ATACmd) 14815 { 14816 case SAT_WRITE_DMA: 14817 DenomTL = 0xFF; 14818 break; 14819 case SAT_WRITE_SECTORS: 14820 DenomTL = 0xFF; 14821 break; 14822 case SAT_WRITE_DMA_EXT: 14823 DenomTL = 0xFFFF; 14824 break; 14825 case SAT_WRITE_DMA_FUA_EXT: 14826 DenomTL = 0xFFFF; 14827 break; 14828 case SAT_WRITE_SECTORS_EXT: 14829 DenomTL = 0xFFFF; 14830 break; 14831 case SAT_WRITE_FPDMA_QUEUED: 14832 DenomTL = 0xFFFF; 14833 break; 14834 default: 14835 TI_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x\n", satIOContext->ATACmd)); 14836 return tiError; 14837 break; 14838 } 14839 14840 Remainder = satOrgIOContext->OrgTL % DenomTL; 14841 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL; 14842 lba = satOrgIOContext->currentLBA; 14843 14844 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */ 14845 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2)); 14846 LBA[2] = (bit8)((lba & 0xF0) >> 8); 14847 LBA[3] = (bit8)(lba & 0xF); /* LSB */ 14848 14849 switch (satOrgIOContext->ATACmd) 14850 { 14851 case SAT_WRITE_DMA: 14852 fis->h.fisType = 0x27; /* Reg host to device */ 14853 fis->h.c_pmPort = 0x80; /* C bit is set */ 14854 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 14855 fis->h.features = 0; /* FIS reserve */ 14856 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 14857 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 14858 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 14859 14860 /* FIS LBA mode set LBA (27:24) */ 14861 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 14862 14863 fis->d.lbaLowExp = 0; 14864 fis->d.lbaMidExp = 0; 14865 fis->d.lbaHighExp = 0; 14866 fis->d.featuresExp = 0; 14867 if (satOrgIOContext->LoopNum == 1) 14868 { 14869 /* last loop */ 14870 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 14871 } 14872 else 14873 { 14874 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 14875 } 14876 fis->d.sectorCountExp = 0; 14877 fis->d.reserved4 = 0; 14878 fis->d.control = 0; /* FIS HOB bit clear */ 14879 fis->d.reserved5 = 0; 14880 14881 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14882 14883 break; 14884 case SAT_WRITE_SECTORS: 14885 fis->h.fisType = 0x27; /* Reg host to device */ 14886 fis->h.c_pmPort = 0x80; /* C bit is set */ 14887 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 14888 fis->h.features = 0; /* FIS reserve */ 14889 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 14890 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 14891 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 14892 14893 /* FIS LBA mode set LBA (27:24) */ 14894 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 14895 14896 fis->d.lbaLowExp = 0; 14897 fis->d.lbaMidExp = 0; 14898 fis->d.lbaHighExp = 0; 14899 fis->d.featuresExp = 0; 14900 if (satOrgIOContext->LoopNum == 1) 14901 { 14902 /* last loop */ 14903 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 14904 } 14905 else 14906 { 14907 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 14908 } 14909 fis->d.sectorCountExp = 0; 14910 fis->d.reserved4 = 0; 14911 fis->d.control = 0; /* FIS HOB bit clear */ 14912 fis->d.reserved5 = 0; 14913 14914 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 14915 14916 break; 14917 case SAT_WRITE_DMA_EXT: 14918 fis->h.fisType = 0x27; /* Reg host to device */ 14919 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14920 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x3D */ 14921 fis->h.features = 0; /* FIS reserve */ 14922 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 14923 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 14924 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 14925 fis->d.device = 0x40; /* FIS LBA mode set */ 14926 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 14927 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14928 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14929 fis->d.featuresExp = 0; /* FIS reserve */ 14930 if (satOrgIOContext->LoopNum == 1) 14931 { 14932 /* last loop */ 14933 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 14934 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 14935 } 14936 else 14937 { 14938 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 14939 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 14940 } 14941 fis->d.reserved4 = 0; 14942 fis->d.control = 0; /* FIS HOB bit clear */ 14943 fis->d.reserved5 = 0; 14944 14945 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14946 14947 break; 14948 case SAT_WRITE_SECTORS_EXT: 14949 fis->h.fisType = 0x27; /* Reg host to device */ 14950 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14951 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 14952 14953 fis->h.features = 0; /* FIS reserve */ 14954 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 14955 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 14956 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 14957 fis->d.device = 0x40; /* FIS LBA mode set */ 14958 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 14959 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14960 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14961 fis->d.featuresExp = 0; /* FIS reserve */ 14962 if (satOrgIOContext->LoopNum == 1) 14963 { 14964 /* last loop */ 14965 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 14966 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 14967 } 14968 else 14969 { 14970 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 14971 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 14972 } 14973 fis->d.reserved4 = 0; 14974 fis->d.control = 0; /* FIS HOB bit clear */ 14975 fis->d.reserved5 = 0; 14976 14977 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 14978 14979 break; 14980 case SAT_WRITE_FPDMA_QUEUED: 14981 fis->h.fisType = 0x27; /* Reg host to device */ 14982 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14983 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 14984 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 14985 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 14986 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 14987 14988 /* Check FUA bit */ 14989 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK) 14990 fis->d.device = 0xC0; /* FIS FUA set */ 14991 else 14992 fis->d.device = 0x40; /* FIS FUA clear */ 14993 14994 fis->d.lbaLowExp = LBA[0];; /* FIS LBA (31:24) */ 14995 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14996 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14997 if (satOrgIOContext->LoopNum == 1) 14998 { 14999 /* last loop */ 15000 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 15001 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 15002 } 15003 else 15004 { 15005 fis->h.features = 0xFF; /* FIS sector count (7:0) */ 15006 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */ 15007 } 15008 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 15009 fis->d.sectorCountExp = 0; 15010 fis->d.reserved4 = 0; 15011 fis->d.control = 0; /* FIS HOB bit clear */ 15012 fis->d.reserved5 = 0; 15013 15014 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 15015 break; 15016 15017 default: 15018 TI_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x\n", satIOContext->ATACmd)); 15019 return tiError; 15020 break; 15021 } 15022 15023 /* Initialize CB for SATA completion. 15024 */ 15025 /* chained data */ 15026 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB; 15027 15028 15029 /* 15030 * Prepare SGL and send FIS to LL layer. 15031 */ 15032 satIOContext->reqType = agRequestType; /* Save it */ 15033 15034 status = sataLLIOStart( tiRoot, 15035 tiIORequest, 15036 tiDeviceHandle, 15037 tiScsiRequest, 15038 satIOContext); 15039 15040 TI_DBG5(("satChainedWriteNVerify_Write: return\n")); 15041 return (status); 15042 15043 } 15044 15045 /* 15046 similar to write12 and verify10; 15047 this will be similar to verify12 15048 */ 15049 GLOBAL bit32 satChainedWriteNVerify_Start_Verify( 15050 tiRoot_t *tiRoot, 15051 tiIORequest_t *tiIORequest, 15052 tiDeviceHandle_t *tiDeviceHandle, 15053 tiScsiInitiatorRequest_t *tiScsiRequest, 15054 satIOContext_t *satIOContext) 15055 { 15056 /* 15057 deal with transfer length; others have been handled previously at this point; 15058 no LBA check; no range check; 15059 */ 15060 bit32 status; 15061 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 15062 satDeviceData_t *pSatDevData; 15063 tiIniScsiCmnd_t *scsiCmnd; 15064 agsaFisRegHostToDevice_t *fis; 15065 bit32 lba = 0; 15066 bit32 tl = 0; 15067 bit32 LoopNum = 1; 15068 bit8 LBA[4]; 15069 bit8 TL[4]; 15070 15071 pSatDevData = satIOContext->pSatDevData; 15072 scsiCmnd = &tiScsiRequest->scsiCmnd; 15073 fis = satIOContext->pFis; 15074 15075 TI_DBG5(("satChainedWriteNVerify_Start_Verify: start\n")); 15076 15077 osti_memset(LBA, 0, sizeof(LBA)); 15078 osti_memset(TL, 0, sizeof(TL)); 15079 15080 /* do not use memcpy due to indexing in LBA and TL */ 15081 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 15082 LBA[1] = scsiCmnd->cdb[3]; 15083 LBA[2] = scsiCmnd->cdb[4]; 15084 LBA[3] = scsiCmnd->cdb[5]; /* LSB */ 15085 15086 TL[0] = scsiCmnd->cdb[6]; /* MSB */ 15087 TL[1] = scsiCmnd->cdb[7]; 15088 TL[2] = scsiCmnd->cdb[7]; 15089 TL[3] = scsiCmnd->cdb[8]; /* LSB */ 15090 15091 lba = satComputeCDB12LBA(satIOContext); 15092 tl = satComputeCDB12TL(satIOContext); 15093 15094 if (pSatDevData->sat48BitSupport == agTRUE) 15095 { 15096 TI_DBG5(("satChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS_EXT\n")); 15097 fis->h.fisType = 0x27; /* Reg host to device */ 15098 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15099 15100 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 15101 fis->h.features = 0; /* FIS reserve */ 15102 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15103 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15104 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15105 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 15106 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 15107 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 15108 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 15109 fis->d.featuresExp = 0; /* FIS reserve */ 15110 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 15111 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 15112 15113 fis->d.reserved4 = 0; 15114 fis->d.control = 0; /* FIS HOB bit clear */ 15115 fis->d.reserved5 = 0; 15116 15117 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 15118 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT; 15119 } 15120 else 15121 { 15122 TI_DBG5(("satChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS\n")); 15123 fis->h.fisType = 0x27; /* Reg host to device */ 15124 fis->h.c_pmPort = 0x80; /* C bit is set */ 15125 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 15126 fis->h.features = 0; /* FIS reserve */ 15127 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15128 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15129 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15130 /* FIS LBA mode set LBA (27:24) */ 15131 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 15132 fis->d.lbaLowExp = 0; 15133 fis->d.lbaMidExp = 0; 15134 fis->d.lbaHighExp = 0; 15135 fis->d.featuresExp = 0; 15136 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 15137 fis->d.sectorCountExp = 0; 15138 fis->d.reserved4 = 0; 15139 fis->d.control = 0; /* FIS HOB bit clear */ 15140 fis->d.reserved5 = 0; 15141 15142 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 15143 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS; 15144 15145 } 15146 15147 satIOContext->currentLBA = lba; 15148 satIOContext->OrgTL = tl; 15149 15150 /* 15151 computing number of loop and remainder for tl 15152 0xFF in case not ext 15153 0xFFFF in case EXT 15154 */ 15155 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 15156 { 15157 LoopNum = satComputeLoopNum(tl, 0xFF); 15158 } 15159 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 15160 { 15161 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 15162 LoopNum = satComputeLoopNum(tl, 0xFFFF); 15163 } 15164 else 15165 { 15166 TI_DBG1(("satChainedWriteNVerify_Start_Verify: error case 1!!!\n")); 15167 LoopNum = 1; 15168 } 15169 15170 satIOContext->LoopNum = LoopNum; 15171 15172 if (LoopNum == 1) 15173 { 15174 TI_DBG5(("satChainedWriteNVerify_Start_Verify: NON CHAINED data\n")); 15175 /* Initialize CB for SATA completion. 15176 */ 15177 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB; 15178 } 15179 else 15180 { 15181 TI_DBG1(("satChainedWriteNVerify_Start_Verify: CHAINED data\n")); 15182 /* re-setting tl */ 15183 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 15184 { 15185 fis->d.sectorCount = 0xFF; 15186 } 15187 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 15188 { 15189 fis->d.sectorCount = 0xFF; 15190 fis->d.sectorCountExp = 0xFF; 15191 } 15192 else 15193 { 15194 TI_DBG1(("satChainedWriteNVerify_Start_Verify: error case 2!!!\n")); 15195 } 15196 15197 /* Initialize CB for SATA completion. 15198 */ 15199 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB; 15200 } 15201 15202 15203 /* 15204 * Prepare SGL and send FIS to LL layer. 15205 */ 15206 satIOContext->reqType = agRequestType; /* Save it */ 15207 15208 status = sataLLIOStart( tiRoot, 15209 tiIORequest, 15210 tiDeviceHandle, 15211 tiScsiRequest, 15212 satIOContext); 15213 return (status); 15214 } 15215 15216 GLOBAL bit32 satChainedWriteNVerify_Verify( 15217 tiRoot_t *tiRoot, 15218 tiIORequest_t *tiIORequest, 15219 tiDeviceHandle_t *tiDeviceHandle, 15220 tiScsiInitiatorRequest_t *tiScsiRequest, 15221 satIOContext_t *satIOContext) 15222 { 15223 bit32 status; 15224 satIOContext_t *satOrgIOContext = agNULL; 15225 agsaFisRegHostToDevice_t *fis; 15226 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 15227 bit32 lba = 0; 15228 bit32 DenomTL = 0xFF; 15229 bit32 Remainder = 0; 15230 bit8 LBA[4]; /* 0 MSB, 3 LSB */ 15231 15232 TI_DBG2(("satChainedWriteNVerify_Verify: start\n")); 15233 15234 fis = satIOContext->pFis; 15235 satOrgIOContext = satIOContext->satOrgIOContext; 15236 15237 osti_memset(LBA,0, sizeof(LBA)); 15238 15239 switch (satOrgIOContext->ATACmd) 15240 { 15241 case SAT_READ_VERIFY_SECTORS: 15242 DenomTL = 0xFF; 15243 break; 15244 case SAT_READ_VERIFY_SECTORS_EXT: 15245 DenomTL = 0xFFFF; 15246 break; 15247 default: 15248 TI_DBG1(("satChainedWriteNVerify_Verify: error incorrect ata command 0x%x\n", satIOContext->ATACmd)); 15249 return tiError; 15250 break; 15251 } 15252 15253 Remainder = satOrgIOContext->OrgTL % DenomTL; 15254 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL; 15255 lba = satOrgIOContext->currentLBA; 15256 15257 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */ 15258 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2)); 15259 LBA[2] = (bit8)((lba & 0xF0) >> 8); 15260 LBA[3] = (bit8)(lba & 0xF); /* LSB */ 15261 15262 switch (satOrgIOContext->ATACmd) 15263 { 15264 case SAT_READ_VERIFY_SECTORS: 15265 fis->h.fisType = 0x27; /* Reg host to device */ 15266 fis->h.c_pmPort = 0x80; /* C bit is set */ 15267 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 15268 fis->h.features = 0; /* FIS reserve */ 15269 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 15270 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 15271 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 15272 15273 /* FIS LBA mode set LBA (27:24) */ 15274 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 15275 15276 fis->d.lbaLowExp = 0; 15277 fis->d.lbaMidExp = 0; 15278 fis->d.lbaHighExp = 0; 15279 fis->d.featuresExp = 0; 15280 if (satOrgIOContext->LoopNum == 1) 15281 { 15282 /* last loop */ 15283 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 15284 } 15285 else 15286 { 15287 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 15288 } 15289 fis->d.sectorCountExp = 0; 15290 fis->d.reserved4 = 0; 15291 fis->d.control = 0; /* FIS HOB bit clear */ 15292 fis->d.reserved5 = 0; 15293 15294 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 15295 15296 break; 15297 case SAT_READ_VERIFY_SECTORS_EXT: 15298 fis->h.fisType = 0x27; /* Reg host to device */ 15299 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15300 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT; /* 0x42 */ 15301 fis->h.features = 0; /* FIS reserve */ 15302 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 15303 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 15304 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 15305 fis->d.device = 0x40; /* FIS LBA mode set */ 15306 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 15307 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 15308 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 15309 fis->d.featuresExp = 0; /* FIS reserve */ 15310 if (satOrgIOContext->LoopNum == 1) 15311 { 15312 /* last loop */ 15313 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 15314 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 15315 } 15316 else 15317 { 15318 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 15319 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 15320 } 15321 fis->d.reserved4 = 0; 15322 fis->d.control = 0; /* FIS HOB bit clear */ 15323 fis->d.reserved5 = 0; 15324 15325 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 15326 15327 break; 15328 15329 default: 15330 TI_DBG1(("satChainedWriteNVerify_Verify: error incorrect ata command 0x%x\n", satIOContext->ATACmd)); 15331 return tiError; 15332 break; 15333 } 15334 15335 /* Initialize CB for SATA completion. 15336 */ 15337 /* chained data */ 15338 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB; 15339 15340 15341 /* 15342 * Prepare SGL and send FIS to LL layer. 15343 */ 15344 satIOContext->reqType = agRequestType; /* Save it */ 15345 15346 status = sataLLIOStart( tiRoot, 15347 tiIORequest, 15348 tiDeviceHandle, 15349 tiScsiRequest, 15350 satIOContext); 15351 15352 TI_DBG5(("satChainedWriteNVerify_Verify: return\n")); 15353 return (status); 15354 15355 } 15356 15357 15358 /*****************************************************************************/ 15359 /*! \brief SAT implementation for SCSI satWriteAndVerify16. 15360 * 15361 * SAT implementation for SCSI satWriteAndVerify16. 15362 * 15363 * \param tiRoot: Pointer to TISA initiator driver/port instance. 15364 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 15365 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 15366 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 15367 * \param satIOContext_t: Pointer to the SAT IO Context 15368 * 15369 * \return If command is started successfully 15370 * - \e tiSuccess: I/O request successfully initiated. 15371 * - \e tiBusy: No resources available, try again later. 15372 * - \e tiIONoDevice: Invalid device handle. 15373 * - \e tiError: Other errors. 15374 */ 15375 /*****************************************************************************/ 15376 GLOBAL bit32 satWriteAndVerify16( 15377 tiRoot_t *tiRoot, 15378 tiIORequest_t *tiIORequest, 15379 tiDeviceHandle_t *tiDeviceHandle, 15380 tiScsiInitiatorRequest_t *tiScsiRequest, 15381 satIOContext_t *satIOContext) 15382 { 15383 /* 15384 combination of write16 and verify16 15385 since write16 has 8 bytes LBA -> problem ATA LBA(upto 6 bytes), no support 15386 */ 15387 bit32 status; 15388 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 15389 satDeviceData_t *pSatDevData; 15390 scsiRspSense_t *pSense; 15391 tiIniScsiCmnd_t *scsiCmnd; 15392 agsaFisRegHostToDevice_t *fis; 15393 bit32 lba = 0; 15394 bit32 tl = 0; 15395 bit32 LoopNum = 1; 15396 bit8 LBA[8]; 15397 bit8 TL[8]; 15398 bit32 rangeChk = agFALSE; /* lba and tl range check */ 15399 bit32 limitChk = agFALSE; /* lba and tl range check */ 15400 15401 pSense = satIOContext->pSense; 15402 pSatDevData = satIOContext->pSatDevData; 15403 scsiCmnd = &tiScsiRequest->scsiCmnd; 15404 fis = satIOContext->pFis; 15405 TI_DBG5(("satWriteAndVerify16:start\n")); 15406 15407 /* checking BYTCHK bit */ 15408 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK) 15409 { 15410 satSetSensePayload( pSense, 15411 SCSI_SNSKEY_ILLEGAL_REQUEST, 15412 0, 15413 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15414 satIOContext); 15415 15416 ostiInitiatorIOCompleted( tiRoot, 15417 tiIORequest, 15418 tiIOSuccess, 15419 SCSI_STAT_CHECK_CONDITION, 15420 satIOContext->pTiSenseData, 15421 satIOContext->interruptContext ); 15422 15423 TI_DBG1(("satWriteAndVerify16: BYTCHK bit checking \n")); 15424 return tiSuccess; 15425 } 15426 15427 15428 /* checking CONTROL */ 15429 /* NACA == 1 or LINK == 1*/ 15430 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 15431 { 15432 satSetSensePayload( pSense, 15433 SCSI_SNSKEY_ILLEGAL_REQUEST, 15434 0, 15435 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15436 satIOContext); 15437 15438 ostiInitiatorIOCompleted( tiRoot, 15439 tiIORequest, 15440 tiIOSuccess, 15441 SCSI_STAT_CHECK_CONDITION, 15442 satIOContext->pTiSenseData, 15443 satIOContext->interruptContext ); 15444 15445 TI_DBG2(("satWriteAndVerify16: return control\n")); 15446 return tiSuccess; 15447 } 15448 15449 osti_memset(LBA, 0, sizeof(LBA)); 15450 osti_memset(TL, 0, sizeof(TL)); 15451 15452 15453 /* do not use memcpy due to indexing in LBA and TL */ 15454 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 15455 LBA[1] = scsiCmnd->cdb[3]; 15456 LBA[2] = scsiCmnd->cdb[4]; 15457 LBA[3] = scsiCmnd->cdb[5]; 15458 LBA[4] = scsiCmnd->cdb[6]; 15459 LBA[5] = scsiCmnd->cdb[7]; 15460 LBA[6] = scsiCmnd->cdb[8]; 15461 LBA[7] = scsiCmnd->cdb[9]; /* LSB */ 15462 15463 TL[0] = 0; 15464 TL[1] = 0; 15465 TL[2] = 0; 15466 TL[3] = 0; 15467 TL[4] = scsiCmnd->cdb[10]; /* MSB */ 15468 TL[5] = scsiCmnd->cdb[11]; 15469 TL[6] = scsiCmnd->cdb[12]; 15470 TL[7] = scsiCmnd->cdb[13]; /* LSB */ 15471 15472 rangeChk = satAddNComparebit64(LBA, TL); 15473 15474 limitChk = satCompareLBALimitbit(LBA); 15475 15476 lba = satComputeCDB16LBA(satIOContext); 15477 tl = satComputeCDB16TL(satIOContext); 15478 15479 15480 /* Table 34, 9.1, p 46 */ 15481 /* 15482 note: As of 2/10/2006, no support for DMA QUEUED 15483 */ 15484 15485 /* 15486 Table 34, 9.1, p 46, b 15487 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 15488 return check condition 15489 */ 15490 if (pSatDevData->satNCQ != agTRUE && 15491 pSatDevData->sat48BitSupport != agTRUE 15492 ) 15493 { 15494 if (limitChk) 15495 { 15496 TI_DBG1(("satWriteAndVerify16: return LBA out of range, not EXT\n")); 15497 satSetSensePayload( pSense, 15498 SCSI_SNSKEY_ILLEGAL_REQUEST, 15499 0, 15500 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 15501 satIOContext); 15502 15503 ostiInitiatorIOCompleted( tiRoot, 15504 tiIORequest, 15505 tiIOSuccess, 15506 SCSI_STAT_CHECK_CONDITION, 15507 satIOContext->pTiSenseData, 15508 satIOContext->interruptContext ); 15509 15510 return tiSuccess; 15511 } 15512 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 15513 { 15514 TI_DBG1(("satWriteAndVerify16: return LBA+TL out of range, not EXT\n")); 15515 satSetSensePayload( pSense, 15516 SCSI_SNSKEY_ILLEGAL_REQUEST, 15517 0, 15518 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 15519 satIOContext); 15520 15521 ostiInitiatorIOCompleted( tiRoot, 15522 tiIORequest, 15523 tiIOSuccess, 15524 SCSI_STAT_CHECK_CONDITION, 15525 satIOContext->pTiSenseData, 15526 satIOContext->interruptContext ); 15527 15528 return tiSuccess; 15529 } 15530 } 15531 15532 15533 /* case 1 and 2 */ 15534 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT) 15535 { 15536 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 15537 { 15538 /* case 2 */ 15539 /* WRITE DMA*/ 15540 /* In case that we can't fit the transfer length, we loop */ 15541 TI_DBG5(("satWriteAndVerify16: case 2\n")); 15542 fis->h.fisType = 0x27; /* Reg host to device */ 15543 fis->h.c_pmPort = 0x80; /* C bit is set */ 15544 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 15545 fis->h.features = 0; /* FIS reserve */ 15546 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 15547 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 15548 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 15549 15550 /* FIS LBA mode set LBA (27:24) */ 15551 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); 15552 15553 fis->d.lbaLowExp = 0; 15554 fis->d.lbaMidExp = 0; 15555 fis->d.lbaHighExp = 0; 15556 fis->d.featuresExp = 0; 15557 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 15558 fis->d.sectorCountExp = 0; 15559 fis->d.reserved4 = 0; 15560 fis->d.control = 0; /* FIS HOB bit clear */ 15561 fis->d.reserved5 = 0; 15562 15563 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 15564 satIOContext->ATACmd = SAT_WRITE_DMA; 15565 } 15566 else 15567 { 15568 /* case 1 */ 15569 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 15570 /* WRITE SECTORS for easier implemetation */ 15571 /* In case that we can't fit the transfer length, we loop */ 15572 TI_DBG5(("satWriteAndVerify16: case 1\n")); 15573 fis->h.fisType = 0x27; /* Reg host to device */ 15574 fis->h.c_pmPort = 0x80; /* C bit is set */ 15575 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 15576 fis->h.features = 0; /* FIS reserve */ 15577 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 15578 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 15579 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 15580 15581 /* FIS LBA mode set LBA (27:24) */ 15582 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); 15583 15584 fis->d.lbaLowExp = 0; 15585 fis->d.lbaMidExp = 0; 15586 fis->d.lbaHighExp = 0; 15587 fis->d.featuresExp = 0; 15588 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 15589 fis->d.sectorCountExp = 0; 15590 fis->d.reserved4 = 0; 15591 fis->d.control = 0; /* FIS HOB bit clear */ 15592 fis->d.reserved5 = 0; 15593 15594 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 15595 satIOContext->ATACmd = SAT_WRITE_SECTORS; 15596 } 15597 } 15598 15599 /* case 3 and 4 */ 15600 if (pSatDevData->sat48BitSupport == agTRUE) 15601 { 15602 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 15603 { 15604 /* case 3 */ 15605 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 15606 TI_DBG5(("satWriteAndVerify16: case 3\n")); 15607 fis->h.fisType = 0x27; /* Reg host to device */ 15608 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15609 15610 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 15611 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 15612 15613 fis->h.features = 0; /* FIS reserve */ 15614 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 15615 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 15616 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 15617 fis->d.device = 0x40; /* FIS LBA mode set */ 15618 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 15619 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 15620 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 15621 fis->d.featuresExp = 0; /* FIS reserve */ 15622 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 15623 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 15624 fis->d.reserved4 = 0; 15625 fis->d.control = 0; /* FIS HOB bit clear */ 15626 fis->d.reserved5 = 0; 15627 15628 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 15629 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 15630 } 15631 else 15632 { 15633 /* case 4 */ 15634 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 15635 /* WRITE SECTORS EXT for easier implemetation */ 15636 TI_DBG5(("satWriteAndVerify16: case 4\n")); 15637 fis->h.fisType = 0x27; /* Reg host to device */ 15638 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15639 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 15640 15641 fis->h.features = 0; /* FIS reserve */ 15642 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 15643 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 15644 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 15645 fis->d.device = 0x40; /* FIS LBA mode set */ 15646 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 15647 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 15648 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 15649 fis->d.featuresExp = 0; /* FIS reserve */ 15650 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 15651 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 15652 fis->d.reserved4 = 0; 15653 fis->d.control = 0; /* FIS HOB bit clear */ 15654 fis->d.reserved5 = 0; 15655 15656 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 15657 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 15658 } 15659 } 15660 15661 /* case 5 */ 15662 if (pSatDevData->satNCQ == agTRUE) 15663 { 15664 /* WRITE FPDMA QUEUED */ 15665 if (pSatDevData->sat48BitSupport != agTRUE) 15666 { 15667 TI_DBG5(("satWriteAndVerify16: case 5 !!! error NCQ but 28 bit address support \n")); 15668 satSetSensePayload( pSense, 15669 SCSI_SNSKEY_ILLEGAL_REQUEST, 15670 0, 15671 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15672 satIOContext); 15673 15674 ostiInitiatorIOCompleted( tiRoot, 15675 tiIORequest, 15676 tiIOSuccess, 15677 SCSI_STAT_CHECK_CONDITION, 15678 satIOContext->pTiSenseData, 15679 satIOContext->interruptContext ); 15680 return tiSuccess; 15681 } 15682 TI_DBG6(("satWriteAndVerify16: case 5\n")); 15683 15684 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 15685 15686 fis->h.fisType = 0x27; /* Reg host to device */ 15687 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15688 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 15689 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 15690 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 15691 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 15692 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 15693 15694 /* Check FUA bit */ 15695 if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK) 15696 fis->d.device = 0xC0; /* FIS FUA set */ 15697 else 15698 fis->d.device = 0x40; /* FIS FUA clear */ 15699 15700 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 15701 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 15702 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 15703 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 15704 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 15705 fis->d.sectorCountExp = 0; 15706 fis->d.reserved4 = 0; 15707 fis->d.control = 0; /* FIS HOB bit clear */ 15708 fis->d.reserved5 = 0; 15709 15710 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 15711 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 15712 } 15713 15714 satIOContext->currentLBA = lba; 15715 satIOContext->OrgTL = tl; 15716 15717 /* 15718 computing number of loop and remainder for tl 15719 0xFF in case not ext 15720 0xFFFF in case EXT 15721 */ 15722 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 15723 { 15724 LoopNum = satComputeLoopNum(tl, 0xFF); 15725 } 15726 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 15727 fis->h.command == SAT_WRITE_DMA_EXT || 15728 fis->h.command == SAT_WRITE_DMA_FUA_EXT 15729 ) 15730 { 15731 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 15732 LoopNum = satComputeLoopNum(tl, 0xFFFF); 15733 } 15734 else 15735 { 15736 /* SAT_WRITE_FPDMA_QUEUEDK */ 15737 LoopNum = satComputeLoopNum(tl, 0xFFFF); 15738 } 15739 15740 satIOContext->LoopNum = LoopNum; 15741 15742 15743 if (LoopNum == 1) 15744 { 15745 TI_DBG5(("satWriteAndVerify16: NON CHAINED data\n")); 15746 /* Initialize CB for SATA completion. 15747 */ 15748 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB; 15749 } 15750 else 15751 { 15752 TI_DBG1(("satWriteAndVerify16: CHAINED data\n")); 15753 /* re-setting tl */ 15754 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 15755 { 15756 fis->d.sectorCount = 0xFF; 15757 } 15758 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 15759 fis->h.command == SAT_WRITE_DMA_EXT || 15760 fis->h.command == SAT_WRITE_DMA_FUA_EXT 15761 ) 15762 { 15763 fis->d.sectorCount = 0xFF; 15764 fis->d.sectorCountExp = 0xFF; 15765 } 15766 else 15767 { 15768 /* SAT_WRITE_FPDMA_QUEUED */ 15769 fis->h.features = 0xFF; 15770 fis->d.featuresExp = 0xFF; 15771 } 15772 15773 /* Initialize CB for SATA completion. 15774 */ 15775 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB; 15776 } 15777 15778 15779 /* 15780 * Prepare SGL and send FIS to LL layer. 15781 */ 15782 satIOContext->reqType = agRequestType; /* Save it */ 15783 15784 status = sataLLIOStart( tiRoot, 15785 tiIORequest, 15786 tiDeviceHandle, 15787 tiScsiRequest, 15788 satIOContext); 15789 return (status); 15790 } 15791 15792 /*****************************************************************************/ 15793 /*! \brief SAT implementation for SCSI satReadMediaSerialNumber. 15794 * 15795 * SAT implementation for SCSI Read Media Serial Number. 15796 * 15797 * \param tiRoot: Pointer to TISA initiator driver/port instance. 15798 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 15799 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 15800 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 15801 * \param satIOContext_t: Pointer to the SAT IO Context 15802 * 15803 * \return If command is started successfully 15804 * - \e tiSuccess: I/O request successfully initiated. 15805 * - \e tiBusy: No resources available, try again later. 15806 * - \e tiIONoDevice: Invalid device handle. 15807 * - \e tiError: Other errors. 15808 */ 15809 /*****************************************************************************/ 15810 GLOBAL bit32 satReadMediaSerialNumber( 15811 tiRoot_t *tiRoot, 15812 tiIORequest_t *tiIORequest, 15813 tiDeviceHandle_t *tiDeviceHandle, 15814 tiScsiInitiatorRequest_t *tiScsiRequest, 15815 satIOContext_t *satIOContext) 15816 { 15817 bit32 status; 15818 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 15819 satDeviceData_t *pSatDevData; 15820 scsiRspSense_t *pSense; 15821 tiIniScsiCmnd_t *scsiCmnd; 15822 agsaFisRegHostToDevice_t *fis; 15823 agsaSATAIdentifyData_t *pSATAIdData; 15824 bit8 *pSerialNumber; 15825 15826 pSense = satIOContext->pSense; 15827 pSatDevData = satIOContext->pSatDevData; 15828 scsiCmnd = &tiScsiRequest->scsiCmnd; 15829 fis = satIOContext->pFis; 15830 pSATAIdData = &(pSatDevData->satIdentifyData); 15831 pSerialNumber = (bit8 *) tiScsiRequest->sglVirtualAddr; 15832 15833 15834 TI_DBG1(("satReadMediaSerialNumber: start\n")); 15835 15836 /* checking CONTROL */ 15837 /* NACA == 1 or LINK == 1*/ 15838 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) ) 15839 { 15840 satSetSensePayload( pSense, 15841 SCSI_SNSKEY_ILLEGAL_REQUEST, 15842 0, 15843 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15844 satIOContext); 15845 15846 ostiInitiatorIOCompleted( tiRoot, 15847 tiIORequest, 15848 tiIOSuccess, 15849 SCSI_STAT_CHECK_CONDITION, 15850 satIOContext->pTiSenseData, 15851 satIOContext->interruptContext ); 15852 15853 TI_DBG1(("satReadMediaSerialNumber: return control\n")); 15854 return tiSuccess; 15855 } 15856 15857 if (tiScsiRequest->scsiCmnd.expDataLength == 4) 15858 { 15859 if (pSATAIdData->commandSetFeatureDefault & 0x4) 15860 { 15861 TI_DBG1(("satReadMediaSerialNumber: Media serial number returning only length\n")); 15862 /* SPC-3 6.16 p192; filling in length */ 15863 pSerialNumber[0] = 0; 15864 pSerialNumber[1] = 0; 15865 pSerialNumber[2] = 0; 15866 pSerialNumber[3] = 0x3C; 15867 } 15868 else 15869 { 15870 /* 1 sector - 4 = 512 - 4 to avoid underflow; 0x1fc*/ 15871 pSerialNumber[0] = 0; 15872 pSerialNumber[1] = 0; 15873 pSerialNumber[2] = 0x1; 15874 pSerialNumber[3] = 0xfc; 15875 } 15876 15877 ostiInitiatorIOCompleted( tiRoot, 15878 tiIORequest, 15879 tiIOSuccess, 15880 SCSI_STAT_GOOD, 15881 agNULL, 15882 satIOContext->interruptContext); 15883 15884 return tiSuccess; 15885 } 15886 15887 if ( pSatDevData->IDDeviceValid == agTRUE) 15888 { 15889 if (pSATAIdData->commandSetFeatureDefault & 0x4) 15890 { 15891 /* word87 bit2 Media serial number is valid */ 15892 /* read word 176 to 205; length is 2*30 = 60 = 0x3C*/ 15893 tdhexdump("ID satReadMediaSerialNumber", (bit8*)pSATAIdData->currentMediaSerialNumber, 2*30); 15894 /* SPC-3 6.16 p192; filling in length */ 15895 pSerialNumber[0] = 0; 15896 pSerialNumber[1] = 0; 15897 pSerialNumber[2] = 0; 15898 pSerialNumber[3] = 0x3C; 15899 osti_memcpy(&pSerialNumber[4], (void *)pSATAIdData->currentMediaSerialNumber, 60); 15900 tdhexdump("satReadMediaSerialNumber", (bit8*)pSerialNumber, 2*30 + 4); 15901 15902 ostiInitiatorIOCompleted( tiRoot, 15903 tiIORequest, 15904 tiIOSuccess, 15905 SCSI_STAT_GOOD, 15906 agNULL, 15907 satIOContext->interruptContext); 15908 return tiSuccess; 15909 15910 15911 } 15912 else 15913 { 15914 /* word87 bit2 Media serial number is NOT valid */ 15915 TI_DBG1(("satReadMediaSerialNumber: Media serial number is NOT valid \n")); 15916 15917 if (pSatDevData->sat48BitSupport == agTRUE) 15918 { 15919 /* READ VERIFY SECTORS EXT */ 15920 fis->h.fisType = 0x27; /* Reg host to device */ 15921 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15922 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 15923 15924 fis->h.features = 0; /* FIS reserve */ 15925 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 15926 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 15927 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 15928 fis->d.device = 0x40; /* FIS LBA mode set */ 15929 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 15930 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 15931 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 15932 fis->d.featuresExp = 0; /* FIS reserve */ 15933 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 15934 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 15935 fis->d.reserved4 = 0; 15936 fis->d.control = 0; /* FIS HOB bit clear */ 15937 fis->d.reserved5 = 0; 15938 15939 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 15940 } 15941 else 15942 { 15943 /* READ VERIFY SECTORS */ 15944 fis->h.fisType = 0x27; /* Reg host to device */ 15945 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15946 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 15947 fis->h.features = 0; /* FIS reserve */ 15948 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 15949 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 15950 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 15951 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */ 15952 fis->d.lbaLowExp = 0; 15953 fis->d.lbaMidExp = 0; 15954 fis->d.lbaHighExp = 0; 15955 fis->d.featuresExp = 0; 15956 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 15957 fis->d.sectorCountExp = 0; 15958 fis->d.reserved4 = 0; 15959 fis->d.control = 0; /* FIS HOB bit clear */ 15960 fis->d.reserved5 = 0; 15961 15962 15963 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 15964 } 15965 satIOContext->satCompleteCB = &satReadMediaSerialNumberCB; 15966 satIOContext->reqType = agRequestType; /* Save it */ 15967 status = sataLLIOStart( tiRoot, 15968 tiIORequest, 15969 tiDeviceHandle, 15970 tiScsiRequest, 15971 satIOContext); 15972 15973 return status; 15974 } 15975 } 15976 else 15977 { 15978 /* temporary failure */ 15979 ostiInitiatorIOCompleted( tiRoot, 15980 tiIORequest, 15981 tiIOFailed, 15982 tiDetailOtherError, 15983 agNULL, 15984 satIOContext->interruptContext); 15985 15986 return tiSuccess; 15987 15988 } 15989 15990 } 15991 15992 /*****************************************************************************/ 15993 /*! \brief SAT implementation for SCSI satReadBuffer. 15994 * 15995 * SAT implementation for SCSI Read Buffer. 15996 * 15997 * \param tiRoot: Pointer to TISA initiator driver/port instance. 15998 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 15999 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 16000 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 16001 * \param satIOContext_t: Pointer to the SAT IO Context 16002 * 16003 * \return If command is started successfully 16004 * - \e tiSuccess: I/O request successfully initiated. 16005 * - \e tiBusy: No resources available, try again later. 16006 * - \e tiIONoDevice: Invalid device handle. 16007 * - \e tiError: Other errors. 16008 */ 16009 /*****************************************************************************/ 16010 /* SAT-2, Revision 00*/ 16011 GLOBAL bit32 satReadBuffer( 16012 tiRoot_t *tiRoot, 16013 tiIORequest_t *tiIORequest, 16014 tiDeviceHandle_t *tiDeviceHandle, 16015 tiScsiInitiatorRequest_t *tiScsiRequest, 16016 satIOContext_t *satIOContext) 16017 { 16018 bit32 status = tiSuccess; 16019 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 16020 scsiRspSense_t *pSense; 16021 tiIniScsiCmnd_t *scsiCmnd; 16022 agsaFisRegHostToDevice_t *fis; 16023 bit32 bufferOffset; 16024 bit32 tl; 16025 bit8 mode; 16026 bit8 bufferID; 16027 bit8 *pBuff; 16028 16029 pSense = satIOContext->pSense; 16030 scsiCmnd = &tiScsiRequest->scsiCmnd; 16031 fis = satIOContext->pFis; 16032 pBuff = (bit8 *) tiScsiRequest->sglVirtualAddr; 16033 16034 TI_DBG2(("satReadBuffer: start\n")); 16035 /* checking CONTROL */ 16036 /* NACA == 1 or LINK == 1*/ 16037 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 16038 { 16039 satSetSensePayload( pSense, 16040 SCSI_SNSKEY_ILLEGAL_REQUEST, 16041 0, 16042 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16043 satIOContext); 16044 ostiInitiatorIOCompleted( tiRoot, 16045 tiIORequest, 16046 tiIOSuccess, 16047 SCSI_STAT_CHECK_CONDITION, 16048 satIOContext->pTiSenseData, 16049 satIOContext->interruptContext ); 16050 TI_DBG1(("satReadBuffer: return control\n")); 16051 return tiSuccess; 16052 } 16053 16054 bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 16055 tl = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 16056 16057 mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK); 16058 bufferID = scsiCmnd->cdb[2]; 16059 16060 if (mode == READ_BUFFER_DATA_MODE) /* 2 */ 16061 { 16062 if (bufferID == 0 && bufferOffset == 0 && tl == 512) 16063 { 16064 /* send ATA READ BUFFER */ 16065 fis->h.fisType = 0x27; /* Reg host to device */ 16066 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16067 fis->h.command = SAT_READ_BUFFER; /* 0xE4 */ 16068 fis->h.features = 0; /* FIS reserve */ 16069 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 16070 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 16071 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 16072 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */ 16073 fis->d.lbaLowExp = 0; 16074 fis->d.lbaMidExp = 0; 16075 fis->d.lbaHighExp = 0; 16076 fis->d.featuresExp = 0; 16077 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 16078 fis->d.sectorCountExp = 0; 16079 fis->d.reserved4 = 0; 16080 fis->d.control = 0; /* FIS HOB bit clear */ 16081 fis->d.reserved5 = 0; 16082 16083 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 16084 satIOContext->satCompleteCB = &satReadBufferCB; 16085 satIOContext->reqType = agRequestType; /* Save it */ 16086 16087 status = sataLLIOStart( tiRoot, 16088 tiIORequest, 16089 tiDeviceHandle, 16090 tiScsiRequest, 16091 satIOContext); 16092 return status; 16093 } 16094 if (bufferID == 0 && bufferOffset == 0 && tl != 512) 16095 { 16096 satSetSensePayload( pSense, 16097 SCSI_SNSKEY_ILLEGAL_REQUEST, 16098 0, 16099 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16100 satIOContext); 16101 ostiInitiatorIOCompleted( tiRoot, 16102 tiIORequest, 16103 tiIOSuccess, 16104 SCSI_STAT_CHECK_CONDITION, 16105 satIOContext->pTiSenseData, 16106 satIOContext->interruptContext ); 16107 TI_DBG1(("satReadBuffer: allocation length is not 512; it is %d\n", tl)); 16108 return tiSuccess; 16109 } 16110 if (bufferID == 0 && bufferOffset != 0) 16111 { 16112 satSetSensePayload( pSense, 16113 SCSI_SNSKEY_ILLEGAL_REQUEST, 16114 0, 16115 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16116 satIOContext); 16117 ostiInitiatorIOCompleted( tiRoot, 16118 tiIORequest, 16119 tiIOSuccess, 16120 SCSI_STAT_CHECK_CONDITION, 16121 satIOContext->pTiSenseData, 16122 satIOContext->interruptContext ); 16123 TI_DBG1(("satReadBuffer: buffer offset is not 0; it is %d\n", bufferOffset)); 16124 return tiSuccess; 16125 } 16126 /* all other cases unsupported */ 16127 TI_DBG1(("satReadBuffer: unsupported case 1\n")); 16128 satSetSensePayload( pSense, 16129 SCSI_SNSKEY_ILLEGAL_REQUEST, 16130 0, 16131 SCSI_SNSCODE_INVALID_COMMAND, 16132 satIOContext); 16133 16134 ostiInitiatorIOCompleted( tiRoot, 16135 tiIORequest, 16136 tiIOSuccess, 16137 SCSI_STAT_CHECK_CONDITION, 16138 satIOContext->pTiSenseData, 16139 satIOContext->interruptContext ); 16140 return tiSuccess; 16141 } 16142 else if (mode == READ_BUFFER_DESCRIPTOR_MODE) /* 3 */ 16143 { 16144 if (tl < READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN) /* 4 */ 16145 { 16146 satSetSensePayload( pSense, 16147 SCSI_SNSKEY_ILLEGAL_REQUEST, 16148 0, 16149 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16150 satIOContext); 16151 ostiInitiatorIOCompleted( tiRoot, 16152 tiIORequest, 16153 tiIOSuccess, 16154 SCSI_STAT_CHECK_CONDITION, 16155 satIOContext->pTiSenseData, 16156 satIOContext->interruptContext ); 16157 TI_DBG1(("satReadBuffer: tl < 4; tl is %d\n", tl)); 16158 return tiSuccess; 16159 } 16160 if (bufferID == 0) 16161 { 16162 /* SPC-4, 6.15.5, p189; SAT-2 Rev00, 8.7.2.3, p41*/ 16163 pBuff[0] = 0xFF; 16164 pBuff[1] = 0x00; 16165 pBuff[2] = 0x02; 16166 pBuff[3] = 0x00; 16167 if (READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN < tl) 16168 { 16169 /* underrrun */ 16170 TI_DBG1(("satReadBuffer: underrun tl %d data %d\n", tl, READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN)); 16171 ostiInitiatorIOCompleted( tiRoot, 16172 tiIORequest, 16173 tiIOUnderRun, 16174 tl - READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN, 16175 agNULL, 16176 satIOContext->interruptContext ); 16177 return tiSuccess; 16178 } 16179 else 16180 { 16181 ostiInitiatorIOCompleted( tiRoot, 16182 tiIORequest, 16183 tiIOSuccess, 16184 SCSI_STAT_GOOD, 16185 agNULL, 16186 satIOContext->interruptContext); 16187 return tiSuccess; 16188 } 16189 } 16190 else 16191 { 16192 /* We don't support other than bufferID 0 */ 16193 satSetSensePayload( pSense, 16194 SCSI_SNSKEY_ILLEGAL_REQUEST, 16195 0, 16196 SCSI_SNSCODE_INVALID_COMMAND, 16197 satIOContext); 16198 16199 ostiInitiatorIOCompleted( tiRoot, 16200 tiIORequest, 16201 tiIOSuccess, 16202 SCSI_STAT_CHECK_CONDITION, 16203 satIOContext->pTiSenseData, 16204 satIOContext->interruptContext ); 16205 return tiSuccess; 16206 } 16207 } 16208 else 16209 { 16210 /* We don't support any other mode */ 16211 TI_DBG1(("satReadBuffer: unsupported mode %d\n", mode)); 16212 satSetSensePayload( pSense, 16213 SCSI_SNSKEY_ILLEGAL_REQUEST, 16214 0, 16215 SCSI_SNSCODE_INVALID_COMMAND, 16216 satIOContext); 16217 16218 ostiInitiatorIOCompleted( tiRoot, 16219 tiIORequest, 16220 tiIOSuccess, 16221 SCSI_STAT_CHECK_CONDITION, 16222 satIOContext->pTiSenseData, 16223 satIOContext->interruptContext ); 16224 return tiSuccess; 16225 } 16226 } 16227 16228 /*****************************************************************************/ 16229 /*! \brief SAT implementation for SCSI satWriteBuffer. 16230 * 16231 * SAT implementation for SCSI Write Buffer. 16232 * 16233 * \param tiRoot: Pointer to TISA initiator driver/port instance. 16234 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 16235 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 16236 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 16237 * \param satIOContext_t: Pointer to the SAT IO Context 16238 * 16239 * \return If command is started successfully 16240 * - \e tiSuccess: I/O request successfully initiated. 16241 * - \e tiBusy: No resources available, try again later. 16242 * - \e tiIONoDevice: Invalid device handle. 16243 * - \e tiError: Other errors. 16244 */ 16245 /*****************************************************************************/ 16246 /* SAT-2, Revision 00*/ 16247 GLOBAL bit32 satWriteBuffer( 16248 tiRoot_t *tiRoot, 16249 tiIORequest_t *tiIORequest, 16250 tiDeviceHandle_t *tiDeviceHandle, 16251 tiScsiInitiatorRequest_t *tiScsiRequest, 16252 satIOContext_t *satIOContext) 16253 { 16254 #ifdef NOT_YET 16255 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 16256 #endif 16257 scsiRspSense_t *pSense; 16258 tiIniScsiCmnd_t *scsiCmnd; 16259 bit32 bufferOffset; 16260 bit32 parmLen; 16261 bit8 mode; 16262 bit8 bufferID; 16263 bit8 *pBuff; 16264 16265 pSense = satIOContext->pSense; 16266 scsiCmnd = &tiScsiRequest->scsiCmnd; 16267 pBuff = (bit8 *) tiScsiRequest->sglVirtualAddr; 16268 16269 TI_DBG2(("satWriteBuffer: start\n")); 16270 16271 /* checking CONTROL */ 16272 /* NACA == 1 or LINK == 1*/ 16273 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 16274 { 16275 satSetSensePayload( pSense, 16276 SCSI_SNSKEY_ILLEGAL_REQUEST, 16277 0, 16278 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16279 satIOContext); 16280 16281 ostiInitiatorIOCompleted( tiRoot, 16282 tiIORequest, 16283 tiIOSuccess, 16284 SCSI_STAT_CHECK_CONDITION, 16285 satIOContext->pTiSenseData, 16286 satIOContext->interruptContext ); 16287 16288 TI_DBG1(("satWriteBuffer: return control\n")); 16289 return tiSuccess; 16290 } 16291 16292 bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 16293 parmLen = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 16294 16295 mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK); 16296 bufferID = scsiCmnd->cdb[2]; 16297 16298 /* for debugging only */ 16299 tdhexdump("satWriteBuffer pBuff", (bit8 *)pBuff, 24); 16300 16301 if (mode == WRITE_BUFFER_DATA_MODE) /* 2 */ 16302 { 16303 if (bufferID == 0 && bufferOffset == 0 && parmLen == 512) 16304 { 16305 TI_DBG1(("satWriteBuffer: sending ATA WRITE BUFFER\n")); 16306 /* send ATA WRITE BUFFER */ 16307 #ifdef NOT_YET 16308 fis->h.fisType = 0x27; /* Reg host to device */ 16309 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16310 fis->h.command = SAT_WRITE_BUFFER; /* 0xE8 */ 16311 fis->h.features = 0; /* FIS reserve */ 16312 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 16313 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 16314 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 16315 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */ 16316 fis->d.lbaLowExp = 0; 16317 fis->d.lbaMidExp = 0; 16318 fis->d.lbaHighExp = 0; 16319 fis->d.featuresExp = 0; 16320 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 16321 fis->d.sectorCountExp = 0; 16322 fis->d.reserved4 = 0; 16323 fis->d.control = 0; /* FIS HOB bit clear */ 16324 fis->d.reserved5 = 0; 16325 16326 16327 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 16328 16329 satIOContext->satCompleteCB = &satWriteBufferCB; 16330 16331 satIOContext->reqType = agRequestType; /* Save it */ 16332 16333 status = sataLLIOStart( tiRoot, 16334 tiIORequest, 16335 tiDeviceHandle, 16336 tiScsiRequest, 16337 satIOContext); 16338 return status; 16339 #endif 16340 /* temp */ 16341 ostiInitiatorIOCompleted( tiRoot, 16342 tiIORequest, 16343 tiIOSuccess, 16344 SCSI_STAT_GOOD, 16345 agNULL, 16346 satIOContext->interruptContext); 16347 return tiSuccess; 16348 } 16349 if ( (bufferID == 0 && bufferOffset != 0) || 16350 (bufferID == 0 && parmLen != 512) 16351 ) 16352 { 16353 satSetSensePayload( pSense, 16354 SCSI_SNSKEY_ILLEGAL_REQUEST, 16355 0, 16356 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16357 satIOContext); 16358 16359 ostiInitiatorIOCompleted( tiRoot, 16360 tiIORequest, 16361 tiIOSuccess, 16362 SCSI_STAT_CHECK_CONDITION, 16363 satIOContext->pTiSenseData, 16364 satIOContext->interruptContext ); 16365 16366 TI_DBG1(("satWriteBuffer: wrong buffer offset %d or parameter length parmLen %d\n", bufferOffset, parmLen)); 16367 return tiSuccess; 16368 } 16369 16370 /* all other cases unsupported */ 16371 TI_DBG1(("satWriteBuffer: unsupported case 1\n")); 16372 satSetSensePayload( pSense, 16373 SCSI_SNSKEY_ILLEGAL_REQUEST, 16374 0, 16375 SCSI_SNSCODE_INVALID_COMMAND, 16376 satIOContext); 16377 16378 ostiInitiatorIOCompleted( tiRoot, 16379 tiIORequest, 16380 tiIOSuccess, 16381 SCSI_STAT_CHECK_CONDITION, 16382 satIOContext->pTiSenseData, 16383 satIOContext->interruptContext ); 16384 16385 return tiSuccess; 16386 16387 } 16388 else if (mode == WRITE_BUFFER_DL_MICROCODE_SAVE_MODE) /* 5 */ 16389 { 16390 TI_DBG1(("satWriteBuffer: not yet supported mode %d\n", mode)); 16391 satSetSensePayload( pSense, 16392 SCSI_SNSKEY_ILLEGAL_REQUEST, 16393 0, 16394 SCSI_SNSCODE_INVALID_COMMAND, 16395 satIOContext); 16396 16397 ostiInitiatorIOCompleted( tiRoot, 16398 tiIORequest, 16399 tiIOSuccess, 16400 SCSI_STAT_CHECK_CONDITION, 16401 satIOContext->pTiSenseData, 16402 satIOContext->interruptContext ); 16403 16404 return tiSuccess; 16405 } 16406 else 16407 { 16408 /* We don't support any other mode */ 16409 TI_DBG1(("satWriteBuffer: unsupported mode %d\n", mode)); 16410 satSetSensePayload( pSense, 16411 SCSI_SNSKEY_ILLEGAL_REQUEST, 16412 0, 16413 SCSI_SNSCODE_INVALID_COMMAND, 16414 satIOContext); 16415 16416 ostiInitiatorIOCompleted( tiRoot, 16417 tiIORequest, 16418 tiIOSuccess, 16419 SCSI_STAT_CHECK_CONDITION, 16420 satIOContext->pTiSenseData, 16421 satIOContext->interruptContext ); 16422 16423 return tiSuccess; 16424 } 16425 16426 } 16427 16428 /*****************************************************************************/ 16429 /*! \brief SAT implementation for SCSI satReassignBlocks. 16430 * 16431 * SAT implementation for SCSI Reassign Blocks. 16432 * 16433 * \param tiRoot: Pointer to TISA initiator driver/port instance. 16434 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 16435 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 16436 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 16437 * \param satIOContext_t: Pointer to the SAT IO Context 16438 * 16439 * \return If command is started successfully 16440 * - \e tiSuccess: I/O request successfully initiated. 16441 * - \e tiBusy: No resources available, try again later. 16442 * - \e tiIONoDevice: Invalid device handle. 16443 * - \e tiError: Other errors. 16444 */ 16445 /*****************************************************************************/ 16446 GLOBAL bit32 satReassignBlocks( 16447 tiRoot_t *tiRoot, 16448 tiIORequest_t *tiIORequest, 16449 tiDeviceHandle_t *tiDeviceHandle, 16450 tiScsiInitiatorRequest_t *tiScsiRequest, 16451 satIOContext_t *satIOContext) 16452 { 16453 /* 16454 assumes all LBA fits in ATA command; no boundary condition is checked here yet 16455 */ 16456 bit32 status; 16457 bit32 agRequestType; 16458 satDeviceData_t *pSatDevData; 16459 scsiRspSense_t *pSense; 16460 tiIniScsiCmnd_t *scsiCmnd; 16461 agsaFisRegHostToDevice_t *fis; 16462 bit8 *pParmList; /* Log Page data buffer */ 16463 bit8 LongLBA; 16464 bit8 LongList; 16465 bit32 defectListLen; 16466 bit8 LBA[8]; 16467 bit32 startingIndex; 16468 16469 pSense = satIOContext->pSense; 16470 pSatDevData = satIOContext->pSatDevData; 16471 scsiCmnd = &tiScsiRequest->scsiCmnd; 16472 fis = satIOContext->pFis; 16473 pParmList = (bit8 *) tiScsiRequest->sglVirtualAddr; 16474 16475 TI_DBG5(("satReassignBlocks: start\n")); 16476 16477 /* checking CONTROL */ 16478 /* NACA == 1 or LINK == 1*/ 16479 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 16480 { 16481 satSetSensePayload( pSense, 16482 SCSI_SNSKEY_ILLEGAL_REQUEST, 16483 0, 16484 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16485 satIOContext); 16486 16487 ostiInitiatorIOCompleted( tiRoot, 16488 tiIORequest, 16489 tiIOSuccess, 16490 SCSI_STAT_CHECK_CONDITION, 16491 satIOContext->pTiSenseData, 16492 satIOContext->interruptContext ); 16493 16494 TI_DBG1(("satReassignBlocks: return control\n")); 16495 return tiSuccess; 16496 } 16497 16498 osti_memset(satIOContext->LBA, 0, 8); 16499 satIOContext->ParmIndex = 0; 16500 satIOContext->ParmLen = 0; 16501 16502 LongList = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLIST_MASK); 16503 LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK); 16504 osti_memset(LBA, 0, sizeof(LBA)); 16505 16506 if (LongList == 0) 16507 { 16508 defectListLen = (pParmList[2] << 8) + pParmList[3]; 16509 } 16510 else 16511 { 16512 defectListLen = (pParmList[0] << (8*3)) + (pParmList[1] << (8*2)) 16513 + (pParmList[2] << 8) + pParmList[3]; 16514 } 16515 /* SBC 5.16.2, p61*/ 16516 satIOContext->ParmLen = defectListLen + 4 /* header size */; 16517 16518 startingIndex = 4; 16519 16520 if (LongLBA == 0) 16521 { 16522 LBA[4] = pParmList[startingIndex]; /* MSB */ 16523 LBA[5] = pParmList[startingIndex+1]; 16524 LBA[6] = pParmList[startingIndex+2]; 16525 LBA[7] = pParmList[startingIndex+3]; /* LSB */ 16526 startingIndex = startingIndex + 4; 16527 } 16528 else 16529 { 16530 LBA[0] = pParmList[startingIndex]; /* MSB */ 16531 LBA[1] = pParmList[startingIndex+1]; 16532 LBA[2] = pParmList[startingIndex+2]; 16533 LBA[3] = pParmList[startingIndex+3]; 16534 LBA[4] = pParmList[startingIndex+4]; 16535 LBA[5] = pParmList[startingIndex+5]; 16536 LBA[6] = pParmList[startingIndex+6]; 16537 LBA[7] = pParmList[startingIndex+7]; /* LSB */ 16538 startingIndex = startingIndex + 8; 16539 } 16540 16541 tdhexdump("satReassignBlocks Parameter list", (bit8 *)pParmList, 4 + defectListLen); 16542 16543 if (pSatDevData->sat48BitSupport == agTRUE) 16544 { 16545 /* sends READ VERIFY SECTOR(S) EXT*/ 16546 fis->h.fisType = 0x27; /* Reg host to device */ 16547 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16548 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 16549 fis->h.features = 0; /* FIS reserve */ 16550 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 16551 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 16552 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 16553 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */ 16554 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */ 16555 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */ 16556 fis->d.featuresExp = 0; /* FIS reserve */ 16557 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 16558 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 16559 fis->d.reserved4 = 0; 16560 fis->d.device = 0x40; /* 01000000 */ 16561 fis->d.control = 0; /* FIS HOB bit clear */ 16562 fis->d.reserved5 = 0; 16563 } 16564 else 16565 { 16566 /* READ VERIFY SECTOR(S)*/ 16567 fis->h.fisType = 0x27; /* Reg host to device */ 16568 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16569 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 16570 fis->h.features = 0; /* FIS features NA */ 16571 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 16572 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 16573 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 16574 fis->d.lbaLowExp = 0; 16575 fis->d.lbaMidExp = 0; 16576 fis->d.lbaHighExp = 0; 16577 fis->d.featuresExp = 0; 16578 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 16579 fis->d.sectorCountExp = 0; 16580 fis->d.reserved4 = 0; 16581 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF)); 16582 /* DEV and LBA 27:24 */ 16583 fis->d.control = 0; /* FIS HOB bit clear */ 16584 fis->d.reserved5 = 0; 16585 } 16586 16587 osti_memcpy(satIOContext->LBA, LBA, 8); 16588 satIOContext->ParmIndex = startingIndex; 16589 16590 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 16591 16592 /* Initialize CB for SATA completion. 16593 */ 16594 satIOContext->satCompleteCB = &satReassignBlocksCB; 16595 16596 /* 16597 * Prepare SGL and send FIS to LL layer. 16598 */ 16599 satIOContext->reqType = agRequestType; /* Save it */ 16600 16601 status = sataLLIOStart( tiRoot, 16602 tiIORequest, 16603 tiDeviceHandle, 16604 tiScsiRequest, 16605 satIOContext); 16606 16607 return status; 16608 } 16609 16610 /*****************************************************************************/ 16611 /*! \brief SAT implementation for SCSI satReassignBlocks_1. 16612 * 16613 * SAT implementation for SCSI Reassign Blocks. This is helper function for 16614 * satReassignBlocks and satReassignBlocksCB. This sends ATA verify command. 16615 * 16616 * \param tiRoot: Pointer to TISA initiator driver/port instance. 16617 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 16618 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 16619 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 16620 * \param satIOContext_t: Pointer to the SAT IO Context 16621 * 16622 * \return If command is started successfully 16623 * - \e tiSuccess: I/O request successfully initiated. 16624 * - \e tiBusy: No resources available, try again later. 16625 * - \e tiIONoDevice: Invalid device handle. 16626 * - \e tiError: Other errors. 16627 */ 16628 /*****************************************************************************/ 16629 /* next LBA; sends READ VERIFY SECTOR; update LBA and ParmIdx */ 16630 GLOBAL bit32 satReassignBlocks_1( 16631 tiRoot_t *tiRoot, 16632 tiIORequest_t *tiIORequest, 16633 tiDeviceHandle_t *tiDeviceHandle, 16634 tiScsiInitiatorRequest_t *tiScsiRequest, 16635 satIOContext_t *satIOContext, 16636 satIOContext_t *satOrgIOContext 16637 ) 16638 { 16639 /* 16640 assumes all LBA fits in ATA command; no boundary condition is checked here yet 16641 tiScsiRequest is OS generated; needs for accessing parameter list 16642 */ 16643 bit32 agRequestType; 16644 satDeviceData_t *pSatDevData; 16645 tiIniScsiCmnd_t *scsiCmnd; 16646 agsaFisRegHostToDevice_t *fis; 16647 bit8 *pParmList; /* Log Page data buffer */ 16648 bit8 LongLBA; 16649 bit8 LBA[8]; 16650 bit32 startingIndex; 16651 16652 pSatDevData = satIOContext->pSatDevData; 16653 scsiCmnd = &tiScsiRequest->scsiCmnd; 16654 fis = satIOContext->pFis; 16655 pParmList = (bit8 *) tiScsiRequest->sglVirtualAddr; 16656 16657 TI_DBG5(("satReassignBlocks_1: start\n")); 16658 16659 LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK); 16660 osti_memset(LBA, 0, sizeof(LBA)); 16661 16662 startingIndex = satOrgIOContext->ParmIndex; 16663 16664 if (LongLBA == 0) 16665 { 16666 LBA[4] = pParmList[startingIndex]; 16667 LBA[5] = pParmList[startingIndex+1]; 16668 LBA[6] = pParmList[startingIndex+2]; 16669 LBA[7] = pParmList[startingIndex+3]; 16670 startingIndex = startingIndex + 4; 16671 } 16672 else 16673 { 16674 LBA[0] = pParmList[startingIndex]; 16675 LBA[1] = pParmList[startingIndex+1]; 16676 LBA[2] = pParmList[startingIndex+2]; 16677 LBA[3] = pParmList[startingIndex+3]; 16678 LBA[4] = pParmList[startingIndex+4]; 16679 LBA[5] = pParmList[startingIndex+5]; 16680 LBA[6] = pParmList[startingIndex+6]; 16681 LBA[7] = pParmList[startingIndex+7]; 16682 startingIndex = startingIndex + 8; 16683 } 16684 16685 if (pSatDevData->sat48BitSupport == agTRUE) 16686 { 16687 /* sends READ VERIFY SECTOR(S) EXT*/ 16688 fis->h.fisType = 0x27; /* Reg host to device */ 16689 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16690 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 16691 fis->h.features = 0; /* FIS reserve */ 16692 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 16693 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 16694 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 16695 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */ 16696 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */ 16697 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */ 16698 fis->d.featuresExp = 0; /* FIS reserve */ 16699 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 16700 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 16701 fis->d.reserved4 = 0; 16702 fis->d.device = 0x40; /* 01000000 */ 16703 fis->d.control = 0; /* FIS HOB bit clear */ 16704 fis->d.reserved5 = 0; 16705 } 16706 else 16707 { 16708 /* READ VERIFY SECTOR(S)*/ 16709 fis->h.fisType = 0x27; /* Reg host to device */ 16710 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16711 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 16712 fis->h.features = 0; /* FIS features NA */ 16713 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 16714 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 16715 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 16716 fis->d.lbaLowExp = 0; 16717 fis->d.lbaMidExp = 0; 16718 fis->d.lbaHighExp = 0; 16719 fis->d.featuresExp = 0; 16720 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 16721 fis->d.sectorCountExp = 0; 16722 fis->d.reserved4 = 0; 16723 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF)); 16724 /* DEV and LBA 27:24 */ 16725 fis->d.control = 0; /* FIS HOB bit clear */ 16726 fis->d.reserved5 = 0; 16727 } 16728 osti_memcpy(satOrgIOContext->LBA, LBA, 8); 16729 satOrgIOContext->ParmIndex = startingIndex; 16730 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 16731 /* Initialize CB for SATA completion. 16732 */ 16733 satIOContext->satCompleteCB = &satReassignBlocksCB; 16734 /* 16735 * Prepare SGL and send FIS to LL layer. 16736 */ 16737 satIOContext->reqType = agRequestType; /* Save it */ 16738 16739 sataLLIOStart( tiRoot, 16740 tiIORequest, 16741 tiDeviceHandle, 16742 tiScsiRequest, 16743 satIOContext ); 16744 return tiSuccess; 16745 } 16746 16747 /*****************************************************************************/ 16748 /*! \brief SAT implementation for SCSI satReassignBlocks_2. 16749 * 16750 * SAT implementation for SCSI Reassign Blocks. This is helper function for 16751 * satReassignBlocks and satReassignBlocksCB. This sends ATA write command. 16752 * 16753 * \param tiRoot: Pointer to TISA initiator driver/port instance. 16754 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 16755 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 16756 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 16757 * \param satIOContext_t: Pointer to the SAT IO Context 16758 * \param LBA: Pointer to the LBA to be processed 16759 * 16760 * \return If command is started successfully 16761 * - \e tiSuccess: I/O request successfully initiated. 16762 * - \e tiBusy: No resources available, try again later. 16763 * - \e tiIONoDevice: Invalid device handle. 16764 * - \e tiError: Other errors. 16765 */ 16766 /*****************************************************************************/ 16767 /* current LBA; sends WRITE */ 16768 GLOBAL bit32 satReassignBlocks_2( 16769 tiRoot_t *tiRoot, 16770 tiIORequest_t *tiIORequest, 16771 tiDeviceHandle_t *tiDeviceHandle, 16772 tiScsiInitiatorRequest_t *tiScsiRequest, 16773 satIOContext_t *satIOContext, 16774 bit8 *LBA 16775 ) 16776 { 16777 /* 16778 assumes all LBA fits in ATA command; no boundary condition is checked here yet 16779 tiScsiRequest is TD generated for writing 16780 */ 16781 bit32 status; 16782 bit32 agRequestType; 16783 satDeviceData_t *pSatDevData; 16784 scsiRspSense_t *pSense; 16785 agsaFisRegHostToDevice_t *fis; 16786 16787 pSense = satIOContext->pSense; 16788 pSatDevData = satIOContext->pSatDevData; 16789 fis = satIOContext->pFis; 16790 16791 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 16792 { 16793 /* case 2 */ 16794 /* WRITE DMA*/ 16795 /* can't fit the transfer length */ 16796 TI_DBG5(("satReassignBlocks_2: case 2\n")); 16797 fis->h.fisType = 0x27; /* Reg host to device */ 16798 fis->h.c_pmPort = 0x80; /* C bit is set */ 16799 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 16800 fis->h.features = 0; /* FIS reserve */ 16801 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 16802 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 16803 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 16804 16805 /* FIS LBA mode set LBA (27:24) */ 16806 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF)); 16807 16808 fis->d.lbaLowExp = 0; 16809 fis->d.lbaMidExp = 0; 16810 fis->d.lbaHighExp = 0; 16811 fis->d.featuresExp = 0; 16812 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 16813 fis->d.sectorCountExp = 0; 16814 fis->d.reserved4 = 0; 16815 fis->d.control = 0; /* FIS HOB bit clear */ 16816 fis->d.reserved5 = 0; 16817 16818 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 16819 satIOContext->ATACmd = SAT_WRITE_DMA; 16820 } 16821 else 16822 { 16823 /* case 1 */ 16824 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 16825 /* WRITE SECTORS for easier implemetation */ 16826 /* can't fit the transfer length */ 16827 TI_DBG5(("satReassignBlocks_2: case 1\n")); 16828 fis->h.fisType = 0x27; /* Reg host to device */ 16829 fis->h.c_pmPort = 0x80; /* C bit is set */ 16830 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 16831 fis->h.features = 0; /* FIS reserve */ 16832 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 16833 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 16834 fis->d.lbaHigh = LBA[7]; /* FIS LBA (23:16) */ 16835 16836 /* FIS LBA mode set LBA (27:24) */ 16837 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF)); 16838 16839 fis->d.lbaLowExp = 0; 16840 fis->d.lbaMidExp = 0; 16841 fis->d.lbaHighExp = 0; 16842 fis->d.featuresExp = 0; 16843 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 16844 fis->d.sectorCountExp = 0; 16845 fis->d.reserved4 = 0; 16846 fis->d.control = 0; /* FIS HOB bit clear */ 16847 fis->d.reserved5 = 0; 16848 16849 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 16850 satIOContext->ATACmd = SAT_WRITE_SECTORS; 16851 } 16852 16853 /* case 3 and 4 */ 16854 if (pSatDevData->sat48BitSupport == agTRUE) 16855 { 16856 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 16857 { 16858 /* case 3 */ 16859 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 16860 TI_DBG5(("satReassignBlocks_2: case 3\n")); 16861 fis->h.fisType = 0x27; /* Reg host to device */ 16862 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16863 16864 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 16865 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 16866 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 16867 16868 fis->h.features = 0; /* FIS reserve */ 16869 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 16870 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 16871 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 16872 fis->d.device = 0x40; /* FIS LBA mode set */ 16873 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */ 16874 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */ 16875 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */ 16876 fis->d.featuresExp = 0; /* FIS reserve */ 16877 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 16878 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 16879 fis->d.reserved4 = 0; 16880 fis->d.control = 0; /* FIS HOB bit clear */ 16881 fis->d.reserved5 = 0; 16882 16883 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 16884 } 16885 else 16886 { 16887 /* case 4 */ 16888 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 16889 /* WRITE SECTORS EXT for easier implemetation */ 16890 TI_DBG5(("satReassignBlocks_2: case 4\n")); 16891 fis->h.fisType = 0x27; /* Reg host to device */ 16892 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16893 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 16894 16895 fis->h.features = 0; /* FIS reserve */ 16896 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 16897 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 16898 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 16899 fis->d.device = 0x40; /* FIS LBA mode set */ 16900 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */ 16901 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */ 16902 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */ 16903 fis->d.featuresExp = 0; /* FIS reserve */ 16904 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 16905 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 16906 fis->d.reserved4 = 0; 16907 fis->d.control = 0; /* FIS HOB bit clear */ 16908 fis->d.reserved5 = 0; 16909 16910 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 16911 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 16912 } 16913 } 16914 /* case 5 */ 16915 if (pSatDevData->satNCQ == agTRUE) 16916 { 16917 /* WRITE FPDMA QUEUED */ 16918 if (pSatDevData->sat48BitSupport != agTRUE) 16919 { 16920 TI_DBG5(("satReassignBlocks_2: case 5 !!! error NCQ but 28 bit address support \n")); 16921 satSetSensePayload( pSense, 16922 SCSI_SNSKEY_HARDWARE_ERROR, 16923 0, 16924 SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED, 16925 satIOContext); 16926 16927 ostiInitiatorIOCompleted( tiRoot, 16928 tiIORequest, 16929 tiIOSuccess, 16930 SCSI_STAT_CHECK_CONDITION, 16931 satIOContext->pTiSenseData, 16932 satIOContext->interruptContext ); 16933 return tiSuccess; 16934 } 16935 TI_DBG6(("satWrite10: case 5\n")); 16936 16937 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 16938 16939 fis->h.fisType = 0x27; /* Reg host to device */ 16940 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16941 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 16942 fis->h.features = 1; /* FIS sector count (7:0) */ 16943 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 16944 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 16945 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 16946 16947 /* Check FUA bit */ 16948 fis->d.device = 0x40; /* FIS FUA clear */ 16949 16950 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */ 16951 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */ 16952 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */ 16953 fis->d.featuresExp = 0; /* FIS sector count (15:8) */ 16954 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 16955 fis->d.sectorCountExp = 0; 16956 fis->d.reserved4 = 0; 16957 fis->d.control = 0; /* FIS HOB bit clear */ 16958 fis->d.reserved5 = 0; 16959 16960 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 16961 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 16962 } 16963 16964 satIOContext->satCompleteCB = &satReassignBlocksCB; 16965 16966 /* 16967 * Prepare SGL and send FIS to LL layer. 16968 */ 16969 satIOContext->reqType = agRequestType; /* Save it */ 16970 16971 status = sataLLIOStart( tiRoot, 16972 tiIORequest, 16973 tiDeviceHandle, 16974 /* not the original, should be the TD generated one */ 16975 tiScsiRequest, 16976 satIOContext); 16977 return (status); 16978 } 16979 16980 16981 /*****************************************************************************/ 16982 /*! \brief SAT implementation for SCSI satPrepareNewIO. 16983 * 16984 * This function fills in the fields of internal IO generated by TD layer. 16985 * This is mostly used in the callback functions. 16986 * 16987 * \param satNewIntIo: Pointer to the internal IO structure. 16988 * \param tiOrgIORequest: Pointer to the original tiIOrequest sent by OS layer 16989 * \param satDevData: Pointer to the device data. 16990 * \param scsiCmnd: Pointer to SCSI command. 16991 * \param satOrgIOContext: Pointer to the original SAT IO Context 16992 * 16993 * \return 16994 * - \e Pointer to the new SAT IO Context 16995 */ 16996 /*****************************************************************************/ 16997 GLOBAL satIOContext_t *satPrepareNewIO( 16998 satInternalIo_t *satNewIntIo, 16999 tiIORequest_t *tiOrgIORequest, 17000 satDeviceData_t *satDevData, 17001 tiIniScsiCmnd_t *scsiCmnd, 17002 satIOContext_t *satOrgIOContext 17003 ) 17004 { 17005 satIOContext_t *satNewIOContext; 17006 tdIORequestBody_t *tdNewIORequestBody; 17007 17008 TI_DBG2(("satPrepareNewIO: start\n")); 17009 17010 /* the one to be used; good 8/2/07 */ 17011 satNewIntIo->satOrgTiIORequest = tiOrgIORequest; /* this is already done in 17012 satAllocIntIoResource() */ 17013 17014 tdNewIORequestBody = (tdIORequestBody_t *)satNewIntIo->satIntRequestBody; 17015 satNewIOContext = &(tdNewIORequestBody->transport.SATA.satIOContext); 17016 17017 satNewIOContext->pSatDevData = satDevData; 17018 satNewIOContext->pFis = &(tdNewIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 17019 satNewIOContext->pScsiCmnd = &(satNewIntIo->satIntTiScsiXchg.scsiCmnd); 17020 if (scsiCmnd != agNULL) 17021 { 17022 /* saves only CBD; not scsi command for LBA and number of blocks */ 17023 osti_memcpy(satNewIOContext->pScsiCmnd->cdb, scsiCmnd->cdb, 16); 17024 } 17025 satNewIOContext->pSense = &(tdNewIORequestBody->transport.SATA.sensePayload); 17026 satNewIOContext->pTiSenseData = &(tdNewIORequestBody->transport.SATA.tiSenseData); 17027 satNewIOContext->pTiSenseData->senseData = satNewIOContext->pSense; 17028 satNewIOContext->tiRequestBody = satNewIntIo->satIntRequestBody; 17029 satNewIOContext->interruptContext = satNewIOContext->interruptContext; 17030 satNewIOContext->satIntIoContext = satNewIntIo; 17031 satNewIOContext->ptiDeviceHandle = satOrgIOContext->ptiDeviceHandle; 17032 satNewIOContext->satOrgIOContext = satOrgIOContext; 17033 /* saves tiScsiXchg; only for writesame10() */ 17034 satNewIOContext->tiScsiXchg = satOrgIOContext->tiScsiXchg; 17035 17036 return satNewIOContext; 17037 } 17038 /***************************************************************************** 17039 *! \brief satIOAbort 17040 * 17041 * This routine is called to initiate a I/O abort to SATL. 17042 * This routine is independent of HW/LL API. 17043 * 17044 * \param tiRoot: Pointer to TISA initiator driver/port instance. 17045 * \param taskTag: Pointer to TISA I/O request context/tag to be aborted. 17046 * 17047 * \return: 17048 * 17049 * \e tiSuccess: I/O request successfully initiated. 17050 * \e tiBusy: No resources available, try again later. 17051 * \e tiError: Other errors that prevent the I/O request to be started. 17052 * 17053 * 17054 *****************************************************************************/ 17055 GLOBAL bit32 satIOAbort( 17056 tiRoot_t *tiRoot, 17057 tiIORequest_t *taskTag ) 17058 { 17059 17060 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 17061 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 17062 agsaRoot_t *agRoot; 17063 tdIORequestBody_t *tdIORequestBody; 17064 tdIORequestBody_t *tdIONewRequestBody; 17065 agsaIORequest_t *agIORequest; 17066 bit32 status; 17067 agsaIORequest_t *agAbortIORequest; 17068 tdIORequestBody_t *tdAbortIORequestBody; 17069 bit32 PhysUpper32; 17070 bit32 PhysLower32; 17071 bit32 memAllocStatus; 17072 void *osMemHandle; 17073 satIOContext_t *satIOContext; 17074 satInternalIo_t *satIntIo; 17075 17076 TI_DBG2(("satIOAbort: start\n")); 17077 17078 agRoot = &(tdsaAllShared->agRootNonInt); 17079 tdIORequestBody = (tdIORequestBody_t *)taskTag->tdData; 17080 17081 /* needs to distinguish internally generated or externally generated */ 17082 satIOContext = &(tdIORequestBody->transport.SATA.satIOContext); 17083 satIntIo = satIOContext->satIntIoContext; 17084 if (satIntIo == agNULL) 17085 { 17086 TI_DBG1(("satIOAbort: External, OS generated\n")); 17087 agIORequest = &(tdIORequestBody->agIORequest); 17088 } 17089 else 17090 { 17091 TI_DBG1(("satIOAbort: Internal, TD generated\n")); 17092 tdIONewRequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody; 17093 agIORequest = &(tdIONewRequestBody->agIORequest); 17094 } 17095 17096 /* allocating agIORequest for abort itself */ 17097 memAllocStatus = ostiAllocMemory( 17098 tiRoot, 17099 &osMemHandle, 17100 (void **)&tdAbortIORequestBody, 17101 &PhysUpper32, 17102 &PhysLower32, 17103 8, 17104 sizeof(tdIORequestBody_t), 17105 agTRUE 17106 ); 17107 if (memAllocStatus != tiSuccess) 17108 { 17109 /* let os process IO */ 17110 TI_DBG1(("satIOAbort: ostiAllocMemory failed...\n")); 17111 return tiError; 17112 } 17113 17114 if (tdAbortIORequestBody == agNULL) 17115 { 17116 /* let os process IO */ 17117 TI_DBG1(("satIOAbort: ostiAllocMemory returned NULL tdAbortIORequestBody\n")); 17118 return tiError; 17119 } 17120 17121 /* setup task management structure */ 17122 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 17123 tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle; 17124 17125 /* initialize agIORequest */ 17126 agAbortIORequest = &(tdAbortIORequestBody->agIORequest); 17127 agAbortIORequest->osData = (void *) tdAbortIORequestBody; 17128 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */ 17129 17130 /* remember IO to be aborted */ 17131 tdAbortIORequestBody->tiIOToBeAbortedRequest = taskTag; 17132 17133 status = saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agIORequest, agNULL ); 17134 17135 TI_DBG5(("satIOAbort: return status=0x%x\n", status)); 17136 17137 if (status == AGSA_RC_SUCCESS) 17138 return tiSuccess; 17139 else 17140 return tiError; 17141 17142 } 17143 17144 17145 /***************************************************************************** 17146 *! \brief satTM 17147 * 17148 * This routine is called to initiate a TM request to SATL. 17149 * This routine is independent of HW/LL API. 17150 * 17151 * \param tiRoot: Pointer to TISA initiator driver/port instance. 17152 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 17153 * \param task: SAM-3 task management request. 17154 * \param lun: Pointer to LUN. 17155 * \param taskTag: Pointer to the associated task where the TM 17156 * command is to be applied. 17157 * \param currentTaskTag: Pointer to tag/context for this TM request. 17158 * 17159 * \return: 17160 * 17161 * \e tiSuccess: I/O request successfully initiated. 17162 * \e tiBusy: No resources available, try again later. 17163 * \e tiIONoDevice: Invalid device handle. 17164 * \e tiError: Other errors that prevent the I/O request to be started. 17165 * 17166 * 17167 *****************************************************************************/ 17168 /* save task in satIOContext */ 17169 osGLOBAL bit32 satTM( 17170 tiRoot_t *tiRoot, 17171 tiDeviceHandle_t *tiDeviceHandle, 17172 bit32 task, 17173 tiLUN_t *lun, 17174 tiIORequest_t *taskTag, 17175 tiIORequest_t *currentTaskTag, 17176 tdIORequestBody_t *tiRequestBody, 17177 bit32 NotifyOS 17178 ) 17179 { 17180 tdIORequestBody_t *tdIORequestBody = agNULL; 17181 satIOContext_t *satIOContext = agNULL; 17182 tdsaDeviceData_t *oneDeviceData = agNULL; 17183 bit32 status; 17184 17185 TI_DBG3(("satTM: tiDeviceHandle=%p task=0x%x\n", tiDeviceHandle, task )); 17186 17187 /* set satIOContext fields and etc */ 17188 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 17189 17190 17191 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody; 17192 satIOContext = &(tdIORequestBody->transport.SATA.satIOContext); 17193 17194 satIOContext->pSatDevData = &oneDeviceData->satDevData; 17195 satIOContext->pFis = 17196 &tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev; 17197 17198 17199 satIOContext->tiRequestBody = tiRequestBody; 17200 satIOContext->ptiDeviceHandle = tiDeviceHandle; 17201 satIOContext->satIntIoContext = agNULL; 17202 satIOContext->satOrgIOContext = agNULL; 17203 17204 /* followings are used only for internal IO */ 17205 satIOContext->currentLBA = 0; 17206 satIOContext->OrgTL = 0; 17207 17208 /* saving task in satIOContext */ 17209 satIOContext->TMF = task; 17210 17211 satIOContext->satToBeAbortedIOContext = agNULL; 17212 17213 if (NotifyOS == agTRUE) 17214 { 17215 satIOContext->NotifyOS = agTRUE; 17216 } 17217 else 17218 { 17219 satIOContext->NotifyOS = agFALSE; 17220 } 17221 /* 17222 * Our SAT supports RESET LUN and partially support ABORT TASK (only if there 17223 * is no more than one I/O pending on the drive. 17224 */ 17225 17226 if (task == AG_LOGICAL_UNIT_RESET) 17227 { 17228 status = satTmResetLUN( tiRoot, 17229 currentTaskTag, 17230 tiDeviceHandle, 17231 agNULL, 17232 satIOContext, 17233 lun); 17234 return status; 17235 } 17236 #ifdef TO_BE_REMOVED 17237 else if (task == AG_TARGET_WARM_RESET) 17238 { 17239 status = satTmWarmReset( tiRoot, 17240 currentTaskTag, 17241 tiDeviceHandle, 17242 agNULL, 17243 satIOContext); 17244 17245 return status; 17246 } 17247 #endif 17248 else if (task == AG_ABORT_TASK) 17249 { 17250 status = satTmAbortTask( tiRoot, 17251 currentTaskTag, 17252 tiDeviceHandle, 17253 agNULL, 17254 satIOContext, 17255 taskTag); 17256 17257 return status; 17258 } 17259 else if (task == TD_INTERNAL_TM_RESET) 17260 { 17261 status = satTDInternalTmReset( tiRoot, 17262 currentTaskTag, 17263 tiDeviceHandle, 17264 agNULL, 17265 satIOContext); 17266 return status; 17267 } 17268 else 17269 { 17270 TI_DBG1(("satTM: tiDeviceHandle=%p UNSUPPORTED TM task=0x%x\n", 17271 tiDeviceHandle, task )); 17272 17273 /* clean up TD layer's IORequestBody */ 17274 ostiFreeMemory( 17275 tiRoot, 17276 tiRequestBody->IOType.InitiatorTMIO.osMemHandle, 17277 sizeof(tdIORequestBody_t) 17278 ); 17279 return tiError; 17280 } 17281 17282 } 17283 17284 17285 /***************************************************************************** 17286 *! \brief satTmResetLUN 17287 * 17288 * This routine is called to initiate a TM RESET LUN request to SATL. 17289 * This routine is independent of HW/LL API. 17290 * 17291 * \param tiRoot: Pointer to TISA initiator driver/port instance. 17292 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 17293 * \param lun: Pointer to LUN. 17294 * \param currentTaskTag: Pointer to tag/context for this TM request. 17295 * 17296 * \return: 17297 * 17298 * \e tiSuccess: I/O request successfully initiated. 17299 * \e tiBusy: No resources available, try again later. 17300 * \e tiIONoDevice: Invalid device handle. 17301 * \e tiError: Other errors that prevent the I/O request to be started. 17302 * 17303 * 17304 *****************************************************************************/ 17305 osGLOBAL bit32 satTmResetLUN( 17306 tiRoot_t *tiRoot, 17307 tiIORequest_t *tiIORequest, /* current task tag */ 17308 tiDeviceHandle_t *tiDeviceHandle, 17309 tiScsiInitiatorRequest_t *tiScsiRequest, 17310 satIOContext_t *satIOContext, 17311 tiLUN_t *lun) 17312 { 17313 17314 tdsaDeviceData_t *tdsaDeviceData; 17315 satDeviceData_t *satDevData; 17316 17317 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 17318 satDevData = &tdsaDeviceData->satDevData; 17319 17320 TI_DBG1(("satTmResetLUN: tiDeviceHandle=%p.\n", tiDeviceHandle )); 17321 17322 /* 17323 * Only support LUN 0 17324 */ 17325 if ( (lun->lun[0] | lun->lun[1] | lun->lun[2] | lun->lun[3] | 17326 lun->lun[4] | lun->lun[5] | lun->lun[6] | lun->lun[7] ) != 0 ) 17327 { 17328 TI_DBG1(("satTmResetLUN: *** REJECT *** LUN not zero, tiDeviceHandle=%p\n", 17329 tiDeviceHandle)); 17330 return tiError; 17331 } 17332 17333 /* 17334 * Check if there is other TM request pending 17335 */ 17336 if (satDevData->satTmTaskTag != agNULL) 17337 { 17338 TI_DBG1(("satTmResetLUN: *** REJECT *** other TM pending, tiDeviceHandle=%p\n", 17339 tiDeviceHandle)); 17340 return tiError; 17341 } 17342 17343 /* 17344 * Save tiIORequest, will be returned at device reset completion to return 17345 * the TM completion. 17346 */ 17347 satDevData->satTmTaskTag = tiIORequest; 17348 17349 /* 17350 * Set flag to indicate device in recovery mode. 17351 */ 17352 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY; 17353 17354 /* 17355 * Issue SATA device reset. Set flag to indicate NOT to automatically abort 17356 * at the completion of SATA device reset. 17357 */ 17358 satDevData->satAbortAfterReset = agFALSE; 17359 17360 /* SAT rev8 6.3.6 p22 */ 17361 satStartResetDevice( 17362 tiRoot, 17363 tiIORequest, /* currentTaskTag */ 17364 tiDeviceHandle, 17365 tiScsiRequest, 17366 satIOContext 17367 ); 17368 17369 17370 return tiSuccess; 17371 17372 } 17373 17374 /***************************************************************************** 17375 *! \brief satTmWarmReset 17376 * 17377 * This routine is called to initiate a TM warm RESET request to SATL. 17378 * This routine is independent of HW/LL API. 17379 * 17380 * \param tiRoot: Pointer to TISA initiator driver/port instance. 17381 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 17382 * \param currentTaskTag: Pointer to tag/context for this TM request. 17383 * 17384 * \return: 17385 * 17386 * \e tiSuccess: I/O request successfully initiated. 17387 * \e tiBusy: No resources available, try again later. 17388 * \e tiIONoDevice: Invalid device handle. 17389 * \e tiError: Other errors that prevent the I/O request to be started. 17390 * 17391 * 17392 *****************************************************************************/ 17393 osGLOBAL bit32 satTmWarmReset( 17394 tiRoot_t *tiRoot, 17395 tiIORequest_t *tiIORequest, /* current task tag */ 17396 tiDeviceHandle_t *tiDeviceHandle, 17397 tiScsiInitiatorRequest_t *tiScsiRequest, 17398 satIOContext_t *satIOContext) 17399 { 17400 17401 tdsaDeviceData_t *tdsaDeviceData; 17402 satDeviceData_t *satDevData; 17403 17404 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 17405 satDevData = &tdsaDeviceData->satDevData; 17406 17407 TI_DBG1(("satTmWarmReset: tiDeviceHandle=%p.\n", tiDeviceHandle )); 17408 17409 /* 17410 * Check if there is other TM request pending 17411 */ 17412 if (satDevData->satTmTaskTag != agNULL) 17413 { 17414 TI_DBG1(("satTmWarmReset: *** REJECT *** other TM pending, tiDeviceHandle=%p\n", 17415 tiDeviceHandle)); 17416 return tiError; 17417 } 17418 17419 /* 17420 * Save tiIORequest, will be returned at device reset completion to return 17421 * the TM completion. 17422 */ 17423 satDevData->satTmTaskTag = tiIORequest; 17424 17425 /* 17426 * Set flag to indicate device in recovery mode. 17427 */ 17428 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY; 17429 17430 /* 17431 * Issue SATA device reset. Set flag to indicate NOT to automatically abort 17432 * at the completion of SATA device reset. 17433 */ 17434 satDevData->satAbortAfterReset = agFALSE; 17435 17436 /* SAT rev8 6.3.6 p22 */ 17437 satStartResetDevice( 17438 tiRoot, 17439 tiIORequest, /* currentTaskTag */ 17440 tiDeviceHandle, 17441 tiScsiRequest, 17442 satIOContext 17443 ); 17444 17445 return tiSuccess; 17446 17447 } 17448 17449 osGLOBAL bit32 satTDInternalTmReset( 17450 tiRoot_t *tiRoot, 17451 tiIORequest_t *tiIORequest, /* current task tag */ 17452 tiDeviceHandle_t *tiDeviceHandle, 17453 tiScsiInitiatorRequest_t *tiScsiRequest, 17454 satIOContext_t *satIOContext) 17455 { 17456 17457 tdsaDeviceData_t *tdsaDeviceData; 17458 satDeviceData_t *satDevData; 17459 17460 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 17461 satDevData = &tdsaDeviceData->satDevData; 17462 17463 TI_DBG1(("satTmWarmReset: tiDeviceHandle=%p.\n", tiDeviceHandle )); 17464 17465 /* 17466 * Check if there is other TM request pending 17467 */ 17468 if (satDevData->satTmTaskTag != agNULL) 17469 { 17470 TI_DBG1(("satTmWarmReset: *** REJECT *** other TM pending, tiDeviceHandle=%p\n", 17471 tiDeviceHandle)); 17472 return tiError; 17473 } 17474 17475 /* 17476 * Save tiIORequest, will be returned at device reset completion to return 17477 * the TM completion. 17478 */ 17479 satDevData->satTmTaskTag = tiIORequest; 17480 17481 /* 17482 * Set flag to indicate device in recovery mode. 17483 */ 17484 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY; 17485 17486 /* 17487 * Issue SATA device reset. Set flag to indicate NOT to automatically abort 17488 * at the completion of SATA device reset. 17489 */ 17490 satDevData->satAbortAfterReset = agFALSE; 17491 17492 /* SAT rev8 6.3.6 p22 */ 17493 satStartResetDevice( 17494 tiRoot, 17495 tiIORequest, /* currentTaskTag */ 17496 tiDeviceHandle, 17497 tiScsiRequest, 17498 satIOContext 17499 ); 17500 17501 return tiSuccess; 17502 17503 } 17504 17505 /***************************************************************************** 17506 *! \brief satTmAbortTask 17507 * 17508 * This routine is called to initiate a TM ABORT TASK request to SATL. 17509 * This routine is independent of HW/LL API. 17510 * 17511 * \param tiRoot: Pointer to TISA initiator driver/port instance. 17512 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 17513 * \param taskTag: Pointer to the associated task where the TM 17514 * command is to be applied. 17515 * \param currentTaskTag: Pointer to tag/context for this TM request. 17516 * 17517 * \return: 17518 * 17519 * \e tiSuccess: I/O request successfully initiated. 17520 * \e tiBusy: No resources available, try again later. 17521 * \e tiIONoDevice: Invalid device handle. 17522 * \e tiError: Other errors that prevent the I/O request to be started. 17523 * 17524 * 17525 *****************************************************************************/ 17526 osGLOBAL bit32 satTmAbortTask( 17527 tiRoot_t *tiRoot, 17528 tiIORequest_t *tiIORequest, /* current task tag */ 17529 tiDeviceHandle_t *tiDeviceHandle, 17530 tiScsiInitiatorRequest_t *tiScsiRequest, /* NULL */ 17531 satIOContext_t *satIOContext, 17532 tiIORequest_t *taskTag) 17533 { 17534 17535 tdsaDeviceData_t *tdsaDeviceData; 17536 satDeviceData_t *satDevData; 17537 satIOContext_t *satTempIOContext = agNULL; 17538 tdIORequestBody_t *tdIORequestBody; 17539 tdIORequestBody_t *TMtdIORequestBody; 17540 tdList_t *elementHdr; 17541 bit32 found = agFALSE; 17542 tiIORequest_t *tiIOReq; 17543 17544 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 17545 satDevData = &tdsaDeviceData->satDevData; 17546 TMtdIORequestBody = (tdIORequestBody_t *)tiIORequest->tdData; 17547 17548 TI_DBG1(("satTmAbortTask: tiDeviceHandle=%p taskTag=%p.\n", tiDeviceHandle, taskTag )); 17549 /* 17550 * Check if there is other TM request pending 17551 */ 17552 if (satDevData->satTmTaskTag != agNULL) 17553 { 17554 TI_DBG1(("satTmAbortTask: REJECT other TM pending, tiDeviceHandle=%p\n", 17555 tiDeviceHandle)); 17556 /* clean up TD layer's IORequestBody */ 17557 ostiFreeMemory( 17558 tiRoot, 17559 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle, 17560 sizeof(tdIORequestBody_t) 17561 ); 17562 return tiError; 17563 } 17564 17565 #ifdef REMOVED 17566 /* 17567 * Check if there is only one I/O pending. 17568 */ 17569 if (satDevData->satPendingIO > 0) 17570 { 17571 TI_DBG1(("satTmAbortTask: REJECT num pending I/O, tiDeviceHandle=%p, satPendingIO=0x%x\n", 17572 tiDeviceHandle, satDevData->satPendingIO)); 17573 /* clean up TD layer's IORequestBody */ 17574 ostiFreeMemory( 17575 tiRoot, 17576 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle, 17577 sizeof(tdIORequestBody_t) 17578 ); 17579 17580 return tiError; 17581 } 17582 #endif 17583 17584 /* 17585 * Check that the only pending I/O matches taskTag. If not return tiError. 17586 */ 17587 elementHdr = satDevData->satIoLinkList.flink; 17588 17589 while (elementHdr != &satDevData->satIoLinkList) 17590 { 17591 satTempIOContext = TDLIST_OBJECT_BASE( satIOContext_t, 17592 satIoContextLink, 17593 elementHdr ); 17594 17595 tdIORequestBody = (tdIORequestBody_t *) satTempIOContext->tiRequestBody; 17596 tiIOReq = tdIORequestBody->tiIORequest; 17597 17598 elementHdr = elementHdr->flink; /* for the next while loop */ 17599 17600 /* 17601 * Check if the tag matches 17602 */ 17603 if ( tiIOReq == taskTag) 17604 { 17605 found = agTRUE; 17606 satIOContext->satToBeAbortedIOContext = satTempIOContext; 17607 TI_DBG1(("satTmAbortTask: found matching tag.\n")); 17608 17609 break; 17610 17611 } /* if matching tag */ 17612 17613 } /* while loop */ 17614 17615 17616 if (found == agFALSE ) 17617 { 17618 TI_DBG1(("satTmAbortTask: *** REJECT *** no match, tiDeviceHandle=%p\n", 17619 tiDeviceHandle )); 17620 17621 /* clean up TD layer's IORequestBody */ 17622 ostiFreeMemory( 17623 tiRoot, 17624 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle, 17625 sizeof(tdIORequestBody_t) 17626 ); 17627 17628 return tiError; 17629 } 17630 17631 /* 17632 * Save tiIORequest, will be returned at device reset completion to return 17633 * the TM completion. 17634 */ 17635 satDevData->satTmTaskTag = tiIORequest; 17636 17637 /* 17638 * Set flag to indicate device in recovery mode. 17639 */ 17640 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY; 17641 17642 17643 /* 17644 * Issue SATA device reset or check power mode. Set flag to to automatically abort 17645 * at the completion of SATA device reset. 17646 * SAT r09 p25 17647 */ 17648 satDevData->satAbortAfterReset = agTRUE; 17649 17650 if ( (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) || 17651 (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) 17652 ) 17653 { 17654 TI_DBG1(("satTmAbortTask: calling satStartCheckPowerMode\n")); 17655 /* send check power mode */ 17656 satStartCheckPowerMode( 17657 tiRoot, 17658 tiIORequest, /* currentTaskTag */ 17659 tiDeviceHandle, 17660 tiScsiRequest, 17661 satIOContext 17662 ); 17663 } 17664 else 17665 { 17666 TI_DBG1(("satTmAbortTask: calling satStartResetDevice\n")); 17667 /* send AGSA_SATA_PROTOCOL_SRST_ASSERT */ 17668 satStartResetDevice( 17669 tiRoot, 17670 tiIORequest, /* currentTaskTag */ 17671 tiDeviceHandle, 17672 tiScsiRequest, 17673 satIOContext 17674 ); 17675 } 17676 17677 17678 return tiSuccess; 17679 } 17680 17681 /***************************************************************************** 17682 *! \brief osSatResetCB 17683 * 17684 * This routine is called to notify the completion of SATA device reset 17685 * which was initiated previously through the call to sataLLReset(). 17686 * This routine is independent of HW/LL API. 17687 * 17688 * \param tiRoot: Pointer to TISA initiator driver/port instance. 17689 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 17690 * \param resetStatus: Reset status either tiSuccess or tiError. 17691 * \param respFis: Pointer to the Register Device-To-Host FIS 17692 * received from the device. 17693 * 17694 * \return: None 17695 * 17696 *****************************************************************************/ 17697 osGLOBAL void osSatResetCB( 17698 tiRoot_t *tiRoot, 17699 tiDeviceHandle_t *tiDeviceHandle, 17700 bit32 resetStatus, 17701 void *respFis) 17702 { 17703 17704 agsaRoot_t *agRoot; 17705 tdsaDeviceData_t *tdsaDeviceData; 17706 satDeviceData_t *satDevData; 17707 satIOContext_t *satIOContext; 17708 tdIORequestBody_t *tdIORequestBodyTmp; 17709 tdList_t *elementHdr; 17710 agsaIORequest_t *agAbortIORequest; 17711 tdIORequestBody_t *tdAbortIORequestBody; 17712 bit32 PhysUpper32; 17713 bit32 PhysLower32; 17714 bit32 memAllocStatus; 17715 void *osMemHandle; 17716 17717 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 17718 agRoot = tdsaDeviceData->agRoot; 17719 satDevData = &tdsaDeviceData->satDevData; 17720 17721 TI_DBG5(("osSatResetCB: tiDeviceHandle=%p resetStatus=0x%x\n", 17722 tiDeviceHandle, resetStatus )); 17723 17724 /* We may need to check FIS to check device operating condition */ 17725 17726 17727 /* 17728 * Check if need to abort all pending I/Os 17729 */ 17730 if ( satDevData->satAbortAfterReset == agTRUE ) 17731 { 17732 /* 17733 * Issue abort to LL layer to all other pending I/Os for the same SATA drive 17734 */ 17735 elementHdr = satDevData->satIoLinkList.flink; 17736 while (elementHdr != &satDevData->satIoLinkList) 17737 { 17738 satIOContext = TDLIST_OBJECT_BASE( satIOContext_t, 17739 satIoContextLink, 17740 elementHdr ); 17741 17742 tdIORequestBodyTmp = (tdIORequestBody_t *)satIOContext->tiRequestBody; 17743 17744 /* 17745 * Issue abort 17746 */ 17747 TI_DBG5(("osSatResetCB: issuing ABORT tiDeviceHandle=%p agIORequest=%p\n", 17748 tiDeviceHandle, &tdIORequestBodyTmp->agIORequest )); 17749 17750 /* allocating agIORequest for abort itself */ 17751 memAllocStatus = ostiAllocMemory( 17752 tiRoot, 17753 &osMemHandle, 17754 (void **)&tdAbortIORequestBody, 17755 &PhysUpper32, 17756 &PhysLower32, 17757 8, 17758 sizeof(tdIORequestBody_t), 17759 agTRUE 17760 ); 17761 17762 if (memAllocStatus != tiSuccess) 17763 { 17764 /* let os process IO */ 17765 TI_DBG1(("osSatResetCB: ostiAllocMemory failed...\n")); 17766 return; 17767 } 17768 17769 if (tdAbortIORequestBody == agNULL) 17770 { 17771 /* let os process IO */ 17772 TI_DBG1(("osSatResetCB: ostiAllocMemory returned NULL tdAbortIORequestBody\n")); 17773 return; 17774 } 17775 /* setup task management structure */ 17776 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 17777 tdAbortIORequestBody->tiDevHandle = tiDeviceHandle; 17778 17779 /* initialize agIORequest */ 17780 agAbortIORequest = &(tdAbortIORequestBody->agIORequest); 17781 agAbortIORequest->osData = (void *) tdAbortIORequestBody; 17782 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */ 17783 17784 saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, &(tdIORequestBodyTmp->agIORequest), agNULL ); 17785 elementHdr = elementHdr->flink; /* for the next while loop */ 17786 17787 } /* while */ 17788 17789 /* Reset flag */ 17790 satDevData->satAbortAfterReset = agFALSE; 17791 17792 } 17793 17794 17795 /* 17796 * Check if the device reset if the result of TM request. 17797 */ 17798 if ( satDevData->satTmTaskTag != agNULL ) 17799 { 17800 TI_DBG5(("osSatResetCB: calling TM completion tiDeviceHandle=%p satTmTaskTag=%p\n", 17801 tiDeviceHandle, satDevData->satTmTaskTag )); 17802 17803 ostiInitiatorEvent( tiRoot, 17804 agNULL, /* portalContext not used */ 17805 tiDeviceHandle, 17806 tiIntrEventTypeTaskManagement, 17807 tiTMOK, 17808 satDevData->satTmTaskTag); 17809 /* 17810 * Reset flag 17811 */ 17812 satDevData->satTmTaskTag = agNULL; 17813 } 17814 17815 } 17816 17817 17818 /***************************************************************************** 17819 *! \brief osSatIOCompleted 17820 * 17821 * This routine is a callback for SATA completion that required FIS status 17822 * translation to SCSI status. 17823 * 17824 * \param tiRoot: Pointer to TISA initiator driver/port instance. 17825 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 17826 * \param respFis: Pointer to status FIS to read. 17827 * \param respFisLen: Length of response FIS to read. 17828 * \param satIOContext: Pointer to SAT context. 17829 * \param interruptContext: Interrupt context 17830 * 17831 * \return: None 17832 * 17833 *****************************************************************************/ 17834 osGLOBAL void osSatIOCompleted( 17835 tiRoot_t *tiRoot, 17836 tiIORequest_t *tiIORequest, 17837 agsaFisHeader_t *agFirstDword, 17838 bit32 respFisLen, 17839 agsaFrameHandle_t agFrameHandle, 17840 satIOContext_t *satIOContext, 17841 bit32 interruptContext) 17842 17843 { 17844 satDeviceData_t *pSatDevData; 17845 scsiRspSense_t *pSense; 17846 #ifdef TD_DEBUG_ENABLE 17847 tiIniScsiCmnd_t *pScsiCmnd; 17848 #endif 17849 agsaFisRegHostToDevice_t *hostToDevFis = agNULL; 17850 bit32 ataStatus = 0; 17851 bit32 ataError; 17852 satInternalIo_t *satIntIo = agNULL; 17853 bit32 status; 17854 tiDeviceHandle_t *tiDeviceHandle; 17855 satIOContext_t *satIOContext2; 17856 tdIORequestBody_t *tdIORequestBody; 17857 agsaFisRegD2HHeader_t *statDevToHostFisHeader = agNULL; 17858 agsaFisSetDevBitsHeader_t *statSetDevBitFisHeader = agNULL; 17859 tiIORequest_t tiIORequestTMP; 17860 17861 pSense = satIOContext->pSense; 17862 pSatDevData = satIOContext->pSatDevData; 17863 #ifdef TD_DEBUG_ENABLE 17864 pScsiCmnd = satIOContext->pScsiCmnd; 17865 #endif 17866 hostToDevFis = satIOContext->pFis; 17867 17868 tiDeviceHandle = &((tdsaDeviceData_t *)(pSatDevData->satSaDeviceData))->tiDeviceHandle; 17869 /* 17870 * Find out the type of response FIS: 17871 * Set Device Bit FIS or Reg Device To Host FIS. 17872 */ 17873 17874 /* First assume it is Reg Device to Host FIS */ 17875 statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H); 17876 ataStatus = statDevToHostFisHeader->status; /* ATA Status register */ 17877 ataError = statDevToHostFisHeader->error; /* ATA Eror register */ 17878 17879 /* for debugging */ 17880 TI_DBG1(("osSatIOCompleted: H to D command 0x%x\n", hostToDevFis->h.command)); 17881 TI_DBG1(("osSatIOCompleted: D to H fistype 0x%x\n", statDevToHostFisHeader->fisType)); 17882 17883 17884 if (statDevToHostFisHeader->fisType == SET_DEV_BITS_FIS) 17885 { 17886 /* It is Set Device Bits FIS */ 17887 statSetDevBitFisHeader = (agsaFisSetDevBitsHeader_t *)&(agFirstDword->D2H); 17888 /* Get ATA Status register */ 17889 ataStatus = (statSetDevBitFisHeader->statusHi_Lo & 0x70); /* bits 4,5,6 */ 17890 ataStatus = ataStatus | (statSetDevBitFisHeader->statusHi_Lo & 0x07); /* bits 0,1,2 */ 17891 17892 /* ATA Eror register */ 17893 ataError = statSetDevBitFisHeader->error; 17894 17895 statDevToHostFisHeader = agNULL; 17896 } 17897 17898 else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS) 17899 { 17900 TI_DBG1(("osSatIOCompleted: *** UNEXPECTED RESP FIS TYPE 0x%x *** tiIORequest=%p\n", 17901 statDevToHostFisHeader->fisType, tiIORequest)); 17902 17903 satSetSensePayload( pSense, 17904 SCSI_SNSKEY_HARDWARE_ERROR, 17905 0, 17906 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE, 17907 satIOContext); 17908 17909 ostiInitiatorIOCompleted( tiRoot, 17910 tiIORequest, 17911 tiIOSuccess, 17912 SCSI_STAT_CHECK_CONDITION, 17913 satIOContext->pTiSenseData, 17914 interruptContext ); 17915 return; 17916 17917 } 17918 17919 if ( ataStatus & DF_ATA_STATUS_MASK ) 17920 { 17921 pSatDevData->satDeviceFaultState = agTRUE; 17922 } 17923 else 17924 { 17925 pSatDevData->satDeviceFaultState = agFALSE; 17926 } 17927 17928 TI_DBG5(("osSatIOCompleted: tiIORequest=%p CDB=0x%x ATA CMD =0x%x\n", 17929 tiIORequest, pScsiCmnd->cdb[0], hostToDevFis->h.command)); 17930 17931 /* 17932 * Decide which ATA command is the translation needed 17933 */ 17934 switch(hostToDevFis->h.command) 17935 { 17936 case SAT_READ_FPDMA_QUEUED: 17937 case SAT_WRITE_FPDMA_QUEUED: 17938 17939 /************************************************************************ 17940 * 17941 * !!!! See Section 13.5.2.4 of SATA 2.5 specs. !!!! 17942 * !!!! If the NCQ error ends up here, it means that the device sent !!!! 17943 * !!!! Set Device Bit FIS (which has SActive register) instead of !!!! 17944 * !!!! Register Device To Host FIS (which does not have SActive !!!! 17945 * !!!! register). The callback ossaSATAEvent() deals with the case !!!! 17946 * !!!! where Register Device To Host FIS was sent by the device. !!!! 17947 * 17948 * For NCQ we need to issue READ LOG EXT command with log page 10h 17949 * to get the error and to allow other I/Os to continue. 17950 * 17951 * Here is the basic flow or sequence of error recovery, note that due 17952 * to the SATA HW assist that we have, this sequence is slighly different 17953 * from the one described in SATA 2.5: 17954 * 17955 * 1. Set SATA device flag to indicate error condition and returning busy 17956 * for all new request. 17957 * return tiSuccess; 17958 17959 * 2. Because the HW/LL layer received Set Device Bit FIS, it can get the 17960 * tag or I/O context for NCQ request, SATL would translate the ATA error 17961 * to SCSI status and return the original NCQ I/O with the appopriate 17962 * SCSI status. 17963 * 17964 * 3. Prepare READ LOG EXT page 10h command. Set flag to indicate that 17965 * the failed I/O has been returned to the OS Layer. Send command. 17966 * 17967 * 4. When the device receives READ LOG EXT page 10h request all other 17968 * pending I/O are implicitly aborted. No completion (aborted) status 17969 * will be sent to the host for these aborted commands. 17970 * 17971 * 5. SATL receives the completion for READ LOG EXT command in 17972 * satReadLogExtCB(). Steps 6,7,8,9 below are the step 1,2,3,4 in 17973 * satReadLogExtCB(). 17974 * 17975 * 6. Check flag that indicates whether the failed I/O has been returned 17976 * to the OS Layer. If not, search the I/O context in device data 17977 * looking for a matched tag. Then return the completion of the failed 17978 * NCQ command with the appopriate/trasnlated SCSI status. 17979 * 17980 * 7. Issue abort to LL layer to all other pending I/Os for the same SATA 17981 * drive. 17982 * 17983 * 8. Free resource allocated for the internally generated READ LOG EXT. 17984 * 17985 * 9. At the completion of abort, in the context of ossaSATACompleted(), 17986 * return the I/O with error status to the OS-App Specific layer. 17987 * When all I/O aborts are completed, clear SATA device flag to 17988 * indicate ready to process new request. 17989 * 17990 ***********************************************************************/ 17991 17992 TI_DBG1(("osSatIOCompleted: NCQ ERROR tiIORequest=%p ataStatus=0x%x ataError=0x%x\n", 17993 tiIORequest, ataStatus, ataError )); 17994 17995 /* Set flag to indicate we are in recovery */ 17996 pSatDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY; 17997 17998 /* Return the failed NCQ I/O to OS-Apps Specifiic layer */ 17999 osSatDefaultTranslation( tiRoot, 18000 tiIORequest, 18001 satIOContext, 18002 pSense, 18003 (bit8)ataStatus, 18004 (bit8)ataError, 18005 interruptContext ); 18006 18007 /* 18008 * Allocate resource for READ LOG EXT page 10h 18009 */ 18010 satIntIo = satAllocIntIoResource( tiRoot, 18011 &(tiIORequestTMP), /* anything but NULL */ 18012 pSatDevData, 18013 sizeof (satReadLogExtPage10h_t), 18014 satIntIo); 18015 18016 if (satIntIo == agNULL) 18017 { 18018 TI_DBG1(("osSatIOCompleted: can't send RLE due to resource lack\n")); 18019 18020 /* Abort I/O after completion of device reset */ 18021 pSatDevData->satAbortAfterReset = agTRUE; 18022 #ifdef NOT_YET 18023 /* needs further investigation */ 18024 /* no report to OS layer */ 18025 satSubTM(tiRoot, 18026 tiDeviceHandle, 18027 TD_INTERNAL_TM_RESET, 18028 agNULL, 18029 agNULL, 18030 agNULL, 18031 agFALSE); 18032 #endif 18033 18034 18035 TI_DBG1(("osSatIOCompleted: calling saSATADeviceReset 1\n")); 18036 return; 18037 } 18038 18039 18040 /* 18041 * Set flag to indicate that the failed I/O has been returned to the 18042 * OS-App specific Layer. 18043 */ 18044 satIntIo->satIntFlag = AG_SAT_INT_IO_FLAG_ORG_IO_COMPLETED; 18045 18046 /* compare to satPrepareNewIO() */ 18047 /* Send READ LOG EXIT page 10h command */ 18048 18049 /* 18050 * Need to initialize all the fields within satIOContext except 18051 * reqType and satCompleteCB which will be set depending on cmd. 18052 */ 18053 18054 tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody; 18055 satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext); 18056 18057 satIOContext2->pSatDevData = pSatDevData; 18058 satIOContext2->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 18059 satIOContext2->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd); 18060 satIOContext2->pSense = &(tdIORequestBody->transport.SATA.sensePayload); 18061 satIOContext2->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData); 18062 satIOContext2->pTiSenseData->senseData = satIOContext2->pSense; 18063 18064 satIOContext2->tiRequestBody = satIntIo->satIntRequestBody; 18065 satIOContext2->interruptContext = interruptContext; 18066 satIOContext2->satIntIoContext = satIntIo; 18067 18068 satIOContext2->ptiDeviceHandle = tiDeviceHandle; 18069 satIOContext2->satOrgIOContext = agNULL; 18070 satIOContext2->tiScsiXchg = agNULL; 18071 18072 status = satSendReadLogExt( tiRoot, 18073 &satIntIo->satIntTiIORequest, 18074 tiDeviceHandle, 18075 &satIntIo->satIntTiScsiXchg, 18076 satIOContext2); 18077 18078 if (status != tiSuccess) 18079 { 18080 TI_DBG1(("osSatIOCompleted: can't send RLE due to LL api failure\n")); 18081 satFreeIntIoResource( tiRoot, 18082 pSatDevData, 18083 satIntIo); 18084 18085 /* Abort I/O after completion of device reset */ 18086 pSatDevData->satAbortAfterReset = agTRUE; 18087 #ifdef NOT_YET 18088 /* needs further investigation */ 18089 /* no report to OS layer */ 18090 satSubTM(tiRoot, 18091 tiDeviceHandle, 18092 TD_INTERNAL_TM_RESET, 18093 agNULL, 18094 agNULL, 18095 agNULL, 18096 agFALSE); 18097 #endif 18098 18099 TI_DBG1(("osSatIOCompleted: calling saSATADeviceReset 2\n")); 18100 return; 18101 } 18102 18103 break; 18104 18105 case SAT_READ_DMA_EXT: 18106 /* fall through */ 18107 /* Use default status/error translation */ 18108 18109 case SAT_READ_DMA: 18110 /* fall through */ 18111 /* Use default status/error translation */ 18112 18113 default: 18114 osSatDefaultTranslation( tiRoot, 18115 tiIORequest, 18116 satIOContext, 18117 pSense, 18118 (bit8)ataStatus, 18119 (bit8)ataError, 18120 interruptContext ); 18121 break; 18122 18123 } /* end switch */ 18124 } 18125 18126 18127 /*****************************************************************************/ 18128 /*! \brief SAT implementation for SCSI STANDARD INQUIRY. 18129 * 18130 * SAT implementation for SCSI STANDARD INQUIRY. 18131 * 18132 * \param pInquiry: Pointer to Inquiry Data buffer. 18133 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data. 18134 * 18135 * \return None. 18136 */ 18137 /*****************************************************************************/ 18138 GLOBAL void satInquiryStandard( 18139 bit8 *pInquiry, 18140 agsaSATAIdentifyData_t *pSATAIdData, 18141 tiIniScsiCmnd_t *scsiCmnd 18142 ) 18143 { 18144 tiLUN_t *pLun; 18145 pLun = &scsiCmnd->lun; 18146 18147 /* 18148 Assumption: Basic Task Mangement is supported 18149 -> BQUE 1 and CMDQUE 0, SPC-4, Table96, p147 18150 */ 18151 /* 18152 See SPC-4, 6.4.2, p 143 18153 and SAT revision 8, 8.1.2, p 28 18154 */ 18155 18156 TI_DBG5(("satInquiryStandard: start\n")); 18157 18158 if (pInquiry == agNULL) 18159 { 18160 TI_DBG1(("satInquiryStandard: pInquiry is NULL, wrong\n")); 18161 return; 18162 } 18163 else 18164 { 18165 TI_DBG5(("satInquiryStandard: pInquiry is NOT NULL\n")); 18166 } 18167 /* 18168 * Reject all other LUN other than LUN 0. 18169 */ 18170 if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] | 18171 pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) ) 18172 { 18173 /* SAT Spec Table 8, p27, footnote 'a' */ 18174 pInquiry[0] = 0x7F; 18175 18176 } 18177 else 18178 { 18179 pInquiry[0] = 0x00; 18180 } 18181 18182 if (pSATAIdData->rm_ataDevice & ATA_REMOVABLE_MEDIA_DEVICE_MASK ) 18183 { 18184 pInquiry[1] = 0x80; 18185 } 18186 else 18187 { 18188 pInquiry[1] = 0x00; 18189 } 18190 pInquiry[2] = 0x05; /* SPC-3 */ 18191 pInquiry[3] = 0x12; /* set HiSup 1; resp data format set to 2 */ 18192 pInquiry[4] = 0x1F; /* 35 - 4 = 31; Additional length */ 18193 pInquiry[5] = 0x00; 18194 /* The following two are for task management. SAT Rev8, p20 */ 18195 if (pSATAIdData->sataCapabilities & 0x100) 18196 { 18197 /* NCQ supported; multiple outstanding SCSI IO are supported */ 18198 pInquiry[6] = 0x00; /* BQUE bit is not set */ 18199 pInquiry[7] = 0x02; /* CMDQUE bit is set */ 18200 } 18201 else 18202 { 18203 pInquiry[6] = 0x80; /* BQUE bit is set */ 18204 pInquiry[7] = 0x00; /* CMDQUE bit is not set */ 18205 } 18206 /* 18207 * Vendor ID. 18208 */ 18209 osti_strncpy((char*)&pInquiry[8], AG_SAT_VENDOR_ID_STRING,8); /* 8 bytes */ 18210 18211 /* 18212 * Product ID 18213 */ 18214 /* when flipped by LL */ 18215 pInquiry[16] = pSATAIdData->modelNumber[1]; 18216 pInquiry[17] = pSATAIdData->modelNumber[0]; 18217 pInquiry[18] = pSATAIdData->modelNumber[3]; 18218 pInquiry[19] = pSATAIdData->modelNumber[2]; 18219 pInquiry[20] = pSATAIdData->modelNumber[5]; 18220 pInquiry[21] = pSATAIdData->modelNumber[4]; 18221 pInquiry[22] = pSATAIdData->modelNumber[7]; 18222 pInquiry[23] = pSATAIdData->modelNumber[6]; 18223 pInquiry[24] = pSATAIdData->modelNumber[9]; 18224 pInquiry[25] = pSATAIdData->modelNumber[8]; 18225 pInquiry[26] = pSATAIdData->modelNumber[11]; 18226 pInquiry[27] = pSATAIdData->modelNumber[10]; 18227 pInquiry[28] = pSATAIdData->modelNumber[13]; 18228 pInquiry[29] = pSATAIdData->modelNumber[12]; 18229 pInquiry[30] = pSATAIdData->modelNumber[15]; 18230 pInquiry[31] = pSATAIdData->modelNumber[14]; 18231 18232 /* when flipped */ 18233 /* 18234 * Product Revision level. 18235 */ 18236 18237 /* 18238 * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA 18239 * device are ASCII spaces (20h), do this translation. 18240 */ 18241 if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) && 18242 (pSATAIdData->firmwareVersion[5] == 0x00 ) && 18243 (pSATAIdData->firmwareVersion[6] == 0x20 ) && 18244 (pSATAIdData->firmwareVersion[7] == 0x00 ) 18245 ) 18246 { 18247 pInquiry[32] = pSATAIdData->firmwareVersion[1]; 18248 pInquiry[33] = pSATAIdData->firmwareVersion[0]; 18249 pInquiry[34] = pSATAIdData->firmwareVersion[3]; 18250 pInquiry[35] = pSATAIdData->firmwareVersion[2]; 18251 } 18252 else 18253 { 18254 pInquiry[32] = pSATAIdData->firmwareVersion[5]; 18255 pInquiry[33] = pSATAIdData->firmwareVersion[4]; 18256 pInquiry[34] = pSATAIdData->firmwareVersion[7]; 18257 pInquiry[35] = pSATAIdData->firmwareVersion[6]; 18258 } 18259 18260 18261 #ifdef REMOVED 18262 /* 18263 * Product ID 18264 */ 18265 /* when flipped by LL */ 18266 pInquiry[16] = pSATAIdData->modelNumber[0]; 18267 pInquiry[17] = pSATAIdData->modelNumber[1]; 18268 pInquiry[18] = pSATAIdData->modelNumber[2]; 18269 pInquiry[19] = pSATAIdData->modelNumber[3]; 18270 pInquiry[20] = pSATAIdData->modelNumber[4]; 18271 pInquiry[21] = pSATAIdData->modelNumber[5]; 18272 pInquiry[22] = pSATAIdData->modelNumber[6]; 18273 pInquiry[23] = pSATAIdData->modelNumber[7]; 18274 pInquiry[24] = pSATAIdData->modelNumber[8]; 18275 pInquiry[25] = pSATAIdData->modelNumber[9]; 18276 pInquiry[26] = pSATAIdData->modelNumber[10]; 18277 pInquiry[27] = pSATAIdData->modelNumber[11]; 18278 pInquiry[28] = pSATAIdData->modelNumber[12]; 18279 pInquiry[29] = pSATAIdData->modelNumber[13]; 18280 pInquiry[30] = pSATAIdData->modelNumber[14]; 18281 pInquiry[31] = pSATAIdData->modelNumber[15]; 18282 18283 /* when flipped */ 18284 /* 18285 * Product Revision level. 18286 */ 18287 18288 /* 18289 * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA 18290 * device are ASCII spaces (20h), do this translation. 18291 */ 18292 if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) && 18293 (pSATAIdData->firmwareVersion[5] == 0x00 ) && 18294 (pSATAIdData->firmwareVersion[6] == 0x20 ) && 18295 (pSATAIdData->firmwareVersion[7] == 0x00 ) 18296 ) 18297 { 18298 pInquiry[32] = pSATAIdData->firmwareVersion[0]; 18299 pInquiry[33] = pSATAIdData->firmwareVersion[1]; 18300 pInquiry[34] = pSATAIdData->firmwareVersion[2]; 18301 pInquiry[35] = pSATAIdData->firmwareVersion[3]; 18302 } 18303 else 18304 { 18305 pInquiry[32] = pSATAIdData->firmwareVersion[4]; 18306 pInquiry[33] = pSATAIdData->firmwareVersion[5]; 18307 pInquiry[34] = pSATAIdData->firmwareVersion[6]; 18308 pInquiry[35] = pSATAIdData->firmwareVersion[7]; 18309 } 18310 #endif 18311 18312 TI_DBG5(("satInquiryStandard: end\n")); 18313 18314 } 18315 18316 18317 /*****************************************************************************/ 18318 /*! \brief SAT implementation for SCSI INQUIRY page 0. 18319 * 18320 * SAT implementation for SCSI INQUIRY page 0. 18321 * 18322 * \param pInquiry: Pointer to Inquiry Data buffer. 18323 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data. 18324 * 18325 * \return None. 18326 */ 18327 /*****************************************************************************/ 18328 GLOBAL void satInquiryPage0( 18329 bit8 *pInquiry, 18330 agsaSATAIdentifyData_t *pSATAIdData) 18331 { 18332 18333 TI_DBG5(("satInquiryPage0: entry\n")); 18334 18335 /* 18336 See SPC-4, 7.6.9, p 345 18337 and SAT revision 8, 10.3.2, p 77 18338 */ 18339 pInquiry[0] = 0x00; 18340 pInquiry[1] = 0x00; /* page code */ 18341 pInquiry[2] = 0x00; /* reserved */ 18342 pInquiry[3] = 7 - 3; /* last index(in this case, 6) - 3; page length */ 18343 18344 /* supported vpd page list */ 18345 pInquiry[4] = 0x00; /* page 0x00 supported */ 18346 pInquiry[5] = 0x80; /* page 0x80 supported */ 18347 pInquiry[6] = 0x83; /* page 0x83 supported */ 18348 pInquiry[7] = 0x89; /* page 0x89 supported */ 18349 18350 } 18351 18352 18353 /*****************************************************************************/ 18354 /*! \brief SAT implementation for SCSI INQUIRY page 83. 18355 * 18356 * SAT implementation for SCSI INQUIRY page 83. 18357 * 18358 * \param pInquiry: Pointer to Inquiry Data buffer. 18359 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data. 18360 * 18361 * \return None. 18362 */ 18363 /*****************************************************************************/ 18364 GLOBAL void satInquiryPage83( 18365 bit8 *pInquiry, 18366 agsaSATAIdentifyData_t *pSATAIdData, 18367 satDeviceData_t *pSatDevData) 18368 { 18369 18370 satSimpleSATAIdentifyData_t *pSimpleData; 18371 18372 /* 18373 * When translating the fields, in some cases using the simple form of SATA 18374 * Identify Device Data is easier. So we define it here. 18375 * Both pSimpleData and pSATAIdData points to the same data. 18376 */ 18377 pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData; 18378 18379 TI_DBG5(("satInquiryPage83: entry\n")); 18380 18381 pInquiry[0] = 0x00; 18382 pInquiry[1] = 0x83; /* page code */ 18383 pInquiry[2] = 0; /* Reserved */ 18384 18385 /* 18386 * If the ATA device returns word 87 bit 8 set to one in its IDENTIFY DEVICE 18387 * data indicating that it supports the WORLD WIDE NAME field 18388 * (i.e., words 108-111), the SATL shall include an identification descriptor 18389 * containing a logical unit name. 18390 */ 18391 if ( pSatDevData->satWWNSupport) 18392 { 18393 /* Fill in SAT Rev8 Table85 */ 18394 /* 18395 * Logical unit name derived from the world wide name. 18396 */ 18397 pInquiry[3] = 12; /* 15-3; page length, no addition ID descriptor assumed*/ 18398 18399 /* 18400 * Identifier descriptor 18401 */ 18402 pInquiry[4] = 0x01; /* Code set: binary codes */ 18403 pInquiry[5] = 0x03; /* Identifier type : NAA */ 18404 pInquiry[6] = 0x00; /* Reserved */ 18405 pInquiry[7] = 0x08; /* Identifier length */ 18406 18407 /* Bit 4-7 NAA field, bit 0-3 MSB of IEEE Company ID */ 18408 pInquiry[8] = (bit8)((pSATAIdData->namingAuthority) >> 8); 18409 pInquiry[9] = (bit8)((pSATAIdData->namingAuthority) & 0xFF); /* IEEE Company ID */ 18410 pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8); /* IEEE Company ID */ 18411 /* Bit 4-7 LSB of IEEE Company ID, bit 0-3 MSB of Vendor Specific ID */ 18412 pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF); 18413 pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8); /* Vendor Specific ID */ 18414 pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF); /* Vendor Specific ID */ 18415 pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8); /* Vendor Specific ID */ 18416 pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF); /* Vendor Specific ID */ 18417 18418 } 18419 else 18420 { 18421 /* Fill in SAT Rev8 Table86 */ 18422 /* 18423 * Logical unit name derived from the model number and serial number. 18424 */ 18425 pInquiry[3] = 72; /* 75 - 3; page length */ 18426 18427 /* 18428 * Identifier descriptor 18429 */ 18430 pInquiry[4] = 0x02; /* Code set: ASCII codes */ 18431 pInquiry[5] = 0x01; /* Identifier type : T10 vendor ID based */ 18432 pInquiry[6] = 0x00; /* Reserved */ 18433 pInquiry[7] = 0x44; /* 0x44, 68 Identifier length */ 18434 18435 /* Byte 8 to 15 is the vendor id string 'ATA '. */ 18436 osti_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8); 18437 18438 18439 /* 18440 * Byte 16 to 75 is vendor specific id 18441 */ 18442 pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8); 18443 pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff); 18444 pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8); 18445 pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff); 18446 pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8); 18447 pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff); 18448 pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8); 18449 pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff); 18450 pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8); 18451 pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff); 18452 pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8); 18453 pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff); 18454 pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8); 18455 pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff); 18456 pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8); 18457 pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff); 18458 pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8); 18459 pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff); 18460 pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8); 18461 pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff); 18462 pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8); 18463 pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff); 18464 pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8); 18465 pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff); 18466 pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8); 18467 pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff); 18468 pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8); 18469 pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff); 18470 pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8); 18471 pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff); 18472 pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8); 18473 pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff); 18474 pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8); 18475 pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff); 18476 pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8); 18477 pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff); 18478 pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8); 18479 pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff); 18480 pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8); 18481 pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff); 18482 18483 pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8); 18484 pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff); 18485 pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8); 18486 pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff); 18487 pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8); 18488 pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff); 18489 pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8); 18490 pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff); 18491 pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8); 18492 pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff); 18493 pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8); 18494 pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff); 18495 pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8); 18496 pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff); 18497 pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8); 18498 pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff); 18499 pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8); 18500 pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff); 18501 pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8); 18502 pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff); 18503 } 18504 18505 } 18506 18507 /*****************************************************************************/ 18508 /*! \brief SAT implementation for SCSI INQUIRY page 89. 18509 * 18510 * SAT implementation for SCSI INQUIRY page 89. 18511 * 18512 * \param pInquiry: Pointer to Inquiry Data buffer. 18513 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data. 18514 * \param pSatDevData Pointer to internal device data structure 18515 * 18516 * \return None. 18517 */ 18518 /*****************************************************************************/ 18519 GLOBAL void satInquiryPage89( 18520 bit8 *pInquiry, 18521 agsaSATAIdentifyData_t *pSATAIdData, 18522 satDeviceData_t *pSatDevData) 18523 { 18524 /* 18525 SAT revision 8, 10.3.5, p 83 18526 */ 18527 satSimpleSATAIdentifyData_t *pSimpleData; 18528 18529 /* 18530 * When translating the fields, in some cases using the simple form of SATA 18531 * Identify Device Data is easier. So we define it here. 18532 * Both pSimpleData and pSATAIdData points to the same data. 18533 */ 18534 pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData; 18535 18536 TI_DBG5(("satInquiryPage89: start\n")); 18537 18538 pInquiry[0] = 0x00; /* Peripheral Qualifier and Peripheral Device Type */ 18539 pInquiry[1] = 0x89; /* page code */ 18540 18541 /* Page length 0x238 */ 18542 pInquiry[2] = 0x02; 18543 pInquiry[3] = 0x38; 18544 18545 pInquiry[4] = 0x0; /* reserved */ 18546 pInquiry[5] = 0x0; /* reserved */ 18547 pInquiry[6] = 0x0; /* reserved */ 18548 pInquiry[7] = 0x0; /* reserved */ 18549 18550 /* SAT Vendor Identification */ 18551 osti_strncpy((char*)&pInquiry[8], "PMC-SIERRA", 8); /* 8 bytes */ 18552 18553 /* SAT Product Idetification */ 18554 osti_strncpy((char*)&pInquiry[16], "Tachyon-SPC ", 16); /* 16 bytes */ 18555 18556 /* SAT Product Revision Level */ 18557 osti_strncpy((char*)&pInquiry[32], "01", 4); /* 4 bytes */ 18558 18559 /* Signature, SAT revision8, Table88, p85 */ 18560 18561 18562 pInquiry[36] = 0x34; /* FIS type */ 18563 if (pSatDevData->satDeviceType == SATA_ATA_DEVICE) 18564 { 18565 /* interrupt assume to be 0 */ 18566 pInquiry[37] = (bit8)((pSatDevData->satPMField) >> (4 * 7)); /* first four bits of PM field */ 18567 } 18568 else 18569 { 18570 /* interrupt assume to be 1 */ 18571 pInquiry[37] = (bit8)(0x40 + (bit8)(((pSatDevData->satPMField) >> (4 * 7)))); /* first four bits of PM field */ 18572 } 18573 pInquiry[38] = 0; 18574 pInquiry[39] = 0; 18575 18576 if (pSatDevData->satDeviceType == SATA_ATA_DEVICE) 18577 { 18578 pInquiry[40] = 0x01; /* LBA Low */ 18579 pInquiry[41] = 0x00; /* LBA Mid */ 18580 pInquiry[42] = 0x00; /* LBA High */ 18581 pInquiry[43] = 0x00; /* Device */ 18582 pInquiry[44] = 0x00; /* LBA Low Exp */ 18583 pInquiry[45] = 0x00; /* LBA Mid Exp */ 18584 pInquiry[46] = 0x00; /* LBA High Exp */ 18585 pInquiry[47] = 0x00; /* Reserved */ 18586 pInquiry[48] = 0x01; /* Sector Count */ 18587 pInquiry[49] = 0x00; /* Sector Count Exp */ 18588 } 18589 else 18590 { 18591 pInquiry[40] = 0x01; /* LBA Low */ 18592 pInquiry[41] = 0x00; /* LBA Mid */ 18593 pInquiry[42] = 0x00; /* LBA High */ 18594 pInquiry[43] = 0x00; /* Device */ 18595 pInquiry[44] = 0x00; /* LBA Low Exp */ 18596 pInquiry[45] = 0x00; /* LBA Mid Exp */ 18597 pInquiry[46] = 0x00; /* LBA High Exp */ 18598 pInquiry[47] = 0x00; /* Reserved */ 18599 pInquiry[48] = 0x01; /* Sector Count */ 18600 pInquiry[49] = 0x00; /* Sector Count Exp */ 18601 } 18602 18603 /* Reserved */ 18604 pInquiry[50] = 0x00; 18605 pInquiry[51] = 0x00; 18606 pInquiry[52] = 0x00; 18607 pInquiry[53] = 0x00; 18608 pInquiry[54] = 0x00; 18609 pInquiry[55] = 0x00; 18610 18611 /* Command Code */ 18612 if (pSatDevData->satDeviceType == SATA_ATA_DEVICE) 18613 { 18614 pInquiry[56] = 0xEC; /* IDENTIFY DEVICE */ 18615 } 18616 else 18617 { 18618 pInquiry[56] = 0xA1; /* IDENTIFY PACKET DEVICE */ 18619 } 18620 /* Reserved */ 18621 pInquiry[57] = 0x0; 18622 pInquiry[58] = 0x0; 18623 pInquiry[59] = 0x0; 18624 18625 /* Identify Device */ 18626 osti_memcpy(&pInquiry[60], pSimpleData, sizeof(satSimpleSATAIdentifyData_t)); 18627 return; 18628 } 18629 18630 /*****************************************************************************/ 18631 /*! \brief SAT implementation for SCSI INQUIRY page 0. 18632 * 18633 * SAT implementation for SCSI INQUIRY page 0. 18634 * 18635 * \param pInquiry: Pointer to Inquiry Data buffer. 18636 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data. 18637 * 18638 * \return None. 18639 */ 18640 /*****************************************************************************/ 18641 GLOBAL void satInquiryPage80( 18642 bit8 *pInquiry, 18643 agsaSATAIdentifyData_t *pSATAIdData) 18644 { 18645 18646 TI_DBG5(("satInquiryPage80: entry\n")); 18647 18648 /* 18649 See SPC-4, 7.6.9, p 345 18650 and SAT revision 8, 10.3.3, p 77 18651 */ 18652 pInquiry[0] = 0x00; 18653 pInquiry[1] = 0x80; /* page code */ 18654 pInquiry[2] = 0x00; /* reserved */ 18655 pInquiry[3] = 0x14; /* page length */ 18656 18657 /* supported vpd page list */ 18658 pInquiry[4] = pSATAIdData->serialNumber[1]; 18659 pInquiry[5] = pSATAIdData->serialNumber[0]; 18660 pInquiry[6] = pSATAIdData->serialNumber[3]; 18661 pInquiry[7] = pSATAIdData->serialNumber[2]; 18662 pInquiry[8] = pSATAIdData->serialNumber[5]; 18663 pInquiry[9] = pSATAIdData->serialNumber[4]; 18664 pInquiry[10] = pSATAIdData->serialNumber[7]; 18665 pInquiry[11] = pSATAIdData->serialNumber[6]; 18666 pInquiry[12] = pSATAIdData->serialNumber[9]; 18667 pInquiry[13] = pSATAIdData->serialNumber[8]; 18668 pInquiry[14] = pSATAIdData->serialNumber[11]; 18669 pInquiry[15] = pSATAIdData->serialNumber[10]; 18670 pInquiry[16] = pSATAIdData->serialNumber[13]; 18671 pInquiry[17] = pSATAIdData->serialNumber[12]; 18672 pInquiry[18] = pSATAIdData->serialNumber[15]; 18673 pInquiry[19] = pSATAIdData->serialNumber[14]; 18674 pInquiry[20] = pSATAIdData->serialNumber[17]; 18675 pInquiry[21] = pSATAIdData->serialNumber[16]; 18676 pInquiry[22] = pSATAIdData->serialNumber[19]; 18677 pInquiry[23] = pSATAIdData->serialNumber[18]; 18678 18679 18680 } 18681 18682 18683 18684 /*****************************************************************************/ 18685 /*! \brief Send READ LOG EXT ATA PAGE 10h command to sata drive. 18686 * 18687 * Send READ LOG EXT ATA command PAGE 10h request to LL layer. 18688 * 18689 * \param tiRoot: Pointer to TISA initiator driver/port instance. 18690 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 18691 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 18692 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 18693 * \param satIOContext_t: Pointer to the SAT IO Context 18694 * 18695 * \return If command is started successfully 18696 * - \e tiSuccess: I/O request successfully initiated. 18697 * - \e tiBusy: No resources available, try again later. 18698 * - \e tiIONoDevice: Invalid device handle. 18699 * - \e tiError: Other errors. 18700 */ 18701 /*****************************************************************************/ 18702 GLOBAL bit32 satSendReadLogExt( 18703 tiRoot_t *tiRoot, 18704 tiIORequest_t *tiIORequest, 18705 tiDeviceHandle_t *tiDeviceHandle, 18706 tiScsiInitiatorRequest_t *tiScsiRequest, 18707 satIOContext_t *satIOContext) 18708 18709 { 18710 18711 bit32 status; 18712 bit32 agRequestType; 18713 agsaFisRegHostToDevice_t *fis; 18714 18715 fis = satIOContext->pFis; 18716 18717 TI_DBG1(("satSendReadLogExt: tiDeviceHandle=%p tiIORequest=%p\n", 18718 tiDeviceHandle, tiIORequest)); 18719 18720 fis->h.fisType = 0x27; /* Reg host to device */ 18721 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18722 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */ 18723 fis->h.features = 0; /* FIS reserve */ 18724 fis->d.lbaLow = 0x10; /* Page number */ 18725 fis->d.lbaMid = 0; /* */ 18726 fis->d.lbaHigh = 0; /* */ 18727 fis->d.device = 0; /* DEV is ignored in SATA */ 18728 fis->d.lbaLowExp = 0; /* */ 18729 fis->d.lbaMidExp = 0; /* */ 18730 fis->d.lbaHighExp = 0; /* */ 18731 fis->d.featuresExp = 0; /* FIS reserve */ 18732 fis->d.sectorCount = 0x01; /* 1 sector counts*/ 18733 fis->d.sectorCountExp = 0x00; /* 1 sector counts */ 18734 fis->d.reserved4 = 0; 18735 fis->d.control = 0; /* FIS HOB bit clear */ 18736 fis->d.reserved5 = 0; 18737 18738 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 18739 18740 /* Initialize CB for SATA completion. 18741 */ 18742 satIOContext->satCompleteCB = &satReadLogExtCB; 18743 18744 /* 18745 * Prepare SGL and send FIS to LL layer. 18746 */ 18747 satIOContext->reqType = agRequestType; /* Save it */ 18748 18749 status = sataLLIOStart( tiRoot, 18750 tiIORequest, 18751 tiDeviceHandle, 18752 tiScsiRequest, 18753 satIOContext); 18754 18755 TI_DBG1(("satSendReadLogExt: end status %d\n", status)); 18756 18757 return (status); 18758 18759 } 18760 18761 18762 /*****************************************************************************/ 18763 /*! \brief SAT default ATA status and ATA error translation to SCSI. 18764 * 18765 * SSAT default ATA status and ATA error translation to SCSI. 18766 * 18767 * \param tiRoot: Pointer to TISA initiator driver/port instance. 18768 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 18769 * \param satIOContext: Pointer to the SAT IO Context 18770 * \param pSense: Pointer to scsiRspSense_t 18771 * \param ataStatus: ATA status register 18772 * \param ataError: ATA error register 18773 * \param interruptContext: Interrupt context 18774 * 18775 * \return None 18776 */ 18777 /*****************************************************************************/ 18778 GLOBAL void osSatDefaultTranslation( 18779 tiRoot_t *tiRoot, 18780 tiIORequest_t *tiIORequest, 18781 satIOContext_t *satIOContext, 18782 scsiRspSense_t *pSense, 18783 bit8 ataStatus, 18784 bit8 ataError, 18785 bit32 interruptContext ) 18786 { 18787 18788 /* 18789 * Check for device fault case 18790 */ 18791 if ( ataStatus & DF_ATA_STATUS_MASK ) 18792 { 18793 satSetSensePayload( pSense, 18794 SCSI_SNSKEY_HARDWARE_ERROR, 18795 0, 18796 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE, 18797 satIOContext); 18798 18799 ostiInitiatorIOCompleted( tiRoot, 18800 tiIORequest, 18801 tiIOSuccess, 18802 SCSI_STAT_CHECK_CONDITION, 18803 satIOContext->pTiSenseData, 18804 interruptContext ); 18805 return; 18806 } 18807 18808 /* 18809 * If status error bit it set, need to check the error register 18810 */ 18811 if ( ataStatus & ERR_ATA_STATUS_MASK ) 18812 { 18813 if ( ataError & NM_ATA_ERROR_MASK ) 18814 { 18815 TI_DBG1(("osSatDefaultTranslation: NM_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n", 18816 ataError, tiIORequest)); 18817 satSetSensePayload( pSense, 18818 SCSI_SNSKEY_NOT_READY, 18819 0, 18820 SCSI_SNSCODE_MEDIUM_NOT_PRESENT, 18821 satIOContext); 18822 } 18823 18824 else if (ataError & UNC_ATA_ERROR_MASK) 18825 { 18826 TI_DBG1(("osSatDefaultTranslation: UNC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n", 18827 ataError, tiIORequest)); 18828 satSetSensePayload( pSense, 18829 SCSI_SNSKEY_MEDIUM_ERROR, 18830 0, 18831 SCSI_SNSCODE_UNRECOVERED_READ_ERROR, 18832 satIOContext); 18833 } 18834 18835 else if (ataError & IDNF_ATA_ERROR_MASK) 18836 { 18837 TI_DBG1(("osSatDefaultTranslation: IDNF_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n", 18838 ataError, tiIORequest)); 18839 satSetSensePayload( pSense, 18840 SCSI_SNSKEY_MEDIUM_ERROR, 18841 0, 18842 SCSI_SNSCODE_RECORD_NOT_FOUND, 18843 satIOContext); 18844 } 18845 18846 else if (ataError & MC_ATA_ERROR_MASK) 18847 { 18848 TI_DBG1(("osSatDefaultTranslation: MC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n", 18849 ataError, tiIORequest)); 18850 satSetSensePayload( pSense, 18851 SCSI_SNSKEY_UNIT_ATTENTION, 18852 0, 18853 SCSI_SNSCODE_NOT_READY_TO_READY_CHANGE, 18854 satIOContext); 18855 } 18856 18857 else if (ataError & MCR_ATA_ERROR_MASK) 18858 { 18859 TI_DBG1(("osSatDefaultTranslation: MCR_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n", 18860 ataError, tiIORequest)); 18861 satSetSensePayload( pSense, 18862 SCSI_SNSKEY_UNIT_ATTENTION, 18863 0, 18864 SCSI_SNSCODE_OPERATOR_MEDIUM_REMOVAL_REQUEST, 18865 satIOContext); 18866 } 18867 18868 else if (ataError & ICRC_ATA_ERROR_MASK) 18869 { 18870 TI_DBG1(("osSatDefaultTranslation: ICRC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n", 18871 ataError, tiIORequest)); 18872 satSetSensePayload( pSense, 18873 SCSI_SNSKEY_ABORTED_COMMAND, 18874 0, 18875 SCSI_SNSCODE_INFORMATION_UNIT_CRC_ERROR, 18876 satIOContext); 18877 } 18878 18879 else if (ataError & ABRT_ATA_ERROR_MASK) 18880 { 18881 TI_DBG1(("osSatDefaultTranslation: ABRT_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n", 18882 ataError, tiIORequest)); 18883 satSetSensePayload( pSense, 18884 SCSI_SNSKEY_ABORTED_COMMAND, 18885 0, 18886 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 18887 satIOContext); 18888 } 18889 18890 else 18891 { 18892 TI_DBG1(("osSatDefaultTranslation: **** UNEXPECTED ATA_ERROR **** ataError= 0x%x, tiIORequest=%p\n", 18893 ataError, tiIORequest)); 18894 satSetSensePayload( pSense, 18895 SCSI_SNSKEY_HARDWARE_ERROR, 18896 0, 18897 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE, 18898 satIOContext); 18899 } 18900 18901 /* Send the completion response now */ 18902 ostiInitiatorIOCompleted( tiRoot, 18903 tiIORequest, 18904 tiIOSuccess, 18905 SCSI_STAT_CHECK_CONDITION, 18906 satIOContext->pTiSenseData, 18907 interruptContext ); 18908 return; 18909 18910 18911 } 18912 18913 else /* (ataStatus & ERR_ATA_STATUS_MASK ) is false */ 18914 { 18915 /* This case should never happen */ 18916 TI_DBG1(("osSatDefaultTranslation: *** UNEXPECTED ATA status 0x%x *** tiIORequest=%p\n", 18917 ataStatus, tiIORequest)); 18918 satSetSensePayload( pSense, 18919 SCSI_SNSKEY_HARDWARE_ERROR, 18920 0, 18921 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE, 18922 satIOContext); 18923 18924 ostiInitiatorIOCompleted( tiRoot, 18925 tiIORequest, 18926 tiIOSuccess, 18927 SCSI_STAT_CHECK_CONDITION, 18928 satIOContext->pTiSenseData, 18929 interruptContext ); 18930 return; 18931 18932 } 18933 18934 18935 } 18936 18937 /*****************************************************************************/ 18938 /*! \brief Allocate resource for SAT intervally generated I/O. 18939 * 18940 * Allocate resource for SAT intervally generated I/O. 18941 * 18942 * \param tiRoot: Pointer to TISA driver/port instance. 18943 * \param satDevData: Pointer to SAT specific device data. 18944 * \param allocLength: Length in byte of the DMA mem to allocate, upto 18945 * one page size. 18946 * \param satIntIo: Pointer (output) to context for SAT internally 18947 * generated I/O that is allocated by this routine. 18948 * 18949 * \return If command is started successfully 18950 * - \e tiSuccess: Success. 18951 * - \e tiError: Failed allocating resource. 18952 */ 18953 /*****************************************************************************/ 18954 GLOBAL satInternalIo_t * satAllocIntIoResource( 18955 tiRoot_t *tiRoot, 18956 tiIORequest_t *tiIORequest, 18957 satDeviceData_t *satDevData, 18958 bit32 dmaAllocLength, 18959 satInternalIo_t *satIntIo) 18960 { 18961 tdList_t *tdList = agNULL; 18962 bit32 memAllocStatus; 18963 18964 TI_DBG1(("satAllocIntIoResource: start\n")); 18965 TI_DBG6(("satAllocIntIoResource: satIntIo %p\n", satIntIo)); 18966 if (satDevData == agNULL) 18967 { 18968 TI_DBG1(("satAllocIntIoResource: ***** ASSERT satDevData is null\n")); 18969 return agNULL; 18970 } 18971 18972 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK); 18973 if (!TDLIST_EMPTY(&(satDevData->satFreeIntIoLinkList))) 18974 { 18975 TDLIST_DEQUEUE_FROM_HEAD(&tdList, &(satDevData->satFreeIntIoLinkList)); 18976 } 18977 else 18978 { 18979 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK); 18980 TI_DBG1(("satAllocIntIoResource() no more internal free link.\n")); 18981 return agNULL; 18982 } 18983 18984 if (tdList == agNULL) 18985 { 18986 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK); 18987 TI_DBG1(("satAllocIntIoResource() FAIL to alloc satIntIo.\n")); 18988 return agNULL; 18989 } 18990 18991 satIntIo = TDLIST_OBJECT_BASE( satInternalIo_t, satIntIoLink, tdList); 18992 TI_DBG6(("satAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id)); 18993 18994 /* Put in active list */ 18995 TDLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink)); 18996 TDLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satActiveIntIoLinkList)); 18997 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK); 18998 18999 #ifdef REMOVED 19000 /* Put in active list */ 19001 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK); 19002 TDLIST_DEQUEUE_THIS (tdList); 19003 TDLIST_ENQUEUE_AT_TAIL (tdList, &(satDevData->satActiveIntIoLinkList)); 19004 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK); 19005 19006 satIntIo = TDLIST_OBJECT_BASE( satInternalIo_t, satIntIoLink, tdList); 19007 TI_DBG6(("satAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id)); 19008 #endif 19009 19010 /* 19011 typedef struct 19012 { 19013 tdList_t satIntIoLink; 19014 tiIORequest_t satIntTiIORequest; 19015 void *satIntRequestBody; 19016 tiScsiInitiatorRequest_t satIntTiScsiXchg; 19017 tiMem_t satIntDmaMem; 19018 tiMem_t satIntReqBodyMem; 19019 bit32 satIntFlag; 19020 } satInternalIo_t; 19021 */ 19022 19023 /* 19024 * Allocate mem for Request Body 19025 */ 19026 satIntIo->satIntReqBodyMem.totalLength = sizeof(tdIORequestBody_t); 19027 19028 memAllocStatus = ostiAllocMemory( tiRoot, 19029 &satIntIo->satIntReqBodyMem.osHandle, 19030 (void **)&satIntIo->satIntRequestBody, 19031 &satIntIo->satIntReqBodyMem.physAddrUpper, 19032 &satIntIo->satIntReqBodyMem.physAddrLower, 19033 8, 19034 satIntIo->satIntReqBodyMem.totalLength, 19035 agTRUE ); 19036 19037 if (memAllocStatus != tiSuccess) 19038 { 19039 TI_DBG1(("satAllocIntIoResource() FAIL to alloc mem for Req Body.\n")); 19040 /* 19041 * Return satIntIo to the free list 19042 */ 19043 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK); 19044 TDLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink); 19045 TDLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList); 19046 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK); 19047 19048 return agNULL; 19049 } 19050 19051 /* 19052 * Allocate DMA memory if required 19053 */ 19054 if (dmaAllocLength != 0) 19055 { 19056 satIntIo->satIntDmaMem.totalLength = dmaAllocLength; 19057 19058 memAllocStatus = ostiAllocMemory( tiRoot, 19059 &satIntIo->satIntDmaMem.osHandle, 19060 (void **)&satIntIo->satIntDmaMem.virtPtr, 19061 &satIntIo->satIntDmaMem.physAddrUpper, 19062 &satIntIo->satIntDmaMem.physAddrLower, 19063 8, 19064 satIntIo->satIntDmaMem.totalLength, 19065 agFALSE); 19066 TI_DBG6(("satAllocIntIoResource: len %d \n", satIntIo->satIntDmaMem.totalLength)); 19067 TI_DBG6(("satAllocIntIoResource: pointer %p \n", satIntIo->satIntDmaMem.osHandle)); 19068 19069 if (memAllocStatus != tiSuccess) 19070 { 19071 TI_DBG1(("satAllocIntIoResource() FAIL to alloc mem for DMA mem.\n")); 19072 /* 19073 * Return satIntIo to the free list 19074 */ 19075 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK); 19076 TDLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink); 19077 TDLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList); 19078 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK); 19079 19080 /* 19081 * Free mem allocated for Req body 19082 */ 19083 ostiFreeMemory( tiRoot, 19084 satIntIo->satIntReqBodyMem.osHandle, 19085 satIntIo->satIntReqBodyMem.totalLength); 19086 19087 return agNULL; 19088 } 19089 } 19090 19091 /* 19092 typedef struct 19093 { 19094 tdList_t satIntIoLink; 19095 tiIORequest_t satIntTiIORequest; 19096 void *satIntRequestBody; 19097 tiScsiInitiatorRequest_t satIntTiScsiXchg; 19098 tiMem_t satIntDmaMem; 19099 tiMem_t satIntReqBodyMem; 19100 bit32 satIntFlag; 19101 } satInternalIo_t; 19102 */ 19103 19104 /* 19105 * Initialize satIntTiIORequest field 19106 */ 19107 satIntIo->satIntTiIORequest.osData = agNULL; /* Not used for internal SAT I/O */ 19108 satIntIo->satIntTiIORequest.tdData = satIntIo->satIntRequestBody; 19109 19110 /* 19111 * saves the original tiIOrequest 19112 */ 19113 satIntIo->satOrgTiIORequest = tiIORequest; 19114 /* 19115 typedef struct tiIniScsiCmnd 19116 { 19117 tiLUN_t lun; 19118 bit32 expDataLength; 19119 bit32 taskAttribute; 19120 bit32 crn; 19121 bit8 cdb[16]; 19122 } tiIniScsiCmnd_t; 19123 19124 typedef struct tiScsiInitiatorExchange 19125 { 19126 void *sglVirtualAddr; 19127 tiIniScsiCmnd_t scsiCmnd; 19128 tiSgl_t agSgl1; 19129 tiSgl_t agSgl2; 19130 tiDataDirection_t dataDirection; 19131 } tiScsiInitiatorRequest_t; 19132 19133 */ 19134 19135 /* 19136 * Initialize satIntTiScsiXchg. Since the internal SAT request is NOT 19137 * originated from SCSI request, only the following fields are initialized: 19138 * - sglVirtualAddr if DMA transfer is involved 19139 * - agSgl1 if DMA transfer is involved 19140 * - expDataLength in scsiCmnd since this field is read by sataLLIOStart() 19141 */ 19142 if (dmaAllocLength != 0) 19143 { 19144 satIntIo->satIntTiScsiXchg.sglVirtualAddr = satIntIo->satIntDmaMem.virtPtr; 19145 19146 OSSA_WRITE_LE_32(agNULL, &satIntIo->satIntTiScsiXchg.agSgl1.len, 0, 19147 satIntIo->satIntDmaMem.totalLength); 19148 satIntIo->satIntTiScsiXchg.agSgl1.lower = satIntIo->satIntDmaMem.physAddrLower; 19149 satIntIo->satIntTiScsiXchg.agSgl1.upper = satIntIo->satIntDmaMem.physAddrUpper; 19150 satIntIo->satIntTiScsiXchg.agSgl1.type = tiSgl; 19151 19152 satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = satIntIo->satIntDmaMem.totalLength; 19153 } 19154 else 19155 { 19156 satIntIo->satIntTiScsiXchg.sglVirtualAddr = agNULL; 19157 19158 satIntIo->satIntTiScsiXchg.agSgl1.len = 0; 19159 satIntIo->satIntTiScsiXchg.agSgl1.lower = 0; 19160 satIntIo->satIntTiScsiXchg.agSgl1.upper = 0; 19161 satIntIo->satIntTiScsiXchg.agSgl1.type = tiSgl; 19162 19163 satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = 0; 19164 } 19165 19166 TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.len %d\n", satIntIo->satIntTiScsiXchg.agSgl1.len)); 19167 19168 TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.upper %d\n", satIntIo->satIntTiScsiXchg.agSgl1.upper)); 19169 19170 TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.lower %d\n", satIntIo->satIntTiScsiXchg.agSgl1.lower)); 19171 19172 TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.type %d\n", satIntIo->satIntTiScsiXchg.agSgl1.type)); 19173 TI_DBG5(("satAllocIntIoResource: return satIntIo %p\n", satIntIo)); 19174 return satIntIo; 19175 19176 } 19177 19178 /*****************************************************************************/ 19179 /*! \brief Free resource for SAT intervally generated I/O. 19180 * 19181 * Free resource for SAT intervally generated I/O that was previously 19182 * allocated in satAllocIntIoResource(). 19183 * 19184 * \param tiRoot: Pointer to TISA driver/port instance. 19185 * \param satDevData: Pointer to SAT specific device data. 19186 * \param satIntIo: Pointer to context for SAT internal I/O that was 19187 * previously allocated in satAllocIntIoResource(). 19188 * 19189 * \return None 19190 */ 19191 /*****************************************************************************/ 19192 GLOBAL void satFreeIntIoResource( 19193 tiRoot_t *tiRoot, 19194 satDeviceData_t *satDevData, 19195 satInternalIo_t *satIntIo) 19196 { 19197 TI_DBG6(("satFreeIntIoResource: start\n")); 19198 19199 if (satIntIo == agNULL) 19200 { 19201 TI_DBG6(("satFreeIntIoResource: allowed call\n")); 19202 return; 19203 } 19204 19205 /* sets the original tiIOrequest to agNULL for internally generated ATA cmnd */ 19206 satIntIo->satOrgTiIORequest = agNULL; 19207 19208 /* 19209 * Free DMA memory if previosly alocated 19210 */ 19211 if (satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength != 0) 19212 { 19213 TI_DBG1(("satFreeIntIoResource: DMA len %d\n", satIntIo->satIntDmaMem.totalLength)); 19214 TI_DBG6(("satFreeIntIoResource: pointer %p\n", satIntIo->satIntDmaMem.osHandle)); 19215 19216 ostiFreeMemory( tiRoot, 19217 satIntIo->satIntDmaMem.osHandle, 19218 satIntIo->satIntDmaMem.totalLength); 19219 satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = 0; 19220 } 19221 19222 if (satIntIo->satIntReqBodyMem.totalLength != 0) 19223 { 19224 TI_DBG1(("satFreeIntIoResource: req body len %d\n", satIntIo->satIntReqBodyMem.totalLength)); 19225 /* 19226 * Free mem allocated for Req body 19227 */ 19228 ostiFreeMemory( tiRoot, 19229 satIntIo->satIntReqBodyMem.osHandle, 19230 satIntIo->satIntReqBodyMem.totalLength); 19231 19232 satIntIo->satIntReqBodyMem.totalLength = 0; 19233 } 19234 19235 TI_DBG6(("satFreeIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id)); 19236 /* 19237 * Return satIntIo to the free list 19238 */ 19239 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK); 19240 TDLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink)); 19241 TDLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satFreeIntIoLinkList)); 19242 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK); 19243 19244 } 19245 19246 19247 /*****************************************************************************/ 19248 /*! \brief SAT implementation for SCSI INQUIRY. 19249 * 19250 * SAT implementation for SCSI INQUIRY. 19251 * This function sends ATA Identify Device data command for SCSI INQUIRY 19252 * 19253 * \param tiRoot: Pointer to TISA initiator driver/port instance. 19254 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 19255 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 19256 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 19257 * \param satIOContext_t: Pointer to the SAT IO Context 19258 * 19259 * \return If command is started successfully 19260 * - \e tiSuccess: I/O request successfully initiated. 19261 * - \e tiBusy: No resources available, try again later. 19262 * - \e tiIONoDevice: Invalid device handle. 19263 * - \e tiError: Other errors. 19264 */ 19265 /*****************************************************************************/ 19266 GLOBAL bit32 satSendIDDev( 19267 tiRoot_t *tiRoot, 19268 tiIORequest_t *tiIORequest, 19269 tiDeviceHandle_t *tiDeviceHandle, 19270 tiScsiInitiatorRequest_t *tiScsiRequest, 19271 satIOContext_t *satIOContext) 19272 19273 { 19274 bit32 status; 19275 bit32 agRequestType; 19276 satDeviceData_t *pSatDevData; 19277 agsaFisRegHostToDevice_t *fis; 19278 #ifdef TD_DEBUG_ENABLE 19279 satInternalIo_t *satIntIoContext; 19280 tdsaDeviceData_t *oneDeviceData; 19281 tdIORequestBody_t *tdIORequestBody; 19282 #endif 19283 19284 pSatDevData = satIOContext->pSatDevData; 19285 fis = satIOContext->pFis; 19286 19287 TI_DBG5(("satSendIDDev: start\n")); 19288 #ifdef TD_DEBUG_ENABLE 19289 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 19290 #endif 19291 TI_DBG5(("satSendIDDev: did %d\n", oneDeviceData->id)); 19292 19293 19294 #ifdef TD_DEBUG_ENABLE 19295 satIntIoContext = satIOContext->satIntIoContext; 19296 tdIORequestBody = satIntIoContext->satIntRequestBody; 19297 #endif 19298 19299 TI_DBG5(("satSendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody)); 19300 19301 fis->h.fisType = 0x27; /* Reg host to device */ 19302 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19303 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE) 19304 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0x40 */ 19305 else 19306 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */ 19307 fis->h.features = 0; /* FIS reserve */ 19308 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 19309 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 19310 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 19311 fis->d.device = 0; /* FIS LBA mode */ 19312 fis->d.lbaLowExp = 0; 19313 fis->d.lbaMidExp = 0; 19314 fis->d.lbaHighExp = 0; 19315 fis->d.featuresExp = 0; 19316 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 19317 fis->d.sectorCountExp = 0; 19318 fis->d.reserved4 = 0; 19319 fis->d.control = 0; /* FIS HOB bit clear */ 19320 fis->d.reserved5 = 0; 19321 19322 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 19323 19324 /* Initialize CB for SATA completion. 19325 */ 19326 satIOContext->satCompleteCB = &satInquiryCB; 19327 19328 /* 19329 * Prepare SGL and send FIS to LL layer. 19330 */ 19331 satIOContext->reqType = agRequestType; /* Save it */ 19332 19333 #ifdef TD_INTERNAL_DEBUG 19334 tdhexdump("satSendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 19335 #ifdef TD_DEBUG_ENABLE 19336 tdhexdump("satSendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t)); 19337 #endif 19338 #endif 19339 19340 status = sataLLIOStart( tiRoot, 19341 tiIORequest, 19342 tiDeviceHandle, 19343 tiScsiRequest, 19344 satIOContext); 19345 19346 TI_DBG6(("satSendIDDev: end status %d\n", status)); 19347 return status; 19348 } 19349 19350 19351 /*****************************************************************************/ 19352 /*! \brief SAT implementation for SCSI INQUIRY. 19353 * 19354 * SAT implementation for SCSI INQUIRY. 19355 * This function prepares TD layer internal resource to send ATA 19356 * Identify Device data command for SCSI INQUIRY 19357 * 19358 * \param tiRoot: Pointer to TISA initiator driver/port instance. 19359 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 19360 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 19361 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 19362 * \param satIOContext_t: Pointer to the SAT IO Context 19363 * 19364 * \return If command is started successfully 19365 * - \e tiSuccess: I/O request successfully initiated. 19366 * - \e tiBusy: No resources available, try again later. 19367 * - \e tiIONoDevice: Invalid device handle. 19368 * - \e tiError: Other errors. 19369 */ 19370 /*****************************************************************************/ 19371 /* prerequsite: tdsaDeviceData and agdevhandle must exist; in other words, LL discovered the device 19372 already */ 19373 /* 19374 convert OS generated IO to TD generated IO due to difference in sgl 19375 */ 19376 GLOBAL bit32 satStartIDDev( 19377 tiRoot_t *tiRoot, 19378 tiIORequest_t *tiIORequest, 19379 tiDeviceHandle_t *tiDeviceHandle, 19380 tiScsiInitiatorRequest_t *tiScsiRequest, 19381 satIOContext_t *satIOContext 19382 ) 19383 { 19384 satInternalIo_t *satIntIo = agNULL; 19385 satDeviceData_t *satDevData = agNULL; 19386 tdIORequestBody_t *tdIORequestBody; 19387 satIOContext_t *satNewIOContext; 19388 bit32 status; 19389 19390 TI_DBG6(("satStartIDDev: start\n")); 19391 19392 satDevData = satIOContext->pSatDevData; 19393 19394 TI_DBG6(("satStartIDDev: before alloc\n")); 19395 19396 /* allocate identify device command */ 19397 satIntIo = satAllocIntIoResource( tiRoot, 19398 tiIORequest, 19399 satDevData, 19400 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */ 19401 satIntIo); 19402 19403 TI_DBG6(("satStartIDDev: before after\n")); 19404 19405 if (satIntIo == agNULL) 19406 { 19407 TI_DBG1(("satStartIDDev: can't alloacate\n")); 19408 19409 #if 0 19410 ostiInitiatorIOCompleted ( 19411 tiRoot, 19412 tiIORequest, 19413 tiIOFailed, 19414 tiDetailOtherError, 19415 agNULL, 19416 satIOContext->interruptContext 19417 ); 19418 #endif 19419 19420 return tiError; 19421 } 19422 19423 /* fill in fields */ 19424 /* real ttttttthe one worked and the same; 5/21/07/ */ 19425 satIntIo->satOrgTiIORequest = tiIORequest; /* changed */ 19426 tdIORequestBody = satIntIo->satIntRequestBody; 19427 satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext); 19428 19429 satNewIOContext->pSatDevData = satDevData; 19430 satNewIOContext->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 19431 satNewIOContext->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd); 19432 satNewIOContext->pSense = &(tdIORequestBody->transport.SATA.sensePayload); 19433 satNewIOContext->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData); 19434 satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */ 19435 satNewIOContext->interruptContext = tiInterruptContext; 19436 satNewIOContext->satIntIoContext = satIntIo; 19437 19438 satNewIOContext->ptiDeviceHandle = agNULL; 19439 satNewIOContext->satOrgIOContext = satIOContext; /* changed */ 19440 19441 /* this is valid only for TD layer generated (not triggered by OS at all) IO */ 19442 satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg); 19443 19444 19445 TI_DBG6(("satStartIDDev: OS satIOContext %p \n", satIOContext)); 19446 TI_DBG6(("satStartIDDev: TD satNewIOContext %p \n", satNewIOContext)); 19447 TI_DBG6(("satStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg)); 19448 TI_DBG6(("satStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg)); 19449 19450 19451 19452 TI_DBG1(("satStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody)); 19453 19454 status = satSendIDDev( tiRoot, 19455 &satIntIo->satIntTiIORequest, /* New tiIORequest */ 19456 tiDeviceHandle, 19457 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */ 19458 satNewIOContext); 19459 19460 if (status != tiSuccess) 19461 { 19462 TI_DBG1(("satStartIDDev: failed in sending\n")); 19463 19464 satFreeIntIoResource( tiRoot, 19465 satDevData, 19466 satIntIo); 19467 19468 #if 0 19469 ostiInitiatorIOCompleted ( 19470 tiRoot, 19471 tiIORequest, 19472 tiIOFailed, 19473 tiDetailOtherError, 19474 agNULL, 19475 satIOContext->interruptContext 19476 ); 19477 #endif 19478 19479 return tiError; 19480 } 19481 19482 19483 TI_DBG6(("satStartIDDev: end\n")); 19484 19485 return status; 19486 19487 19488 } 19489 19490 /*****************************************************************************/ 19491 /*! \brief satComputeCDB10LBA. 19492 * 19493 * This fuctions computes LBA of CDB10. 19494 * 19495 * \param satIOContext_t: Pointer to the SAT IO Context 19496 * 19497 * \return 19498 * - \e LBA 19499 */ 19500 /*****************************************************************************/ 19501 bit32 satComputeCDB10LBA(satIOContext_t *satIOContext) 19502 { 19503 tiIniScsiCmnd_t *scsiCmnd; 19504 tiScsiInitiatorRequest_t *tiScsiRequest; 19505 bit32 lba = 0; 19506 19507 TI_DBG5(("satComputeCDB10LBA: start\n")); 19508 tiScsiRequest = satIOContext->tiScsiXchg; 19509 scsiCmnd = &(tiScsiRequest->scsiCmnd); 19510 19511 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 19512 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 19513 19514 return lba; 19515 } 19516 19517 /*****************************************************************************/ 19518 /*! \brief satComputeCDB10TL. 19519 * 19520 * This fuctions computes transfer length of CDB10. 19521 * 19522 * \param satIOContext_t: Pointer to the SAT IO Context 19523 * 19524 * \return 19525 * - \e TL 19526 */ 19527 /*****************************************************************************/ 19528 bit32 satComputeCDB10TL(satIOContext_t *satIOContext) 19529 { 19530 19531 tiIniScsiCmnd_t *scsiCmnd; 19532 tiScsiInitiatorRequest_t *tiScsiRequest; 19533 bit32 tl = 0; 19534 19535 TI_DBG5(("satComputeCDB10TL: start\n")); 19536 tiScsiRequest = satIOContext->tiScsiXchg; 19537 scsiCmnd = &(tiScsiRequest->scsiCmnd); 19538 19539 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 19540 return tl; 19541 } 19542 19543 /*****************************************************************************/ 19544 /*! \brief satComputeCDB12LBA. 19545 * 19546 * This fuctions computes LBA of CDB12. 19547 * 19548 * \param satIOContext_t: Pointer to the SAT IO Context 19549 * 19550 * \return 19551 * - \e LBA 19552 */ 19553 /*****************************************************************************/ 19554 bit32 satComputeCDB12LBA(satIOContext_t *satIOContext) 19555 { 19556 tiIniScsiCmnd_t *scsiCmnd; 19557 tiScsiInitiatorRequest_t *tiScsiRequest; 19558 bit32 lba = 0; 19559 19560 TI_DBG5(("satComputeCDB10LBA: start\n")); 19561 tiScsiRequest = satIOContext->tiScsiXchg; 19562 scsiCmnd = &(tiScsiRequest->scsiCmnd); 19563 19564 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 19565 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 19566 19567 return lba; 19568 } 19569 19570 /*****************************************************************************/ 19571 /*! \brief satComputeCDB12TL. 19572 * 19573 * This fuctions computes transfer length of CDB12. 19574 * 19575 * \param satIOContext_t: Pointer to the SAT IO Context 19576 * 19577 * \return 19578 * - \e TL 19579 */ 19580 /*****************************************************************************/ 19581 bit32 satComputeCDB12TL(satIOContext_t *satIOContext) 19582 { 19583 19584 tiIniScsiCmnd_t *scsiCmnd; 19585 tiScsiInitiatorRequest_t *tiScsiRequest; 19586 bit32 tl = 0; 19587 19588 TI_DBG5(("satComputeCDB10TL: start\n")); 19589 tiScsiRequest = satIOContext->tiScsiXchg; 19590 scsiCmnd = &(tiScsiRequest->scsiCmnd); 19591 19592 tl = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2)) 19593 + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9]; 19594 return tl; 19595 } 19596 19597 19598 /*****************************************************************************/ 19599 /*! \brief satComputeCDB16LBA. 19600 * 19601 * This fuctions computes LBA of CDB16. 19602 * 19603 * \param satIOContext_t: Pointer to the SAT IO Context 19604 * 19605 * \return 19606 * - \e LBA 19607 */ 19608 /*****************************************************************************/ 19609 /* 19610 CBD16 has bit64 LBA 19611 But it has to be less than (2^28 - 1) 19612 Therefore, use last four bytes to compute LBA is OK 19613 */ 19614 bit32 satComputeCDB16LBA(satIOContext_t *satIOContext) 19615 { 19616 tiIniScsiCmnd_t *scsiCmnd; 19617 tiScsiInitiatorRequest_t *tiScsiRequest; 19618 bit32 lba = 0; 19619 19620 TI_DBG5(("satComputeCDB10LBA: start\n")); 19621 tiScsiRequest = satIOContext->tiScsiXchg; 19622 scsiCmnd = &(tiScsiRequest->scsiCmnd); 19623 19624 lba = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2)) 19625 + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9]; 19626 19627 return lba; 19628 } 19629 19630 /*****************************************************************************/ 19631 /*! \brief satComputeCDB16TL. 19632 * 19633 * This fuctions computes transfer length of CDB16. 19634 * 19635 * \param satIOContext_t: Pointer to the SAT IO Context 19636 * 19637 * \return 19638 * - \e TL 19639 */ 19640 /*****************************************************************************/ 19641 bit32 satComputeCDB16TL(satIOContext_t *satIOContext) 19642 { 19643 19644 tiIniScsiCmnd_t *scsiCmnd; 19645 tiScsiInitiatorRequest_t *tiScsiRequest; 19646 bit32 tl = 0; 19647 19648 TI_DBG5(("satComputeCDB10TL: start\n")); 19649 tiScsiRequest = satIOContext->tiScsiXchg; 19650 scsiCmnd = &(tiScsiRequest->scsiCmnd); 19651 19652 tl = (scsiCmnd->cdb[10] << (8*3)) + (scsiCmnd->cdb[11] << (8*2)) 19653 + (scsiCmnd->cdb[12] << 8) + scsiCmnd->cdb[13]; 19654 return tl; 19655 } 19656 19657 /*****************************************************************************/ 19658 /*! \brief satComputeLoopNum. 19659 * 19660 * This fuctions computes the number of interation needed for a transfer 19661 * length with a specific number. 19662 * 19663 * \param a: a numerator 19664 * \param b: a denominator 19665 * 19666 * \return 19667 * - \e number of interation 19668 */ 19669 /*****************************************************************************/ 19670 /* 19671 (tl, denom) 19672 tl can be upto bit32 because CDB16 has bit32 tl 19673 Therefore, fine 19674 either (tl, 0xFF) or (tl, 0xFFFF) 19675 */ 19676 bit32 satComputeLoopNum(bit32 a, bit32 b) 19677 { 19678 19679 bit32 quo = 0, rem = 0; 19680 bit32 LoopNum = 0; 19681 19682 TI_DBG5(("satComputeLoopNum: start\n")); 19683 19684 quo = a/b; 19685 19686 if (quo == 0) 19687 { 19688 LoopNum = 1; 19689 } 19690 else 19691 { 19692 rem = a % b; 19693 if (rem == 0) 19694 { 19695 LoopNum = quo; 19696 } 19697 else 19698 { 19699 LoopNum = quo + 1; 19700 } 19701 } 19702 19703 return LoopNum; 19704 } 19705 19706 /*****************************************************************************/ 19707 /*! \brief satAddNComparebit64. 19708 * 19709 * 19710 * 19711 * 19712 * \param a: lba 19713 * \param b: tl 19714 * 19715 * \return 19716 * - \e TRUE if (lba + tl > SAT_TR_LBA_LIMIT) 19717 * - \e FALSE otherwise 19718 * \note: a and b must be in the same length 19719 */ 19720 /*****************************************************************************/ 19721 /* 19722 input: bit8 a[8], bit8 b[8] (lba, tl) must be in same length 19723 if (lba + tl > SAT_TR_LBA_LIMIT) 19724 then returns true 19725 else returns false 19726 (LBA,TL) 19727 */ 19728 bit32 satAddNComparebit64(bit8 *a, bit8 *b) 19729 { 19730 bit16 ans[8]; // 0 MSB, 8 LSB 19731 bit8 final_ans[9]; // 0 MSB, 9 LSB 19732 bit8 max[9]; 19733 int i; 19734 19735 TI_DBG5(("satAddNComparebit64: start\n")); 19736 19737 osti_memset(ans, 0, sizeof(ans)); 19738 osti_memset(final_ans, 0, sizeof(final_ans)); 19739 osti_memset(max, 0, sizeof(max)); 19740 19741 max[0] = 0x1; //max = 0x1 0000 0000 0000 0000 19742 19743 // adding from LSB to MSB 19744 for(i=7;i>=0;i--) 19745 { 19746 ans[i] = (bit16)(a[i] + b[i]); 19747 if (i != 7) 19748 { 19749 ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8)); 19750 } 19751 } 19752 19753 /* 19754 filling in the final answer 19755 */ 19756 final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8)); 19757 final_ans[1] = (bit8)(ans[0] & 0xFF); 19758 19759 for(i=2;i<=8;i++) 19760 { 19761 final_ans[i] = (bit8)(ans[i-1] & 0xFF); 19762 } 19763 19764 //compare final_ans to max 19765 for(i=0;i<=8;i++) 19766 { 19767 if (final_ans[i] > max[i]) 19768 { 19769 TI_DBG5(("satAddNComparebit64: yes at %d\n", i)); 19770 return agTRUE; 19771 } 19772 else if (final_ans[i] < max[i]) 19773 { 19774 TI_DBG5(("satAddNComparebit64: no at %d\n", i)); 19775 return agFALSE; 19776 } 19777 else 19778 { 19779 continue; 19780 } 19781 } 19782 19783 19784 return agFALSE; 19785 } 19786 19787 /*****************************************************************************/ 19788 /*! \brief satAddNComparebit32. 19789 * 19790 * 19791 * 19792 * 19793 * \param a: lba 19794 * \param b: tl 19795 * 19796 * \return 19797 * - \e TRUE if (lba + tl > SAT_TR_LBA_LIMIT) 19798 * - \e FALSE otherwise 19799 * \note: a and b must be in the same length 19800 */ 19801 /*****************************************************************************/ 19802 /* 19803 input: bit8 a[4], bit8 b[4] (lba, tl) must be in same length 19804 if (lba + tl > SAT_TR_LBA_LIMIT) 19805 then returns true 19806 else returns false 19807 (LBA,TL) 19808 */ 19809 bit32 satAddNComparebit32(bit8 *a, bit8 *b) 19810 { 19811 bit16 ans[4]; // 0 MSB, 4 LSB 19812 bit8 final_ans[5]; // 0 MSB, 5 LSB 19813 bit8 max[4]; 19814 int i; 19815 19816 TI_DBG5(("satAddNComparebit32: start\n")); 19817 19818 osti_memset(ans, 0, sizeof(ans)); 19819 osti_memset(final_ans, 0, sizeof(final_ans)); 19820 osti_memset(max, 0, sizeof(max)); 19821 19822 max[0] = 0x10; // max =0x1000 0000 19823 19824 // adding from LSB to MSB 19825 for(i=3;i>=0;i--) 19826 { 19827 ans[i] = (bit16)(a[i] + b[i]); 19828 if (i != 3) 19829 { 19830 ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8)); 19831 } 19832 } 19833 19834 19835 /* 19836 filling in the final answer 19837 */ 19838 final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8)); 19839 final_ans[1] = (bit8)(ans[0] & 0xFF); 19840 19841 for(i=2;i<=4;i++) 19842 { 19843 final_ans[i] = (bit8)(ans[i-1] & 0xFF); 19844 } 19845 19846 //compare final_ans to max 19847 if (final_ans[0] != 0) 19848 { 19849 TI_DBG5(("satAddNComparebit32: yes bigger and out of range\n")); 19850 return agTRUE; 19851 } 19852 for(i=1;i<=4;i++) 19853 { 19854 if (final_ans[i] > max[i-1]) 19855 { 19856 TI_DBG5(("satAddNComparebit32: yes at %d\n", i)); 19857 return agTRUE; 19858 } 19859 else if (final_ans[i] < max[i-1]) 19860 { 19861 TI_DBG5(("satAddNComparebit32: no at %d\n", i)); 19862 return agFALSE; 19863 } 19864 else 19865 { 19866 continue; 19867 } 19868 } 19869 19870 19871 return agFALSE; 19872 } 19873 19874 /*****************************************************************************/ 19875 /*! \brief satCompareLBALimitbit. 19876 * 19877 * 19878 * 19879 * 19880 * \param lba: lba 19881 * 19882 * \return 19883 * - \e TRUE if (lba > SAT_TR_LBA_LIMIT - 1) 19884 * - \e FALSE otherwise 19885 * \note: a and b must be in the same length 19886 */ 19887 /*****************************************************************************/ 19888 19889 /* 19890 lba 19891 */ 19892 /* 19893 input: bit8 lba[8] 19894 if (lba > SAT_TR_LBA_LIMIT - 1) 19895 then returns true 19896 else returns false 19897 (LBA,TL) 19898 */ 19899 bit32 satCompareLBALimitbit(bit8 *lba) 19900 { 19901 bit32 i; 19902 bit8 limit[8]; 19903 19904 /* limit is 0xF FF FF = 2^28 - 1 */ 19905 limit[0] = 0x0; /* MSB */ 19906 limit[1] = 0x0; 19907 limit[2] = 0x0; 19908 limit[3] = 0x0; 19909 limit[4] = 0xF; 19910 limit[5] = 0xFF; 19911 limit[6] = 0xFF; 19912 limit[7] = 0xFF; /* LSB */ 19913 19914 //compare lba to limit 19915 for(i=0;i<8;i++) 19916 { 19917 if (lba[i] > limit[i]) 19918 { 19919 TI_DBG5(("satCompareLBALimitbit64: yes at %d\n", i)); 19920 return agTRUE; 19921 } 19922 else if (lba[i] < limit[i]) 19923 { 19924 TI_DBG5(("satCompareLBALimitbit64: no at %d\n", i)); 19925 return agFALSE; 19926 } 19927 else 19928 { 19929 continue; 19930 } 19931 } 19932 19933 19934 return agFALSE; 19935 19936 } 19937 /***************************************************************************** 19938 *! \brief 19939 * Purpose: bitwise set 19940 * 19941 * Parameters: 19942 * data - input output buffer 19943 * index - bit to set 19944 * 19945 * Return: 19946 * none 19947 * 19948 *****************************************************************************/ 19949 GLOBAL void 19950 satBitSet(bit8 *data, bit32 index) 19951 { 19952 data[index/8] |= (1 << (index%8)); 19953 } 19954 19955 /***************************************************************************** 19956 *! \brief 19957 * Purpose: bitwise clear 19958 * 19959 * Parameters: 19960 * data - input output buffer 19961 * index - bit to clear 19962 * 19963 * Return: 19964 * none 19965 * 19966 *****************************************************************************/ 19967 GLOBAL void 19968 satBitClear(bit8 *data, bit32 index) 19969 { 19970 data[index/8] &= ~(1 << (index%8)); 19971 } 19972 19973 /***************************************************************************** 19974 *! \brief 19975 * Purpose: bitwise test 19976 * 19977 * Parameters: 19978 * data - input output buffer 19979 * index - bit to test 19980 * 19981 * Return: 19982 * 0 - not set 19983 * 1 - set 19984 * 19985 *****************************************************************************/ 19986 GLOBAL agBOOLEAN 19987 satBitTest(bit8 *data, bit32 index) 19988 { 19989 return ( (BOOLEAN)((data[index/8] & (1 << (index%8)) ) ? 1: 0)); 19990 } 19991 19992 19993 /******************************************************************************/ 19994 /*! \brief allocate an available SATA tag 19995 * 19996 * allocate an available SATA tag 19997 * 19998 * \param tiRoot Pointer to TISA initiator driver/port instance. 19999 * \param pSatDevData 20000 * \param pTag 20001 * 20002 * \return -Success or fail- 20003 */ 20004 /*******************************************************************************/ 20005 GLOBAL bit32 satTagAlloc( 20006 tiRoot_t *tiRoot, 20007 satDeviceData_t *pSatDevData, 20008 bit8 *pTag 20009 ) 20010 { 20011 bit32 retCode = agFALSE; 20012 bit32 i; 20013 20014 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK); 20015 for ( i = 0; i < pSatDevData->satNCQMaxIO; i ++ ) 20016 { 20017 if ( 0 == satBitTest((bit8 *)&pSatDevData->freeSATAFDMATagBitmap, i) ) 20018 { 20019 satBitSet((bit8*)&pSatDevData->freeSATAFDMATagBitmap, i); 20020 *pTag = (bit8) i; 20021 retCode = agTRUE; 20022 break; 20023 } 20024 } 20025 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK); 20026 return retCode; 20027 } 20028 20029 /******************************************************************************/ 20030 /*! \brief release an SATA tag 20031 * 20032 * release an available SATA tag 20033 * 20034 * \param tiRoot Pointer to TISA initiator driver/port instance. 20035 * \param pSatDevData 20036 * \param Tag 20037 * 20038 * \return -the tag- 20039 */ 20040 /*******************************************************************************/ 20041 GLOBAL bit32 satTagRelease( 20042 tiRoot_t *tiRoot, 20043 satDeviceData_t *pSatDevData, 20044 bit8 tag 20045 ) 20046 { 20047 bit32 retCode = agFALSE; 20048 20049 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK); 20050 if ( tag < pSatDevData->satNCQMaxIO ) 20051 { 20052 satBitClear( (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, (bit32)tag); 20053 retCode = agTRUE; 20054 } 20055 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK); 20056 return retCode; 20057 } 20058 20059 /***************************************************************************** 20060 *! \brief satSubTM 20061 * 20062 * This routine is called to initiate a TM request to SATL. 20063 * This routine is independent of HW/LL API. 20064 * 20065 * \param tiRoot: Pointer to TISA initiator driver/port instance. 20066 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 20067 * \param task: SAM-3 task management request. 20068 * \param lun: Pointer to LUN. 20069 * \param taskTag: Pointer to the associated task where the TM 20070 * command is to be applied. 20071 * \param currentTaskTag: Pointer to tag/context for this TM request. 20072 * \param NotifyOS flag determines whether notify OS layer or not 20073 * 20074 * \return: 20075 * 20076 * \e tiSuccess: I/O request successfully initiated. 20077 * \e tiBusy: No resources available, try again later. 20078 * \e tiIONoDevice: Invalid device handle. 20079 * \e tiError: Other errors that prevent the I/O request to be started. 20080 * 20081 * \note: 20082 * This funcion is triggered bottom up. Not yet in use. 20083 *****************************************************************************/ 20084 /* called for bottom up */ 20085 osGLOBAL bit32 satSubTM( 20086 tiRoot_t *tiRoot, 20087 tiDeviceHandle_t *tiDeviceHandle, 20088 bit32 task, 20089 tiLUN_t *lun, 20090 tiIORequest_t *taskTag, 20091 tiIORequest_t *currentTaskTag, 20092 bit32 NotifyOS 20093 ) 20094 { 20095 void *osMemHandle; 20096 tdIORequestBody_t *TMtdIORequestBody; 20097 bit32 PhysUpper32; 20098 bit32 PhysLower32; 20099 bit32 memAllocStatus; 20100 agsaIORequest_t *agIORequest = agNULL; 20101 20102 TI_DBG6(("satSubTM: start\n")); 20103 20104 /* allocation tdIORequestBody and pass it to satTM() */ 20105 memAllocStatus = ostiAllocMemory( 20106 tiRoot, 20107 &osMemHandle, 20108 (void **)&TMtdIORequestBody, 20109 &PhysUpper32, 20110 &PhysLower32, 20111 8, 20112 sizeof(tdIORequestBody_t), 20113 agTRUE 20114 ); 20115 20116 if (memAllocStatus != tiSuccess) 20117 { 20118 TI_DBG1(("satSubTM: ostiAllocMemory failed... \n")); 20119 return tiError; 20120 } 20121 20122 if (TMtdIORequestBody == agNULL) 20123 { 20124 TI_DBG1(("satSubTM: ostiAllocMemory returned NULL TMIORequestBody\n")); 20125 return tiError; 20126 } 20127 20128 /* setup task management structure */ 20129 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 20130 TMtdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = agNULL; 20131 TMtdIORequestBody->IOType.InitiatorTMIO.TaskTag = agNULL; 20132 20133 /* initialize tiDevhandle */ 20134 TMtdIORequestBody->tiDevHandle = tiDeviceHandle; 20135 20136 /* initialize tiIORequest */ 20137 TMtdIORequestBody->tiIORequest = agNULL; 20138 20139 /* initialize agIORequest */ 20140 agIORequest = &(TMtdIORequestBody->agIORequest); 20141 agIORequest->osData = (void *) TMtdIORequestBody; 20142 agIORequest->sdkData = agNULL; /* SA takes care of this */ 20143 satTM(tiRoot, 20144 tiDeviceHandle, 20145 task, /* TD_INTERNAL_TM_RESET */ 20146 agNULL, 20147 agNULL, 20148 agNULL, 20149 TMtdIORequestBody, 20150 agFALSE); 20151 20152 return tiSuccess; 20153 } 20154 20155 20156 /*****************************************************************************/ 20157 /*! \brief SAT implementation for satStartResetDevice. 20158 * 20159 * SAT implementation for sending SRT and send FIS request to LL layer. 20160 * 20161 * \param tiRoot: Pointer to TISA initiator driver/port instance. 20162 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 20163 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 20164 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 20165 * \param satIOContext_t: Pointer to the SAT IO Context 20166 * 20167 * \return If command is started successfully 20168 * - \e tiSuccess: I/O request successfully initiated. 20169 * - \e tiBusy: No resources available, try again later. 20170 * - \e tiIONoDevice: Invalid device handle. 20171 * - \e tiError: Other errors. 20172 * \note : triggerred by OS layer or bottom up 20173 */ 20174 /*****************************************************************************/ 20175 /* OS triggerred or bottom up */ 20176 GLOBAL bit32 20177 satStartResetDevice( 20178 tiRoot_t *tiRoot, 20179 tiIORequest_t *tiIORequest, /* currentTaskTag */ 20180 tiDeviceHandle_t *tiDeviceHandle, 20181 tiScsiInitiatorRequest_t *tiScsiRequest, /* should be NULL */ 20182 satIOContext_t *satIOContext 20183 ) 20184 { 20185 satInternalIo_t *satIntIo = agNULL; 20186 satDeviceData_t *satDevData = agNULL; 20187 satIOContext_t *satNewIOContext; 20188 bit32 status; 20189 tiIORequest_t *currentTaskTag = agNULL; 20190 20191 TI_DBG1(("satStartResetDevice: start\n")); 20192 20193 currentTaskTag = tiIORequest; 20194 20195 satDevData = satIOContext->pSatDevData; 20196 20197 TI_DBG6(("satStartResetDevice: before alloc\n")); 20198 20199 /* allocate any fis for seting SRT bit in device control */ 20200 satIntIo = satAllocIntIoResource( tiRoot, 20201 tiIORequest, 20202 satDevData, 20203 0, 20204 satIntIo); 20205 20206 TI_DBG6(("satStartResetDevice: before after\n")); 20207 20208 if (satIntIo == agNULL) 20209 { 20210 TI_DBG1(("satStartResetDevice: can't alloacate\n")); 20211 if (satIOContext->NotifyOS) 20212 { 20213 ostiInitiatorEvent( tiRoot, 20214 NULL, 20215 NULL, 20216 tiIntrEventTypeTaskManagement, 20217 tiTMFailed, 20218 currentTaskTag ); 20219 } 20220 return tiError; 20221 } 20222 20223 satNewIOContext = satPrepareNewIO(satIntIo, 20224 tiIORequest, 20225 satDevData, 20226 agNULL, 20227 satIOContext); 20228 20229 TI_DBG6(("satStartResetDevice: OS satIOContext %p \n", satIOContext)); 20230 TI_DBG6(("satStartResetDevice: TD satNewIOContext %p \n", satNewIOContext)); 20231 TI_DBG6(("satStartResetDevice: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg)); 20232 TI_DBG6(("satStartResetDevice: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg)); 20233 20234 20235 20236 TI_DBG6(("satStartResetDevice: satNewIOContext %p \n", satNewIOContext)); 20237 20238 if (satDevData->satDeviceType == SATA_ATAPI_DEVICE) 20239 { 20240 status = satDeviceReset(tiRoot, 20241 &satIntIo->satIntTiIORequest, /* New tiIORequest */ 20242 tiDeviceHandle, 20243 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */ 20244 satNewIOContext); 20245 } 20246 else 20247 { 20248 status = satResetDevice(tiRoot, 20249 &satIntIo->satIntTiIORequest, /* New tiIORequest */ 20250 tiDeviceHandle, 20251 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */ 20252 satNewIOContext); 20253 } 20254 20255 if (status != tiSuccess) 20256 { 20257 TI_DBG1(("satStartResetDevice: failed in sending\n")); 20258 20259 satFreeIntIoResource( tiRoot, 20260 satDevData, 20261 satIntIo); 20262 if (satIOContext->NotifyOS) 20263 { 20264 ostiInitiatorEvent( tiRoot, 20265 NULL, 20266 NULL, 20267 tiIntrEventTypeTaskManagement, 20268 tiTMFailed, 20269 currentTaskTag ); 20270 } 20271 20272 return tiError; 20273 } 20274 20275 20276 TI_DBG6(("satStartResetDevice: end\n")); 20277 20278 return status; 20279 } 20280 20281 /*****************************************************************************/ 20282 /*! \brief SAT implementation for satResetDevice. 20283 * 20284 * SAT implementation for building SRT FIS and sends the request to LL layer. 20285 * 20286 * \param tiRoot: Pointer to TISA initiator driver/port instance. 20287 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 20288 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 20289 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 20290 * \param satIOContext_t: Pointer to the SAT IO Context 20291 * 20292 * \return If command is started successfully 20293 * - \e tiSuccess: I/O request successfully initiated. 20294 * - \e tiBusy: No resources available, try again later. 20295 * - \e tiIONoDevice: Invalid device handle. 20296 * - \e tiError: Other errors. 20297 */ 20298 /*****************************************************************************/ 20299 20300 /* 20301 create any fis and set SRST bit in device control 20302 */ 20303 GLOBAL bit32 20304 satResetDevice( 20305 tiRoot_t *tiRoot, 20306 tiIORequest_t *tiIORequest, 20307 tiDeviceHandle_t *tiDeviceHandle, 20308 tiScsiInitiatorRequest_t *tiScsiRequest, 20309 satIOContext_t *satIOContext 20310 ) 20311 { 20312 bit32 status; 20313 bit32 agRequestType; 20314 agsaFisRegHostToDevice_t *fis; 20315 #ifdef TD_DEBUG_ENABLE 20316 tdIORequestBody_t *tdIORequestBody; 20317 satInternalIo_t *satIntIoContext; 20318 #endif 20319 20320 fis = satIOContext->pFis; 20321 20322 TI_DBG2(("satResetDevice: start\n")); 20323 20324 #ifdef TD_DEBUG_ENABLE 20325 satIntIoContext = satIOContext->satIntIoContext; 20326 tdIORequestBody = satIntIoContext->satIntRequestBody; 20327 #endif 20328 TI_DBG5(("satResetDevice: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody)); 20329 /* any fis should work */ 20330 fis->h.fisType = 0x27; /* Reg host to device */ 20331 fis->h.c_pmPort = 0; /* C Bit is not set */ 20332 fis->h.command = 0; /* any command */ 20333 fis->h.features = 0; /* FIS reserve */ 20334 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 20335 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 20336 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 20337 fis->d.device = 0; /* FIS LBA mode */ 20338 fis->d.lbaLowExp = 0; 20339 fis->d.lbaMidExp = 0; 20340 fis->d.lbaHighExp = 0; 20341 fis->d.featuresExp = 0; 20342 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 20343 fis->d.sectorCountExp = 0; 20344 fis->d.reserved4 = 0; 20345 fis->d.control = 0x4; /* SRST bit is set */ 20346 fis->d.reserved5 = 0; 20347 20348 agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT; 20349 20350 satIOContext->satCompleteCB = &satResetDeviceCB; 20351 20352 /* 20353 * Prepare SGL and send FIS to LL layer. 20354 */ 20355 satIOContext->reqType = agRequestType; /* Save it */ 20356 20357 #ifdef TD_INTERNAL_DEBUG 20358 tdhexdump("satResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 20359 #ifdef TD_DEBUG_ENABLE 20360 tdhexdump("satResetDevice LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t)); 20361 #endif 20362 #endif 20363 20364 status = sataLLIOStart( tiRoot, 20365 tiIORequest, 20366 tiDeviceHandle, 20367 tiScsiRequest, 20368 satIOContext); 20369 20370 TI_DBG6(("satResetDevice: end status %d\n", status)); 20371 return status; 20372 } 20373 20374 /***************************************************************************** 20375 *! \brief satResetDeviceCB 20376 * 20377 * This routine is a callback function called from ossaSATACompleted(). 20378 * This CB routine deals with SRT completion. This function send DSRT 20379 * 20380 * \param agRoot: Handles for this instance of SAS/SATA hardware 20381 * \param agIORequest: Pointer to the LL I/O request context for this I/O. 20382 * \param agIOStatus: Status of completed I/O. 20383 * \param agFirstDword:Pointer to the four bytes of FIS. 20384 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS 20385 * length. 20386 * \param agParam: Additional info based on status. 20387 * \param ioContext: Pointer to satIOContext_t. 20388 * 20389 * \return: none 20390 * 20391 *****************************************************************************/ 20392 GLOBAL void satResetDeviceCB( 20393 agsaRoot_t *agRoot, 20394 agsaIORequest_t *agIORequest, 20395 bit32 agIOStatus, 20396 agsaFisHeader_t *agFirstDword, 20397 bit32 agIOInfoLen, 20398 agsaFrameHandle_t agFrameHandle, 20399 void *ioContext 20400 ) 20401 { 20402 /* callback for satResetDevice */ 20403 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 20404 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 20405 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 20406 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 20407 tdIORequestBody_t *tdIORequestBody; 20408 tdIORequestBody_t *tdOrgIORequestBody; 20409 satIOContext_t *satIOContext; 20410 satIOContext_t *satOrgIOContext; 20411 satIOContext_t *satNewIOContext; 20412 satInternalIo_t *satIntIo; 20413 satInternalIo_t *satNewIntIo = agNULL; 20414 satDeviceData_t *satDevData; 20415 tiIORequest_t *tiOrgIORequest; 20416 #ifdef TD_DEBUG_ENABLE 20417 bit32 ataStatus = 0; 20418 bit32 ataError; 20419 agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL; 20420 #endif 20421 bit32 status; 20422 20423 TI_DBG1(("satResetDeviceCB: start\n")); 20424 TI_DBG6(("satResetDeviceCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen)); 20425 20426 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; 20427 satIOContext = (satIOContext_t *) ioContext; 20428 satIntIo = satIOContext->satIntIoContext; 20429 satDevData = satIOContext->pSatDevData; 20430 if (satIntIo == agNULL) 20431 { 20432 TI_DBG6(("satResetDeviceCB: External, OS generated\n")); 20433 satOrgIOContext = satIOContext; 20434 tiOrgIORequest = tdIORequestBody->tiIORequest; 20435 } 20436 else 20437 { 20438 TI_DBG6(("satResetDeviceCB: Internal, TD generated\n")); 20439 satOrgIOContext = satIOContext->satOrgIOContext; 20440 if (satOrgIOContext == agNULL) 20441 { 20442 TI_DBG6(("satResetDeviceCB: satOrgIOContext is NULL, wrong\n")); 20443 return; 20444 } 20445 else 20446 { 20447 TI_DBG6(("satResetDeviceCB: satOrgIOContext is NOT NULL\n")); 20448 } 20449 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody; 20450 tiOrgIORequest = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest; 20451 } 20452 20453 tdIORequestBody->ioCompleted = agTRUE; 20454 tdIORequestBody->ioStarted = agFALSE; 20455 20456 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS) 20457 { 20458 TI_DBG1(("satResetDeviceCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus)); 20459 if (satOrgIOContext->NotifyOS == agTRUE) 20460 { 20461 ostiInitiatorEvent( tiRoot, 20462 NULL, 20463 NULL, 20464 tiIntrEventTypeTaskManagement, 20465 tiTMFailed, 20466 tiOrgIORequest ); 20467 } 20468 20469 satDevData->satTmTaskTag = agNULL; 20470 20471 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 20472 20473 satFreeIntIoResource( tiRoot, 20474 satDevData, 20475 satIntIo); 20476 return; 20477 } 20478 20479 if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED || 20480 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION || 20481 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK || 20482 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS || 20483 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION || 20484 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED || 20485 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION || 20486 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR || 20487 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY 20488 ) 20489 { 20490 TI_DBG1(("satResetDeviceCB: OSSA_IO_OPEN_CNX_ERROR\n")); 20491 20492 if (satOrgIOContext->NotifyOS == agTRUE) 20493 { 20494 ostiInitiatorEvent( tiRoot, 20495 NULL, 20496 NULL, 20497 tiIntrEventTypeTaskManagement, 20498 tiTMFailed, 20499 tiOrgIORequest ); 20500 } 20501 20502 satDevData->satTmTaskTag = agNULL; 20503 20504 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 20505 20506 satFreeIntIoResource( tiRoot, 20507 satDevData, 20508 satIntIo); 20509 return; 20510 } 20511 20512 if (agIOStatus != OSSA_IO_SUCCESS) 20513 { 20514 #ifdef TD_DEBUG_ENABLE 20515 /* only agsaFisPioSetup_t is expected */ 20516 satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup); 20517 ataStatus = satPIOSetupHeader->status; /* ATA Status register */ 20518 ataError = satPIOSetupHeader->error; /* ATA Eror register */ 20519 #endif 20520 TI_DBG1(("satResetDeviceCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError)); 20521 20522 if (satOrgIOContext->NotifyOS == agTRUE) 20523 { 20524 ostiInitiatorEvent( tiRoot, 20525 NULL, 20526 NULL, 20527 tiIntrEventTypeTaskManagement, 20528 tiTMFailed, 20529 tiOrgIORequest ); 20530 } 20531 20532 satDevData->satTmTaskTag = agNULL; 20533 20534 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 20535 20536 satFreeIntIoResource( tiRoot, 20537 satDevData, 20538 satIntIo); 20539 return; 20540 } 20541 20542 /* success */ 20543 20544 satNewIntIo = satAllocIntIoResource( tiRoot, 20545 tiOrgIORequest, 20546 satDevData, 20547 0, 20548 satNewIntIo); 20549 if (satNewIntIo == agNULL) 20550 { 20551 satDevData->satTmTaskTag = agNULL; 20552 20553 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 20554 20555 /* memory allocation failure */ 20556 satFreeIntIoResource( tiRoot, 20557 satDevData, 20558 satNewIntIo); 20559 20560 if (satOrgIOContext->NotifyOS == agTRUE) 20561 { 20562 ostiInitiatorEvent( tiRoot, 20563 NULL, 20564 NULL, 20565 tiIntrEventTypeTaskManagement, 20566 tiTMFailed, 20567 tiOrgIORequest ); 20568 } 20569 20570 20571 TI_DBG1(("satResetDeviceCB: momory allocation fails\n")); 20572 return; 20573 } /* end of memory allocation failure */ 20574 20575 /* 20576 * Need to initialize all the fields within satIOContext 20577 */ 20578 20579 satNewIOContext = satPrepareNewIO( 20580 satNewIntIo, 20581 tiOrgIORequest, 20582 satDevData, 20583 agNULL, 20584 satOrgIOContext 20585 ); 20586 20587 20588 20589 20590 /* send AGSA_SATA_PROTOCOL_SRST_DEASSERT */ 20591 status = satDeResetDevice(tiRoot, 20592 tiOrgIORequest, 20593 satOrgIOContext->ptiDeviceHandle, 20594 agNULL, 20595 satNewIOContext 20596 ); 20597 20598 if (status != tiSuccess) 20599 { 20600 if (satOrgIOContext->NotifyOS == agTRUE) 20601 { 20602 ostiInitiatorEvent( tiRoot, 20603 NULL, 20604 NULL, 20605 tiIntrEventTypeTaskManagement, 20606 tiTMFailed, 20607 tiOrgIORequest ); 20608 } 20609 20610 /* sending AGSA_SATA_PROTOCOL_SRST_DEASSERT fails */ 20611 20612 satDevData->satTmTaskTag = agNULL; 20613 20614 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 20615 20616 satFreeIntIoResource( tiRoot, 20617 satDevData, 20618 satNewIntIo); 20619 return; 20620 20621 } 20622 20623 satDevData->satTmTaskTag = agNULL; 20624 20625 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 20626 20627 satFreeIntIoResource( tiRoot, 20628 satDevData, 20629 satIntIo); 20630 TI_DBG5(("satResetDeviceCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO)); 20631 TI_DBG6(("satResetDeviceCB: end\n")); 20632 return; 20633 20634 } 20635 20636 20637 /*****************************************************************************/ 20638 /*! \brief SAT implementation for satDeResetDevice. 20639 * 20640 * SAT implementation for building DSRT FIS and sends the request to LL layer. 20641 * 20642 * \param tiRoot: Pointer to TISA initiator driver/port instance. 20643 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 20644 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 20645 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 20646 * \param satIOContext_t: Pointer to the SAT IO Context 20647 * 20648 * \return If command is started successfully 20649 * - \e tiSuccess: I/O request successfully initiated. 20650 * - \e tiBusy: No resources available, try again later. 20651 * - \e tiIONoDevice: Invalid device handle. 20652 * - \e tiError: Other errors. 20653 */ 20654 /*****************************************************************************/ 20655 GLOBAL bit32 satDeResetDevice( 20656 tiRoot_t *tiRoot, 20657 tiIORequest_t *tiIORequest, 20658 tiDeviceHandle_t *tiDeviceHandle, 20659 tiScsiInitiatorRequest_t *tiScsiRequest, 20660 satIOContext_t *satIOContext 20661 ) 20662 { 20663 bit32 status; 20664 bit32 agRequestType; 20665 agsaFisRegHostToDevice_t *fis; 20666 #ifdef TD_DEBUG_ENABLE 20667 tdIORequestBody_t *tdIORequestBody; 20668 satInternalIo_t *satIntIoContext; 20669 #endif 20670 fis = satIOContext->pFis; 20671 20672 TI_DBG6(("satDeResetDevice: start\n")); 20673 20674 #ifdef TD_DEBUG_ENABLE 20675 satIntIoContext = satIOContext->satIntIoContext; 20676 tdIORequestBody = satIntIoContext->satIntRequestBody; 20677 TI_DBG5(("satDeResetDevice: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody)); 20678 #endif 20679 /* any fis should work */ 20680 fis->h.fisType = 0x27; /* Reg host to device */ 20681 fis->h.c_pmPort = 0; /* C Bit is not set */ 20682 fis->h.command = 0; /* any command */ 20683 fis->h.features = 0; /* FIS reserve */ 20684 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 20685 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 20686 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 20687 fis->d.device = 0; /* FIS LBA mode */ 20688 fis->d.lbaLowExp = 0; 20689 fis->d.lbaMidExp = 0; 20690 fis->d.lbaHighExp = 0; 20691 fis->d.featuresExp = 0; 20692 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 20693 fis->d.sectorCountExp = 0; 20694 fis->d.reserved4 = 0; 20695 fis->d.control = 0; /* SRST bit is not set */ 20696 fis->d.reserved5 = 0; 20697 20698 agRequestType = AGSA_SATA_PROTOCOL_SRST_DEASSERT; 20699 20700 satIOContext->satCompleteCB = &satDeResetDeviceCB; 20701 20702 /* 20703 * Prepare SGL and send FIS to LL layer. 20704 */ 20705 satIOContext->reqType = agRequestType; /* Save it */ 20706 20707 #ifdef TD_INTERNAL_DEBUG 20708 tdhexdump("satDeResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 20709 #ifdef TD_DEBUG_ENABLE 20710 tdhexdump("satDeResetDevice LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t)); 20711 #endif 20712 #endif 20713 20714 status = sataLLIOStart( tiRoot, 20715 tiIORequest, 20716 tiDeviceHandle, 20717 tiScsiRequest, 20718 satIOContext); 20719 20720 TI_DBG6(("satDeResetDevice: end status %d\n", status)); 20721 return status; 20722 20723 } 20724 20725 /***************************************************************************** 20726 *! \brief satDeResetDeviceCB 20727 * 20728 * This routine is a callback function called from ossaSATACompleted(). 20729 * This CB routine deals with DSRT completion. 20730 * 20731 * \param agRoot: Handles for this instance of SAS/SATA hardware 20732 * \param agIORequest: Pointer to the LL I/O request context for this I/O. 20733 * \param agIOStatus: Status of completed I/O. 20734 * \param agFirstDword:Pointer to the four bytes of FIS. 20735 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS 20736 * length. 20737 * \param agParam: Additional info based on status. 20738 * \param ioContext: Pointer to satIOContext_t. 20739 * 20740 * \return: none 20741 * 20742 *****************************************************************************/ 20743 GLOBAL void satDeResetDeviceCB( 20744 agsaRoot_t *agRoot, 20745 agsaIORequest_t *agIORequest, 20746 bit32 agIOStatus, 20747 agsaFisHeader_t *agFirstDword, 20748 bit32 agIOInfoLen, 20749 agsaFrameHandle_t agFrameHandle, 20750 void *ioContext 20751 ) 20752 { 20753 /* callback for satDeResetDevice */ 20754 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 20755 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 20756 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 20757 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 20758 tdIORequestBody_t *tdIORequestBody; 20759 tdIORequestBody_t *tdOrgIORequestBody = agNULL; 20760 satIOContext_t *satIOContext; 20761 satIOContext_t *satOrgIOContext; 20762 satInternalIo_t *satIntIo; 20763 satDeviceData_t *satDevData; 20764 tiIORequest_t *tiOrgIORequest; 20765 #ifdef TD_DEBUG_ENABLE 20766 bit32 ataStatus = 0; 20767 bit32 ataError; 20768 agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL; 20769 #endif 20770 bit32 report = agFALSE; 20771 bit32 AbortTM = agFALSE; 20772 20773 TI_DBG1(("satDeResetDeviceCB: start\n")); 20774 TI_DBG6(("satDeResetDeviceCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen)); 20775 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; 20776 satIOContext = (satIOContext_t *) ioContext; 20777 satIntIo = satIOContext->satIntIoContext; 20778 satDevData = satIOContext->pSatDevData; 20779 if (satIntIo == agNULL) 20780 { 20781 TI_DBG6(("satDeResetDeviceCB: External, OS generated\n")); 20782 satOrgIOContext = satIOContext; 20783 tiOrgIORequest = tdIORequestBody->tiIORequest; 20784 } 20785 else 20786 { 20787 TI_DBG6(("satDeResetDeviceCB: Internal, TD generated\n")); 20788 satOrgIOContext = satIOContext->satOrgIOContext; 20789 if (satOrgIOContext == agNULL) 20790 { 20791 TI_DBG6(("satDeResetDeviceCB: satOrgIOContext is NULL, wrong\n")); 20792 return; 20793 } 20794 else 20795 { 20796 TI_DBG6(("satDeResetDeviceCB: satOrgIOContext is NOT NULL\n")); 20797 } 20798 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody; 20799 tiOrgIORequest = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest; 20800 } 20801 20802 tdIORequestBody->ioCompleted = agTRUE; 20803 tdIORequestBody->ioStarted = agFALSE; 20804 20805 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS) 20806 { 20807 TI_DBG1(("satDeResetDeviceCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus)); 20808 if (satOrgIOContext->NotifyOS == agTRUE) 20809 { 20810 ostiInitiatorEvent( tiRoot, 20811 NULL, 20812 NULL, 20813 tiIntrEventTypeTaskManagement, 20814 tiTMFailed, 20815 tiOrgIORequest ); 20816 } 20817 20818 satDevData->satTmTaskTag = agNULL; 20819 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 20820 20821 satFreeIntIoResource( tiRoot, 20822 satDevData, 20823 satIntIo); 20824 return; 20825 } 20826 20827 if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED || 20828 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION || 20829 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK || 20830 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS || 20831 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION || 20832 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED || 20833 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION || 20834 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR || 20835 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY 20836 ) 20837 { 20838 TI_DBG1(("satDeResetDeviceCB: OSSA_IO_OPEN_CNX_ERROR\n")); 20839 20840 if (satOrgIOContext->NotifyOS == agTRUE) 20841 { 20842 ostiInitiatorEvent( tiRoot, 20843 NULL, 20844 NULL, 20845 tiIntrEventTypeTaskManagement, 20846 tiTMFailed, 20847 tiOrgIORequest ); 20848 } 20849 20850 satDevData->satTmTaskTag = agNULL; 20851 20852 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 20853 20854 satFreeIntIoResource( tiRoot, 20855 satDevData, 20856 satIntIo); 20857 return; 20858 } 20859 20860 if (agIOStatus != OSSA_IO_SUCCESS) 20861 { 20862 #ifdef TD_DEBUG_ENABLE 20863 /* only agsaFisPioSetup_t is expected */ 20864 satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup); 20865 ataStatus = satPIOSetupHeader->status; /* ATA Status register */ 20866 ataError = satPIOSetupHeader->error; /* ATA Eror register */ 20867 #endif 20868 TI_DBG1(("satDeResetDeviceCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError)); 20869 20870 if (satOrgIOContext->NotifyOS == agTRUE) 20871 { 20872 ostiInitiatorEvent( tiRoot, 20873 NULL, 20874 NULL, 20875 tiIntrEventTypeTaskManagement, 20876 tiTMFailed, 20877 tiOrgIORequest ); 20878 } 20879 20880 satDevData->satTmTaskTag = agNULL; 20881 20882 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 20883 20884 satFreeIntIoResource( tiRoot, 20885 satDevData, 20886 satIntIo); 20887 return; 20888 } 20889 20890 /* success */ 20891 TI_DBG1(("satDeResetDeviceCB: success \n")); 20892 TI_DBG1(("satDeResetDeviceCB: TMF %d\n", satOrgIOContext->TMF)); 20893 20894 if (satOrgIOContext->TMF == AG_ABORT_TASK) 20895 { 20896 AbortTM = agTRUE; 20897 } 20898 20899 if (satOrgIOContext->NotifyOS == agTRUE) 20900 { 20901 report = agTRUE; 20902 } 20903 20904 if (AbortTM == agTRUE) 20905 { 20906 TI_DBG1(("satDeResetDeviceCB: calling satAbort\n")); 20907 satAbort(agRoot, satOrgIOContext->satToBeAbortedIOContext); 20908 } 20909 satDevData->satTmTaskTag = agNULL; 20910 20911 satDevData->satDriveState = SAT_DEV_STATE_NORMAL; 20912 20913 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 20914 20915 TI_DBG1(("satDeResetDeviceCB: satPendingIO %d satNCQMaxIO %d\n", satDevData->satPendingIO, satDevData->satNCQMaxIO )); 20916 TI_DBG1(("satDeResetDeviceCB: satPendingNCQIO %d satPendingNONNCQIO %d\n", satDevData->satPendingNCQIO, satDevData->satPendingNONNCQIO)); 20917 20918 satFreeIntIoResource( tiRoot, 20919 satDevData, 20920 satIntIo); 20921 20922 /* clean up TD layer's IORequestBody */ 20923 if (tdOrgIORequestBody != agNULL) 20924 { 20925 ostiFreeMemory( 20926 tiRoot, 20927 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 20928 sizeof(tdIORequestBody_t) 20929 ); 20930 } 20931 else 20932 { 20933 TI_DBG1(("satDeResetDeviceCB: tdOrgIORequestBody is NULL, wrong\n")); 20934 } 20935 20936 20937 if (report) 20938 { 20939 ostiInitiatorEvent( tiRoot, 20940 NULL, 20941 NULL, 20942 tiIntrEventTypeTaskManagement, 20943 tiTMOK, 20944 tiOrgIORequest ); 20945 } 20946 20947 20948 TI_DBG5(("satDeResetDeviceCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO)); 20949 TI_DBG6(("satDeResetDeviceCB: end\n")); 20950 return; 20951 20952 } 20953 20954 /*****************************************************************************/ 20955 /*! \brief SAT implementation for satStartCheckPowerMode. 20956 * 20957 * SAT implementation for abort task management for non-ncq sata disk. 20958 * This function sends CHECK POWER MODE 20959 * 20960 * \param tiRoot: Pointer to TISA initiator driver/port instance. 20961 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 20962 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 20963 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 20964 * \param satIOContext_t: Pointer to the SAT IO Context 20965 * 20966 * \return If command is started successfully 20967 * - \e tiSuccess: I/O request successfully initiated. 20968 * - \e tiBusy: No resources available, try again later. 20969 * - \e tiIONoDevice: Invalid device handle. 20970 * - \e tiError: Other errors. 20971 */ 20972 /*****************************************************************************/ 20973 GLOBAL bit32 satStartCheckPowerMode( 20974 tiRoot_t *tiRoot, 20975 tiIORequest_t *tiIORequest, 20976 tiDeviceHandle_t *tiDeviceHandle, 20977 tiScsiInitiatorRequest_t *tiScsiRequest, /* NULL */ 20978 satIOContext_t *satIOContext 20979 ) 20980 { 20981 satInternalIo_t *satIntIo = agNULL; 20982 satDeviceData_t *satDevData = agNULL; 20983 satIOContext_t *satNewIOContext; 20984 bit32 status; 20985 tiIORequest_t *currentTaskTag = agNULL; 20986 20987 TI_DBG6(("satStartCheckPowerMode: start\n")); 20988 20989 currentTaskTag = tiIORequest; 20990 20991 satDevData = satIOContext->pSatDevData; 20992 20993 TI_DBG6(("satStartCheckPowerMode: before alloc\n")); 20994 20995 /* allocate any fis for seting SRT bit in device control */ 20996 satIntIo = satAllocIntIoResource( tiRoot, 20997 tiIORequest, 20998 satDevData, 20999 0, 21000 satIntIo); 21001 21002 TI_DBG6(("satStartCheckPowerMode: before after\n")); 21003 21004 if (satIntIo == agNULL) 21005 { 21006 TI_DBG1(("satStartCheckPowerMode: can't alloacate\n")); 21007 if (satIOContext->NotifyOS) 21008 { 21009 ostiInitiatorEvent( tiRoot, 21010 NULL, 21011 NULL, 21012 tiIntrEventTypeTaskManagement, 21013 tiTMFailed, 21014 currentTaskTag ); 21015 } 21016 return tiError; 21017 } 21018 21019 satNewIOContext = satPrepareNewIO(satIntIo, 21020 tiIORequest, 21021 satDevData, 21022 agNULL, 21023 satIOContext); 21024 21025 TI_DBG6(("satStartCheckPowerMode: OS satIOContext %p \n", satIOContext)); 21026 TI_DBG6(("satStartCheckPowerMode: TD satNewIOContext %p \n", satNewIOContext)); 21027 TI_DBG6(("satStartCheckPowerMode: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg)); 21028 TI_DBG6(("satStartCheckPowerMode: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg)); 21029 21030 21031 21032 TI_DBG1(("satStartCheckPowerMode: satNewIOContext %p \n", satNewIOContext)); 21033 21034 status = satCheckPowerMode(tiRoot, 21035 &satIntIo->satIntTiIORequest, /* New tiIORequest */ 21036 tiDeviceHandle, 21037 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */ 21038 satNewIOContext); 21039 21040 if (status != tiSuccess) 21041 { 21042 TI_DBG1(("satStartCheckPowerMode: failed in sending\n")); 21043 21044 satFreeIntIoResource( tiRoot, 21045 satDevData, 21046 satIntIo); 21047 if (satIOContext->NotifyOS) 21048 { 21049 ostiInitiatorEvent( tiRoot, 21050 NULL, 21051 NULL, 21052 tiIntrEventTypeTaskManagement, 21053 tiTMFailed, 21054 currentTaskTag ); 21055 } 21056 21057 return tiError; 21058 } 21059 21060 21061 TI_DBG6(("satStartCheckPowerMode: end\n")); 21062 21063 return status; 21064 } 21065 21066 /*****************************************************************************/ 21067 /*! \brief SAT implementation for satCheckPowerMode. 21068 * 21069 * This function creates CHECK POWER MODE fis and sends the request to LL layer 21070 * 21071 * \param tiRoot: Pointer to TISA initiator driver/port instance. 21072 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 21073 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 21074 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 21075 * \param satIOContext_t: Pointer to the SAT IO Context 21076 * 21077 * \return If command is started successfully 21078 * - \e tiSuccess: I/O request successfully initiated. 21079 * - \e tiBusy: No resources available, try again later. 21080 * - \e tiIONoDevice: Invalid device handle. 21081 * - \e tiError: Other errors. 21082 */ 21083 /*****************************************************************************/ 21084 GLOBAL bit32 satCheckPowerMode( 21085 tiRoot_t *tiRoot, 21086 tiIORequest_t *tiIORequest, 21087 tiDeviceHandle_t *tiDeviceHandle, 21088 tiScsiInitiatorRequest_t *tiScsiRequest, 21089 satIOContext_t *satIOContext 21090 ) 21091 { 21092 /* 21093 sends SAT_CHECK_POWER_MODE as a part of ABORT TASKMANGEMENT for NCQ commands 21094 internally generated - no directly corresponding scsi 21095 */ 21096 bit32 status; 21097 bit32 agRequestType; 21098 agsaFisRegHostToDevice_t *fis; 21099 21100 fis = satIOContext->pFis; 21101 TI_DBG5(("satCheckPowerMode: start\n")); 21102 /* 21103 * Send the ATA CHECK POWER MODE command. 21104 */ 21105 fis->h.fisType = 0x27; /* Reg host to device */ 21106 fis->h.c_pmPort = 0x80; /* C Bit is set */ 21107 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */ 21108 fis->h.features = 0; 21109 fis->d.lbaLow = 0; 21110 fis->d.lbaMid = 0; 21111 fis->d.lbaHigh = 0; 21112 fis->d.device = 0; 21113 fis->d.lbaLowExp = 0; 21114 fis->d.lbaMidExp = 0; 21115 fis->d.lbaHighExp = 0; 21116 fis->d.featuresExp = 0; 21117 fis->d.sectorCount = 0; 21118 fis->d.sectorCountExp = 0; 21119 fis->d.reserved4 = 0; 21120 fis->d.control = 0; /* FIS HOB bit clear */ 21121 fis->d.reserved5 = 0; 21122 21123 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 21124 21125 /* Initialize CB for SATA completion. 21126 */ 21127 satIOContext->satCompleteCB = &satCheckPowerModeCB; 21128 21129 /* 21130 * Prepare SGL and send FIS to LL layer. 21131 */ 21132 satIOContext->reqType = agRequestType; /* Save it */ 21133 21134 status = sataLLIOStart( tiRoot, 21135 tiIORequest, 21136 tiDeviceHandle, 21137 tiScsiRequest, 21138 satIOContext); 21139 21140 TI_DBG5(("satCheckPowerMode: return\n")); 21141 21142 return status; 21143 } 21144 21145 /***************************************************************************** 21146 *! \brief satCheckPowerModeCB 21147 * 21148 * This routine is a callback function called from ossaSATACompleted(). 21149 * This CB routine deals with CHECK POWER MODE completion as abort task 21150 * management. 21151 * 21152 * \param agRoot: Handles for this instance of SAS/SATA hardware 21153 * \param agIORequest: Pointer to the LL I/O request context for this I/O. 21154 * \param agIOStatus: Status of completed I/O. 21155 * \param agFirstDword:Pointer to the four bytes of FIS. 21156 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS 21157 * length. 21158 * \param agParam: Additional info based on status. 21159 * \param ioContext: Pointer to satIOContext_t. 21160 * 21161 * \return: none 21162 * 21163 *****************************************************************************/ 21164 GLOBAL void satCheckPowerModeCB( 21165 agsaRoot_t *agRoot, 21166 agsaIORequest_t *agIORequest, 21167 bit32 agIOStatus, 21168 agsaFisHeader_t *agFirstDword, 21169 bit32 agIOInfoLen, 21170 agsaFrameHandle_t agFrameHandle, 21171 void *ioContext 21172 ) 21173 { 21174 /* callback for satDeResetDevice */ 21175 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 21176 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 21177 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 21178 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 21179 tdIORequestBody_t *tdIORequestBody; 21180 tdIORequestBody_t *tdOrgIORequestBody = agNULL; 21181 satIOContext_t *satIOContext; 21182 satIOContext_t *satOrgIOContext; 21183 satInternalIo_t *satIntIo; 21184 satDeviceData_t *satDevData; 21185 21186 tiIORequest_t *tiOrgIORequest; 21187 #ifdef TD_DEBUG_ENABLE 21188 bit32 ataStatus = 0; 21189 bit32 ataError; 21190 agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL; 21191 #endif 21192 bit32 report = agFALSE; 21193 bit32 AbortTM = agFALSE; 21194 21195 21196 TI_DBG1(("satCheckPowerModeCB: start\n")); 21197 21198 TI_DBG1(("satCheckPowerModeCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen)); 21199 21200 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; 21201 satIOContext = (satIOContext_t *) ioContext; 21202 satIntIo = satIOContext->satIntIoContext; 21203 satDevData = satIOContext->pSatDevData; 21204 if (satIntIo == agNULL) 21205 { 21206 TI_DBG6(("satCheckPowerModeCB: External, OS generated\n")); 21207 satOrgIOContext = satIOContext; 21208 tiOrgIORequest = tdIORequestBody->tiIORequest; 21209 } 21210 else 21211 { 21212 TI_DBG6(("satCheckPowerModeCB: Internal, TD generated\n")); 21213 satOrgIOContext = satIOContext->satOrgIOContext; 21214 if (satOrgIOContext == agNULL) 21215 { 21216 TI_DBG6(("satCheckPowerModeCB: satOrgIOContext is NULL, wrong\n")); 21217 return; 21218 } 21219 else 21220 { 21221 TI_DBG6(("satCheckPowerModeCB: satOrgIOContext is NOT NULL\n")); 21222 } 21223 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody; 21224 tiOrgIORequest = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest; 21225 } 21226 21227 21228 tdIORequestBody->ioCompleted = agTRUE; 21229 tdIORequestBody->ioStarted = agFALSE; 21230 21231 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS) 21232 { 21233 TI_DBG1(("satCheckPowerModeCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus)); 21234 21235 if (satOrgIOContext->NotifyOS == agTRUE) 21236 { 21237 ostiInitiatorEvent( tiRoot, 21238 NULL, 21239 NULL, 21240 tiIntrEventTypeTaskManagement, 21241 tiTMFailed, 21242 tiOrgIORequest ); 21243 } 21244 21245 satDevData->satTmTaskTag = agNULL; 21246 21247 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 21248 21249 satFreeIntIoResource( tiRoot, 21250 satDevData, 21251 satIntIo); 21252 return; 21253 } 21254 21255 if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED || 21256 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION || 21257 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK || 21258 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS || 21259 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION || 21260 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED || 21261 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION || 21262 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR || 21263 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY 21264 ) 21265 { 21266 TI_DBG1(("satCheckPowerModeCB: OSSA_IO_OPEN_CNX_ERROR\n")); 21267 21268 if (satOrgIOContext->NotifyOS == agTRUE) 21269 { 21270 ostiInitiatorEvent( tiRoot, 21271 NULL, 21272 NULL, 21273 tiIntrEventTypeTaskManagement, 21274 tiTMFailed, 21275 tiOrgIORequest ); 21276 } 21277 21278 satDevData->satTmTaskTag = agNULL; 21279 21280 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 21281 21282 satFreeIntIoResource( tiRoot, 21283 satDevData, 21284 satIntIo); 21285 return; 21286 } 21287 21288 if (agIOStatus != OSSA_IO_SUCCESS) 21289 { 21290 #ifdef TD_DEBUG_ENABLE 21291 /* only agsaFisPioSetup_t is expected */ 21292 satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup); 21293 ataStatus = satPIOSetupHeader->status; /* ATA Status register */ 21294 ataError = satPIOSetupHeader->error; /* ATA Eror register */ 21295 #endif 21296 TI_DBG1(("satCheckPowerModeCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError)); 21297 21298 if (satOrgIOContext->NotifyOS == agTRUE) 21299 { 21300 ostiInitiatorEvent( tiRoot, 21301 NULL, 21302 NULL, 21303 tiIntrEventTypeTaskManagement, 21304 tiTMFailed, 21305 tiOrgIORequest ); 21306 } 21307 21308 satDevData->satTmTaskTag = agNULL; 21309 21310 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 21311 21312 satFreeIntIoResource( tiRoot, 21313 satDevData, 21314 satIntIo); 21315 return; 21316 } 21317 21318 /* success */ 21319 TI_DBG1(("satCheckPowerModeCB: success\n")); 21320 TI_DBG1(("satCheckPowerModeCB: TMF %d\n", satOrgIOContext->TMF)); 21321 21322 if (satOrgIOContext->TMF == AG_ABORT_TASK) 21323 { 21324 AbortTM = agTRUE; 21325 } 21326 21327 if (satOrgIOContext->NotifyOS == agTRUE) 21328 { 21329 report = agTRUE; 21330 } 21331 if (AbortTM == agTRUE) 21332 { 21333 TI_DBG1(("satCheckPowerModeCB: calling satAbort\n")); 21334 satAbort(agRoot, satOrgIOContext->satToBeAbortedIOContext); 21335 } 21336 satDevData->satTmTaskTag = agNULL; 21337 21338 satDevData->satDriveState = SAT_DEV_STATE_NORMAL; 21339 21340 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 21341 21342 TI_DBG1(("satCheckPowerModeCB: satPendingIO %d satNCQMaxIO %d\n", satDevData->satPendingIO, satDevData->satNCQMaxIO )); 21343 TI_DBG1(("satCheckPowerModeCB: satPendingNCQIO %d satPendingNONNCQIO %d\n", satDevData->satPendingNCQIO, satDevData->satPendingNONNCQIO)); 21344 21345 satFreeIntIoResource( tiRoot, 21346 satDevData, 21347 satIntIo); 21348 21349 /* clean up TD layer's IORequestBody */ 21350 if (tdOrgIORequestBody != agNULL) 21351 { 21352 ostiFreeMemory( 21353 tiRoot, 21354 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 21355 sizeof(tdIORequestBody_t) 21356 ); 21357 } 21358 else 21359 { 21360 TI_DBG1(("satCheckPowerModeCB: tdOrgIORequestBody is NULL, wrong\n")); 21361 } 21362 if (report) 21363 { 21364 ostiInitiatorEvent( tiRoot, 21365 NULL, 21366 NULL, 21367 tiIntrEventTypeTaskManagement, 21368 tiTMOK, 21369 tiOrgIORequest ); 21370 } 21371 21372 TI_DBG5(("satCheckPowerModeCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO)); 21373 TI_DBG2(("satCheckPowerModeCB: end\n")); 21374 return; 21375 21376 } 21377 21378 /*****************************************************************************/ 21379 /*! \brief SAT implementation for satAddSATAStartIDDev. 21380 * 21381 * This function sends identify device data to find out the uniqueness 21382 * of device. 21383 * 21384 * \param tiRoot: Pointer to TISA initiator driver/port instance. 21385 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 21386 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 21387 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 21388 * \param satIOContext_t: Pointer to the SAT IO Context 21389 * 21390 * \return If command is started successfully 21391 * - \e tiSuccess: I/O request successfully initiated. 21392 * - \e tiBusy: No resources available, try again later. 21393 * - \e tiIONoDevice: Invalid device handle. 21394 * - \e tiError: Other errors. 21395 */ 21396 /*****************************************************************************/ 21397 GLOBAL bit32 satAddSATAStartIDDev( 21398 tiRoot_t *tiRoot, 21399 tiIORequest_t *tiIORequest, 21400 tiDeviceHandle_t *tiDeviceHandle, 21401 tiScsiInitiatorRequest_t *tiScsiRequest, // NULL 21402 satIOContext_t *satIOContext 21403 ) 21404 { 21405 satInternalIo_t *satIntIo = agNULL; 21406 satDeviceData_t *satDevData = agNULL; 21407 tdIORequestBody_t *tdIORequestBody; 21408 satIOContext_t *satNewIOContext; 21409 bit32 status; 21410 21411 TI_DBG2(("satAddSATAStartIDDev: start\n")); 21412 21413 satDevData = satIOContext->pSatDevData; 21414 21415 TI_DBG2(("satAddSATAStartIDDev: before alloc\n")); 21416 21417 /* allocate identify device command */ 21418 satIntIo = satAllocIntIoResource( tiRoot, 21419 tiIORequest, 21420 satDevData, 21421 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */ 21422 satIntIo); 21423 21424 TI_DBG2(("satAddSATAStartIDDev: after alloc\n")); 21425 21426 if (satIntIo == agNULL) 21427 { 21428 TI_DBG1(("satAddSATAStartIDDev: can't alloacate\n")); 21429 21430 return tiError; 21431 } 21432 21433 /* fill in fields */ 21434 /* real ttttttthe one worked and the same; 5/21/07/ */ 21435 satIntIo->satOrgTiIORequest = tiIORequest; /* changed */ 21436 tdIORequestBody = satIntIo->satIntRequestBody; 21437 satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext); 21438 21439 satNewIOContext->pSatDevData = satDevData; 21440 satNewIOContext->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 21441 satNewIOContext->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd); 21442 satNewIOContext->pSense = &(tdIORequestBody->transport.SATA.sensePayload); 21443 satNewIOContext->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData); 21444 satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */ 21445 satNewIOContext->interruptContext = tiInterruptContext; 21446 satNewIOContext->satIntIoContext = satIntIo; 21447 21448 satNewIOContext->ptiDeviceHandle = agNULL; 21449 satNewIOContext->satOrgIOContext = satIOContext; /* changed */ 21450 21451 /* this is valid only for TD layer generated (not triggered by OS at all) IO */ 21452 satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg); 21453 21454 21455 TI_DBG6(("satAddSATAStartIDDev: OS satIOContext %p \n", satIOContext)); 21456 TI_DBG6(("satAddSATAStartIDDev: TD satNewIOContext %p \n", satNewIOContext)); 21457 TI_DBG6(("satAddSATAStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg)); 21458 TI_DBG6(("satAddSATAStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg)); 21459 21460 21461 21462 TI_DBG2(("satAddSATAStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody)); 21463 21464 status = satAddSATASendIDDev( tiRoot, 21465 &satIntIo->satIntTiIORequest, /* New tiIORequest */ 21466 tiDeviceHandle, 21467 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */ 21468 satNewIOContext); 21469 21470 if (status != tiSuccess) 21471 { 21472 TI_DBG1(("satAddSATAStartIDDev: failed in sending\n")); 21473 21474 satFreeIntIoResource( tiRoot, 21475 satDevData, 21476 satIntIo); 21477 21478 return tiError; 21479 } 21480 21481 21482 TI_DBG6(("satAddSATAStartIDDev: end\n")); 21483 21484 return status; 21485 21486 21487 } 21488 21489 /*****************************************************************************/ 21490 /*! \brief SAT implementation for satAddSATASendIDDev. 21491 * 21492 * This function creates identify device data fis and send it to LL 21493 * 21494 * \param tiRoot: Pointer to TISA initiator driver/port instance. 21495 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 21496 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 21497 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 21498 * \param satIOContext_t: Pointer to the SAT IO Context 21499 * 21500 * \return If command is started successfully 21501 * - \e tiSuccess: I/O request successfully initiated. 21502 * - \e tiBusy: No resources available, try again later. 21503 * - \e tiIONoDevice: Invalid device handle. 21504 * - \e tiError: Other errors. 21505 */ 21506 /*****************************************************************************/ 21507 GLOBAL bit32 satAddSATASendIDDev( 21508 tiRoot_t *tiRoot, 21509 tiIORequest_t *tiIORequest, 21510 tiDeviceHandle_t *tiDeviceHandle, 21511 tiScsiInitiatorRequest_t *tiScsiRequest, 21512 satIOContext_t *satIOContext) 21513 { 21514 bit32 status; 21515 bit32 agRequestType; 21516 satDeviceData_t *pSatDevData; 21517 agsaFisRegHostToDevice_t *fis; 21518 #ifdef TD_DEBUG_ENABLE 21519 tdIORequestBody_t *tdIORequestBody; 21520 satInternalIo_t *satIntIoContext; 21521 #endif 21522 21523 pSatDevData = satIOContext->pSatDevData; 21524 fis = satIOContext->pFis; 21525 TI_DBG2(("satAddSATASendIDDev: start\n")); 21526 #ifdef TD_DEBUG_ENABLE 21527 satIntIoContext = satIOContext->satIntIoContext; 21528 tdIORequestBody = satIntIoContext->satIntRequestBody; 21529 #endif 21530 TI_DBG5(("satAddSATASendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody)); 21531 21532 fis->h.fisType = 0x27; /* Reg host to device */ 21533 fis->h.c_pmPort = 0x80; /* C Bit is set */ 21534 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE) 21535 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0x40 */ 21536 else 21537 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */ 21538 fis->h.features = 0; /* FIS reserve */ 21539 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 21540 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 21541 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 21542 fis->d.device = 0; /* FIS LBA mode */ 21543 fis->d.lbaLowExp = 0; 21544 fis->d.lbaMidExp = 0; 21545 fis->d.lbaHighExp = 0; 21546 fis->d.featuresExp = 0; 21547 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 21548 fis->d.sectorCountExp = 0; 21549 fis->d.reserved4 = 0; 21550 fis->d.control = 0; /* FIS HOB bit clear */ 21551 fis->d.reserved5 = 0; 21552 21553 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 21554 21555 /* Initialize CB for SATA completion. 21556 */ 21557 satIOContext->satCompleteCB = &satAddSATAIDDevCB; 21558 21559 /* 21560 * Prepare SGL and send FIS to LL layer. 21561 */ 21562 satIOContext->reqType = agRequestType; /* Save it */ 21563 21564 #ifdef TD_INTERNAL_DEBUG 21565 tdhexdump("satAddSATASendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 21566 #ifdef TD_DEBUG_ENABLE 21567 tdhexdump("satAddSATASendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t)); 21568 #endif 21569 #endif 21570 21571 status = sataLLIOStart( tiRoot, 21572 tiIORequest, 21573 tiDeviceHandle, 21574 tiScsiRequest, 21575 satIOContext); 21576 21577 TI_DBG2(("satAddSATASendIDDev: end status %d\n", status)); 21578 return status; 21579 } 21580 21581 /***************************************************************************** 21582 *! \brief satAddSATAIDDevCB 21583 * 21584 * This routine is a callback function for satAddSATASendIDDev() 21585 * Using Identify Device Data, this function finds whether devicedata is 21586 * new or old. If new, add it to the devicelist. 21587 * 21588 * \param agRoot: Handles for this instance of SAS/SATA hardware 21589 * \param agIORequest: Pointer to the LL I/O request context for this I/O. 21590 * \param agIOStatus: Status of completed I/O. 21591 * \param agFirstDword:Pointer to the four bytes of FIS. 21592 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS 21593 * length. 21594 * \param agParam: Additional info based on status. 21595 * \param ioContext: Pointer to satIOContext_t. 21596 * 21597 * \return: none 21598 * 21599 *****************************************************************************/ 21600 void satAddSATAIDDevCB( 21601 agsaRoot_t *agRoot, 21602 agsaIORequest_t *agIORequest, 21603 bit32 agIOStatus, 21604 agsaFisHeader_t *agFirstDword, 21605 bit32 agIOInfoLen, 21606 void *agParam, 21607 void *ioContext 21608 ) 21609 { 21610 21611 /* 21612 In the process of Inquiry 21613 Process SAT_IDENTIFY_DEVICE 21614 */ 21615 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 21616 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 21617 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 21618 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 21619 tdIORequestBody_t *tdIORequestBody; 21620 tdIORequestBody_t *tdOrgIORequestBody; 21621 satIOContext_t *satIOContext; 21622 satIOContext_t *satOrgIOContext; 21623 satIOContext_t *satNewIOContext; 21624 satInternalIo_t *satIntIo; 21625 satInternalIo_t *satNewIntIo = agNULL; 21626 satDeviceData_t *satDevData; 21627 tiIORequest_t *tiOrgIORequest = agNULL; 21628 agsaSATAIdentifyData_t *pSATAIdData; 21629 bit16 *tmpptr, tmpptr_tmp; 21630 bit32 x; 21631 tdsaDeviceData_t *NewOneDeviceData = agNULL; 21632 tdsaDeviceData_t *oneDeviceData = agNULL; 21633 tdList_t *DeviceListList; 21634 int new_device = agTRUE; 21635 bit8 PhyID; 21636 void *sglVirtualAddr; 21637 bit32 retry_status; 21638 agsaContext_t *agContext; 21639 tdsaPortContext_t *onePortContext; 21640 bit32 status = 0; 21641 21642 TI_DBG2(("satAddSATAIDDevCB: start\n")); 21643 TI_DBG6(("satAddSATAIDDevCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen)); 21644 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; 21645 satIOContext = (satIOContext_t *) ioContext; 21646 satIntIo = satIOContext->satIntIoContext; 21647 satDevData = satIOContext->pSatDevData; 21648 21649 NewOneDeviceData = (tdsaDeviceData_t *)tdIORequestBody->tiDevHandle->tdData; 21650 TI_DBG2(("satAddSATAIDDevCB: NewOneDeviceData %p did %d\n", NewOneDeviceData, NewOneDeviceData->id)); 21651 PhyID = NewOneDeviceData->phyID; 21652 TI_DBG2(("satAddSATAIDDevCB: phyID %d\n", PhyID)); 21653 agContext = &(NewOneDeviceData->agDeviceResetContext); 21654 agContext->osData = agNULL; 21655 if (satIntIo == agNULL) 21656 { 21657 TI_DBG1(("satAddSATAIDDevCB: External, OS generated\n")); 21658 TI_DBG1(("satAddSATAIDDevCB: Not possible case\n")); 21659 satOrgIOContext = satIOContext; 21660 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody; 21661 tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData); 21662 21663 /* put onedevicedata back to free list */ 21664 osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t)); 21665 TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink)); 21666 TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList)); 21667 21668 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 21669 21670 satFreeIntIoResource( tiRoot, 21671 satDevData, 21672 satIntIo); 21673 /* clean up TD layer's IORequestBody */ 21674 ostiFreeMemory( 21675 tiRoot, 21676 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 21677 sizeof(tdIORequestBody_t) 21678 ); 21679 21680 /* notifying link up */ 21681 ostiPortEvent ( 21682 tiRoot, 21683 tiPortLinkUp, 21684 tiSuccess, 21685 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext 21686 ); 21687 #ifdef INITIATOR_DRIVER 21688 /* triggers discovery */ 21689 ostiPortEvent( 21690 tiRoot, 21691 tiPortDiscoveryReady, 21692 tiSuccess, 21693 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext 21694 ); 21695 #endif 21696 return; 21697 } 21698 else 21699 { 21700 TI_DBG1(("satAddSATAIDDevCB: Internal, TD generated\n")); 21701 satOrgIOContext = satIOContext->satOrgIOContext; 21702 if (satOrgIOContext == agNULL) 21703 { 21704 TI_DBG6(("satAddSATAIDDevCB: satOrgIOContext is NULL\n")); 21705 return; 21706 } 21707 else 21708 { 21709 TI_DBG6(("satAddSATAIDDevCB: satOrgIOContext is NOT NULL\n")); 21710 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody; 21711 sglVirtualAddr = satIntIo->satIntTiScsiXchg.sglVirtualAddr; 21712 } 21713 } 21714 tiOrgIORequest = tdIORequestBody->tiIORequest; 21715 21716 tdIORequestBody->ioCompleted = agTRUE; 21717 tdIORequestBody->ioStarted = agFALSE; 21718 TI_DBG2(("satAddSATAIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid)); 21719 /* protect against double completion for old port */ 21720 if (satOrgIOContext->pid != tdsaAllShared->Ports[PhyID].portContext->id) 21721 { 21722 TI_DBG2(("satAddSATAIDDevCB: incorrect pid\n")); 21723 TI_DBG2(("satAddSATAIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid)); 21724 TI_DBG2(("satAddSATAIDDevCB: tiPortalContext pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id)); 21725 tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData); 21726 /* put onedevicedata back to free list */ 21727 osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t)); 21728 TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink)); 21729 TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList)); 21730 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 21731 21732 satFreeIntIoResource( tiRoot, 21733 satDevData, 21734 satIntIo); 21735 /* clean up TD layer's IORequestBody */ 21736 ostiFreeMemory( 21737 tiRoot, 21738 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 21739 sizeof(tdIORequestBody_t) 21740 ); 21741 /* no notification to OS layer */ 21742 return; 21743 } 21744 /* completion after portcontext is invalidated */ 21745 onePortContext = NewOneDeviceData->tdPortContext; 21746 if (onePortContext != agNULL) 21747 { 21748 if (onePortContext->valid == agFALSE) 21749 { 21750 TI_DBG1(("satAddSATAIDDevCB: portcontext is invalid\n")); 21751 TI_DBG1(("satAddSATAIDDevCB: onePortContext->id pid %d\n", onePortContext->id)); 21752 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 21753 21754 satFreeIntIoResource( tiRoot, 21755 satDevData, 21756 satIntIo); 21757 /* clean up TD layer's IORequestBody */ 21758 ostiFreeMemory( 21759 tiRoot, 21760 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 21761 sizeof(tdIORequestBody_t) 21762 ); 21763 /* no notification to OS layer */ 21764 return; 21765 } 21766 } 21767 else 21768 { 21769 TI_DBG1(("satAddSATAIDDevCB: onePortContext is NULL!!!\n")); 21770 return; 21771 } 21772 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS) 21773 { 21774 TI_DBG1(("satAddSATAIDDevCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus)); 21775 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES) 21776 { 21777 satDevData->satPendingNONNCQIO--; 21778 satDevData->satPendingIO--; 21779 retry_status = sataLLIOStart(tiRoot, 21780 &satIntIo->satIntTiIORequest, 21781 &(NewOneDeviceData->tiDeviceHandle), 21782 satIOContext->tiScsiXchg, 21783 satIOContext); 21784 if (retry_status != tiSuccess) 21785 { 21786 /* simply give up */ 21787 satDevData->ID_Retries = 0; 21788 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21789 return; 21790 } 21791 satDevData->ID_Retries++; 21792 tdIORequestBody->ioCompleted = agFALSE; 21793 tdIORequestBody->ioStarted = agTRUE; 21794 return; 21795 } 21796 else 21797 { 21798 if (tdsaAllShared->ResetInDiscovery == 0) 21799 { 21800 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21801 } 21802 else /* ResetInDiscovery in on */ 21803 { 21804 /* RESET only one after ID retries */ 21805 if (satDevData->NumOfIDRetries <= 0) 21806 { 21807 satDevData->NumOfIDRetries++; 21808 satDevData->ID_Retries = 0; 21809 satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21810 /* send link reset */ 21811 saLocalPhyControl(agRoot, 21812 agContext, 21813 tdsaRotateQnumber(tiRoot, NewOneDeviceData), 21814 PhyID, 21815 AGSA_PHY_HARD_RESET, 21816 agNULL); 21817 } 21818 else 21819 { 21820 satDevData->ID_Retries = 0; 21821 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21822 } 21823 } 21824 return; 21825 } 21826 } 21827 if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED || 21828 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION || 21829 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK || 21830 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS || 21831 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION || 21832 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED || 21833 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION || 21834 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR || 21835 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY 21836 ) 21837 { 21838 TI_DBG1(("satAddSATAIDDevCB: OSSA_IO_OPEN_CNX_ERROR\n")); 21839 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES) 21840 { 21841 satDevData->satPendingNONNCQIO--; 21842 satDevData->satPendingIO--; 21843 retry_status = sataLLIOStart(tiRoot, 21844 &satIntIo->satIntTiIORequest, 21845 &(NewOneDeviceData->tiDeviceHandle), 21846 satIOContext->tiScsiXchg, 21847 satIOContext); 21848 if (retry_status != tiSuccess) 21849 { 21850 /* simply give up */ 21851 satDevData->ID_Retries = 0; 21852 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21853 return; 21854 } 21855 satDevData->ID_Retries++; 21856 tdIORequestBody->ioCompleted = agFALSE; 21857 tdIORequestBody->ioStarted = agTRUE; 21858 return; 21859 } 21860 else 21861 { 21862 if (tdsaAllShared->ResetInDiscovery == 0) 21863 { 21864 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21865 } 21866 else /* ResetInDiscovery in on */ 21867 { 21868 /* RESET only one after ID retries */ 21869 if (satDevData->NumOfIDRetries <= 0) 21870 { 21871 satDevData->NumOfIDRetries++; 21872 satDevData->ID_Retries = 0; 21873 satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21874 /* send link reset */ 21875 saLocalPhyControl(agRoot, 21876 agContext, 21877 tdsaRotateQnumber(tiRoot, NewOneDeviceData), 21878 PhyID, 21879 AGSA_PHY_HARD_RESET, 21880 agNULL); 21881 } 21882 else 21883 { 21884 satDevData->ID_Retries = 0; 21885 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21886 } 21887 } 21888 return; 21889 } 21890 } 21891 21892 if ( agIOStatus != OSSA_IO_SUCCESS || 21893 (agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0) 21894 ) 21895 { 21896 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES) 21897 { 21898 satIOContext->pSatDevData->satPendingNONNCQIO--; 21899 satIOContext->pSatDevData->satPendingIO--; 21900 retry_status = sataLLIOStart(tiRoot, 21901 &satIntIo->satIntTiIORequest, 21902 &(NewOneDeviceData->tiDeviceHandle), 21903 satIOContext->tiScsiXchg, 21904 satIOContext); 21905 if (retry_status != tiSuccess) 21906 { 21907 /* simply give up */ 21908 satDevData->ID_Retries = 0; 21909 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21910 return; 21911 } 21912 satDevData->ID_Retries++; 21913 tdIORequestBody->ioCompleted = agFALSE; 21914 tdIORequestBody->ioStarted = agTRUE; 21915 return; 21916 } 21917 else 21918 { 21919 if (tdsaAllShared->ResetInDiscovery == 0) 21920 { 21921 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21922 } 21923 else /* ResetInDiscovery in on */ 21924 { 21925 /* RESET only one after ID retries */ 21926 if (satDevData->NumOfIDRetries <= 0) 21927 { 21928 satDevData->NumOfIDRetries++; 21929 satDevData->ID_Retries = 0; 21930 satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21931 /* send link reset */ 21932 saLocalPhyControl(agRoot, 21933 agContext, 21934 tdsaRotateQnumber(tiRoot, NewOneDeviceData), 21935 PhyID, 21936 AGSA_PHY_HARD_RESET, 21937 agNULL); 21938 } 21939 else 21940 { 21941 satDevData->ID_Retries = 0; 21942 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21943 } 21944 } 21945 return; 21946 } 21947 } 21948 21949 /* success */ 21950 TI_DBG2(("satAddSATAIDDevCB: Success\n")); 21951 /* Convert to host endian */ 21952 tmpptr = (bit16*)sglVirtualAddr; 21953 //tdhexdump("satAddSATAIDDevCB before", (bit8 *)sglVirtualAddr, sizeof(agsaSATAIdentifyData_t)); 21954 for (x=0; x < sizeof(agsaSATAIdentifyData_t)/sizeof(bit16); x++) 21955 { 21956 OSSA_READ_LE_16(AGROOT, &tmpptr_tmp, tmpptr, 0); 21957 *tmpptr = tmpptr_tmp; 21958 tmpptr++; 21959 /*Print tmpptr_tmp here for debugging purpose*/ 21960 } 21961 21962 pSATAIdData = (agsaSATAIdentifyData_t *)sglVirtualAddr; 21963 //tdhexdump("satAddSATAIDDevCB after", (bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t)); 21964 21965 TI_DBG5(("satAddSATAIDDevCB: OS satOrgIOContext %p \n", satOrgIOContext)); 21966 TI_DBG5(("satAddSATAIDDevCB: TD satIOContext %p \n", satIOContext)); 21967 TI_DBG5(("satAddSATAIDDevCB: OS tiScsiXchg %p \n", satOrgIOContext->tiScsiXchg)); 21968 TI_DBG5(("satAddSATAIDDevCB: TD tiScsiXchg %p \n", satIOContext->tiScsiXchg)); 21969 21970 21971 /* compare idenitfy device data to the exiting list */ 21972 DeviceListList = tdsaAllShared->MainDeviceList.flink; 21973 while (DeviceListList != &(tdsaAllShared->MainDeviceList)) 21974 { 21975 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 21976 TI_DBG1(("satAddSATAIDDevCB: LOOP oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 21977 //tdhexdump("satAddSATAIDDevCB LOOP", (bit8 *)&oneDeviceData->satDevData.satIdentifyData, sizeof(agsaSATAIdentifyData_t)); 21978 21979 /* what is unique ID for sata device -> response of identify devicedata; not really 21980 Let's compare serial number, firmware version, model number 21981 */ 21982 if ( oneDeviceData->DeviceType == TD_SATA_DEVICE && 21983 (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.serialNumber, 21984 pSATAIdData->serialNumber, 21985 20) == 0) && 21986 (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.firmwareVersion, 21987 pSATAIdData->firmwareVersion, 21988 8) == 0) && 21989 (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.modelNumber, 21990 pSATAIdData->modelNumber, 21991 40) == 0) 21992 ) 21993 { 21994 TI_DBG2(("satAddSATAIDDevCB: did %d\n", oneDeviceData->id)); 21995 new_device = agFALSE; 21996 break; 21997 } 21998 DeviceListList = DeviceListList->flink; 21999 } 22000 22001 if (new_device == agFALSE) 22002 { 22003 TI_DBG2(("satAddSATAIDDevCB: old device data\n")); 22004 oneDeviceData->valid = agTRUE; 22005 oneDeviceData->valid2 = agTRUE; 22006 /* save data field from new device data */ 22007 oneDeviceData->agRoot = agRoot; 22008 oneDeviceData->agDevHandle = NewOneDeviceData->agDevHandle; 22009 oneDeviceData->agDevHandle->osData = oneDeviceData; /* TD layer */ 22010 oneDeviceData->tdPortContext = NewOneDeviceData->tdPortContext; 22011 oneDeviceData->phyID = NewOneDeviceData->phyID; 22012 22013 /* 22014 one SATA directly attached device per phy; 22015 Therefore, deregister then register 22016 */ 22017 saDeregisterDeviceHandle(agRoot, agNULL, NewOneDeviceData->agDevHandle, 0); 22018 22019 if (oneDeviceData->registered == agFALSE) 22020 { 22021 TI_DBG2(("satAddSATAIDDevCB: re-registering old device data\n")); 22022 /* already has old information; just register it again */ 22023 saRegisterNewDevice( /* satAddSATAIDDevCB */ 22024 agRoot, 22025 &oneDeviceData->agContext, 22026 tdsaRotateQnumber(tiRoot, oneDeviceData), 22027 &oneDeviceData->agDeviceInfo, 22028 oneDeviceData->tdPortContext->agPortContext, 22029 0 22030 ); 22031 } 22032 22033 // tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData); 22034 /* put onedevicedata back to free list */ 22035 osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t)); 22036 TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink)); 22037 TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList)); 22038 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22039 22040 satFreeIntIoResource( tiRoot, 22041 satDevData, 22042 satIntIo); 22043 22044 if (satDevData->satDeviceType == SATA_ATAPI_DEVICE) 22045 { 22046 /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/ 22047 satNewIntIo = satAllocIntIoResource( tiRoot, 22048 tiOrgIORequest, 22049 satDevData, 22050 0, 22051 satNewIntIo); 22052 22053 if (satNewIntIo == agNULL) 22054 { 22055 TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n")); 22056 /* clean up TD layer's IORequestBody */ 22057 ostiFreeMemory( 22058 tiRoot, 22059 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22060 sizeof(tdIORequestBody_t) 22061 ); 22062 return; 22063 } /* end memory allocation */ 22064 22065 satNewIOContext = satPrepareNewIO(satNewIntIo, 22066 tiOrgIORequest, 22067 satDevData, 22068 agNULL, 22069 satOrgIOContext 22070 ); 22071 /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/ 22072 status = satSetFeatures(tiRoot, 22073 &satNewIntIo->satIntTiIORequest, 22074 satNewIOContext->ptiDeviceHandle, 22075 &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */ 22076 satNewIOContext, 22077 agFALSE); 22078 if (status != tiSuccess) 22079 { 22080 satFreeIntIoResource( tiRoot, 22081 satDevData, 22082 satIntIo); 22083 /* clean up TD layer's IORequestBody */ 22084 ostiFreeMemory( 22085 tiRoot, 22086 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22087 sizeof(tdIORequestBody_t) 22088 ); 22089 } 22090 } 22091 else 22092 { 22093 /* clean up TD layer's IORequestBody */ 22094 ostiFreeMemory( 22095 tiRoot, 22096 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22097 sizeof(tdIORequestBody_t) 22098 ); 22099 TI_DBG2(("satAddSATAIDDevCB: pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id)); 22100 /* notifying link up */ 22101 ostiPortEvent( 22102 tiRoot, 22103 tiPortLinkUp, 22104 tiSuccess, 22105 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext 22106 ); 22107 22108 22109 #ifdef INITIATOR_DRIVER 22110 /* triggers discovery */ 22111 ostiPortEvent( 22112 tiRoot, 22113 tiPortDiscoveryReady, 22114 tiSuccess, 22115 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext 22116 ); 22117 #endif 22118 } 22119 return; 22120 } 22121 22122 TI_DBG2(("satAddSATAIDDevCB: new device data\n")); 22123 /* copy ID Dev data to satDevData */ 22124 satDevData->satIdentifyData = *pSATAIdData; 22125 22126 22127 satDevData->IDDeviceValid = agTRUE; 22128 #ifdef TD_INTERNAL_DEBUG 22129 tdhexdump("satAddSATAIDDevCB ID Dev data",(bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t)); 22130 tdhexdump("satAddSATAIDDevCB Device ID Dev data",(bit8 *)&satDevData->satIdentifyData, sizeof(agsaSATAIdentifyData_t)); 22131 #endif 22132 22133 /* set satDevData fields from IndentifyData */ 22134 satSetDevInfo(satDevData,pSATAIdData); 22135 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22136 22137 satFreeIntIoResource( tiRoot, 22138 satDevData, 22139 satIntIo); 22140 22141 if (satDevData->satDeviceType == SATA_ATAPI_DEVICE) 22142 { 22143 /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/ 22144 satNewIntIo = satAllocIntIoResource( tiRoot, 22145 tiOrgIORequest, 22146 satDevData, 22147 0, 22148 satNewIntIo); 22149 22150 if (satNewIntIo == agNULL) 22151 { 22152 TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n")); 22153 /* clean up TD layer's IORequestBody */ 22154 ostiFreeMemory( 22155 tiRoot, 22156 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22157 sizeof(tdIORequestBody_t) 22158 ); 22159 return; 22160 } /* end memory allocation */ 22161 22162 satNewIOContext = satPrepareNewIO(satNewIntIo, 22163 tiOrgIORequest, 22164 satDevData, 22165 agNULL, 22166 satOrgIOContext 22167 ); 22168 /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/ 22169 status = satSetFeatures(tiRoot, 22170 &satNewIntIo->satIntTiIORequest, 22171 satNewIOContext->ptiDeviceHandle, 22172 &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */ 22173 satNewIOContext, 22174 agFALSE); 22175 if (status != tiSuccess) 22176 { 22177 satFreeIntIoResource( tiRoot, 22178 satDevData, 22179 satIntIo); 22180 /* clean up TD layer's IORequestBody */ 22181 ostiFreeMemory( 22182 tiRoot, 22183 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22184 sizeof(tdIORequestBody_t) 22185 ); 22186 } 22187 22188 } 22189 else 22190 { 22191 /* clean up TD layer's IORequestBody */ 22192 ostiFreeMemory( 22193 tiRoot, 22194 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22195 sizeof(tdIORequestBody_t) 22196 ); 22197 22198 TI_DBG2(("satAddSATAIDDevCB: pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id)); 22199 /* notifying link up */ 22200 ostiPortEvent ( 22201 tiRoot, 22202 tiPortLinkUp, 22203 tiSuccess, 22204 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext 22205 ); 22206 #ifdef INITIATOR_DRIVER 22207 /* triggers discovery */ 22208 ostiPortEvent( 22209 tiRoot, 22210 tiPortDiscoveryReady, 22211 tiSuccess, 22212 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext 22213 ); 22214 #endif 22215 } 22216 22217 TI_DBG2(("satAddSATAIDDevCB: end\n")); 22218 return; 22219 22220 } 22221 22222 /***************************************************************************** 22223 *! \brief satAddSATAIDDevCBReset 22224 * 22225 * This routine cleans up IOs for failed Identify device data 22226 * 22227 * \param agRoot: Handles for this instance of SAS/SATA hardware 22228 * \param oneDeviceData: Pointer to the device data. 22229 * \param ioContext: Pointer to satIOContext_t. 22230 * \param tdIORequestBody: Pointer to the request body 22231 * \param flag: Decrement pending io or not 22232 * 22233 * \return: none 22234 * 22235 *****************************************************************************/ 22236 void satAddSATAIDDevCBReset( 22237 agsaRoot_t *agRoot, 22238 tdsaDeviceData_t *oneDeviceData, 22239 satIOContext_t *satIOContext, 22240 tdIORequestBody_t *tdIORequestBody 22241 ) 22242 { 22243 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 22244 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 22245 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 22246 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 22247 satInternalIo_t *satIntIo; 22248 satDeviceData_t *satDevData; 22249 22250 TI_DBG2(("satAddSATAIDDevCBReset: start\n")); 22251 satIntIo = satIOContext->satIntIoContext; 22252 satDevData = satIOContext->pSatDevData; 22253 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22254 22255 satFreeIntIoResource( tiRoot, 22256 satDevData, 22257 satIntIo); 22258 /* clean up TD layer's IORequestBody */ 22259 ostiFreeMemory( 22260 tiRoot, 22261 tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22262 sizeof(tdIORequestBody_t) 22263 ); 22264 return; 22265 } 22266 22267 22268 /***************************************************************************** 22269 *! \brief satAddSATAIDDevCBCleanup 22270 * 22271 * This routine cleans up IOs for failed Identify device data 22272 * 22273 * \param agRoot: Handles for this instance of SAS/SATA hardware 22274 * \param oneDeviceData: Pointer to the device data. 22275 * \param ioContext: Pointer to satIOContext_t. 22276 * \param tdIORequestBody: Pointer to the request body 22277 * 22278 * \return: none 22279 * 22280 *****************************************************************************/ 22281 void satAddSATAIDDevCBCleanup( 22282 agsaRoot_t *agRoot, 22283 tdsaDeviceData_t *oneDeviceData, 22284 satIOContext_t *satIOContext, 22285 tdIORequestBody_t *tdIORequestBody 22286 ) 22287 { 22288 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 22289 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 22290 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 22291 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 22292 satInternalIo_t *satIntIo; 22293 satDeviceData_t *satDevData; 22294 bit8 PhyID; 22295 22296 TI_DBG2(("satAddSATAIDDevCBCleanup: start\n")); 22297 satIntIo = satIOContext->satIntIoContext; 22298 satDevData = satIOContext->pSatDevData; 22299 PhyID = oneDeviceData->phyID; 22300 tdsaAbortAll(tiRoot, agRoot, oneDeviceData); 22301 /* put onedevicedata back to free list */ 22302 osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t)); 22303 TDLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink)); 22304 TDLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList)); 22305 22306 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22307 22308 22309 satFreeIntIoResource( tiRoot, 22310 satDevData, 22311 satIntIo); 22312 22313 /* clean up TD layer's IORequestBody */ 22314 ostiFreeMemory( 22315 tiRoot, 22316 tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22317 sizeof(tdIORequestBody_t) 22318 ); 22319 22320 /* notifying link up */ 22321 ostiPortEvent ( 22322 tiRoot, 22323 tiPortLinkUp, 22324 tiSuccess, 22325 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext 22326 ); 22327 #ifdef INITIATOR_DRIVER 22328 /* triggers discovery */ 22329 ostiPortEvent( 22330 tiRoot, 22331 tiPortDiscoveryReady, 22332 tiSuccess, 22333 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext 22334 ); 22335 #endif 22336 22337 return; 22338 } 22339 22340 /*****************************************************************************/ 22341 /*! \brief SAT implementation for tdsaDiscoveryStartIDDev. 22342 * 22343 * This function sends identify device data to SATA device in discovery 22344 * 22345 * 22346 * \param tiRoot: Pointer to TISA initiator driver/port instance. 22347 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 22348 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 22349 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 22350 * \param oneDeviceData : Pointer to the device data. 22351 * 22352 * \return If command is started successfully 22353 * - \e tiSuccess: I/O request successfully initiated. 22354 * - \e tiBusy: No resources available, try again later. 22355 * - \e tiIONoDevice: Invalid device handle. 22356 * - \e tiError: Other errors. 22357 */ 22358 /*****************************************************************************/ 22359 GLOBAL bit32 22360 tdsaDiscoveryStartIDDev(tiRoot_t *tiRoot, 22361 tiIORequest_t *tiIORequest, /* agNULL */ 22362 tiDeviceHandle_t *tiDeviceHandle, 22363 tiScsiInitiatorRequest_t *tiScsiRequest, /* agNULL */ 22364 tdsaDeviceData_t *oneDeviceData 22365 ) 22366 { 22367 void *osMemHandle; 22368 tdIORequestBody_t *tdIORequestBody; 22369 bit32 PhysUpper32; 22370 bit32 PhysLower32; 22371 bit32 memAllocStatus; 22372 agsaIORequest_t *agIORequest = agNULL; /* identify device data itself */ 22373 satIOContext_t *satIOContext = agNULL; 22374 bit32 status; 22375 22376 /* allocate tdiorequestbody and call tdsaDiscoveryIntStartIDDev 22377 tdsaDiscoveryIntStartIDDev(tiRoot, agNULL, tiDeviceHandle, satIOContext); 22378 22379 */ 22380 22381 TI_DBG3(("tdsaDiscoveryStartIDDev: start\n")); 22382 TI_DBG3(("tdsaDiscoveryStartIDDev: did %d\n", oneDeviceData->id)); 22383 22384 /* allocation tdIORequestBody and pass it to satTM() */ 22385 memAllocStatus = ostiAllocMemory( 22386 tiRoot, 22387 &osMemHandle, 22388 (void **)&tdIORequestBody, 22389 &PhysUpper32, 22390 &PhysLower32, 22391 8, 22392 sizeof(tdIORequestBody_t), 22393 agTRUE 22394 ); 22395 22396 if (memAllocStatus != tiSuccess) 22397 { 22398 TI_DBG1(("tdsaDiscoveryStartIDDev: ostiAllocMemory failed... loc 1\n")); 22399 return tiError; 22400 } 22401 if (tdIORequestBody == agNULL) 22402 { 22403 TI_DBG1(("tdsaDiscoveryStartIDDev: ostiAllocMemory returned NULL tdIORequestBody loc 2\n")); 22404 return tiError; 22405 } 22406 22407 /* setup identify device data IO structure */ 22408 tdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 22409 tdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = agNULL; 22410 tdIORequestBody->IOType.InitiatorTMIO.TaskTag = agNULL; 22411 22412 /* initialize tiDevhandle */ 22413 tdIORequestBody->tiDevHandle = &(oneDeviceData->tiDeviceHandle); 22414 tdIORequestBody->tiDevHandle->tdData = oneDeviceData; 22415 22416 /* initialize tiIORequest */ 22417 tdIORequestBody->tiIORequest = agNULL; 22418 22419 /* initialize agIORequest */ 22420 agIORequest = &(tdIORequestBody->agIORequest); 22421 agIORequest->osData = (void *) tdIORequestBody; 22422 agIORequest->sdkData = agNULL; /* SA takes care of this */ 22423 22424 /* set up satIOContext */ 22425 satIOContext = &(tdIORequestBody->transport.SATA.satIOContext); 22426 satIOContext->pSatDevData = &(oneDeviceData->satDevData); 22427 satIOContext->pFis = 22428 &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 22429 22430 satIOContext->tiRequestBody = tdIORequestBody; 22431 satIOContext->ptiDeviceHandle = &(oneDeviceData->tiDeviceHandle); 22432 satIOContext->tiScsiXchg = agNULL; 22433 satIOContext->satIntIoContext = agNULL; 22434 satIOContext->satOrgIOContext = agNULL; 22435 /* followings are used only for internal IO */ 22436 satIOContext->currentLBA = 0; 22437 satIOContext->OrgTL = 0; 22438 satIOContext->satToBeAbortedIOContext = agNULL; 22439 satIOContext->NotifyOS = agFALSE; 22440 22441 /* saving port ID just in case of full discovery to full discovery transition */ 22442 satIOContext->pid = oneDeviceData->tdPortContext->id; 22443 osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0x0, sizeof(agsaSATAIdentifyData_t)); 22444 status = tdsaDiscoveryIntStartIDDev(tiRoot, 22445 tiIORequest, /* agNULL */ 22446 tiDeviceHandle, /* &(oneDeviceData->tiDeviceHandle)*/ 22447 agNULL, 22448 satIOContext 22449 ); 22450 if (status != tiSuccess) 22451 { 22452 TI_DBG1(("tdsaDiscoveryStartIDDev: failed in sending %d\n", status)); 22453 ostiFreeMemory(tiRoot, osMemHandle, sizeof(tdIORequestBody_t)); 22454 } 22455 return status; 22456 } 22457 22458 /*****************************************************************************/ 22459 /*! \brief SAT implementation for tdsaDiscoveryIntStartIDDev. 22460 * 22461 * This function sends identify device data to SATA device. 22462 * 22463 * \param tiRoot: Pointer to TISA initiator driver/port instance. 22464 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 22465 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 22466 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 22467 * \param satIOContext_t: Pointer to the SAT IO Context 22468 * 22469 * \return If command is started successfully 22470 * - \e tiSuccess: I/O request successfully initiated. 22471 * - \e tiBusy: No resources available, try again later. 22472 * - \e tiIONoDevice: Invalid device handle. 22473 * - \e tiError: Other errors. 22474 */ 22475 /*****************************************************************************/ 22476 GLOBAL bit32 22477 tdsaDiscoveryIntStartIDDev(tiRoot_t *tiRoot, 22478 tiIORequest_t *tiIORequest, /* agNULL */ 22479 tiDeviceHandle_t *tiDeviceHandle, 22480 tiScsiInitiatorRequest_t *tiScsiRequest, /* agNULL */ 22481 satIOContext_t *satIOContext 22482 ) 22483 { 22484 satInternalIo_t *satIntIo = agNULL; 22485 satDeviceData_t *satDevData = agNULL; 22486 tdIORequestBody_t *tdIORequestBody; 22487 satIOContext_t *satNewIOContext; 22488 bit32 status; 22489 22490 TI_DBG3(("tdsaDiscoveryIntStartIDDev: start\n")); 22491 22492 satDevData = satIOContext->pSatDevData; 22493 22494 /* allocate identify device command */ 22495 satIntIo = satAllocIntIoResource( tiRoot, 22496 tiIORequest, 22497 satDevData, 22498 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */ 22499 satIntIo); 22500 22501 if (satIntIo == agNULL) 22502 { 22503 TI_DBG2(("tdsaDiscoveryIntStartIDDev: can't alloacate\n")); 22504 22505 return tiError; 22506 } 22507 22508 /* fill in fields */ 22509 /* real ttttttthe one worked and the same; 5/21/07/ */ 22510 satIntIo->satOrgTiIORequest = tiIORequest; /* changed */ 22511 tdIORequestBody = satIntIo->satIntRequestBody; 22512 satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext); 22513 22514 satNewIOContext->pSatDevData = satDevData; 22515 satNewIOContext->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 22516 satNewIOContext->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd); 22517 satNewIOContext->pSense = &(tdIORequestBody->transport.SATA.sensePayload); 22518 satNewIOContext->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData); 22519 satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */ 22520 satNewIOContext->interruptContext = tiInterruptContext; 22521 satNewIOContext->satIntIoContext = satIntIo; 22522 22523 satNewIOContext->ptiDeviceHandle = agNULL; 22524 satNewIOContext->satOrgIOContext = satIOContext; /* changed */ 22525 22526 /* this is valid only for TD layer generated (not triggered by OS at all) IO */ 22527 satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg); 22528 22529 22530 TI_DBG6(("tdsaDiscoveryIntStartIDDev: OS satIOContext %p \n", satIOContext)); 22531 TI_DBG6(("tdsaDiscoveryIntStartIDDev: TD satNewIOContext %p \n", satNewIOContext)); 22532 TI_DBG6(("tdsaDiscoveryIntStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg)); 22533 TI_DBG6(("tdsaDiscoveryIntStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg)); 22534 22535 22536 22537 TI_DBG3(("tdsaDiscoveryIntStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody)); 22538 22539 status = tdsaDiscoverySendIDDev(tiRoot, 22540 &satIntIo->satIntTiIORequest, /* New tiIORequest */ 22541 tiDeviceHandle, 22542 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */ 22543 satNewIOContext); 22544 22545 if (status != tiSuccess) 22546 { 22547 TI_DBG1(("tdsaDiscoveryIntStartIDDev: failed in sending %d\n", status)); 22548 22549 satFreeIntIoResource( tiRoot, 22550 satDevData, 22551 satIntIo); 22552 22553 return tiError; 22554 } 22555 22556 22557 TI_DBG6(("tdsaDiscoveryIntStartIDDev: end\n")); 22558 22559 return status; 22560 } 22561 22562 22563 /*****************************************************************************/ 22564 /*! \brief SAT implementation for tdsaDiscoverySendIDDev. 22565 * 22566 * This function prepares identify device data FIS and sends it to SATA device. 22567 * 22568 * \param tiRoot: Pointer to TISA initiator driver/port instance. 22569 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 22570 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 22571 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 22572 * \param satIOContext_t: Pointer to the SAT IO Context 22573 * 22574 * \return If command is started successfully 22575 * - \e tiSuccess: I/O request successfully initiated. 22576 * - \e tiBusy: No resources available, try again later. 22577 * - \e tiIONoDevice: Invalid device handle. 22578 * - \e tiError: Other errors. 22579 */ 22580 /*****************************************************************************/ 22581 GLOBAL bit32 22582 tdsaDiscoverySendIDDev(tiRoot_t *tiRoot, 22583 tiIORequest_t *tiIORequest, 22584 tiDeviceHandle_t *tiDeviceHandle, 22585 tiScsiInitiatorRequest_t *tiScsiRequest, 22586 satIOContext_t *satIOContext 22587 ) 22588 { 22589 bit32 status; 22590 bit32 agRequestType; 22591 satDeviceData_t *pSatDevData; 22592 agsaFisRegHostToDevice_t *fis; 22593 #ifdef TD_DEBUG_ENABLE 22594 tdIORequestBody_t *tdIORequestBody; 22595 satInternalIo_t *satIntIoContext; 22596 #endif 22597 22598 pSatDevData = satIOContext->pSatDevData; 22599 fis = satIOContext->pFis; 22600 TI_DBG3(("tdsaDiscoverySendIDDev: start\n")); 22601 #ifdef TD_DEBUG_ENABLE 22602 satIntIoContext = satIOContext->satIntIoContext; 22603 tdIORequestBody = satIntIoContext->satIntRequestBody; 22604 #endif 22605 TI_DBG5(("tdsaDiscoverySendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody)); 22606 22607 fis->h.fisType = 0x27; /* Reg host to device */ 22608 fis->h.c_pmPort = 0x80; /* C Bit is set */ 22609 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE) 22610 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0xA1 */ 22611 else 22612 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */ 22613 fis->h.features = 0; /* FIS reserve */ 22614 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 22615 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 22616 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 22617 fis->d.device = 0; /* FIS LBA mode */ 22618 fis->d.lbaLowExp = 0; 22619 fis->d.lbaMidExp = 0; 22620 fis->d.lbaHighExp = 0; 22621 fis->d.featuresExp = 0; 22622 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 22623 fis->d.sectorCountExp = 0; 22624 fis->d.reserved4 = 0; 22625 fis->d.control = 0; /* FIS HOB bit clear */ 22626 fis->d.reserved5 = 0; 22627 22628 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 22629 22630 /* Initialize CB for SATA completion. 22631 */ 22632 satIOContext->satCompleteCB = &tdsaDiscoveryStartIDDevCB; 22633 22634 /* 22635 * Prepare SGL and send FIS to LL layer. 22636 */ 22637 satIOContext->reqType = agRequestType; /* Save it */ 22638 22639 #ifdef TD_INTERNAL_DEBUG 22640 tdhexdump("tdsaDiscoverySendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 22641 #ifdef TD_DEBUG_ENABLE 22642 tdhexdump("tdsaDiscoverySendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t)); 22643 #endif 22644 #endif 22645 status = sataLLIOStart( tiRoot, 22646 tiIORequest, 22647 tiDeviceHandle, 22648 tiScsiRequest, 22649 satIOContext); 22650 TI_DBG3(("tdsaDiscoverySendIDDev: end status %d\n", status)); 22651 return status; 22652 } 22653 22654 22655 /***************************************************************************** 22656 *! \brief tdsaDiscoveryStartIDDevCB 22657 * 22658 * This routine is a callback function for tdsaDiscoverySendIDDev() 22659 * Using Identify Device Data, this function finds whether devicedata is 22660 * new or old. If new, add it to the devicelist. This is done as a part 22661 * of discovery. 22662 * 22663 * \param agRoot: Handles for this instance of SAS/SATA hardware 22664 * \param agIORequest: Pointer to the LL I/O request context for this I/O. 22665 * \param agIOStatus: Status of completed I/O. 22666 * \param agFirstDword:Pointer to the four bytes of FIS. 22667 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS 22668 * length. 22669 * \param agParam: Additional info based on status. 22670 * \param ioContext: Pointer to satIOContext_t. 22671 * 22672 * \return: none 22673 * 22674 *****************************************************************************/ 22675 void tdsaDiscoveryStartIDDevCB( 22676 agsaRoot_t *agRoot, 22677 agsaIORequest_t *agIORequest, 22678 bit32 agIOStatus, 22679 agsaFisHeader_t *agFirstDword, 22680 bit32 agIOInfoLen, 22681 void *agParam, 22682 void *ioContext 22683 ) 22684 { 22685 /* 22686 In the process of SAT_IDENTIFY_DEVICE during discovery 22687 */ 22688 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 22689 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 22690 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 22691 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 22692 tdIORequestBody_t *tdIORequestBody; 22693 tdIORequestBody_t *tdOrgIORequestBody; 22694 satIOContext_t *satIOContext; 22695 satIOContext_t *satOrgIOContext; 22696 satIOContext_t *satNewIOContext; 22697 satInternalIo_t *satIntIo; 22698 satInternalIo_t *satNewIntIo = agNULL; 22699 satDeviceData_t *satDevData; 22700 tiIORequest_t *tiOrgIORequest = agNULL; 22701 22702 #ifdef TD_DEBUG_ENABLE 22703 bit32 ataStatus = 0; 22704 bit32 ataError; 22705 agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL; 22706 #endif 22707 agsaSATAIdentifyData_t *pSATAIdData; 22708 bit16 *tmpptr, tmpptr_tmp; 22709 bit32 x; 22710 tdsaDeviceData_t *oneDeviceData = agNULL; 22711 void *sglVirtualAddr; 22712 tdsaPortContext_t *onePortContext = agNULL; 22713 tiPortalContext_t *tiPortalContext = agNULL; 22714 bit32 retry_status; 22715 22716 TI_DBG3(("tdsaDiscoveryStartIDDevCB: start\n")); 22717 22718 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; 22719 satIOContext = (satIOContext_t *) ioContext; 22720 satIntIo = satIOContext->satIntIoContext; 22721 satDevData = satIOContext->pSatDevData; 22722 oneDeviceData = (tdsaDeviceData_t *)tdIORequestBody->tiDevHandle->tdData; 22723 TI_DBG3(("tdsaDiscoveryStartIDDevCB: did %d\n", oneDeviceData->id)); 22724 onePortContext = oneDeviceData->tdPortContext; 22725 if (onePortContext == agNULL) 22726 { 22727 TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext is NULL\n")); 22728 return; 22729 } 22730 tiPortalContext= onePortContext->tiPortalContext; 22731 22732 satDevData->IDDeviceValid = agFALSE; 22733 22734 if (satIntIo == agNULL) 22735 { 22736 TI_DBG1(("tdsaDiscoveryStartIDDevCB: External, OS generated\n")); 22737 TI_DBG1(("tdsaDiscoveryStartIDDevCB: Not possible case\n")); 22738 satOrgIOContext = satIOContext; 22739 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody; 22740 22741 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22742 22743 satFreeIntIoResource( tiRoot, 22744 satDevData, 22745 satIntIo); 22746 22747 /* clean up TD layer's IORequestBody */ 22748 ostiFreeMemory( 22749 tiRoot, 22750 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22751 sizeof(tdIORequestBody_t) 22752 ); 22753 return; 22754 } 22755 else 22756 { 22757 TI_DBG3(("tdsaDiscoveryStartIDDevCB: Internal, TD generated\n")); 22758 satOrgIOContext = satIOContext->satOrgIOContext; 22759 if (satOrgIOContext == agNULL) 22760 { 22761 TI_DBG6(("tdsaDiscoveryStartIDDevCB: satOrgIOContext is NULL\n")); 22762 return; 22763 } 22764 else 22765 { 22766 TI_DBG6(("tdsaDiscoveryStartIDDevCB: satOrgIOContext is NOT NULL\n")); 22767 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody; 22768 sglVirtualAddr = satIntIo->satIntTiScsiXchg.sglVirtualAddr; 22769 } 22770 } 22771 22772 tiOrgIORequest = tdIORequestBody->tiIORequest; 22773 tdIORequestBody->ioCompleted = agTRUE; 22774 tdIORequestBody->ioStarted = agFALSE; 22775 22776 TI_DBG3(("tdsaDiscoveryStartIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid)); 22777 22778 /* protect against double completion for old port */ 22779 if (satOrgIOContext->pid != oneDeviceData->tdPortContext->id) 22780 { 22781 TI_DBG3(("tdsaDiscoveryStartIDDevCB: incorrect pid\n")); 22782 TI_DBG3(("tdsaDiscoveryStartIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid)); 22783 TI_DBG3(("tdsaDiscoveryStartIDDevCB: tiPortalContext pid %d\n", oneDeviceData->tdPortContext->id)); 22784 22785 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22786 22787 satFreeIntIoResource( tiRoot, 22788 satDevData, 22789 satIntIo); 22790 22791 /* clean up TD layer's IORequestBody */ 22792 ostiFreeMemory( 22793 tiRoot, 22794 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22795 sizeof(tdIORequestBody_t) 22796 ); 22797 22798 return; 22799 } 22800 22801 /* completion after portcontext is invalidated */ 22802 if (onePortContext != agNULL) 22803 { 22804 if (onePortContext->valid == agFALSE) 22805 { 22806 TI_DBG1(("tdsaDiscoveryStartIDDevCB: portcontext is invalid\n")); 22807 TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext->id pid %d\n", onePortContext->id)); 22808 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22809 22810 satFreeIntIoResource( tiRoot, 22811 satDevData, 22812 satIntIo); 22813 22814 /* clean up TD layer's IORequestBody */ 22815 ostiFreeMemory( 22816 tiRoot, 22817 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22818 sizeof(tdIORequestBody_t) 22819 ); 22820 22821 /* no notification to OS layer */ 22822 return; 22823 } 22824 } 22825 22826 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS) 22827 { 22828 TI_DBG1(("tdsaDiscoveryStartIDDevCB: agFirstDword is NULL when error, status %d\n", agIOStatus)); 22829 TI_DBG1(("tdsaDiscoveryStartIDDevCB: did %d\n", oneDeviceData->id)); 22830 22831 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES) 22832 { 22833 satIOContext->pSatDevData->satPendingNONNCQIO--; 22834 satIOContext->pSatDevData->satPendingIO--; 22835 retry_status = sataLLIOStart(tiRoot, 22836 &satIntIo->satIntTiIORequest, 22837 &(oneDeviceData->tiDeviceHandle), 22838 satIOContext->tiScsiXchg, 22839 satIOContext); 22840 if (retry_status != tiSuccess) 22841 { 22842 /* simply give up */ 22843 satDevData->ID_Retries = 0; 22844 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22845 22846 satFreeIntIoResource( tiRoot, 22847 satDevData, 22848 satIntIo); 22849 22850 /* clean up TD layer's IORequestBody */ 22851 ostiFreeMemory( 22852 tiRoot, 22853 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22854 sizeof(tdIORequestBody_t) 22855 ); 22856 return; 22857 } 22858 satDevData->ID_Retries++; 22859 tdIORequestBody->ioCompleted = agFALSE; 22860 tdIORequestBody->ioStarted = agTRUE; 22861 return; 22862 } 22863 else 22864 { 22865 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22866 satFreeIntIoResource( tiRoot, 22867 satDevData, 22868 satIntIo); 22869 22870 /* clean up TD layer's IORequestBody */ 22871 ostiFreeMemory( 22872 tiRoot, 22873 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22874 sizeof(tdIORequestBody_t) 22875 ); 22876 if (tdsaAllShared->ResetInDiscovery != 0) 22877 { 22878 /* ResetInDiscovery in on */ 22879 if (satDevData->NumOfIDRetries <= 0) 22880 { 22881 satDevData->NumOfIDRetries++; 22882 satDevData->ID_Retries = 0; 22883 /* send link reset */ 22884 tdsaPhyControlSend(tiRoot, 22885 oneDeviceData, 22886 SMP_PHY_CONTROL_HARD_RESET, 22887 agNULL, 22888 tdsaRotateQnumber(tiRoot, oneDeviceData) 22889 ); 22890 } 22891 } 22892 return; 22893 } 22894 } 22895 22896 if (agIOStatus == OSSA_IO_ABORTED || 22897 agIOStatus == OSSA_IO_UNDERFLOW || 22898 agIOStatus == OSSA_IO_XFER_ERROR_BREAK || 22899 agIOStatus == OSSA_IO_XFER_ERROR_PHY_NOT_READY || 22900 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED || 22901 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK || 22902 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS || 22903 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION || 22904 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED || 22905 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY || 22906 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION || 22907 agIOStatus == OSSA_IO_XFER_ERROR_NAK_RECEIVED || 22908 agIOStatus == OSSA_IO_XFER_ERROR_DMA || 22909 agIOStatus == OSSA_IO_XFER_ERROR_SATA_LINK_TIMEOUT || 22910 agIOStatus == OSSA_IO_XFER_ERROR_REJECTED_NCQ_MODE || 22911 agIOStatus == OSSA_IO_XFER_OPEN_RETRY_TIMEOUT || 22912 agIOStatus == OSSA_IO_NO_DEVICE || 22913 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION || 22914 agIOStatus == OSSA_IO_PORT_IN_RESET || 22915 agIOStatus == OSSA_IO_DS_NON_OPERATIONAL || 22916 agIOStatus == OSSA_IO_DS_IN_RECOVERY || 22917 agIOStatus == OSSA_IO_DS_IN_ERROR 22918 ) 22919 { 22920 TI_DBG1(("tdsaDiscoveryStartIDDevCB: OSSA_IO_OPEN_CNX_ERROR 0x%x\n", agIOStatus)); 22921 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES) 22922 { 22923 satIOContext->pSatDevData->satPendingNONNCQIO--; 22924 satIOContext->pSatDevData->satPendingIO--; 22925 retry_status = sataLLIOStart(tiRoot, 22926 &satIntIo->satIntTiIORequest, 22927 &(oneDeviceData->tiDeviceHandle), 22928 satIOContext->tiScsiXchg, 22929 satIOContext); 22930 if (retry_status != tiSuccess) 22931 { 22932 /* simply give up */ 22933 satDevData->ID_Retries = 0; 22934 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22935 22936 satFreeIntIoResource( tiRoot, 22937 satDevData, 22938 satIntIo); 22939 22940 /* clean up TD layer's IORequestBody */ 22941 ostiFreeMemory( 22942 tiRoot, 22943 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22944 sizeof(tdIORequestBody_t) 22945 ); 22946 return; 22947 } 22948 satDevData->ID_Retries++; 22949 tdIORequestBody->ioCompleted = agFALSE; 22950 tdIORequestBody->ioStarted = agTRUE; 22951 return; 22952 } 22953 else 22954 { 22955 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22956 satFreeIntIoResource( tiRoot, 22957 satDevData, 22958 satIntIo); 22959 22960 /* clean up TD layer's IORequestBody */ 22961 ostiFreeMemory( 22962 tiRoot, 22963 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22964 sizeof(tdIORequestBody_t) 22965 ); 22966 if (tdsaAllShared->ResetInDiscovery != 0) 22967 { 22968 /* ResetInDiscovery in on */ 22969 if (satDevData->NumOfIDRetries <= 0) 22970 { 22971 satDevData->NumOfIDRetries++; 22972 satDevData->ID_Retries = 0; 22973 /* send link reset */ 22974 tdsaPhyControlSend(tiRoot, 22975 oneDeviceData, 22976 SMP_PHY_CONTROL_HARD_RESET, 22977 agNULL, 22978 tdsaRotateQnumber(tiRoot, oneDeviceData) 22979 ); 22980 } 22981 } 22982 return; 22983 } 22984 } 22985 22986 if ( agIOStatus != OSSA_IO_SUCCESS || 22987 (agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0) 22988 ) 22989 { 22990 #ifdef TD_DEBUG_ENABLE 22991 /* only agsaFisPioSetup_t is expected */ 22992 satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup); 22993 ataStatus = satPIOSetupHeader->status; /* ATA Status register */ 22994 ataError = satPIOSetupHeader->error; /* ATA Eror register */ 22995 #endif 22996 TI_DBG1(("tdsaDiscoveryStartIDDevCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError)); 22997 22998 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES) 22999 { 23000 satIOContext->pSatDevData->satPendingNONNCQIO--; 23001 satIOContext->pSatDevData->satPendingIO--; 23002 retry_status = sataLLIOStart(tiRoot, 23003 &satIntIo->satIntTiIORequest, 23004 &(oneDeviceData->tiDeviceHandle), 23005 satIOContext->tiScsiXchg, 23006 satIOContext); 23007 if (retry_status != tiSuccess) 23008 { 23009 /* simply give up */ 23010 satDevData->ID_Retries = 0; 23011 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 23012 23013 satFreeIntIoResource( tiRoot, 23014 satDevData, 23015 satIntIo); 23016 23017 /* clean up TD layer's IORequestBody */ 23018 ostiFreeMemory( 23019 tiRoot, 23020 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 23021 sizeof(tdIORequestBody_t) 23022 ); 23023 return; 23024 } 23025 satDevData->ID_Retries++; 23026 tdIORequestBody->ioCompleted = agFALSE; 23027 tdIORequestBody->ioStarted = agTRUE; 23028 return; 23029 } 23030 else 23031 { 23032 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 23033 satFreeIntIoResource( tiRoot, 23034 satDevData, 23035 satIntIo); 23036 23037 /* clean up TD layer's IORequestBody */ 23038 ostiFreeMemory( 23039 tiRoot, 23040 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 23041 sizeof(tdIORequestBody_t) 23042 ); 23043 if (tdsaAllShared->ResetInDiscovery != 0) 23044 { 23045 /* ResetInDiscovery in on */ 23046 if (satDevData->NumOfIDRetries <= 0) 23047 { 23048 satDevData->NumOfIDRetries++; 23049 satDevData->ID_Retries = 0; 23050 /* send link reset */ 23051 tdsaPhyControlSend(tiRoot, 23052 oneDeviceData, 23053 SMP_PHY_CONTROL_HARD_RESET, 23054 agNULL, 23055 tdsaRotateQnumber(tiRoot, oneDeviceData) 23056 ); 23057 } 23058 } 23059 return; 23060 } 23061 } 23062 23063 23064 /* success */ 23065 TI_DBG3(("tdsaDiscoveryStartIDDevCB: Success\n")); 23066 TI_DBG3(("tdsaDiscoveryStartIDDevCB: Success did %d\n", oneDeviceData->id)); 23067 23068 /* Convert to host endian */ 23069 tmpptr = (bit16*)sglVirtualAddr; 23070 for (x=0; x < sizeof(agsaSATAIdentifyData_t)/sizeof(bit16); x++) 23071 { 23072 OSSA_READ_LE_16(AGROOT, &tmpptr_tmp, tmpptr, 0); 23073 *tmpptr = tmpptr_tmp; 23074 tmpptr++; 23075 } 23076 23077 pSATAIdData = (agsaSATAIdentifyData_t *)sglVirtualAddr; 23078 //tdhexdump("satAddSATAIDDevCB before", (bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t)); 23079 23080 TI_DBG5(("tdsaDiscoveryStartIDDevCB: OS satOrgIOContext %p \n", satOrgIOContext)); 23081 TI_DBG5(("tdsaDiscoveryStartIDDevCB: TD satIOContext %p \n", satIOContext)); 23082 TI_DBG5(("tdsaDiscoveryStartIDDevCB: OS tiScsiXchg %p \n", satOrgIOContext->tiScsiXchg)); 23083 TI_DBG5(("tdsaDiscoveryStartIDDevCB: TD tiScsiXchg %p \n", satIOContext->tiScsiXchg)); 23084 23085 23086 /* copy ID Dev data to satDevData */ 23087 satDevData->satIdentifyData = *pSATAIdData; 23088 satDevData->IDDeviceValid = agTRUE; 23089 23090 #ifdef TD_INTERNAL_DEBUG 23091 tdhexdump("tdsaDiscoveryStartIDDevCB ID Dev data",(bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t)); 23092 tdhexdump("tdsaDiscoveryStartIDDevCB Device ID Dev data",(bit8 *)&satDevData->satIdentifyData, sizeof(agsaSATAIdentifyData_t)); 23093 #endif 23094 23095 /* set satDevData fields from IndentifyData */ 23096 satSetDevInfo(satDevData,pSATAIdData); 23097 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 23098 23099 satFreeIntIoResource( tiRoot, 23100 satDevData, 23101 satIntIo); 23102 23103 if (satDevData->satDeviceType == SATA_ATAPI_DEVICE) 23104 { 23105 /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/ 23106 satNewIntIo = satAllocIntIoResource( tiRoot, 23107 tiOrgIORequest, 23108 satDevData, 23109 0, 23110 satNewIntIo); 23111 23112 if (satNewIntIo == agNULL) 23113 { 23114 TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n")); 23115 /* clean up TD layer's IORequestBody */ 23116 ostiFreeMemory( 23117 tiRoot, 23118 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 23119 sizeof(tdIORequestBody_t) 23120 ); 23121 return; 23122 } /* end memory allocation */ 23123 23124 satNewIOContext = satPrepareNewIO(satNewIntIo, 23125 tiOrgIORequest, 23126 satDevData, 23127 agNULL, 23128 satOrgIOContext 23129 ); 23130 /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/ 23131 retry_status = satSetFeatures(tiRoot, 23132 &satNewIntIo->satIntTiIORequest, 23133 satNewIOContext->ptiDeviceHandle, 23134 &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */ 23135 satNewIOContext, 23136 agFALSE); 23137 if (retry_status != tiSuccess) 23138 { 23139 satFreeIntIoResource(tiRoot, satDevData, satIntIo); 23140 /* clean up TD layer's IORequestBody */ 23141 ostiFreeMemory( 23142 tiRoot, 23143 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 23144 sizeof(tdIORequestBody_t) 23145 ); 23146 } 23147 } 23148 else 23149 { 23150 /* clean up TD layer's IORequestBody */ 23151 ostiFreeMemory( 23152 tiRoot, 23153 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 23154 sizeof(tdIORequestBody_t) 23155 ); 23156 if (onePortContext != agNULL) 23157 { 23158 if (onePortContext->DiscoveryState == ITD_DSTATE_COMPLETED) 23159 { 23160 TI_DBG1(("tdsaDiscoveryStartIDDevCB: ID completed after discovery is done; tiDeviceArrival\n")); 23161 /* in case registration is finished after discovery is finished */ 23162 ostiInitiatorEvent( 23163 tiRoot, 23164 tiPortalContext, 23165 agNULL, 23166 tiIntrEventTypeDeviceChange, 23167 tiDeviceArrival, 23168 agNULL 23169 ); 23170 } 23171 } 23172 else 23173 { 23174 TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext is NULL, wrong\n")); 23175 } 23176 } 23177 TI_DBG3(("tdsaDiscoveryStartIDDevCB: end\n")); 23178 return; 23179 } 23180 /***************************************************************************** 23181 *! \brief satAbort 23182 * 23183 * This routine does local abort for outstanding FIS. 23184 * 23185 * \param agRoot: Handles for this instance of SAS/SATA hardware 23186 * \param satIOContext: Pointer to satIOContext_t. 23187 * 23188 * \return: none 23189 * 23190 *****************************************************************************/ 23191 GLOBAL void satAbort(agsaRoot_t *agRoot, 23192 satIOContext_t *satIOContext) 23193 { 23194 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 23195 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 23196 tdIORequestBody_t *tdIORequestBody; /* io to be aborted */ 23197 tdIORequestBody_t *tdAbortIORequestBody; /* abort io itself */ 23198 agsaIORequest_t *agToBeAbortedIORequest; /* io to be aborted */ 23199 agsaIORequest_t *agAbortIORequest; /* abort io itself */ 23200 bit32 PhysUpper32; 23201 bit32 PhysLower32; 23202 bit32 memAllocStatus; 23203 void *osMemHandle; 23204 23205 TI_DBG1(("satAbort: start\n")); 23206 23207 if (satIOContext == agNULL) 23208 { 23209 TI_DBG1(("satAbort: satIOContext is NULL, wrong\n")); 23210 return; 23211 } 23212 tdIORequestBody = (tdIORequestBody_t *)satIOContext->tiRequestBody; 23213 agToBeAbortedIORequest = (agsaIORequest_t *)&(tdIORequestBody->agIORequest); 23214 /* allocating agIORequest for abort itself */ 23215 memAllocStatus = ostiAllocMemory( 23216 tiRoot, 23217 &osMemHandle, 23218 (void **)&tdAbortIORequestBody, 23219 &PhysUpper32, 23220 &PhysLower32, 23221 8, 23222 sizeof(tdIORequestBody_t), 23223 agTRUE 23224 ); 23225 23226 if (memAllocStatus != tiSuccess) 23227 { 23228 /* let os process IO */ 23229 TI_DBG1(("satAbort: ostiAllocMemory failed...\n")); 23230 return; 23231 } 23232 23233 if (tdAbortIORequestBody == agNULL) 23234 { 23235 /* let os process IO */ 23236 TI_DBG1(("satAbort: ostiAllocMemory returned NULL tdAbortIORequestBody\n")); 23237 return; 23238 } 23239 /* setup task management structure */ 23240 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 23241 tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle; 23242 23243 /* initialize agIORequest */ 23244 agAbortIORequest = &(tdAbortIORequestBody->agIORequest); 23245 agAbortIORequest->osData = (void *) tdAbortIORequestBody; 23246 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */ 23247 23248 23249 /* 23250 * Issue abort 23251 */ 23252 saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agToBeAbortedIORequest, agNULL ); 23253 23254 23255 TI_DBG1(("satAbort: end\n")); 23256 return; 23257 } 23258 23259 /***************************************************************************** 23260 *! \brief satSATADeviceReset 23261 * 23262 * This routine is called to reset all phys of port which a device belongs to 23263 * 23264 * \param tiRoot: Pointer to TISA initiator driver/port instance. 23265 * \param oneDeviceData: Pointer to the device data. 23266 * \param flag: reset flag 23267 * 23268 * \return: 23269 * 23270 * none 23271 * 23272 *****************************************************************************/ 23273 osGLOBAL void 23274 satSATADeviceReset( tiRoot_t *tiRoot, 23275 tdsaDeviceData_t *oneDeviceData, 23276 bit32 flag) 23277 { 23278 agsaRoot_t *agRoot; 23279 tdsaPortContext_t *onePortContext; 23280 bit32 i; 23281 23282 TI_DBG1(("satSATADeviceReset: start\n")); 23283 agRoot = oneDeviceData->agRoot; 23284 onePortContext = oneDeviceData->tdPortContext; 23285 23286 if (agRoot == agNULL) 23287 { 23288 TI_DBG1(("satSATADeviceReset: Error!!! agRoot is NULL\n")); 23289 return; 23290 } 23291 if (onePortContext == agNULL) 23292 { 23293 TI_DBG1(("satSATADeviceReset: Error!!! onePortContext is NULL\n")); 23294 return; 23295 } 23296 23297 for(i=0;i<TD_MAX_NUM_PHYS;i++) 23298 { 23299 if (onePortContext->PhyIDList[i] == agTRUE) 23300 { 23301 saLocalPhyControl(agRoot, agNULL, tdsaRotateQnumber(tiRoot, agNULL), i, flag, agNULL); 23302 } 23303 } 23304 23305 return; 23306 } 23307 23308 #endif /* #ifdef SATA_ENABLE */ 23309