1 /******************************************************************************* 2 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 3 * 4 *Redistribution and use in source and binary forms, with or without modification, are permitted provided 5 *that the following conditions are met: 6 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 7 *following disclaimer. 8 *2. Redistributions in binary form must reproduce the above copyright notice, 9 *this list of conditions and the following disclaimer in the documentation and/or other materials provided 10 *with the distribution. 11 * 12 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 13 *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 14 *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 15 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 16 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 17 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 18 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 19 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 20 21 ********************************************************************************/ 22 /*****************************************************************************/ 23 /** \file 24 * 25 * The file implementing SCSI/ATA Translation (SAT). 26 * The routines in this file are independent from HW LL API. 27 * 28 */ 29 /*****************************************************************************/ 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 #include <dev/pms/config.h> 33 34 #include <dev/pms/freebsd/driver/common/osenv.h> 35 #include <dev/pms/freebsd/driver/common/ostypes.h> 36 #include <dev/pms/freebsd/driver/common/osdebug.h> 37 38 #ifdef SATA_ENABLE 39 40 #include <dev/pms/RefTisa/sallsdk/api/sa.h> 41 #include <dev/pms/RefTisa/sallsdk/api/saapi.h> 42 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h> 43 44 #include <dev/pms/RefTisa/tisa/api/titypes.h> 45 #include <dev/pms/RefTisa/tisa/api/ostiapi.h> 46 #include <dev/pms/RefTisa/tisa/api/tiapi.h> 47 #include <dev/pms/RefTisa/tisa/api/tiglobal.h> 48 49 #ifdef FDS_SM 50 #include <dev/pms/RefTisa/sat/api/sm.h> 51 #include <dev/pms/RefTisa/sat/api/smapi.h> 52 #include <dev/pms/RefTisa/sat/api/tdsmapi.h> 53 #endif 54 55 #ifdef FDS_DM 56 #include <dev/pms/RefTisa/discovery/api/dm.h> 57 #include <dev/pms/RefTisa/discovery/api/dmapi.h> 58 #include <dev/pms/RefTisa/discovery/api/tddmapi.h> 59 #endif 60 61 #include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h> 62 #include <dev/pms/freebsd/driver/common/osstring.h> 63 #include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h> 64 65 #ifdef INITIATOR_DRIVER 66 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h> 67 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h> 68 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h> 69 #endif 70 71 #ifdef TARGET_DRIVER 72 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h> 73 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h> 74 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h> 75 #endif 76 77 #include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h> 78 #include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h> 79 80 #include <dev/pms/RefTisa/tisa/sassata/sata/host/sat.h> 81 #include <dev/pms/RefTisa/tisa/sassata/sata/host/satproto.h> 82 83 /***************************************************************************** 84 *! \brief satIOStart 85 * 86 * This routine is called to initiate a new SCSI request to SATL. 87 * 88 * \param tiRoot: Pointer to TISA initiator driver/port instance. 89 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 90 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 91 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 92 * \param satIOContext_t: Pointer to the SAT IO Context 93 * 94 * \return: 95 * 96 * \e tiSuccess: I/O request successfully initiated. 97 * \e tiBusy: No resources available, try again later. 98 * \e tiIONoDevice: Invalid device handle. 99 * \e tiError: Other errors that prevent the I/O request to be started. 100 * 101 * 102 *****************************************************************************/ 103 GLOBAL bit32 satIOStart( 104 tiRoot_t *tiRoot, 105 tiIORequest_t *tiIORequest, 106 tiDeviceHandle_t *tiDeviceHandle, 107 tiScsiInitiatorRequest_t *tiScsiRequest, 108 satIOContext_t *satIOContext 109 ) 110 { 111 112 bit32 retVal = tiSuccess; 113 satDeviceData_t *pSatDevData; 114 scsiRspSense_t *pSense; 115 tiIniScsiCmnd_t *scsiCmnd; 116 tiLUN_t *pLun; 117 satInternalIo_t *pSatIntIo; 118 #ifdef TD_DEBUG_ENABLE 119 tdsaDeviceData_t *oneDeviceData; 120 #endif 121 122 pSense = satIOContext->pSense; 123 pSatDevData = satIOContext->pSatDevData; 124 scsiCmnd = &tiScsiRequest->scsiCmnd; 125 pLun = &scsiCmnd->lun; 126 127 /* 128 * Reject all other LUN other than LUN 0. 129 */ 130 if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] | 131 pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) && 132 (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY) 133 ) 134 { 135 TI_DBG1(("satIOStart: *** REJECT *** LUN not zero, cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n", 136 scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle)); 137 satSetSensePayload( pSense, 138 SCSI_SNSKEY_ILLEGAL_REQUEST, 139 0, 140 SCSI_SNSCODE_LOGICAL_NOT_SUPPORTED, 141 satIOContext); 142 143 ostiInitiatorIOCompleted( tiRoot, 144 tiIORequest, 145 tiIOSuccess, 146 SCSI_STAT_CHECK_CONDITION, 147 satIOContext->pTiSenseData, 148 satIOContext->interruptContext ); 149 retVal = tiSuccess; 150 goto ext; 151 } 152 153 TI_DBG6(("satIOStart: satPendingIO %d satNCQMaxIO %d\n",pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO )); 154 155 /* this may happen after tiCOMReset until OS sends inquiry */ 156 if (pSatDevData->IDDeviceValid == agFALSE && (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY)) 157 { 158 #ifdef TD_DEBUG_ENABLE 159 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 160 #endif 161 TI_DBG1(("satIOStart: invalid identify device data did %d\n", oneDeviceData->id)); 162 retVal = tiIONoDevice; 163 goto ext; 164 } 165 /* 166 * Check if we need to return BUSY, i.e. recovery in progress 167 */ 168 if (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY) 169 { 170 #ifdef TD_DEBUG_ENABLE 171 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 172 #endif 173 TI_DBG1(("satIOStart: IN RECOVERY STATE cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n", 174 scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle)); 175 TI_DBG1(("satIOStart: IN RECOVERY STATE did %d\n", oneDeviceData->id)); 176 177 TI_DBG1(("satIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO )); 178 TI_DBG1(("satIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO)); 179 retVal = tiError; 180 goto ext; 181 // return tiBusy; 182 } 183 184 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE) 185 { 186 if (scsiCmnd->cdb[0] == SCSIOPC_REPORT_LUN) 187 { 188 return satReportLun(tiRoot, tiIORequest, tiDeviceHandle, tiScsiRequest, satIOContext); 189 } 190 else 191 { 192 return satPacket(tiRoot, tiIORequest, tiDeviceHandle, tiScsiRequest, satIOContext); 193 } 194 } 195 else /* pSatDevData->satDeviceType != SATA_ATAPI_DEVICE */ 196 { 197 /* Parse CDB */ 198 switch(scsiCmnd->cdb[0]) 199 { 200 case SCSIOPC_READ_6: 201 retVal = satRead6( tiRoot, 202 tiIORequest, 203 tiDeviceHandle, 204 tiScsiRequest, 205 satIOContext); 206 break; 207 208 case SCSIOPC_READ_10: 209 retVal = satRead10( tiRoot, 210 tiIORequest, 211 tiDeviceHandle, 212 tiScsiRequest, 213 satIOContext); 214 break; 215 216 case SCSIOPC_READ_12: 217 TI_DBG5(("satIOStart: SCSIOPC_READ_12\n")); 218 retVal = satRead12( tiRoot, 219 tiIORequest, 220 tiDeviceHandle, 221 tiScsiRequest, 222 satIOContext); 223 break; 224 225 case SCSIOPC_READ_16: 226 retVal = satRead16( tiRoot, 227 tiIORequest, 228 tiDeviceHandle, 229 tiScsiRequest, 230 satIOContext); 231 break; 232 233 case SCSIOPC_WRITE_6: 234 retVal = satWrite6( tiRoot, 235 tiIORequest, 236 tiDeviceHandle, 237 tiScsiRequest, 238 satIOContext); 239 break; 240 241 case SCSIOPC_WRITE_10: 242 retVal = satWrite10( tiRoot, 243 tiIORequest, 244 tiDeviceHandle, 245 tiScsiRequest, 246 satIOContext); 247 break; 248 249 case SCSIOPC_WRITE_12: 250 TI_DBG5(("satIOStart: SCSIOPC_WRITE_12 \n")); 251 retVal = satWrite12( tiRoot, 252 tiIORequest, 253 tiDeviceHandle, 254 tiScsiRequest, 255 satIOContext); 256 257 break; 258 259 case SCSIOPC_WRITE_16: 260 TI_DBG5(("satIOStart: SCSIOPC_WRITE_16\n")); 261 retVal = satWrite16( tiRoot, 262 tiIORequest, 263 tiDeviceHandle, 264 tiScsiRequest, 265 satIOContext); 266 267 break; 268 269 case SCSIOPC_VERIFY_10: 270 retVal = satVerify10( tiRoot, 271 tiIORequest, 272 tiDeviceHandle, 273 tiScsiRequest, 274 satIOContext); 275 break; 276 277 case SCSIOPC_VERIFY_12: 278 TI_DBG5(("satIOStart: SCSIOPC_VERIFY_12\n")); 279 retVal = satVerify12( tiRoot, 280 tiIORequest, 281 tiDeviceHandle, 282 tiScsiRequest, 283 satIOContext); 284 break; 285 286 case SCSIOPC_VERIFY_16: 287 TI_DBG5(("satIOStart: SCSIOPC_VERIFY_16\n")); 288 retVal = satVerify16( tiRoot, 289 tiIORequest, 290 tiDeviceHandle, 291 tiScsiRequest, 292 satIOContext); 293 break; 294 295 case SCSIOPC_TEST_UNIT_READY: 296 retVal = satTestUnitReady( tiRoot, 297 tiIORequest, 298 tiDeviceHandle, 299 tiScsiRequest, 300 satIOContext); 301 break; 302 303 case SCSIOPC_INQUIRY: 304 retVal = satInquiry( tiRoot, 305 tiIORequest, 306 tiDeviceHandle, 307 tiScsiRequest, 308 satIOContext); 309 break; 310 311 case SCSIOPC_REQUEST_SENSE: 312 retVal = satRequestSense( tiRoot, 313 tiIORequest, 314 tiDeviceHandle, 315 tiScsiRequest, 316 satIOContext); 317 break; 318 319 case SCSIOPC_MODE_SENSE_6: 320 retVal = satModeSense6( tiRoot, 321 tiIORequest, 322 tiDeviceHandle, 323 tiScsiRequest, 324 satIOContext); 325 break; 326 327 case SCSIOPC_MODE_SENSE_10: 328 retVal = satModeSense10( tiRoot, 329 tiIORequest, 330 tiDeviceHandle, 331 tiScsiRequest, 332 satIOContext); 333 break; 334 335 336 case SCSIOPC_READ_CAPACITY_10: 337 retVal = satReadCapacity10( tiRoot, 338 tiIORequest, 339 tiDeviceHandle, 340 tiScsiRequest, 341 satIOContext); 342 break; 343 344 case SCSIOPC_READ_CAPACITY_16: 345 retVal = satReadCapacity16( tiRoot, 346 tiIORequest, 347 tiDeviceHandle, 348 tiScsiRequest, 349 satIOContext); 350 break; 351 352 case SCSIOPC_REPORT_LUN: 353 retVal = satReportLun( tiRoot, 354 tiIORequest, 355 tiDeviceHandle, 356 tiScsiRequest, 357 satIOContext); 358 break; 359 360 case SCSIOPC_FORMAT_UNIT: 361 TI_DBG5(("satIOStart: SCSIOPC_FORMAT_UNIT\n")); 362 retVal = satFormatUnit( tiRoot, 363 tiIORequest, 364 tiDeviceHandle, 365 tiScsiRequest, 366 satIOContext); 367 break; 368 case SCSIOPC_SEND_DIAGNOSTIC: /* Table 28, p40 */ 369 TI_DBG5(("satIOStart: SCSIOPC_SEND_DIAGNOSTIC\n")); 370 retVal = satSendDiagnostic( tiRoot, 371 tiIORequest, 372 tiDeviceHandle, 373 tiScsiRequest, 374 satIOContext); 375 break; 376 377 case SCSIOPC_START_STOP_UNIT: 378 TI_DBG5(("satIOStart: SCSIOPC_START_STOP_UNIT\n")); 379 retVal = satStartStopUnit( tiRoot, 380 tiIORequest, 381 tiDeviceHandle, 382 tiScsiRequest, 383 satIOContext); 384 break; 385 386 case SCSIOPC_WRITE_SAME_10: /* sector and LBA; SAT p64 case 3 accessing payload and very 387 inefficient now */ 388 TI_DBG5(("satIOStart: SCSIOPC_WRITE_SAME_10\n")); 389 retVal = satWriteSame10( tiRoot, 390 tiIORequest, 391 tiDeviceHandle, 392 tiScsiRequest, 393 satIOContext); 394 break; 395 396 case SCSIOPC_WRITE_SAME_16: /* no support due to transfer length(sector count) */ 397 TI_DBG5(("satIOStart: SCSIOPC_WRITE_SAME_16\n")); 398 retVal = satWriteSame16( tiRoot, 399 tiIORequest, 400 tiDeviceHandle, 401 tiScsiRequest, 402 satIOContext); 403 break; 404 405 case SCSIOPC_LOG_SENSE: /* SCT and log parameter(informational exceptions) */ 406 TI_DBG5(("satIOStart: SCSIOPC_LOG_SENSE\n")); 407 retVal = satLogSense( tiRoot, 408 tiIORequest, 409 tiDeviceHandle, 410 tiScsiRequest, 411 satIOContext); 412 break; 413 414 case SCSIOPC_MODE_SELECT_6: /*mode layout and AlloLen check */ 415 TI_DBG5(("satIOStart: SCSIOPC_MODE_SELECT_6\n")); 416 retVal = satModeSelect6( tiRoot, 417 tiIORequest, 418 tiDeviceHandle, 419 tiScsiRequest, 420 satIOContext); 421 break; 422 423 case SCSIOPC_MODE_SELECT_10: /* mode layout and AlloLen check and sharing CB with satModeSelect6*/ 424 TI_DBG5(("satIOStart: SCSIOPC_MODE_SELECT_10\n")); 425 retVal = satModeSelect10( tiRoot, 426 tiIORequest, 427 tiDeviceHandle, 428 tiScsiRequest, 429 satIOContext); 430 break; 431 432 case SCSIOPC_SYNCHRONIZE_CACHE_10: /* on error what to return, sharing CB with 433 satSynchronizeCache16 */ 434 TI_DBG5(("satIOStart: SCSIOPC_SYNCHRONIZE_CACHE_10\n")); 435 retVal = satSynchronizeCache10( tiRoot, 436 tiIORequest, 437 tiDeviceHandle, 438 tiScsiRequest, 439 satIOContext); 440 break; 441 442 case SCSIOPC_SYNCHRONIZE_CACHE_16:/* on error what to return, sharing CB with 443 satSynchronizeCache16 */ 444 445 TI_DBG5(("satIOStart: SCSIOPC_SYNCHRONIZE_CACHE_16\n")); 446 retVal = satSynchronizeCache16( tiRoot, 447 tiIORequest, 448 tiDeviceHandle, 449 tiScsiRequest, 450 satIOContext); 451 break; 452 453 case SCSIOPC_WRITE_AND_VERIFY_10: /* single write and multiple writes */ 454 TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_10\n")); 455 retVal = satWriteAndVerify10( tiRoot, 456 tiIORequest, 457 tiDeviceHandle, 458 tiScsiRequest, 459 satIOContext); 460 break; 461 462 case SCSIOPC_WRITE_AND_VERIFY_12: 463 TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_12\n")); 464 retVal = satWriteAndVerify12( tiRoot, 465 tiIORequest, 466 tiDeviceHandle, 467 tiScsiRequest, 468 satIOContext); 469 break; 470 471 case SCSIOPC_WRITE_AND_VERIFY_16: 472 TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_16\n")); 473 retVal = satWriteAndVerify16( tiRoot, 474 tiIORequest, 475 tiDeviceHandle, 476 tiScsiRequest, 477 satIOContext); 478 479 break; 480 481 case SCSIOPC_READ_MEDIA_SERIAL_NUMBER: 482 TI_DBG5(("satIOStart: SCSIOPC_READ_MEDIA_SERIAL_NUMBER\n")); 483 retVal = satReadMediaSerialNumber( tiRoot, 484 tiIORequest, 485 tiDeviceHandle, 486 tiScsiRequest, 487 satIOContext); 488 489 break; 490 491 case SCSIOPC_READ_BUFFER: 492 TI_DBG5(("satIOStart: SCSIOPC_READ_BUFFER\n")); 493 retVal = satReadBuffer( tiRoot, 494 tiIORequest, 495 tiDeviceHandle, 496 tiScsiRequest, 497 satIOContext); 498 499 break; 500 501 case SCSIOPC_WRITE_BUFFER: 502 TI_DBG5(("satIOStart: SCSIOPC_WRITE_BUFFER\n")); 503 retVal = satWriteBuffer( tiRoot, 504 tiIORequest, 505 tiDeviceHandle, 506 tiScsiRequest, 507 satIOContext); 508 509 break; 510 511 case SCSIOPC_REASSIGN_BLOCKS: 512 TI_DBG5(("satIOStart: SCSIOPC_REASSIGN_BLOCKS\n")); 513 retVal = satReassignBlocks( tiRoot, 514 tiIORequest, 515 tiDeviceHandle, 516 tiScsiRequest, 517 satIOContext); 518 519 break; 520 521 default: 522 /* Not implemented SCSI cmd, set up error response */ 523 TI_DBG1(("satIOStart: unsupported SCSI cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n", 524 scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle)); 525 526 satSetSensePayload( pSense, 527 SCSI_SNSKEY_ILLEGAL_REQUEST, 528 0, 529 SCSI_SNSCODE_INVALID_COMMAND, 530 satIOContext); 531 532 ostiInitiatorIOCompleted( tiRoot, 533 tiIORequest, 534 tiIOSuccess, 535 SCSI_STAT_CHECK_CONDITION, 536 satIOContext->pTiSenseData, 537 satIOContext->interruptContext ); 538 retVal = tiSuccess; 539 540 break; 541 542 } /* end switch */ 543 } 544 if (retVal == tiBusy) 545 { 546 #ifdef TD_DEBUG_ENABLE 547 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 548 #endif 549 TI_DBG1(("satIOStart: BUSY did %d\n", oneDeviceData->id)); 550 TI_DBG3(("satIOStart: LL is busy or target queue is full\n")); 551 TI_DBG3(("satIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO )); 552 TI_DBG3(("satIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO)); 553 pSatIntIo = satIOContext->satIntIoContext; 554 555 /* interal structure free */ 556 satFreeIntIoResource( tiRoot, 557 pSatDevData, 558 pSatIntIo); 559 } 560 561 ext: 562 return retVal; 563 } 564 565 566 /*****************************************************************************/ 567 /*! \brief Setup up the SCSI Sense response. 568 * 569 * This function is used to setup up the Sense Data payload for 570 * CHECK CONDITION status. 571 * 572 * \param pSense: Pointer to the scsiRspSense_t sense data structure. 573 * \param SnsKey: SCSI Sense Key. 574 * \param SnsInfo: SCSI Sense Info. 575 * \param SnsCode: SCSI Sense Code. 576 * 577 * \return: None 578 */ 579 /*****************************************************************************/ 580 void satSetSensePayload( scsiRspSense_t *pSense, 581 bit8 SnsKey, 582 bit32 SnsInfo, 583 bit16 SnsCode, 584 satIOContext_t *satIOContext 585 ) 586 { 587 /* for fixed format sense data, SPC-4, p37 */ 588 bit32 i; 589 bit32 senseLength; 590 591 TI_DBG5(("satSetSensePayload: start\n")); 592 593 senseLength = sizeof(scsiRspSense_t); 594 595 /* zero out the data area */ 596 for (i=0;i< senseLength;i++) 597 { 598 ((bit8*)pSense)[i] = 0; 599 } 600 601 /* 602 * SCSI Sense Data part of response data 603 */ 604 pSense->snsRespCode = 0x70; /* 0xC0 == vendor specific */ 605 /* 0x70 == standard current error */ 606 pSense->senseKey = SnsKey; 607 /* 608 * Put sense info in scsi order format 609 */ 610 pSense->info[0] = (bit8)((SnsInfo >> 24) & 0xff); 611 pSense->info[1] = (bit8)((SnsInfo >> 16) & 0xff); 612 pSense->info[2] = (bit8)((SnsInfo >> 8) & 0xff); 613 pSense->info[3] = (bit8)((SnsInfo) & 0xff); 614 pSense->addSenseLen = 11; /* fixed size of sense data = 18 */ 615 pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF); 616 pSense->senseQual = (bit8)(SnsCode & 0xFF); 617 /* 618 * Set pointer in scsi status 619 */ 620 switch(SnsKey) 621 { 622 /* 623 * set illegal request sense key specific error in cdb, no bit pointer 624 */ 625 case SCSI_SNSKEY_ILLEGAL_REQUEST: 626 pSense->skeySpecific[0] = 0xC8; 627 break; 628 629 default: 630 break; 631 } 632 /* setting sense data length */ 633 if (satIOContext != agNULL) 634 { 635 satIOContext->pTiSenseData->senseLen = 18; 636 } 637 else 638 { 639 TI_DBG1(("satSetSensePayload: satIOContext is NULL\n")); 640 } 641 } 642 643 /*****************************************************************************/ 644 /*! \brief Setup up the SCSI Sense response. 645 * 646 * This function is used to setup up the Sense Data payload for 647 * CHECK CONDITION status. 648 * 649 * \param pSense: Pointer to the scsiRspSense_t sense data structure. 650 * \param SnsKey: SCSI Sense Key. 651 * \param SnsInfo: SCSI Sense Info. 652 * \param SnsCode: SCSI Sense Code. 653 * 654 * \return: None 655 */ 656 /*****************************************************************************/ 657 658 void satSetDeferredSensePayload( scsiRspSense_t *pSense, 659 bit8 SnsKey, 660 bit32 SnsInfo, 661 bit16 SnsCode, 662 satIOContext_t *satIOContext 663 ) 664 { 665 /* for fixed format sense data, SPC-4, p37 */ 666 bit32 i; 667 bit32 senseLength; 668 669 senseLength = sizeof(scsiRspSense_t); 670 671 /* zero out the data area */ 672 for (i=0;i< senseLength;i++) 673 { 674 ((bit8*)pSense)[i] = 0; 675 } 676 677 /* 678 * SCSI Sense Data part of response data 679 */ 680 pSense->snsRespCode = 0x71; /* 0xC0 == vendor specific */ 681 /* 0x70 == standard current error */ 682 pSense->senseKey = SnsKey; 683 /* 684 * Put sense info in scsi order format 685 */ 686 pSense->info[0] = (bit8)((SnsInfo >> 24) & 0xff); 687 pSense->info[1] = (bit8)((SnsInfo >> 16) & 0xff); 688 pSense->info[2] = (bit8)((SnsInfo >> 8) & 0xff); 689 pSense->info[3] = (bit8)((SnsInfo) & 0xff); 690 pSense->addSenseLen = 11; /* fixed size of sense data = 18 */ 691 pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF); 692 pSense->senseQual = (bit8)(SnsCode & 0xFF); 693 /* 694 * Set pointer in scsi status 695 */ 696 switch(SnsKey) 697 { 698 /* 699 * set illegal request sense key specific error in cdb, no bit pointer 700 */ 701 case SCSI_SNSKEY_ILLEGAL_REQUEST: 702 pSense->skeySpecific[0] = 0xC8; 703 break; 704 705 default: 706 break; 707 } 708 709 /* setting sense data length */ 710 if (satIOContext != agNULL) 711 { 712 satIOContext->pTiSenseData->senseLen = 18; 713 } 714 else 715 { 716 TI_DBG1(("satSetDeferredSensePayload: satIOContext is NULL\n")); 717 } 718 719 } 720 /*****************************************************************************/ 721 /*! \brief SAT implementation for ATAPI Packet Command. 722 * 723 * SAT implementation for ATAPI Packet and send FIS request to LL layer. 724 * 725 * \param tiRoot: Pointer to TISA initiator driver/port instance. 726 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 727 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 728 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 729 * \param satIOContext_t: Pointer to the SAT IO Context 730 * 731 * \return If command is started successfully 732 * - \e tiSuccess: I/O request successfully initiated. 733 * - \e tiBusy: No resources available, try again later. 734 * - \e tiIONoDevice: Invalid device handle. 735 * - \e tiError: Other errors. 736 */ 737 /*****************************************************************************/ 738 GLOBAL bit32 satPacket( 739 tiRoot_t *tiRoot, 740 tiIORequest_t *tiIORequest, 741 tiDeviceHandle_t *tiDeviceHandle, 742 tiScsiInitiatorRequest_t *tiScsiRequest, 743 satIOContext_t *satIOContext) 744 { 745 bit32 status; 746 bit32 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT; 747 satDeviceData_t *pSatDevData; 748 tiIniScsiCmnd_t *scsiCmnd; 749 agsaFisRegHostToDevice_t *fis; 750 751 pSatDevData = satIOContext->pSatDevData; 752 scsiCmnd = &tiScsiRequest->scsiCmnd; 753 fis = satIOContext->pFis; 754 755 TI_DBG3(("satPacket: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n", 756 scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3], 757 scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7], 758 scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11])); 759 760 fis->h.fisType = 0x27; /* Reg host to device */ 761 fis->h.c_pmPort = 0x80; /* C Bit is set 1*/ 762 fis->h.command = SAT_PACKET; /* 0xA0 */ 763 if (pSatDevData->satDMADIRSupport) /* DMADIR enabled*/ 764 { 765 fis->h.features = (tiScsiRequest->dataDirection == tiDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */ 766 } 767 else 768 { 769 fis->h.features = 0; /* FIS reserve */ 770 } 771 /* Byte count low and byte count high */ 772 if ( scsiCmnd->expDataLength > 0xFFFF ) 773 { 774 fis->d.lbaMid = 0xFF; /* FIS LBA (7 :0 ) */ 775 fis->d.lbaHigh = 0xFF; /* FIS LBA (15:8 ) */ 776 } 777 else 778 { 779 fis->d.lbaMid = (bit8)scsiCmnd->expDataLength; /* FIS LBA (7 :0 ) */ 780 fis->d.lbaHigh = (bit8)(scsiCmnd->expDataLength>>8); /* FIS LBA (15:8 ) */ 781 } 782 783 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 784 fis->d.device = 0; /* FIS LBA (27:24) and FIS LBA mode */ 785 fis->d.lbaLowExp = 0; 786 fis->d.lbaMidExp = 0; 787 fis->d.lbaHighExp = 0; 788 fis->d.featuresExp = 0; 789 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 790 fis->d.sectorCountExp = 0; 791 fis->d.reserved4 = 0; 792 fis->d.control = 0; /* FIS HOB bit clear */ 793 fis->d.reserved5 = 0; 794 795 satIOContext->ATACmd = SAT_PACKET; 796 797 if (tiScsiRequest->dataDirection == tiDirectionIn) 798 { 799 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT; 800 } 801 else 802 { 803 agRequestType = AGSA_SATA_PROTOCOL_H2D_PKT; 804 } 805 806 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 807 { 808 /*DMA transfer mode*/ 809 fis->h.features |= 0x01; 810 } 811 else 812 { 813 /*PIO transfer mode*/ 814 fis->h.features |= 0x0; 815 } 816 817 satIOContext->satCompleteCB = &satPacketCB; 818 819 /* 820 * Prepare SGL and send FIS to LL layer. 821 */ 822 satIOContext->reqType = agRequestType; /* Save it */ 823 824 status = sataLLIOStart( tiRoot, 825 tiIORequest, 826 tiDeviceHandle, 827 tiScsiRequest, 828 satIOContext); 829 830 TI_DBG5(("satPacket: return\n")); 831 return (status); 832 } 833 834 /*****************************************************************************/ 835 /*! \brief SAT implementation for satSetFeatures. 836 * 837 * This function creates SetFeatures fis and sends the request to LL layer 838 * 839 * \param tiRoot: Pointer to TISA initiator driver/port instance. 840 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 841 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 842 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 843 * \param satIOContext_t: Pointer to the SAT IO Context 844 * 845 * \return If command is started successfully 846 * - \e tiSuccess: I/O request successfully initiated. 847 * - \e tiBusy: No resources available, try again later. 848 * - \e tiIONoDevice: Invalid device handle. 849 * - \e tiError: Other errors. 850 */ 851 /*****************************************************************************/ 852 GLOBAL bit32 satSetFeatures( 853 tiRoot_t *tiRoot, 854 tiIORequest_t *tiIORequest, 855 tiDeviceHandle_t *tiDeviceHandle, 856 tiScsiInitiatorRequest_t *tiScsiRequest, 857 satIOContext_t *satIOContext, 858 bit8 bIsDMAMode 859 ) 860 { 861 bit32 status; 862 bit32 agRequestType; 863 agsaFisRegHostToDevice_t *fis; 864 865 fis = satIOContext->pFis; 866 TI_DBG3(("satSetFeatures: start\n")); 867 868 /* 869 * Send the Set Features command. 870 */ 871 fis->h.fisType = 0x27; /* Reg host to device */ 872 fis->h.c_pmPort = 0x80; /* C Bit is set */ 873 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 874 fis->h.features = 0x03; /* set transfer mode */ 875 fis->d.lbaLow = 0; 876 fis->d.lbaMid = 0; 877 fis->d.lbaHigh = 0; 878 fis->d.device = 0; 879 fis->d.lbaLowExp = 0; 880 fis->d.lbaMidExp = 0; 881 fis->d.lbaHighExp = 0; 882 fis->d.featuresExp = 0; 883 fis->d.sectorCountExp = 0; 884 fis->d.reserved4 = 0; 885 fis->d.control = 0; /* FIS HOB bit clear */ 886 fis->d.reserved5 = 0; 887 888 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 889 890 /* Initialize CB for SATA completion. 891 */ 892 if (bIsDMAMode) 893 { 894 fis->d.sectorCount = 0x45; 895 /*satIOContext->satCompleteCB = &satSetFeaturesDMACB;*/ 896 } 897 else 898 { 899 fis->d.sectorCount = 0x0C; 900 /*satIOContext->satCompleteCB = &satSetFeaturesPIOCB;*/ 901 } 902 satIOContext->satCompleteCB = &satSetFeaturesCB; 903 904 /* 905 * Prepare SGL and send FIS to LL layer. 906 */ 907 satIOContext->reqType = agRequestType; /* Save it */ 908 909 status = sataLLIOStart( tiRoot, 910 tiIORequest, 911 tiDeviceHandle, 912 tiScsiRequest, 913 satIOContext); 914 915 TI_DBG5(("satSetFeatures: return\n")); 916 917 return status; 918 } 919 /*****************************************************************************/ 920 /*! \brief SAT implementation for SCSI REQUEST SENSE to ATAPI device. 921 * 922 * SAT implementation for SCSI REQUEST SENSE. 923 * 924 * \param tiRoot: Pointer to TISA initiator driver/port instance. 925 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 926 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 927 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 928 * \param satIOContext_t: Pointer to the SAT IO Context 929 * 930 * \return If command is started successfully 931 * - \e tiSuccess: I/O request successfully initiated. 932 * - \e tiBusy: No resources available, try again later. 933 * - \e tiIONoDevice: Invalid device handle. 934 * - \e tiError: Other errors. 935 */ 936 /*****************************************************************************/ 937 GLOBAL bit32 satRequestSenseForATAPI( 938 tiRoot_t *tiRoot, 939 tiIORequest_t *tiIORequest, 940 tiDeviceHandle_t *tiDeviceHandle, 941 tiScsiInitiatorRequest_t *tiScsiRequest, 942 satIOContext_t *satIOContext) 943 { 944 bit32 status; 945 bit32 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT; 946 satDeviceData_t *pSatDevData; 947 tiIniScsiCmnd_t *scsiCmnd; 948 agsaFisRegHostToDevice_t *fis; 949 950 pSatDevData = satIOContext->pSatDevData; 951 scsiCmnd = &tiScsiRequest->scsiCmnd; 952 fis = satIOContext->pFis; 953 954 scsiCmnd->cdb[0] = SCSIOPC_REQUEST_SENSE; 955 scsiCmnd->cdb[1] = 0; 956 scsiCmnd->cdb[2] = 0; 957 scsiCmnd->cdb[3] = 0; 958 scsiCmnd->cdb[4] = SENSE_DATA_LENGTH; 959 scsiCmnd->cdb[5] = 0; 960 TI_DBG3(("satRequestSenseForATAPI: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n", 961 scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3], 962 scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7], 963 scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11])); 964 965 fis->h.fisType = 0x27; /* Reg host to device */ 966 fis->h.c_pmPort = 0x80; /* C Bit is set 1*/ 967 fis->h.command = SAT_PACKET; /* 0xA0 */ 968 if (pSatDevData->satDMADIRSupport) /* DMADIR enabled*/ 969 { 970 fis->h.features = (tiScsiRequest->dataDirection == tiDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */ 971 } 972 else 973 { 974 fis->h.features = 0; /* FIS reserve */ 975 } 976 977 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 978 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 979 fis->d.lbaHigh = 0x20; /* FIS LBA (23:16) */ 980 fis->d.device = 0; /* FIS LBA (27:24) and FIS LBA mode */ 981 fis->d.lbaLowExp = 0; 982 fis->d.lbaMidExp = 0; 983 fis->d.lbaHighExp = 0; 984 fis->d.featuresExp = 0; 985 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 986 fis->d.sectorCountExp = 0; 987 fis->d.reserved4 = 0; 988 fis->d.control = 0; /* FIS HOB bit clear */ 989 fis->d.reserved5 = (bit32)(scsiCmnd->cdb[0]|(scsiCmnd->cdb[1]<<8)|(scsiCmnd->cdb[2]<<16)|(scsiCmnd->cdb[3]<<24)); 990 991 satIOContext->ATACmd = SAT_PACKET; 992 993 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT; 994 995 //if (pSatDevData->sat48BitSupport == agTRUE) 996 { 997 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 998 { 999 fis->h.features |= 0x01; 1000 } 1001 else 1002 { 1003 fis->h.features |= 0x0; 1004 } 1005 } 1006 1007 satIOContext->satCompleteCB = &satRequestSenseForATAPICB; 1008 1009 /* 1010 * Prepare SGL and send FIS to LL layer. 1011 */ 1012 satIOContext->reqType = agRequestType; /* Save it */ 1013 1014 status = sataLLIOStart( tiRoot, 1015 tiIORequest, 1016 tiDeviceHandle, 1017 tiScsiRequest, 1018 satIOContext); 1019 1020 TI_DBG5(("satRequestSenseForATAPI: return\n")); 1021 return (status); 1022 } 1023 /*****************************************************************************/ 1024 /*! \brief SAT implementation for satDeviceReset. 1025 * 1026 * This function creates DEVICE RESET fis and sends the request to LL layer 1027 * 1028 * \param tiRoot: Pointer to TISA initiator driver/port instance. 1029 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 1030 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 1031 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 1032 * \param satIOContext_t: Pointer to the SAT IO Context 1033 * 1034 * \return If command is started successfully 1035 * - \e tiSuccess: I/O request successfully initiated. 1036 * - \e tiBusy: No resources available, try again later. 1037 * - \e tiIONoDevice: Invalid device handle. 1038 * - \e tiError: Other errors. 1039 */ 1040 /*****************************************************************************/ 1041 GLOBAL bit32 satDeviceReset( 1042 tiRoot_t *tiRoot, 1043 tiIORequest_t *tiIORequest, 1044 tiDeviceHandle_t *tiDeviceHandle, 1045 tiScsiInitiatorRequest_t *tiScsiRequest, 1046 satIOContext_t *satIOContext 1047 ) 1048 { 1049 bit32 status; 1050 bit32 agRequestType; 1051 agsaFisRegHostToDevice_t *fis; 1052 1053 fis = satIOContext->pFis; 1054 1055 TI_DBG3(("satDeviceReset: start\n")); 1056 1057 /* 1058 * Send the Execute Device Diagnostic command. 1059 */ 1060 fis->h.fisType = 0x27; /* Reg host to device */ 1061 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1062 fis->h.command = SAT_DEVICE_RESET; /* 0x90 */ 1063 fis->h.features = 0; 1064 fis->d.lbaLow = 0; 1065 fis->d.lbaMid = 0; 1066 fis->d.lbaHigh = 0; 1067 fis->d.device = 0; 1068 fis->d.lbaLowExp = 0; 1069 fis->d.lbaMidExp = 0; 1070 fis->d.lbaHighExp = 0; 1071 fis->d.featuresExp = 0; 1072 fis->d.sectorCount = 0; 1073 fis->d.sectorCountExp = 0; 1074 fis->d.reserved4 = 0; 1075 fis->d.control = 0; /* FIS HOB bit clear */ 1076 fis->d.reserved5 = 0; 1077 1078 agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET; 1079 1080 /* Initialize CB for SATA completion. 1081 */ 1082 satIOContext->satCompleteCB = &satDeviceResetCB; 1083 1084 /* 1085 * Prepare SGL and send FIS to LL layer. 1086 */ 1087 satIOContext->reqType = agRequestType; /* Save it */ 1088 1089 status = sataLLIOStart( tiRoot, 1090 tiIORequest, 1091 tiDeviceHandle, 1092 tiScsiRequest, 1093 satIOContext); 1094 1095 TI_DBG3(("satDeviceReset: return\n")); 1096 1097 return status; 1098 } 1099 1100 /*****************************************************************************/ 1101 /*! \brief SAT implementation for saExecuteDeviceDiagnostic. 1102 * 1103 * This function creates Execute Device Diagnostic fis and sends the request to LL layer 1104 * 1105 * \param tiRoot: Pointer to TISA initiator driver/port instance. 1106 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 1107 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 1108 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 1109 * \param satIOContext_t: Pointer to the SAT IO Context 1110 * 1111 * \return If command is started successfully 1112 * - \e tiSuccess: I/O request successfully initiated. 1113 * - \e tiBusy: No resources available, try again later. 1114 * - \e tiIONoDevice: Invalid device handle. 1115 * - \e tiError: Other errors. 1116 */ 1117 /*****************************************************************************/ 1118 GLOBAL bit32 satExecuteDeviceDiagnostic( 1119 tiRoot_t *tiRoot, 1120 tiIORequest_t *tiIORequest, 1121 tiDeviceHandle_t *tiDeviceHandle, 1122 tiScsiInitiatorRequest_t *tiScsiRequest, 1123 satIOContext_t *satIOContext 1124 ) 1125 { 1126 bit32 status; 1127 bit32 agRequestType; 1128 agsaFisRegHostToDevice_t *fis; 1129 1130 fis = satIOContext->pFis; 1131 1132 TI_DBG3(("satExecuteDeviceDiagnostic: start\n")); 1133 1134 /* 1135 * Send the Execute Device Diagnostic command. 1136 */ 1137 fis->h.fisType = 0x27; /* Reg host to device */ 1138 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1139 fis->h.command = SAT_EXECUTE_DEVICE_DIAGNOSTIC; /* 0x90 */ 1140 fis->h.features = 0; 1141 fis->d.lbaLow = 0; 1142 fis->d.lbaMid = 0; 1143 fis->d.lbaHigh = 0; 1144 fis->d.device = 0; 1145 fis->d.lbaLowExp = 0; 1146 fis->d.lbaMidExp = 0; 1147 fis->d.lbaHighExp = 0; 1148 fis->d.featuresExp = 0; 1149 fis->d.sectorCount = 0; 1150 fis->d.sectorCountExp = 0; 1151 fis->d.reserved4 = 0; 1152 fis->d.control = 0; /* FIS HOB bit clear */ 1153 fis->d.reserved5 = 0; 1154 1155 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 1156 1157 /* Initialize CB for SATA completion. 1158 */ 1159 satIOContext->satCompleteCB = &satExecuteDeviceDiagnosticCB; 1160 1161 /* 1162 * Prepare SGL and send FIS to LL layer. 1163 */ 1164 satIOContext->reqType = agRequestType; /* Save it */ 1165 1166 status = sataLLIOStart( tiRoot, 1167 tiIORequest, 1168 tiDeviceHandle, 1169 tiScsiRequest, 1170 satIOContext); 1171 1172 TI_DBG5(("satExecuteDeviceDiagnostic: return\n")); 1173 1174 return status; 1175 } 1176 1177 1178 /*****************************************************************************/ 1179 /*! \brief SAT implementation for SCSI READ10. 1180 * 1181 * SAT implementation for SCSI READ10 and send FIS request to LL layer. 1182 * 1183 * \param tiRoot: Pointer to TISA initiator driver/port instance. 1184 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 1185 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 1186 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 1187 * \param satIOContext_t: Pointer to the SAT IO Context 1188 * 1189 * \return If command is started successfully 1190 * - \e tiSuccess: I/O request successfully initiated. 1191 * - \e tiBusy: No resources available, try again later. 1192 * - \e tiIONoDevice: Invalid device handle. 1193 * - \e tiError: Other errors. 1194 */ 1195 /*****************************************************************************/ 1196 GLOBAL bit32 satRead10( 1197 tiRoot_t *tiRoot, 1198 tiIORequest_t *tiIORequest, 1199 tiDeviceHandle_t *tiDeviceHandle, 1200 tiScsiInitiatorRequest_t *tiScsiRequest, 1201 satIOContext_t *satIOContext) 1202 { 1203 1204 bit32 status; 1205 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 1206 satDeviceData_t *pSatDevData; 1207 scsiRspSense_t *pSense; 1208 tiIniScsiCmnd_t *scsiCmnd; 1209 agsaFisRegHostToDevice_t *fis; 1210 bit32 lba = 0; 1211 bit32 tl = 0; 1212 bit32 LoopNum = 1; 1213 bit8 LBA[4]; 1214 bit8 TL[4]; 1215 bit32 rangeChk = agFALSE; /* lba and tl range check */ 1216 1217 pSense = satIOContext->pSense; 1218 pSatDevData = satIOContext->pSatDevData; 1219 scsiCmnd = &tiScsiRequest->scsiCmnd; 1220 fis = satIOContext->pFis; 1221 1222 TI_DBG5(("satRead10: start\n")); 1223 TI_DBG5(("satRead10: pSatDevData=%p\n", pSatDevData)); 1224 // tdhexdump("satRead10", (bit8 *)scsiCmnd->cdb, 10); 1225 1226 /* checking FUA_NV */ 1227 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 1228 { 1229 satSetSensePayload( pSense, 1230 SCSI_SNSKEY_ILLEGAL_REQUEST, 1231 0, 1232 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 1233 satIOContext); 1234 1235 ostiInitiatorIOCompleted( tiRoot, 1236 tiIORequest, 1237 tiIOSuccess, 1238 SCSI_STAT_CHECK_CONDITION, 1239 satIOContext->pTiSenseData, 1240 satIOContext->interruptContext ); 1241 1242 TI_DBG1(("satRead10: return FUA_NV\n")); 1243 return tiSuccess; 1244 1245 } 1246 1247 /* checking CONTROL */ 1248 /* NACA == 1 or LINK == 1*/ 1249 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 1250 { 1251 satSetSensePayload( pSense, 1252 SCSI_SNSKEY_ILLEGAL_REQUEST, 1253 0, 1254 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 1255 satIOContext); 1256 1257 ostiInitiatorIOCompleted( tiRoot, 1258 tiIORequest, 1259 tiIOSuccess, 1260 SCSI_STAT_CHECK_CONDITION, 1261 satIOContext->pTiSenseData, 1262 satIOContext->interruptContext ); 1263 1264 TI_DBG1(("satRead10: return control\n")); 1265 return tiSuccess; 1266 } 1267 1268 osti_memset(LBA, 0, sizeof(LBA)); 1269 osti_memset(TL, 0, sizeof(TL)); 1270 1271 /* do not use memcpy due to indexing in LBA and TL */ 1272 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 1273 LBA[1] = scsiCmnd->cdb[3]; 1274 LBA[2] = scsiCmnd->cdb[4]; 1275 LBA[3] = scsiCmnd->cdb[5]; /* LSB */ 1276 1277 TL[0] = 0; 1278 TL[1] = 0; 1279 TL[2] = scsiCmnd->cdb[7]; /* MSB */ 1280 TL[3] = scsiCmnd->cdb[8]; /* LSB */ 1281 1282 rangeChk = satAddNComparebit32(LBA, TL); 1283 1284 /* cbd10; computing LBA and transfer length */ 1285 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 1286 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 1287 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 1288 1289 1290 TI_DBG5(("satRead10: lba %d functioned lba %d\n", lba, satComputeCDB10LBA(satIOContext))); 1291 TI_DBG5(("satRead10: lba 0x%x functioned lba 0x%x\n", lba, satComputeCDB10LBA(satIOContext))); 1292 TI_DBG5(("satRead10: tl %d functioned tl %d\n", tl, satComputeCDB10TL(satIOContext))); 1293 1294 /* Table 34, 9.1, p 46 */ 1295 /* 1296 note: As of 2/10/2006, no support for DMA QUEUED 1297 */ 1298 1299 /* 1300 Table 34, 9.1, p 46, b 1301 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 1302 return check condition 1303 */ 1304 1305 if (pSatDevData->satNCQ != agTRUE && 1306 pSatDevData->sat48BitSupport != agTRUE 1307 ) 1308 { 1309 if (lba > SAT_TR_LBA_LIMIT - 1) 1310 { 1311 TI_DBG1(("satRead10: return LBA out of range, not EXT\n")); 1312 satSetSensePayload( pSense, 1313 SCSI_SNSKEY_ILLEGAL_REQUEST, 1314 0, 1315 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 1316 satIOContext); 1317 1318 ostiInitiatorIOCompleted( tiRoot, 1319 tiIORequest, 1320 tiIOSuccess, 1321 SCSI_STAT_CHECK_CONDITION, 1322 satIOContext->pTiSenseData, 1323 satIOContext->interruptContext ); 1324 1325 return tiSuccess; 1326 } 1327 1328 1329 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 1330 { 1331 TI_DBG1(("satRead10: return LBA+TL out of range, not EXT\n")); 1332 satSetSensePayload( pSense, 1333 SCSI_SNSKEY_ILLEGAL_REQUEST, 1334 0, 1335 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 1336 satIOContext); 1337 1338 ostiInitiatorIOCompleted( tiRoot, 1339 tiIORequest, 1340 tiIOSuccess, 1341 SCSI_STAT_CHECK_CONDITION, 1342 satIOContext->pTiSenseData, 1343 satIOContext->interruptContext ); 1344 1345 return tiSuccess; 1346 } 1347 } 1348 1349 /* case 1 and 2 */ 1350 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT) 1351 { 1352 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 1353 { 1354 /* case 2 */ 1355 /* READ DMA*/ 1356 /* in case that we can't fit the transfer length, 1357 we need to make it fit by sending multiple ATA cmnds */ 1358 TI_DBG5(("satRead10: case 2\n")); 1359 1360 1361 fis->h.fisType = 0x27; /* Reg host to device */ 1362 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1363 fis->h.command = SAT_READ_DMA; /* 0xC8 */ 1364 fis->h.features = 0; /* FIS reserve */ 1365 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 1366 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 1367 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 1368 fis->d.device = 1369 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 1370 fis->d.lbaLowExp = 0; 1371 fis->d.lbaMidExp = 0; 1372 fis->d.lbaHighExp = 0; 1373 fis->d.featuresExp = 0; 1374 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 1375 fis->d.sectorCountExp = 0; 1376 fis->d.reserved4 = 0; 1377 fis->d.control = 0; /* FIS HOB bit clear */ 1378 fis->d.reserved5 = 0; 1379 1380 1381 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 1382 satIOContext->ATACmd = SAT_READ_DMA; 1383 } 1384 else 1385 { 1386 /* case 1 */ 1387 /* READ MULTIPLE or READ SECTOR(S) */ 1388 /* READ SECTORS for easier implemetation */ 1389 /* in case that we can't fit the transfer length, 1390 we need to make it fit by sending multiple ATA cmnds */ 1391 TI_DBG5(("satRead10: case 1\n")); 1392 1393 fis->h.fisType = 0x27; /* Reg host to device */ 1394 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1395 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 1396 fis->h.features = 0; /* FIS reserve */ 1397 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 1398 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 1399 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 1400 fis->d.device = 1401 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 1402 fis->d.lbaLowExp = 0; 1403 fis->d.lbaMidExp = 0; 1404 fis->d.lbaHighExp = 0; 1405 fis->d.featuresExp = 0; 1406 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 1407 fis->d.sectorCountExp = 0; 1408 fis->d.reserved4 = 0; 1409 fis->d.control = 0; /* FIS HOB bit clear */ 1410 fis->d.reserved5 = 0; 1411 1412 1413 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 1414 satIOContext->ATACmd = SAT_READ_SECTORS; 1415 } 1416 } 1417 1418 /* case 3 and 4 */ 1419 if (pSatDevData->sat48BitSupport == agTRUE) 1420 { 1421 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 1422 { 1423 /* case 3 */ 1424 /* READ DMA EXT */ 1425 TI_DBG5(("satRead10: case 3\n")); 1426 fis->h.fisType = 0x27; /* Reg host to device */ 1427 1428 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1429 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */ 1430 fis->h.features = 0; /* FIS reserve */ 1431 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 1432 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 1433 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 1434 fis->d.device = 0x40; /* FIS LBA mode set */ 1435 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 1436 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 1437 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 1438 fis->d.featuresExp = 0; /* FIS reserve */ 1439 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 1440 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 1441 fis->d.reserved4 = 0; 1442 fis->d.control = 0; /* FIS HOB bit clear */ 1443 fis->d.reserved5 = 0; 1444 1445 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 1446 satIOContext->ATACmd = SAT_READ_DMA_EXT; 1447 1448 } 1449 else 1450 { 1451 /* case 4 */ 1452 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/ 1453 /* READ SECTORS EXT for easier implemetation */ 1454 TI_DBG5(("satRead10: case 4\n")); 1455 fis->h.fisType = 0x27; /* Reg host to device */ 1456 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1457 1458 /* Check FUA bit */ 1459 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK) 1460 { 1461 1462 /* for now, no support for FUA */ 1463 satSetSensePayload( pSense, 1464 SCSI_SNSKEY_ILLEGAL_REQUEST, 1465 0, 1466 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 1467 satIOContext); 1468 1469 ostiInitiatorIOCompleted( tiRoot, 1470 tiIORequest, 1471 tiIOSuccess, 1472 SCSI_STAT_CHECK_CONDITION, 1473 satIOContext->pTiSenseData, 1474 satIOContext->interruptContext ); 1475 return tiSuccess; 1476 } 1477 1478 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 1479 1480 fis->h.features = 0; /* FIS reserve */ 1481 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 1482 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 1483 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 1484 fis->d.device = 0x40; /* FIS LBA mode set */ 1485 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 1486 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 1487 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 1488 fis->d.featuresExp = 0; /* FIS reserve */ 1489 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 1490 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 1491 fis->d.reserved4 = 0; 1492 fis->d.control = 0; /* FIS HOB bit clear */ 1493 fis->d.reserved5 = 0; 1494 1495 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 1496 satIOContext->ATACmd = SAT_READ_SECTORS_EXT; 1497 } 1498 } 1499 1500 /* case 5 */ 1501 if (pSatDevData->satNCQ == agTRUE) 1502 { 1503 /* READ FPDMA QUEUED */ 1504 if (pSatDevData->sat48BitSupport != agTRUE) 1505 { 1506 TI_DBG5(("satRead10: case 5 !!! error NCQ but 28 bit address support \n")); 1507 satSetSensePayload( pSense, 1508 SCSI_SNSKEY_ILLEGAL_REQUEST, 1509 0, 1510 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 1511 satIOContext); 1512 1513 ostiInitiatorIOCompleted( tiRoot, 1514 tiIORequest, 1515 tiIOSuccess, 1516 SCSI_STAT_CHECK_CONDITION, 1517 satIOContext->pTiSenseData, 1518 satIOContext->interruptContext ); 1519 return tiSuccess; 1520 } 1521 1522 TI_DBG6(("satRead10: case 5\n")); 1523 1524 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */ 1525 1526 fis->h.fisType = 0x27; /* Reg host to device */ 1527 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1528 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */ 1529 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 1530 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 1531 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 1532 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 1533 1534 /* Check FUA bit */ 1535 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK) 1536 fis->d.device = 0xC0; /* FIS FUA set */ 1537 else 1538 fis->d.device = 0x40; /* FIS FUA clear */ 1539 1540 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 1541 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 1542 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 1543 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 1544 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 1545 fis->d.sectorCountExp = 0; 1546 fis->d.reserved4 = 0; 1547 fis->d.control = 0; /* FIS HOB bit clear */ 1548 fis->d.reserved5 = 0; 1549 1550 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ; 1551 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED; 1552 } 1553 1554 1555 // tdhexdump("satRead10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t)); 1556 1557 /* saves the current LBA and orginal TL */ 1558 satIOContext->currentLBA = lba; 1559 satIOContext->OrgTL = tl; 1560 1561 /* 1562 computing number of loop and remainder for tl 1563 0xFF in case not ext 1564 0xFFFF in case EXT 1565 */ 1566 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 1567 { 1568 LoopNum = satComputeLoopNum(tl, 0xFF); 1569 } 1570 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 1571 { 1572 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 1573 LoopNum = satComputeLoopNum(tl, 0xFFFF); 1574 } 1575 else 1576 { 1577 /* SAT_READ_FPDMA_QUEUED */ 1578 LoopNum = satComputeLoopNum(tl, 0xFFFF); 1579 } 1580 1581 satIOContext->LoopNum = LoopNum; 1582 1583 /* Initialize CB for SATA completion. 1584 */ 1585 if (LoopNum == 1) 1586 { 1587 TI_DBG5(("satRead10: NON CHAINED data\n")); 1588 satIOContext->satCompleteCB = &satNonChainedDataIOCB; 1589 } 1590 else 1591 { 1592 TI_DBG1(("satRead10: CHAINED data\n")); 1593 /* re-setting tl */ 1594 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 1595 { 1596 fis->d.sectorCount = 0xFF; 1597 } 1598 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 1599 { 1600 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 1601 fis->d.sectorCount = 0xFF; 1602 fis->d.sectorCountExp = 0xFF; 1603 } 1604 else 1605 { 1606 /* SAT_READ_FPDMA_QUEUED */ 1607 fis->h.features = 0xFF; 1608 fis->d.featuresExp = 0xFF; 1609 } 1610 1611 /* chained data */ 1612 satIOContext->satCompleteCB = &satChainedDataIOCB; 1613 1614 } 1615 1616 /* 1617 * Prepare SGL and send FIS to LL layer. 1618 */ 1619 satIOContext->reqType = agRequestType; /* Save it */ 1620 1621 status = sataLLIOStart( tiRoot, 1622 tiIORequest, 1623 tiDeviceHandle, 1624 tiScsiRequest, 1625 satIOContext); 1626 1627 TI_DBG5(("satRead10: return\n")); 1628 return (status); 1629 1630 } 1631 1632 1633 /*****************************************************************************/ 1634 /*! \brief SAT implementation for SCSI satRead_1. 1635 * 1636 * SAT implementation for SCSI satRead_1 1637 * Sub function of satRead10 1638 * 1639 * \param tiRoot: Pointer to TISA initiator driver/port instance. 1640 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 1641 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 1642 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 1643 * \param satIOContext_t: Pointer to the SAT IO Context 1644 * 1645 * \return If command is started successfully 1646 * - \e tiSuccess: I/O request successfully initiated. 1647 * - \e tiBusy: No resources available, try again later. 1648 * - \e tiIONoDevice: Invalid device handle. 1649 * - \e tiError: Other errors. 1650 */ 1651 /*****************************************************************************/ 1652 /* 1653 * as a part of loop for read10 1654 */ 1655 GLOBAL bit32 satRead_1( 1656 tiRoot_t *tiRoot, 1657 tiIORequest_t *tiIORequest, 1658 tiDeviceHandle_t *tiDeviceHandle, 1659 tiScsiInitiatorRequest_t *tiScsiRequest, 1660 satIOContext_t *satIOContext) 1661 { 1662 /* 1663 Assumption: error check on lba and tl has been done in satRead*() 1664 lba = lba + tl; 1665 */ 1666 bit32 status; 1667 satIOContext_t *satOrgIOContext = agNULL; 1668 tiIniScsiCmnd_t *scsiCmnd; 1669 agsaFisRegHostToDevice_t *fis; 1670 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 1671 bit32 lba = 0; 1672 bit32 DenomTL = 0xFF; 1673 bit32 Remainder = 0; 1674 bit8 LBA[4]; /* 0 MSB, 3 LSB */ 1675 1676 TI_DBG2(("satRead_1: start\n")); 1677 1678 fis = satIOContext->pFis; 1679 satOrgIOContext = satIOContext->satOrgIOContext; 1680 scsiCmnd = satOrgIOContext->pScsiCmnd; 1681 1682 osti_memset(LBA,0, sizeof(LBA)); 1683 1684 switch (satOrgIOContext->ATACmd) 1685 { 1686 case SAT_READ_DMA: 1687 DenomTL = 0xFF; 1688 break; 1689 case SAT_READ_SECTORS: 1690 DenomTL = 0xFF; 1691 break; 1692 case SAT_READ_DMA_EXT: 1693 DenomTL = 0xFFFF; 1694 break; 1695 case SAT_READ_SECTORS_EXT: 1696 DenomTL = 0xFFFF; 1697 break; 1698 case SAT_READ_FPDMA_QUEUED: 1699 DenomTL = 0xFFFF; 1700 break; 1701 default: 1702 TI_DBG1(("satRead_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd)); 1703 return tiError; 1704 break; 1705 } 1706 1707 Remainder = satOrgIOContext->OrgTL % DenomTL; 1708 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL; 1709 lba = satOrgIOContext->currentLBA; 1710 1711 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); 1712 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2)); 1713 LBA[2] = (bit8)((lba & 0xF0) >> 8); 1714 LBA[3] = (bit8)(lba & 0xF); 1715 1716 1717 switch (satOrgIOContext->ATACmd) 1718 { 1719 case SAT_READ_DMA: 1720 fis->h.fisType = 0x27; /* Reg host to device */ 1721 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1722 fis->h.command = SAT_READ_DMA; /* 0xC8 */ 1723 fis->h.features = 0; /* FIS reserve */ 1724 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 1725 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 1726 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 1727 fis->d.device = 1728 (bit8)((0x4 << 4) | (LBA[0] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 1729 fis->d.lbaLowExp = 0; 1730 fis->d.lbaMidExp = 0; 1731 fis->d.lbaHighExp = 0; 1732 fis->d.featuresExp = 0; 1733 1734 if (satOrgIOContext->LoopNum == 1) 1735 { 1736 /* last loop */ 1737 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 1738 } 1739 else 1740 { 1741 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 1742 } 1743 1744 fis->d.sectorCountExp = 0; 1745 fis->d.reserved4 = 0; 1746 fis->d.control = 0; /* FIS HOB bit clear */ 1747 fis->d.reserved5 = 0; 1748 1749 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 1750 1751 break; 1752 case SAT_READ_SECTORS: 1753 fis->h.fisType = 0x27; /* Reg host to device */ 1754 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1755 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 1756 fis->h.features = 0; /* FIS reserve */ 1757 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 1758 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 1759 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 1760 fis->d.device = 1761 (bit8)((0x4 << 4) | (LBA[0] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 1762 fis->d.lbaLowExp = 0; 1763 fis->d.lbaMidExp = 0; 1764 fis->d.lbaHighExp = 0; 1765 fis->d.featuresExp = 0; 1766 if (satOrgIOContext->LoopNum == 1) 1767 { 1768 /* last loop */ 1769 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 1770 } 1771 else 1772 { 1773 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 1774 } 1775 fis->d.sectorCountExp = 0; 1776 fis->d.reserved4 = 0; 1777 fis->d.control = 0; /* FIS HOB bit clear */ 1778 fis->d.reserved5 = 0; 1779 1780 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 1781 1782 break; 1783 case SAT_READ_DMA_EXT: 1784 fis->h.fisType = 0x27; /* Reg host to device */ 1785 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1786 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */ 1787 fis->h.features = 0; /* FIS reserve */ 1788 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 1789 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 1790 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 1791 fis->d.device = 0x40; /* FIS LBA mode set */ 1792 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 1793 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 1794 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 1795 fis->d.featuresExp = 0; /* FIS reserve */ 1796 if (satOrgIOContext->LoopNum == 1) 1797 { 1798 /* last loop */ 1799 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 1800 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 1801 1802 } 1803 else 1804 { 1805 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 1806 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 1807 } 1808 fis->d.reserved4 = 0; 1809 fis->d.control = 0; /* FIS HOB bit clear */ 1810 fis->d.reserved5 = 0; 1811 1812 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 1813 1814 break; 1815 case SAT_READ_SECTORS_EXT: 1816 fis->h.fisType = 0x27; /* Reg host to device */ 1817 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1818 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 1819 fis->h.features = 0; /* FIS reserve */ 1820 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 1821 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 1822 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 1823 fis->d.device = 0x40; /* FIS LBA mode set */ 1824 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 1825 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 1826 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 1827 fis->d.featuresExp = 0; /* FIS reserve */ 1828 if (satOrgIOContext->LoopNum == 1) 1829 { 1830 /* last loop */ 1831 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 1832 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 1833 } 1834 else 1835 { 1836 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 1837 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 1838 } 1839 fis->d.reserved4 = 0; 1840 fis->d.control = 0; /* FIS HOB bit clear */ 1841 fis->d.reserved5 = 0; 1842 1843 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 1844 break; 1845 case SAT_READ_FPDMA_QUEUED: 1846 fis->h.fisType = 0x27; /* Reg host to device */ 1847 fis->h.c_pmPort = 0x80; /* C Bit is set */ 1848 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */ 1849 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 1850 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 1851 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 1852 1853 /* Check FUA bit */ 1854 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK) 1855 fis->d.device = 0xC0; /* FIS FUA set */ 1856 else 1857 fis->d.device = 0x40; /* FIS FUA clear */ 1858 1859 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 1860 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 1861 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 1862 if (satOrgIOContext->LoopNum == 1) 1863 { 1864 /* last loop */ 1865 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 1866 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 1867 } 1868 else 1869 { 1870 fis->h.features = 0xFF; /* FIS sector count (7:0) */ 1871 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */ 1872 } 1873 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 1874 fis->d.sectorCountExp = 0; 1875 fis->d.reserved4 = 0; 1876 fis->d.control = 0; /* FIS HOB bit clear */ 1877 fis->d.reserved5 = 0; 1878 1879 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ; 1880 break; 1881 default: 1882 TI_DBG1(("satRead_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd)); 1883 return tiError; 1884 break; 1885 } 1886 1887 /* Initialize CB for SATA completion. 1888 */ 1889 /* chained data */ 1890 satIOContext->satCompleteCB = &satChainedDataIOCB; 1891 1892 1893 /* 1894 * Prepare SGL and send FIS to LL layer. 1895 */ 1896 satIOContext->reqType = agRequestType; /* Save it */ 1897 1898 status = sataLLIOStart( tiRoot, 1899 tiIORequest, 1900 tiDeviceHandle, 1901 tiScsiRequest, 1902 satIOContext); 1903 1904 TI_DBG5(("satRead_1: return\n")); 1905 return (status); 1906 } 1907 /*****************************************************************************/ 1908 /*! \brief SAT implementation for SCSI READ12. 1909 * 1910 * SAT implementation for SCSI READ12 and send FIS request to LL layer. 1911 * 1912 * \param tiRoot: Pointer to TISA initiator driver/port instance. 1913 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 1914 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 1915 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 1916 * \param satIOContext_t: Pointer to the SAT IO Context 1917 * 1918 * \return If command is started successfully 1919 * - \e tiSuccess: I/O request successfully initiated. 1920 * - \e tiBusy: No resources available, try again later. 1921 * - \e tiIONoDevice: Invalid device handle. 1922 * - \e tiError: Other errors. 1923 */ 1924 /*****************************************************************************/ 1925 GLOBAL bit32 satRead12( 1926 tiRoot_t *tiRoot, 1927 tiIORequest_t *tiIORequest, 1928 tiDeviceHandle_t *tiDeviceHandle, 1929 tiScsiInitiatorRequest_t *tiScsiRequest, 1930 satIOContext_t *satIOContext) 1931 { 1932 bit32 status; 1933 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 1934 satDeviceData_t *pSatDevData; 1935 scsiRspSense_t *pSense; 1936 tiIniScsiCmnd_t *scsiCmnd; 1937 agsaFisRegHostToDevice_t *fis; 1938 bit32 lba = 0; 1939 bit32 tl = 0; 1940 bit32 LoopNum = 1; 1941 bit8 LBA[4]; 1942 bit8 TL[4]; 1943 bit32 rangeChk = agFALSE; /* lba and tl range check */ 1944 1945 pSense = satIOContext->pSense; 1946 pSatDevData = satIOContext->pSatDevData; 1947 scsiCmnd = &tiScsiRequest->scsiCmnd; 1948 fis = satIOContext->pFis; 1949 1950 TI_DBG5(("satRead12: start\n")); 1951 1952 /* checking FUA_NV */ 1953 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 1954 { 1955 satSetSensePayload( pSense, 1956 SCSI_SNSKEY_ILLEGAL_REQUEST, 1957 0, 1958 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 1959 satIOContext); 1960 1961 ostiInitiatorIOCompleted( tiRoot, 1962 tiIORequest, 1963 tiIOSuccess, 1964 SCSI_STAT_CHECK_CONDITION, 1965 satIOContext->pTiSenseData, 1966 satIOContext->interruptContext ); 1967 1968 TI_DBG1(("satRead12: return FUA_NV\n")); 1969 return tiSuccess; 1970 1971 } 1972 1973 /* checking CONTROL */ 1974 /* NACA == 1 or LINK == 1*/ 1975 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) ) 1976 { 1977 satSetSensePayload( pSense, 1978 SCSI_SNSKEY_ILLEGAL_REQUEST, 1979 0, 1980 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 1981 satIOContext); 1982 1983 ostiInitiatorIOCompleted( tiRoot, 1984 tiIORequest, 1985 tiIOSuccess, 1986 SCSI_STAT_CHECK_CONDITION, 1987 satIOContext->pTiSenseData, 1988 satIOContext->interruptContext ); 1989 1990 TI_DBG2(("satRead12: return control\n")); 1991 return tiSuccess; 1992 } 1993 1994 osti_memset(LBA, 0, sizeof(LBA)); 1995 osti_memset(TL, 0, sizeof(TL)); 1996 1997 /* do not use memcpy due to indexing in LBA and TL */ 1998 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 1999 LBA[1] = scsiCmnd->cdb[3]; 2000 LBA[2] = scsiCmnd->cdb[4]; 2001 LBA[3] = scsiCmnd->cdb[5]; /* LSB */ 2002 2003 TL[0] = scsiCmnd->cdb[6]; /* MSB */ 2004 TL[1] = scsiCmnd->cdb[7]; 2005 TL[2] = scsiCmnd->cdb[8]; 2006 TL[3] = scsiCmnd->cdb[9]; /* LSB */ 2007 2008 rangeChk = satAddNComparebit32(LBA, TL); 2009 2010 lba = satComputeCDB12LBA(satIOContext); 2011 tl = satComputeCDB12TL(satIOContext); 2012 2013 /* Table 34, 9.1, p 46 */ 2014 /* 2015 note: As of 2/10/2006, no support for DMA QUEUED 2016 */ 2017 2018 /* 2019 Table 34, 9.1, p 46, b 2020 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 2021 return check condition 2022 */ 2023 if (pSatDevData->satNCQ != agTRUE && 2024 pSatDevData->sat48BitSupport != agTRUE 2025 ) 2026 { 2027 if (lba > SAT_TR_LBA_LIMIT - 1) 2028 { 2029 TI_DBG1(("satRead12: return LBA out of range, not EXT\n")); 2030 satSetSensePayload( pSense, 2031 SCSI_SNSKEY_ILLEGAL_REQUEST, 2032 0, 2033 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 2034 satIOContext); 2035 2036 ostiInitiatorIOCompleted( tiRoot, 2037 tiIORequest, 2038 tiIOSuccess, 2039 SCSI_STAT_CHECK_CONDITION, 2040 satIOContext->pTiSenseData, 2041 satIOContext->interruptContext ); 2042 2043 return tiSuccess; 2044 } 2045 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 2046 { 2047 TI_DBG1(("satRead12: return LBA+TL out of range, not EXT\n")); 2048 satSetSensePayload( pSense, 2049 SCSI_SNSKEY_ILLEGAL_REQUEST, 2050 0, 2051 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 2052 satIOContext); 2053 2054 ostiInitiatorIOCompleted( tiRoot, 2055 tiIORequest, 2056 tiIOSuccess, 2057 SCSI_STAT_CHECK_CONDITION, 2058 satIOContext->pTiSenseData, 2059 satIOContext->interruptContext ); 2060 2061 return tiSuccess; 2062 } 2063 } 2064 2065 /* case 1 and 2 */ 2066 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT) 2067 { 2068 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 2069 { 2070 /* case 2 */ 2071 /* READ DMA*/ 2072 /* in case that we can't fit the transfer length, 2073 we need to make it fit by sending multiple ATA cmnds */ 2074 TI_DBG5(("satRead12: case 2\n")); 2075 2076 2077 fis->h.fisType = 0x27; /* Reg host to device */ 2078 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2079 fis->h.command = SAT_READ_DMA; /* 0xC8 */ 2080 fis->h.features = 0; /* FIS reserve */ 2081 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 2082 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 2083 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 2084 fis->d.device = 2085 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 2086 fis->d.lbaLowExp = 0; 2087 fis->d.lbaMidExp = 0; 2088 fis->d.lbaHighExp = 0; 2089 fis->d.featuresExp = 0; 2090 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 2091 fis->d.sectorCountExp = 0; 2092 fis->d.reserved4 = 0; 2093 fis->d.control = 0; /* FIS HOB bit clear */ 2094 fis->d.reserved5 = 0; 2095 2096 2097 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 2098 satIOContext->ATACmd = SAT_READ_DMA; 2099 } 2100 else 2101 { 2102 /* case 1 */ 2103 /* READ MULTIPLE or READ SECTOR(S) */ 2104 /* READ SECTORS for easier implemetation */ 2105 /* can't fit the transfer length but need to make it fit by sending multiple*/ 2106 TI_DBG5(("satRead12: case 1\n")); 2107 2108 fis->h.fisType = 0x27; /* Reg host to device */ 2109 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2110 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 2111 fis->h.features = 0; /* FIS reserve */ 2112 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 2113 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 2114 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 2115 fis->d.device = 2116 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 2117 fis->d.lbaLowExp = 0; 2118 fis->d.lbaMidExp = 0; 2119 fis->d.lbaHighExp = 0; 2120 fis->d.featuresExp = 0; 2121 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 2122 fis->d.sectorCountExp = 0; 2123 fis->d.reserved4 = 0; 2124 fis->d.control = 0; /* FIS HOB bit clear */ 2125 fis->d.reserved5 = 0; 2126 2127 2128 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 2129 satIOContext->ATACmd = SAT_READ_SECTORS; 2130 } 2131 } 2132 2133 /* case 3 and 4 */ 2134 if (pSatDevData->sat48BitSupport == agTRUE) 2135 { 2136 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 2137 { 2138 /* case 3 */ 2139 /* READ DMA EXT */ 2140 TI_DBG5(("satRead12: case 3\n")); 2141 fis->h.fisType = 0x27; /* Reg host to device */ 2142 2143 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2144 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */ 2145 fis->h.features = 0; /* FIS reserve */ 2146 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 2147 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 2148 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 2149 fis->d.device = 0x40; /* FIS LBA mode set */ 2150 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 2151 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 2152 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 2153 fis->d.featuresExp = 0; /* FIS reserve */ 2154 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 2155 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 2156 fis->d.reserved4 = 0; 2157 fis->d.control = 0; /* FIS HOB bit clear */ 2158 fis->d.reserved5 = 0; 2159 2160 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 2161 satIOContext->ATACmd = SAT_READ_DMA_EXT; 2162 2163 } 2164 else 2165 { 2166 /* case 4 */ 2167 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/ 2168 /* READ SECTORS EXT for easier implemetation */ 2169 TI_DBG5(("satRead12: case 4\n")); 2170 fis->h.fisType = 0x27; /* Reg host to device */ 2171 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2172 2173 /* Check FUA bit */ 2174 if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK) 2175 { 2176 /* for now, no support for FUA */ 2177 satSetSensePayload( pSense, 2178 SCSI_SNSKEY_ILLEGAL_REQUEST, 2179 0, 2180 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 2181 satIOContext); 2182 2183 ostiInitiatorIOCompleted( tiRoot, 2184 tiIORequest, 2185 tiIOSuccess, 2186 SCSI_STAT_CHECK_CONDITION, 2187 satIOContext->pTiSenseData, 2188 satIOContext->interruptContext ); 2189 return tiSuccess; 2190 } 2191 2192 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 2193 2194 fis->h.features = 0; /* FIS reserve */ 2195 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 2196 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 2197 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 2198 fis->d.device = 0x40; /* FIS LBA mode set */ 2199 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 2200 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 2201 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 2202 fis->d.featuresExp = 0; /* FIS reserve */ 2203 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 2204 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 2205 fis->d.reserved4 = 0; 2206 fis->d.control = 0; /* FIS HOB bit clear */ 2207 fis->d.reserved5 = 0; 2208 2209 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 2210 satIOContext->ATACmd = SAT_READ_SECTORS_EXT; 2211 } 2212 } 2213 2214 /* case 5 */ 2215 if (pSatDevData->satNCQ == agTRUE) 2216 { 2217 /* READ FPDMA QUEUED */ 2218 if (pSatDevData->sat48BitSupport != agTRUE) 2219 { 2220 TI_DBG5(("satRead12: case 5 !!! error NCQ but 28 bit address support \n")); 2221 satSetSensePayload( pSense, 2222 SCSI_SNSKEY_ILLEGAL_REQUEST, 2223 0, 2224 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 2225 satIOContext); 2226 2227 ostiInitiatorIOCompleted( tiRoot, 2228 tiIORequest, 2229 tiIOSuccess, 2230 SCSI_STAT_CHECK_CONDITION, 2231 satIOContext->pTiSenseData, 2232 satIOContext->interruptContext ); 2233 return tiSuccess; 2234 } 2235 2236 TI_DBG6(("satRead12: case 5\n")); 2237 2238 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */ 2239 2240 fis->h.fisType = 0x27; /* Reg host to device */ 2241 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2242 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */ 2243 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 2244 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 2245 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 2246 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 2247 2248 /* Check FUA bit */ 2249 if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK) 2250 fis->d.device = 0xC0; /* FIS FUA set */ 2251 else 2252 fis->d.device = 0x40; /* FIS FUA clear */ 2253 2254 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 2255 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 2256 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 2257 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 2258 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 2259 fis->d.sectorCountExp = 0; 2260 fis->d.reserved4 = 0; 2261 fis->d.control = 0; /* FIS HOB bit clear */ 2262 fis->d.reserved5 = 0; 2263 2264 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ; 2265 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED; 2266 } 2267 2268 /* saves the current LBA and orginal TL */ 2269 satIOContext->currentLBA = lba; 2270 satIOContext->OrgTL = tl; 2271 2272 /* 2273 computing number of loop and remainder for tl 2274 0xFF in case not ext 2275 0xFFFF in case EXT 2276 */ 2277 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 2278 { 2279 LoopNum = satComputeLoopNum(tl, 0xFF); 2280 } 2281 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 2282 { 2283 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 2284 LoopNum = satComputeLoopNum(tl, 0xFFFF); 2285 } 2286 else 2287 { 2288 /* SAT_READ_FPDMA_QUEUEDK */ 2289 LoopNum = satComputeLoopNum(tl, 0xFFFF); 2290 } 2291 2292 satIOContext->LoopNum = LoopNum; 2293 2294 if (LoopNum == 1) 2295 { 2296 TI_DBG5(("satRead12: NON CHAINED data\n")); 2297 satIOContext->satCompleteCB = &satNonChainedDataIOCB; 2298 } 2299 else 2300 { 2301 TI_DBG1(("satRead12: CHAINED data\n")); 2302 /* re-setting tl */ 2303 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 2304 { 2305 fis->d.sectorCount = 0xFF; 2306 } 2307 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 2308 { 2309 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 2310 fis->d.sectorCount = 0xFF; 2311 fis->d.sectorCountExp = 0xFF; 2312 } 2313 else 2314 { 2315 /* SAT_READ_FPDMA_QUEUED */ 2316 fis->h.features = 0xFF; 2317 fis->d.featuresExp = 0xFF; 2318 } 2319 2320 /* chained data */ 2321 satIOContext->satCompleteCB = &satChainedDataIOCB; 2322 } 2323 2324 /* 2325 * Prepare SGL and send FIS to LL layer. 2326 */ 2327 satIOContext->reqType = agRequestType; /* Save it */ 2328 2329 status = sataLLIOStart( tiRoot, 2330 tiIORequest, 2331 tiDeviceHandle, 2332 tiScsiRequest, 2333 satIOContext); 2334 2335 TI_DBG5(("satRead12: return\n")); 2336 return (status); 2337 } 2338 /*****************************************************************************/ 2339 /*! \brief SAT implementation for SCSI READ16. 2340 * 2341 * SAT implementation for SCSI READ16 and send FIS request to LL layer. 2342 * 2343 * \param tiRoot: Pointer to TISA initiator driver/port instance. 2344 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 2345 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 2346 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 2347 * \param satIOContext_t: Pointer to the SAT IO Context 2348 * 2349 * \return If command is started successfully 2350 * - \e tiSuccess: I/O request successfully initiated. 2351 * - \e tiBusy: No resources available, try again later. 2352 * - \e tiIONoDevice: Invalid device handle. 2353 * - \e tiError: Other errors. 2354 */ 2355 /*****************************************************************************/ 2356 GLOBAL bit32 satRead16( 2357 tiRoot_t *tiRoot, 2358 tiIORequest_t *tiIORequest, 2359 tiDeviceHandle_t *tiDeviceHandle, 2360 tiScsiInitiatorRequest_t *tiScsiRequest, 2361 satIOContext_t *satIOContext) 2362 { 2363 bit32 status; 2364 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 2365 satDeviceData_t *pSatDevData; 2366 scsiRspSense_t *pSense; 2367 tiIniScsiCmnd_t *scsiCmnd; 2368 agsaFisRegHostToDevice_t *fis; 2369 bit32 lba = 0; 2370 bit32 tl = 0; 2371 bit32 LoopNum = 1; 2372 bit8 LBA[8]; 2373 bit8 TL[8]; 2374 bit32 rangeChk = agFALSE; /* lba and tl range check */ 2375 bit32 limitChk = agFALSE; /* lba and tl range check */ 2376 2377 pSense = satIOContext->pSense; 2378 pSatDevData = satIOContext->pSatDevData; 2379 scsiCmnd = &tiScsiRequest->scsiCmnd; 2380 fis = satIOContext->pFis; 2381 2382 TI_DBG5(("satRead16: start\n")); 2383 2384 /* checking FUA_NV */ 2385 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 2386 { 2387 satSetSensePayload( pSense, 2388 SCSI_SNSKEY_ILLEGAL_REQUEST, 2389 0, 2390 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 2391 satIOContext); 2392 2393 ostiInitiatorIOCompleted( tiRoot, 2394 tiIORequest, 2395 tiIOSuccess, 2396 SCSI_STAT_CHECK_CONDITION, 2397 satIOContext->pTiSenseData, 2398 satIOContext->interruptContext ); 2399 2400 TI_DBG1(("satRead16: return FUA_NV\n")); 2401 return tiSuccess; 2402 2403 } 2404 2405 /* checking CONTROL */ 2406 /* NACA == 1 or LINK == 1*/ 2407 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 2408 { 2409 satSetSensePayload( pSense, 2410 SCSI_SNSKEY_ILLEGAL_REQUEST, 2411 0, 2412 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 2413 satIOContext); 2414 2415 ostiInitiatorIOCompleted( tiRoot, 2416 tiIORequest, 2417 tiIOSuccess, 2418 SCSI_STAT_CHECK_CONDITION, 2419 satIOContext->pTiSenseData, 2420 satIOContext->interruptContext ); 2421 2422 TI_DBG1(("satRead16: return control\n")); 2423 return tiSuccess; 2424 } 2425 2426 2427 osti_memset(LBA, 0, sizeof(LBA)); 2428 osti_memset(TL, 0, sizeof(TL)); 2429 2430 2431 /* do not use memcpy due to indexing in LBA and TL */ 2432 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 2433 LBA[1] = scsiCmnd->cdb[3]; 2434 LBA[2] = scsiCmnd->cdb[4]; 2435 LBA[3] = scsiCmnd->cdb[5]; 2436 LBA[4] = scsiCmnd->cdb[6]; 2437 LBA[5] = scsiCmnd->cdb[7]; 2438 LBA[6] = scsiCmnd->cdb[8]; 2439 LBA[7] = scsiCmnd->cdb[9]; /* LSB */ 2440 2441 TL[0] = 0; 2442 TL[1] = 0; 2443 TL[2] = 0; 2444 TL[3] = 0; 2445 TL[4] = scsiCmnd->cdb[10]; /* MSB */ 2446 TL[5] = scsiCmnd->cdb[11]; 2447 TL[6] = scsiCmnd->cdb[12]; 2448 TL[7] = scsiCmnd->cdb[13]; /* LSB */ 2449 2450 rangeChk = satAddNComparebit64(LBA, TL); 2451 2452 limitChk = satCompareLBALimitbit(LBA); 2453 2454 lba = satComputeCDB16LBA(satIOContext); 2455 tl = satComputeCDB16TL(satIOContext); 2456 2457 2458 /* Table 34, 9.1, p 46 */ 2459 /* 2460 note: As of 2/10/2006, no support for DMA QUEUED 2461 */ 2462 2463 /* 2464 Table 34, 9.1, p 46, b 2465 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 2466 return check condition 2467 */ 2468 if (pSatDevData->satNCQ != agTRUE && 2469 pSatDevData->sat48BitSupport != agTRUE 2470 ) 2471 { 2472 if (limitChk) 2473 { 2474 TI_DBG1(("satRead16: return LBA out of range, not EXT\n")); 2475 satSetSensePayload( pSense, 2476 SCSI_SNSKEY_ILLEGAL_REQUEST, 2477 0, 2478 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 2479 satIOContext); 2480 2481 ostiInitiatorIOCompleted( tiRoot, 2482 tiIORequest, 2483 tiIOSuccess, 2484 SCSI_STAT_CHECK_CONDITION, 2485 satIOContext->pTiSenseData, 2486 satIOContext->interruptContext ); 2487 2488 return tiSuccess; 2489 } 2490 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 2491 { 2492 TI_DBG1(("satRead16: return LBA+TL out of range, not EXT\n")); 2493 satSetSensePayload( pSense, 2494 SCSI_SNSKEY_ILLEGAL_REQUEST, 2495 0, 2496 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 2497 satIOContext); 2498 2499 ostiInitiatorIOCompleted( tiRoot, 2500 tiIORequest, 2501 tiIOSuccess, 2502 SCSI_STAT_CHECK_CONDITION, 2503 satIOContext->pTiSenseData, 2504 satIOContext->interruptContext ); 2505 2506 return tiSuccess; 2507 } 2508 } 2509 2510 /* case 1 and 2 */ 2511 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT) 2512 { 2513 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 2514 { 2515 /* case 2 */ 2516 /* READ DMA*/ 2517 /* in case that we can't fit the transfer length, 2518 we need to make it fit by sending multiple ATA cmnds */ 2519 TI_DBG5(("satRead16: case 2\n")); 2520 2521 2522 fis->h.fisType = 0x27; /* Reg host to device */ 2523 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2524 fis->h.command = SAT_READ_DMA; /* 0xC8 */ 2525 fis->h.features = 0; /* FIS reserve */ 2526 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 2527 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 2528 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 2529 fis->d.device = 2530 (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 2531 fis->d.lbaLowExp = 0; 2532 fis->d.lbaMidExp = 0; 2533 fis->d.lbaHighExp = 0; 2534 fis->d.featuresExp = 0; 2535 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 2536 fis->d.sectorCountExp = 0; 2537 fis->d.reserved4 = 0; 2538 fis->d.control = 0; /* FIS HOB bit clear */ 2539 fis->d.reserved5 = 0; 2540 2541 2542 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 2543 satIOContext->ATACmd = SAT_READ_DMA; 2544 } 2545 else 2546 { 2547 /* case 1 */ 2548 /* READ MULTIPLE or READ SECTOR(S) */ 2549 /* READ SECTORS for easier implemetation */ 2550 /* can't fit the transfer length but need to make it fit by sending multiple*/ 2551 TI_DBG5(("satRead16: case 1\n")); 2552 2553 fis->h.fisType = 0x27; /* Reg host to device */ 2554 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2555 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 2556 fis->h.features = 0; /* FIS reserve */ 2557 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 2558 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 2559 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 2560 fis->d.device = 2561 (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 2562 fis->d.lbaLowExp = 0; 2563 fis->d.lbaMidExp = 0; 2564 fis->d.lbaHighExp = 0; 2565 fis->d.featuresExp = 0; 2566 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 2567 fis->d.sectorCountExp = 0; 2568 fis->d.reserved4 = 0; 2569 fis->d.control = 0; /* FIS HOB bit clear */ 2570 fis->d.reserved5 = 0; 2571 2572 2573 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 2574 satIOContext->ATACmd = SAT_READ_SECTORS; 2575 } 2576 } 2577 2578 /* case 3 and 4 */ 2579 if (pSatDevData->sat48BitSupport == agTRUE) 2580 { 2581 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 2582 { 2583 /* case 3 */ 2584 /* READ DMA EXT */ 2585 TI_DBG5(("satRead16: case 3\n")); 2586 fis->h.fisType = 0x27; /* Reg host to device */ 2587 2588 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2589 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */ 2590 fis->h.features = 0; /* FIS reserve */ 2591 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 2592 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 2593 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 2594 fis->d.device = 0x40; /* FIS LBA mode set */ 2595 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 2596 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 2597 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 2598 fis->d.featuresExp = 0; /* FIS reserve */ 2599 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 2600 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 2601 fis->d.reserved4 = 0; 2602 fis->d.control = 0; /* FIS HOB bit clear */ 2603 fis->d.reserved5 = 0; 2604 2605 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 2606 satIOContext->ATACmd = SAT_READ_DMA_EXT; 2607 2608 } 2609 else 2610 { 2611 /* case 4 */ 2612 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/ 2613 /* READ SECTORS EXT for easier implemetation */ 2614 TI_DBG5(("satRead16: case 4\n")); 2615 fis->h.fisType = 0x27; /* Reg host to device */ 2616 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2617 2618 /* Check FUA bit */ 2619 if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK) 2620 { 2621 2622 /* for now, no support for FUA */ 2623 satSetSensePayload( pSense, 2624 SCSI_SNSKEY_ILLEGAL_REQUEST, 2625 0, 2626 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 2627 satIOContext); 2628 2629 ostiInitiatorIOCompleted( tiRoot, 2630 tiIORequest, 2631 tiIOSuccess, 2632 SCSI_STAT_CHECK_CONDITION, 2633 satIOContext->pTiSenseData, 2634 satIOContext->interruptContext ); 2635 return tiSuccess; 2636 } 2637 2638 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 2639 2640 fis->h.features = 0; /* FIS reserve */ 2641 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 2642 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 2643 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 2644 fis->d.device = 0x40; /* FIS LBA mode set */ 2645 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 2646 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 2647 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 2648 fis->d.featuresExp = 0; /* FIS reserve */ 2649 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 2650 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 2651 fis->d.reserved4 = 0; 2652 fis->d.control = 0; /* FIS HOB bit clear */ 2653 fis->d.reserved5 = 0; 2654 2655 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 2656 satIOContext->ATACmd = SAT_READ_SECTORS_EXT; 2657 } 2658 } 2659 2660 2661 /* case 5 */ 2662 if (pSatDevData->satNCQ == agTRUE) 2663 { 2664 /* READ FPDMA QUEUED */ 2665 if (pSatDevData->sat48BitSupport != agTRUE) 2666 { 2667 TI_DBG5(("satRead16: case 5 !!! error NCQ but 28 bit address support \n")); 2668 satSetSensePayload( pSense, 2669 SCSI_SNSKEY_ILLEGAL_REQUEST, 2670 0, 2671 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 2672 satIOContext); 2673 2674 ostiInitiatorIOCompleted( tiRoot, 2675 tiIORequest, 2676 tiIOSuccess, 2677 SCSI_STAT_CHECK_CONDITION, 2678 satIOContext->pTiSenseData, 2679 satIOContext->interruptContext ); 2680 return tiSuccess; 2681 } 2682 2683 TI_DBG6(("satRead16: case 5\n")); 2684 2685 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */ 2686 2687 fis->h.fisType = 0x27; /* Reg host to device */ 2688 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2689 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */ 2690 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 2691 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 2692 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 2693 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 2694 2695 /* Check FUA bit */ 2696 if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK) 2697 fis->d.device = 0xC0; /* FIS FUA set */ 2698 else 2699 fis->d.device = 0x40; /* FIS FUA clear */ 2700 2701 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 2702 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 2703 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 2704 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 2705 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 2706 fis->d.sectorCountExp = 0; 2707 fis->d.reserved4 = 0; 2708 fis->d.control = 0; /* FIS HOB bit clear */ 2709 fis->d.reserved5 = 0; 2710 2711 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ; 2712 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED; 2713 } 2714 2715 /* saves the current LBA and orginal TL */ 2716 satIOContext->currentLBA = lba; 2717 satIOContext->OrgTL = tl; 2718 2719 /* 2720 computing number of loop and remainder for tl 2721 0xFF in case not ext 2722 0xFFFF in case EXT 2723 */ 2724 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 2725 { 2726 LoopNum = satComputeLoopNum(tl, 0xFF); 2727 } 2728 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 2729 { 2730 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 2731 LoopNum = satComputeLoopNum(tl, 0xFFFF); 2732 } 2733 else 2734 { 2735 /* SAT_READ_FPDMA_QUEUEDK */ 2736 LoopNum = satComputeLoopNum(tl, 0xFFFF); 2737 } 2738 satIOContext->LoopNum = LoopNum; 2739 2740 if (LoopNum == 1) 2741 { 2742 TI_DBG5(("satRead16: NON CHAINED data\n")); 2743 satIOContext->satCompleteCB = &satNonChainedDataIOCB; 2744 } 2745 else 2746 { 2747 TI_DBG1(("satRead16: CHAINED data\n")); 2748 /* re-setting tl */ 2749 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 2750 { 2751 fis->d.sectorCount = 0xFF; 2752 } 2753 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 2754 { 2755 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 2756 fis->d.sectorCount = 0xFF; 2757 fis->d.sectorCountExp = 0xFF; 2758 } 2759 else 2760 { 2761 /* SAT_READ_FPDMA_QUEUED */ 2762 fis->h.features = 0xFF; 2763 fis->d.featuresExp = 0xFF; 2764 } 2765 2766 /* chained data */ 2767 satIOContext->satCompleteCB = &satChainedDataIOCB; 2768 } 2769 2770 /* 2771 * Prepare SGL and send FIS to LL layer. 2772 */ 2773 satIOContext->reqType = agRequestType; /* Save it */ 2774 2775 status = sataLLIOStart( tiRoot, 2776 tiIORequest, 2777 tiDeviceHandle, 2778 tiScsiRequest, 2779 satIOContext); 2780 2781 TI_DBG5(("satRead16: return\n")); 2782 return (status); 2783 2784 } 2785 2786 /*****************************************************************************/ 2787 /*! \brief SAT implementation for SCSI READ6. 2788 * 2789 * SAT implementation for SCSI READ6 and send FIS request to LL layer. 2790 * 2791 * \param tiRoot: Pointer to TISA initiator driver/port instance. 2792 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 2793 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 2794 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 2795 * \param satIOContext_t: Pointer to the SAT IO Context 2796 * 2797 * \return If command is started successfully 2798 * - \e tiSuccess: I/O request successfully initiated. 2799 * - \e tiBusy: No resources available, try again later. 2800 * - \e tiIONoDevice: Invalid device handle. 2801 * - \e tiError: Other errors. 2802 */ 2803 /*****************************************************************************/ 2804 GLOBAL bit32 satRead6( 2805 tiRoot_t *tiRoot, 2806 tiIORequest_t *tiIORequest, 2807 tiDeviceHandle_t *tiDeviceHandle, 2808 tiScsiInitiatorRequest_t *tiScsiRequest, 2809 satIOContext_t *satIOContext) 2810 { 2811 2812 bit32 status; 2813 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 2814 satDeviceData_t *pSatDevData; 2815 scsiRspSense_t *pSense; 2816 tiIniScsiCmnd_t *scsiCmnd; 2817 agsaFisRegHostToDevice_t *fis; 2818 bit32 lba = 0; 2819 bit16 tl = 0; 2820 2821 pSense = satIOContext->pSense; 2822 pSatDevData = satIOContext->pSatDevData; 2823 scsiCmnd = &tiScsiRequest->scsiCmnd; 2824 fis = satIOContext->pFis; 2825 2826 2827 TI_DBG5(("satRead6: start\n")); 2828 2829 /* no FUA checking since read6 */ 2830 2831 2832 /* checking CONTROL */ 2833 /* NACA == 1 or LINK == 1*/ 2834 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 2835 { 2836 satSetSensePayload( pSense, 2837 SCSI_SNSKEY_ILLEGAL_REQUEST, 2838 0, 2839 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 2840 satIOContext); 2841 2842 ostiInitiatorIOCompleted( tiRoot, 2843 tiIORequest, 2844 tiIOSuccess, 2845 SCSI_STAT_CHECK_CONDITION, 2846 satIOContext->pTiSenseData, 2847 satIOContext->interruptContext ); 2848 2849 TI_DBG2(("satRead6: return control\n")); 2850 return tiSuccess; 2851 } 2852 2853 /* cbd6; computing LBA and transfer length */ 2854 lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2)) 2855 + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3]; 2856 tl = scsiCmnd->cdb[4]; 2857 2858 2859 /* Table 34, 9.1, p 46 */ 2860 /* 2861 note: As of 2/10/2006, no support for DMA QUEUED 2862 */ 2863 2864 /* 2865 Table 34, 9.1, p 46, b 2866 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 2867 return check condition 2868 */ 2869 if (pSatDevData->satNCQ != agTRUE && 2870 pSatDevData->sat48BitSupport != agTRUE 2871 ) 2872 { 2873 if (lba > SAT_TR_LBA_LIMIT - 1) 2874 { 2875 satSetSensePayload( pSense, 2876 SCSI_SNSKEY_ILLEGAL_REQUEST, 2877 0, 2878 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 2879 satIOContext); 2880 2881 ostiInitiatorIOCompleted( tiRoot, 2882 tiIORequest, 2883 tiIOSuccess, 2884 SCSI_STAT_CHECK_CONDITION, 2885 satIOContext->pTiSenseData, 2886 satIOContext->interruptContext ); 2887 2888 TI_DBG1(("satRead6: return LBA out of range\n")); 2889 return tiSuccess; 2890 } 2891 } 2892 2893 /* case 1 and 2 */ 2894 if (lba + tl <= SAT_TR_LBA_LIMIT) 2895 { 2896 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 2897 { 2898 /* case 2 */ 2899 /* READ DMA*/ 2900 TI_DBG5(("satRead6: case 2\n")); 2901 2902 2903 fis->h.fisType = 0x27; /* Reg host to device */ 2904 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2905 fis->h.command = SAT_READ_DMA; /* 0xC8 */ 2906 fis->h.features = 0; /* FIS reserve */ 2907 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 2908 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 2909 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 2910 fis->d.device = 0x40; /* FIS LBA mode */ 2911 fis->d.lbaLowExp = 0; 2912 fis->d.lbaMidExp = 0; 2913 fis->d.lbaHighExp = 0; 2914 fis->d.featuresExp = 0; 2915 if (tl == 0) 2916 { 2917 /* temporary fix */ 2918 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */ 2919 } 2920 else 2921 { 2922 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 2923 } 2924 fis->d.sectorCountExp = 0; 2925 fis->d.reserved4 = 0; 2926 fis->d.control = 0; /* FIS HOB bit clear */ 2927 fis->d.reserved5 = 0; 2928 2929 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 2930 } 2931 else 2932 { 2933 /* case 1 */ 2934 /* READ SECTORS for easier implemetation */ 2935 TI_DBG5(("satRead6: case 1\n")); 2936 2937 fis->h.fisType = 0x27; /* Reg host to device */ 2938 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2939 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 2940 fis->h.features = 0; /* FIS reserve */ 2941 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 2942 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 2943 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 2944 fis->d.device = 0x40; /* FIS LBA mode */ 2945 fis->d.lbaLowExp = 0; 2946 fis->d.lbaMidExp = 0; 2947 fis->d.lbaHighExp = 0; 2948 fis->d.featuresExp = 0; 2949 if (tl == 0) 2950 { 2951 /* temporary fix */ 2952 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */ 2953 } 2954 else 2955 { 2956 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 2957 } 2958 fis->d.sectorCountExp = 0; 2959 fis->d.reserved4 = 0; 2960 fis->d.control = 0; /* FIS HOB bit clear */ 2961 fis->d.reserved5 = 0; 2962 2963 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 2964 2965 } 2966 } 2967 2968 /* case 3 and 4 */ 2969 if (pSatDevData->sat48BitSupport == agTRUE) 2970 { 2971 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 2972 { 2973 /* case 3 */ 2974 /* READ DMA EXT only */ 2975 TI_DBG5(("satRead6: case 3\n")); 2976 fis->h.fisType = 0x27; /* Reg host to device */ 2977 fis->h.c_pmPort = 0x80; /* C Bit is set */ 2978 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */ 2979 fis->h.features = 0; /* FIS reserve */ 2980 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 2981 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 2982 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 2983 fis->d.device = 0x40; /* FIS LBA mode set */ 2984 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 2985 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 2986 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 2987 fis->d.featuresExp = 0; /* FIS reserve */ 2988 if (tl == 0) 2989 { 2990 /* sector count is 256, 0x100*/ 2991 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 2992 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */ 2993 } 2994 else 2995 { 2996 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 2997 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 2998 } 2999 fis->d.reserved4 = 0; 3000 fis->d.control = 0; /* FIS HOB bit clear */ 3001 fis->d.reserved5 = 0; 3002 3003 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 3004 } 3005 else 3006 { 3007 /* case 4 */ 3008 /* READ SECTORS EXT for easier implemetation */ 3009 TI_DBG5(("satRead6: case 4\n")); 3010 3011 fis->h.fisType = 0x27; /* Reg host to device */ 3012 fis->h.c_pmPort = 0x80; /* C Bit is set */ 3013 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 3014 fis->h.features = 0; /* FIS reserve */ 3015 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 3016 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 3017 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 3018 fis->d.device = 0x40; /* FIS LBA mode set */ 3019 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 3020 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 3021 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 3022 fis->d.featuresExp = 0; /* FIS reserve */ 3023 if (tl == 0) 3024 { 3025 /* sector count is 256, 0x100*/ 3026 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 3027 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */ 3028 } 3029 else 3030 { 3031 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 3032 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 3033 } 3034 fis->d.reserved4 = 0; 3035 fis->d.control = 0; /* FIS HOB bit clear */ 3036 fis->d.reserved5 = 0; 3037 3038 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 3039 } 3040 } 3041 3042 /* case 5 */ 3043 if (pSatDevData->satNCQ == agTRUE) 3044 { 3045 /* READ FPDMA QUEUED */ 3046 if (pSatDevData->sat48BitSupport != agTRUE) 3047 { 3048 /* sanity check */ 3049 TI_DBG5(("satRead6: case 5 !!! error NCQ but 28 bit address support \n")); 3050 satSetSensePayload( pSense, 3051 SCSI_SNSKEY_ILLEGAL_REQUEST, 3052 0, 3053 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 3054 satIOContext); 3055 3056 ostiInitiatorIOCompleted( tiRoot, 3057 tiIORequest, 3058 tiIOSuccess, 3059 SCSI_STAT_CHECK_CONDITION, 3060 satIOContext->pTiSenseData, 3061 satIOContext->interruptContext ); 3062 return tiSuccess; 3063 } 3064 TI_DBG5(("satRead6: case 5\n")); 3065 3066 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */ 3067 3068 fis->h.fisType = 0x27; /* Reg host to device */ 3069 fis->h.c_pmPort = 0x80; /* C Bit is set */ 3070 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */ 3071 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 3072 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 3073 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 3074 fis->d.device = 0x40; /* FIS FUA clear */ 3075 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 3076 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 3077 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 3078 if (tl == 0) 3079 { 3080 /* sector count is 256, 0x100*/ 3081 fis->h.features = 0; /* FIS sector count (7:0) */ 3082 fis->d.featuresExp = 0x01; /* FIS sector count (15:8) */ 3083 } 3084 else 3085 { 3086 fis->h.features = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 3087 fis->d.featuresExp = 0; /* FIS sector count (15:8) */ 3088 } 3089 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 3090 fis->d.sectorCountExp = 0; 3091 fis->d.reserved4 = 0; 3092 fis->d.control = 0; /* FIS HOB bit clear */ 3093 fis->d.reserved5 = 0; 3094 3095 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ; 3096 } 3097 3098 /* Initialize CB for SATA completion. 3099 */ 3100 satIOContext->satCompleteCB = &satNonChainedDataIOCB; 3101 3102 /* 3103 * Prepare SGL and send FIS to LL layer. 3104 */ 3105 satIOContext->reqType = agRequestType; /* Save it */ 3106 3107 status = sataLLIOStart( tiRoot, 3108 tiIORequest, 3109 tiDeviceHandle, 3110 tiScsiRequest, 3111 satIOContext); 3112 return (status); 3113 3114 } 3115 3116 /*****************************************************************************/ 3117 /*! \brief SAT implementation for SCSI WRITE16. 3118 * 3119 * SAT implementation for SCSI WRITE16 and send FIS request to LL layer. 3120 * 3121 * \param tiRoot: Pointer to TISA initiator driver/port instance. 3122 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 3123 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 3124 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 3125 * \param satIOContext_t: Pointer to the SAT IO Context 3126 * 3127 * \return If command is started successfully 3128 * - \e tiSuccess: I/O request successfully initiated. 3129 * - \e tiBusy: No resources available, try again later. 3130 * - \e tiIONoDevice: Invalid device handle. 3131 * - \e tiError: Other errors. 3132 */ 3133 /*****************************************************************************/ 3134 GLOBAL bit32 satWrite16( 3135 tiRoot_t *tiRoot, 3136 tiIORequest_t *tiIORequest, 3137 tiDeviceHandle_t *tiDeviceHandle, 3138 tiScsiInitiatorRequest_t *tiScsiRequest, 3139 satIOContext_t *satIOContext) 3140 { 3141 bit32 status; 3142 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 3143 satDeviceData_t *pSatDevData; 3144 scsiRspSense_t *pSense; 3145 tiIniScsiCmnd_t *scsiCmnd; 3146 agsaFisRegHostToDevice_t *fis; 3147 bit32 lba = 0; 3148 bit32 tl = 0; 3149 bit32 LoopNum = 1; 3150 bit8 LBA[8]; 3151 bit8 TL[8]; 3152 bit32 rangeChk = agFALSE; /* lba and tl range check */ 3153 bit32 limitChk = agFALSE; /* lba and tl range check */ 3154 3155 pSense = satIOContext->pSense; 3156 pSatDevData = satIOContext->pSatDevData; 3157 scsiCmnd = &tiScsiRequest->scsiCmnd; 3158 fis = satIOContext->pFis; 3159 3160 TI_DBG5(("satWrite16: start\n")); 3161 3162 /* checking FUA_NV */ 3163 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 3164 { 3165 satSetSensePayload( pSense, 3166 SCSI_SNSKEY_ILLEGAL_REQUEST, 3167 0, 3168 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 3169 satIOContext); 3170 3171 ostiInitiatorIOCompleted( tiRoot, 3172 tiIORequest, 3173 tiIOSuccess, 3174 SCSI_STAT_CHECK_CONDITION, 3175 satIOContext->pTiSenseData, 3176 satIOContext->interruptContext ); 3177 3178 TI_DBG1(("satWrite16: return FUA_NV\n")); 3179 return tiSuccess; 3180 3181 } 3182 3183 /* checking CONTROL */ 3184 /* NACA == 1 or LINK == 1*/ 3185 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 3186 { 3187 satSetSensePayload( pSense, 3188 SCSI_SNSKEY_ILLEGAL_REQUEST, 3189 0, 3190 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 3191 satIOContext); 3192 3193 ostiInitiatorIOCompleted( tiRoot, 3194 tiIORequest, 3195 tiIOSuccess, 3196 SCSI_STAT_CHECK_CONDITION, 3197 satIOContext->pTiSenseData, 3198 satIOContext->interruptContext ); 3199 3200 TI_DBG1(("satWrite16: return control\n")); 3201 return tiSuccess; 3202 } 3203 3204 3205 osti_memset(LBA, 0, sizeof(LBA)); 3206 osti_memset(TL, 0, sizeof(TL)); 3207 3208 3209 /* do not use memcpy due to indexing in LBA and TL */ 3210 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 3211 LBA[1] = scsiCmnd->cdb[3]; 3212 LBA[2] = scsiCmnd->cdb[4]; 3213 LBA[3] = scsiCmnd->cdb[5]; 3214 LBA[4] = scsiCmnd->cdb[6]; 3215 LBA[5] = scsiCmnd->cdb[7]; 3216 LBA[6] = scsiCmnd->cdb[8]; 3217 LBA[7] = scsiCmnd->cdb[9]; /* LSB */ 3218 3219 TL[0] = 0; 3220 TL[1] = 0; 3221 TL[2] = 0; 3222 TL[3] = 0; 3223 TL[4] = scsiCmnd->cdb[10]; /* MSB */ 3224 TL[5] = scsiCmnd->cdb[11]; 3225 TL[6] = scsiCmnd->cdb[12]; 3226 TL[7] = scsiCmnd->cdb[13]; /* LSB */ 3227 3228 rangeChk = satAddNComparebit64(LBA, TL); 3229 3230 limitChk = satCompareLBALimitbit(LBA); 3231 3232 lba = satComputeCDB16LBA(satIOContext); 3233 tl = satComputeCDB16TL(satIOContext); 3234 3235 3236 3237 /* Table 34, 9.1, p 46 */ 3238 /* 3239 note: As of 2/10/2006, no support for DMA QUEUED 3240 */ 3241 3242 /* 3243 Table 34, 9.1, p 46, b 3244 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 3245 return check condition 3246 */ 3247 if (pSatDevData->satNCQ != agTRUE && 3248 pSatDevData->sat48BitSupport != agTRUE 3249 ) 3250 { 3251 if (limitChk) 3252 { 3253 TI_DBG1(("satWrite16: return LBA out of range, not EXT\n")); 3254 satSetSensePayload( pSense, 3255 SCSI_SNSKEY_ILLEGAL_REQUEST, 3256 0, 3257 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 3258 satIOContext); 3259 3260 ostiInitiatorIOCompleted( tiRoot, 3261 tiIORequest, 3262 tiIOSuccess, 3263 SCSI_STAT_CHECK_CONDITION, 3264 satIOContext->pTiSenseData, 3265 satIOContext->interruptContext ); 3266 3267 return tiSuccess; 3268 } 3269 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 3270 { 3271 TI_DBG1(("satWrite16: return LBA+TL out of range, not EXT\n")); 3272 satSetSensePayload( pSense, 3273 SCSI_SNSKEY_ILLEGAL_REQUEST, 3274 0, 3275 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 3276 satIOContext); 3277 3278 ostiInitiatorIOCompleted( tiRoot, 3279 tiIORequest, 3280 tiIOSuccess, 3281 SCSI_STAT_CHECK_CONDITION, 3282 satIOContext->pTiSenseData, 3283 satIOContext->interruptContext ); 3284 3285 return tiSuccess; 3286 } 3287 } 3288 3289 /* case 1 and 2 */ 3290 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT) 3291 { 3292 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 3293 { 3294 /* case 2 */ 3295 /* WRITE DMA*/ 3296 /* In case that we can't fit the transfer length, we loop */ 3297 TI_DBG5(("satWrite16: case 2\n")); 3298 fis->h.fisType = 0x27; /* Reg host to device */ 3299 fis->h.c_pmPort = 0x80; /* C bit is set */ 3300 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 3301 fis->h.features = 0; /* FIS reserve */ 3302 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 3303 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 3304 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 3305 3306 /* FIS LBA mode set LBA (27:24) */ 3307 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); 3308 3309 fis->d.lbaLowExp = 0; 3310 fis->d.lbaMidExp = 0; 3311 fis->d.lbaHighExp = 0; 3312 fis->d.featuresExp = 0; 3313 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 3314 fis->d.sectorCountExp = 0; 3315 fis->d.reserved4 = 0; 3316 fis->d.control = 0; /* FIS HOB bit clear */ 3317 fis->d.reserved5 = 0; 3318 3319 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 3320 satIOContext->ATACmd = SAT_WRITE_DMA; 3321 } 3322 else 3323 { 3324 /* case 1 */ 3325 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 3326 /* WRITE SECTORS for easier implemetation */ 3327 /* In case that we can't fit the transfer length, we loop */ 3328 TI_DBG5(("satWrite16: case 1\n")); 3329 fis->h.fisType = 0x27; /* Reg host to device */ 3330 fis->h.c_pmPort = 0x80; /* C bit is set */ 3331 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 3332 fis->h.features = 0; /* FIS reserve */ 3333 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 3334 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 3335 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 3336 3337 /* FIS LBA mode set LBA (27:24) */ 3338 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); 3339 3340 fis->d.lbaLowExp = 0; 3341 fis->d.lbaMidExp = 0; 3342 fis->d.lbaHighExp = 0; 3343 fis->d.featuresExp = 0; 3344 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 3345 fis->d.sectorCountExp = 0; 3346 fis->d.reserved4 = 0; 3347 fis->d.control = 0; /* FIS HOB bit clear */ 3348 fis->d.reserved5 = 0; 3349 3350 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 3351 satIOContext->ATACmd = SAT_WRITE_SECTORS; 3352 } 3353 } 3354 3355 /* case 3 and 4 */ 3356 if (pSatDevData->sat48BitSupport == agTRUE) 3357 { 3358 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 3359 { 3360 /* case 3 */ 3361 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 3362 TI_DBG5(("satWrite16: case 3\n")); 3363 fis->h.fisType = 0x27; /* Reg host to device */ 3364 fis->h.c_pmPort = 0x80; /* C Bit is set */ 3365 3366 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 3367 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 3368 3369 fis->h.features = 0; /* FIS reserve */ 3370 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 3371 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 3372 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 3373 fis->d.device = 0x40; /* FIS LBA mode set */ 3374 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 3375 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 3376 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 3377 fis->d.featuresExp = 0; /* FIS reserve */ 3378 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 3379 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 3380 fis->d.reserved4 = 0; 3381 fis->d.control = 0; /* FIS HOB bit clear */ 3382 fis->d.reserved5 = 0; 3383 3384 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 3385 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 3386 } 3387 else 3388 { 3389 /* case 4 */ 3390 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 3391 /* WRITE SECTORS EXT for easier implemetation */ 3392 TI_DBG5(("satWrite16: case 4\n")); 3393 fis->h.fisType = 0x27; /* Reg host to device */ 3394 fis->h.c_pmPort = 0x80; /* C Bit is set */ 3395 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 3396 3397 fis->h.features = 0; /* FIS reserve */ 3398 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 3399 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 3400 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 3401 fis->d.device = 0x40; /* FIS LBA mode set */ 3402 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 3403 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 3404 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 3405 fis->d.featuresExp = 0; /* FIS reserve */ 3406 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 3407 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 3408 fis->d.reserved4 = 0; 3409 fis->d.control = 0; /* FIS HOB bit clear */ 3410 fis->d.reserved5 = 0; 3411 3412 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 3413 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 3414 } 3415 } 3416 3417 /* case 5 */ 3418 if (pSatDevData->satNCQ == agTRUE) 3419 { 3420 /* WRITE FPDMA QUEUED */ 3421 if (pSatDevData->sat48BitSupport != agTRUE) 3422 { 3423 TI_DBG5(("satWrite16: case 5 !!! error NCQ but 28 bit address support \n")); 3424 satSetSensePayload( pSense, 3425 SCSI_SNSKEY_ILLEGAL_REQUEST, 3426 0, 3427 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 3428 satIOContext); 3429 3430 ostiInitiatorIOCompleted( tiRoot, 3431 tiIORequest, 3432 tiIOSuccess, 3433 SCSI_STAT_CHECK_CONDITION, 3434 satIOContext->pTiSenseData, 3435 satIOContext->interruptContext ); 3436 return tiSuccess; 3437 } 3438 TI_DBG6(("satWrite16: case 5\n")); 3439 3440 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 3441 3442 fis->h.fisType = 0x27; /* Reg host to device */ 3443 fis->h.c_pmPort = 0x80; /* C Bit is set */ 3444 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 3445 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 3446 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 3447 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 3448 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 3449 3450 /* Check FUA bit */ 3451 if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK) 3452 fis->d.device = 0xC0; /* FIS FUA set */ 3453 else 3454 fis->d.device = 0x40; /* FIS FUA clear */ 3455 3456 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 3457 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 3458 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 3459 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 3460 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 3461 fis->d.sectorCountExp = 0; 3462 fis->d.reserved4 = 0; 3463 fis->d.control = 0; /* FIS HOB bit clear */ 3464 fis->d.reserved5 = 0; 3465 3466 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 3467 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 3468 } 3469 3470 satIOContext->currentLBA = lba; 3471 satIOContext->OrgTL = tl; 3472 3473 /* 3474 computing number of loop and remainder for tl 3475 0xFF in case not ext 3476 0xFFFF in case EXT 3477 */ 3478 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 3479 { 3480 LoopNum = satComputeLoopNum(tl, 0xFF); 3481 } 3482 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 3483 fis->h.command == SAT_WRITE_DMA_EXT || 3484 fis->h.command == SAT_WRITE_DMA_FUA_EXT 3485 ) 3486 { 3487 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 3488 LoopNum = satComputeLoopNum(tl, 0xFFFF); 3489 } 3490 else 3491 { 3492 /* SAT_WRITE_FPDMA_QUEUEDK */ 3493 LoopNum = satComputeLoopNum(tl, 0xFFFF); 3494 } 3495 3496 satIOContext->LoopNum = LoopNum; 3497 3498 3499 if (LoopNum == 1) 3500 { 3501 TI_DBG5(("satWrite16: NON CHAINED data\n")); 3502 /* Initialize CB for SATA completion. 3503 */ 3504 satIOContext->satCompleteCB = &satNonChainedDataIOCB; 3505 } 3506 else 3507 { 3508 TI_DBG1(("satWrite16: CHAINED data\n")); 3509 /* re-setting tl */ 3510 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 3511 { 3512 fis->d.sectorCount = 0xFF; 3513 } 3514 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 3515 fis->h.command == SAT_WRITE_DMA_EXT || 3516 fis->h.command == SAT_WRITE_DMA_FUA_EXT 3517 ) 3518 { 3519 fis->d.sectorCount = 0xFF; 3520 fis->d.sectorCountExp = 0xFF; 3521 } 3522 else 3523 { 3524 /* SAT_WRITE_FPDMA_QUEUED */ 3525 fis->h.features = 0xFF; 3526 fis->d.featuresExp = 0xFF; 3527 } 3528 3529 /* Initialize CB for SATA completion. 3530 */ 3531 satIOContext->satCompleteCB = &satChainedDataIOCB; 3532 } 3533 3534 3535 /* 3536 * Prepare SGL and send FIS to LL layer. 3537 */ 3538 satIOContext->reqType = agRequestType; /* Save it */ 3539 3540 status = sataLLIOStart( tiRoot, 3541 tiIORequest, 3542 tiDeviceHandle, 3543 tiScsiRequest, 3544 satIOContext); 3545 return (status); 3546 } 3547 3548 /*****************************************************************************/ 3549 /*! \brief SAT implementation for SCSI WRITE12. 3550 * 3551 * SAT implementation for SCSI WRITE12 and send FIS request to LL layer. 3552 * 3553 * \param tiRoot: Pointer to TISA initiator driver/port instance. 3554 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 3555 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 3556 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 3557 * \param satIOContext_t: Pointer to the SAT IO Context 3558 * 3559 * \return If command is started successfully 3560 * - \e tiSuccess: I/O request successfully initiated. 3561 * - \e tiBusy: No resources available, try again later. 3562 * - \e tiIONoDevice: Invalid device handle. 3563 * - \e tiError: Other errors. 3564 */ 3565 /*****************************************************************************/ 3566 GLOBAL bit32 satWrite12( 3567 tiRoot_t *tiRoot, 3568 tiIORequest_t *tiIORequest, 3569 tiDeviceHandle_t *tiDeviceHandle, 3570 tiScsiInitiatorRequest_t *tiScsiRequest, 3571 satIOContext_t *satIOContext) 3572 { 3573 bit32 status; 3574 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 3575 satDeviceData_t *pSatDevData; 3576 scsiRspSense_t *pSense; 3577 tiIniScsiCmnd_t *scsiCmnd; 3578 agsaFisRegHostToDevice_t *fis; 3579 bit32 lba = 0; 3580 bit32 tl = 0; 3581 bit32 LoopNum = 1; 3582 bit8 LBA[4]; 3583 bit8 TL[4]; 3584 bit32 rangeChk = agFALSE; /* lba and tl range check */ 3585 3586 pSense = satIOContext->pSense; 3587 pSatDevData = satIOContext->pSatDevData; 3588 scsiCmnd = &tiScsiRequest->scsiCmnd; 3589 fis = satIOContext->pFis; 3590 3591 TI_DBG5(("satWrite12: start\n")); 3592 3593 /* checking FUA_NV */ 3594 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 3595 { 3596 satSetSensePayload( pSense, 3597 SCSI_SNSKEY_ILLEGAL_REQUEST, 3598 0, 3599 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 3600 satIOContext); 3601 3602 ostiInitiatorIOCompleted( tiRoot, 3603 tiIORequest, 3604 tiIOSuccess, 3605 SCSI_STAT_CHECK_CONDITION, 3606 satIOContext->pTiSenseData, 3607 satIOContext->interruptContext ); 3608 3609 TI_DBG1(("satWrite12: return FUA_NV\n")); 3610 return tiSuccess; 3611 3612 } 3613 3614 3615 /* checking CONTROL */ 3616 /* NACA == 1 or LINK == 1*/ 3617 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) ) 3618 { 3619 satSetSensePayload( pSense, 3620 SCSI_SNSKEY_ILLEGAL_REQUEST, 3621 0, 3622 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 3623 satIOContext); 3624 3625 ostiInitiatorIOCompleted( tiRoot, 3626 tiIORequest, 3627 tiIOSuccess, 3628 SCSI_STAT_CHECK_CONDITION, 3629 satIOContext->pTiSenseData, 3630 satIOContext->interruptContext ); 3631 3632 TI_DBG1(("satWrite12: return control\n")); 3633 return tiSuccess; 3634 } 3635 3636 3637 osti_memset(LBA, 0, sizeof(LBA)); 3638 osti_memset(TL, 0, sizeof(TL)); 3639 3640 /* do not use memcpy due to indexing in LBA and TL */ 3641 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 3642 LBA[1] = scsiCmnd->cdb[3]; 3643 LBA[2] = scsiCmnd->cdb[4]; 3644 LBA[3] = scsiCmnd->cdb[5]; /* LSB */ 3645 3646 TL[0] = scsiCmnd->cdb[6]; /* MSB */ 3647 TL[1] = scsiCmnd->cdb[7]; 3648 TL[2] = scsiCmnd->cdb[8]; 3649 TL[3] = scsiCmnd->cdb[9]; /* LSB */ 3650 3651 rangeChk = satAddNComparebit32(LBA, TL); 3652 3653 lba = satComputeCDB12LBA(satIOContext); 3654 tl = satComputeCDB12TL(satIOContext); 3655 3656 3657 /* Table 34, 9.1, p 46 */ 3658 /* 3659 note: As of 2/10/2006, no support for DMA QUEUED 3660 */ 3661 3662 /* 3663 Table 34, 9.1, p 46, b 3664 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 3665 return check condition 3666 */ 3667 if (pSatDevData->satNCQ != agTRUE && 3668 pSatDevData->sat48BitSupport != agTRUE 3669 ) 3670 { 3671 if (lba > SAT_TR_LBA_LIMIT - 1) 3672 { 3673 satSetSensePayload( pSense, 3674 SCSI_SNSKEY_ILLEGAL_REQUEST, 3675 0, 3676 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 3677 satIOContext); 3678 3679 ostiInitiatorIOCompleted( tiRoot, 3680 tiIORequest, 3681 tiIOSuccess, 3682 SCSI_STAT_CHECK_CONDITION, 3683 satIOContext->pTiSenseData, 3684 satIOContext->interruptContext ); 3685 3686 TI_DBG1(("satWrite12: return LBA out of range, not EXT\n")); 3687 return tiSuccess; 3688 } 3689 3690 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 3691 { 3692 TI_DBG1(("satWrite12: return LBA+TL out of range, not EXT\n")); 3693 satSetSensePayload( pSense, 3694 SCSI_SNSKEY_ILLEGAL_REQUEST, 3695 0, 3696 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 3697 satIOContext); 3698 3699 ostiInitiatorIOCompleted( tiRoot, 3700 tiIORequest, 3701 tiIOSuccess, 3702 SCSI_STAT_CHECK_CONDITION, 3703 satIOContext->pTiSenseData, 3704 satIOContext->interruptContext ); 3705 3706 return tiSuccess; 3707 } 3708 } 3709 3710 3711 /* case 1 and 2 */ 3712 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT) 3713 { 3714 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 3715 { 3716 /* case 2 */ 3717 /* WRITE DMA*/ 3718 /* In case that we can't fit the transfer length, we loop */ 3719 TI_DBG5(("satWrite12: case 2\n")); 3720 fis->h.fisType = 0x27; /* Reg host to device */ 3721 fis->h.c_pmPort = 0x80; /* C bit is set */ 3722 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 3723 fis->h.features = 0; /* FIS reserve */ 3724 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 3725 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 3726 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 3727 3728 /* FIS LBA mode set LBA (27:24) */ 3729 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 3730 3731 fis->d.lbaLowExp = 0; 3732 fis->d.lbaMidExp = 0; 3733 fis->d.lbaHighExp = 0; 3734 fis->d.featuresExp = 0; 3735 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 3736 fis->d.sectorCountExp = 0; 3737 fis->d.reserved4 = 0; 3738 fis->d.control = 0; /* FIS HOB bit clear */ 3739 fis->d.reserved5 = 0; 3740 3741 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 3742 satIOContext->ATACmd = SAT_WRITE_DMA; 3743 } 3744 else 3745 { 3746 /* case 1 */ 3747 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 3748 /* WRITE SECTORS for easier implemetation */ 3749 /* In case that we can't fit the transfer length, we loop */ 3750 TI_DBG5(("satWrite12: case 1\n")); 3751 fis->h.fisType = 0x27; /* Reg host to device */ 3752 fis->h.c_pmPort = 0x80; /* C bit is set */ 3753 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 3754 fis->h.features = 0; /* FIS reserve */ 3755 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 3756 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 3757 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 3758 3759 /* FIS LBA mode set LBA (27:24) */ 3760 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 3761 3762 fis->d.lbaLowExp = 0; 3763 fis->d.lbaMidExp = 0; 3764 fis->d.lbaHighExp = 0; 3765 fis->d.featuresExp = 0; 3766 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 3767 fis->d.sectorCountExp = 0; 3768 fis->d.reserved4 = 0; 3769 fis->d.control = 0; /* FIS HOB bit clear */ 3770 fis->d.reserved5 = 0; 3771 3772 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 3773 satIOContext->ATACmd = SAT_WRITE_SECTORS; 3774 } 3775 } 3776 3777 /* case 3 and 4 */ 3778 if (pSatDevData->sat48BitSupport == agTRUE) 3779 { 3780 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 3781 { 3782 /* case 3 */ 3783 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 3784 TI_DBG5(("satWrite12: case 3\n")); 3785 fis->h.fisType = 0x27; /* Reg host to device */ 3786 fis->h.c_pmPort = 0x80; /* C Bit is set */ 3787 3788 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 3789 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 3790 3791 fis->h.features = 0; /* FIS reserve */ 3792 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 3793 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 3794 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 3795 fis->d.device = 0x40; /* FIS LBA mode set */ 3796 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 3797 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 3798 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 3799 fis->d.featuresExp = 0; /* FIS reserve */ 3800 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 3801 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 3802 fis->d.reserved4 = 0; 3803 fis->d.control = 0; /* FIS HOB bit clear */ 3804 fis->d.reserved5 = 0; 3805 3806 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 3807 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 3808 } 3809 else 3810 { 3811 /* case 4 */ 3812 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 3813 /* WRITE SECTORS EXT for easier implemetation */ 3814 TI_DBG5(("satWrite12: case 4\n")); 3815 fis->h.fisType = 0x27; /* Reg host to device */ 3816 fis->h.c_pmPort = 0x80; /* C Bit is set */ 3817 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 3818 3819 fis->h.features = 0; /* FIS reserve */ 3820 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 3821 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 3822 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 3823 fis->d.device = 0x40; /* FIS LBA mode set */ 3824 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 3825 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 3826 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 3827 fis->d.featuresExp = 0; /* FIS reserve */ 3828 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 3829 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 3830 fis->d.reserved4 = 0; 3831 fis->d.control = 0; /* FIS HOB bit clear */ 3832 fis->d.reserved5 = 0; 3833 3834 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 3835 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 3836 } 3837 } 3838 3839 /* case 5 */ 3840 if (pSatDevData->satNCQ == agTRUE) 3841 { 3842 /* WRITE FPDMA QUEUED */ 3843 if (pSatDevData->sat48BitSupport != agTRUE) 3844 { 3845 TI_DBG5(("satWrite12: case 5 !!! error NCQ but 28 bit address support \n")); 3846 satSetSensePayload( pSense, 3847 SCSI_SNSKEY_ILLEGAL_REQUEST, 3848 0, 3849 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 3850 satIOContext); 3851 3852 ostiInitiatorIOCompleted( tiRoot, 3853 tiIORequest, 3854 tiIOSuccess, 3855 SCSI_STAT_CHECK_CONDITION, 3856 satIOContext->pTiSenseData, 3857 satIOContext->interruptContext ); 3858 return tiSuccess; 3859 } 3860 TI_DBG6(("satWrite12: case 5\n")); 3861 3862 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 3863 3864 fis->h.fisType = 0x27; /* Reg host to device */ 3865 fis->h.c_pmPort = 0x80; /* C Bit is set */ 3866 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 3867 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 3868 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 3869 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 3870 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 3871 3872 /* Check FUA bit */ 3873 if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK) 3874 fis->d.device = 0xC0; /* FIS FUA set */ 3875 else 3876 fis->d.device = 0x40; /* FIS FUA clear */ 3877 3878 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 3879 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 3880 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 3881 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 3882 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 3883 fis->d.sectorCountExp = 0; 3884 fis->d.reserved4 = 0; 3885 fis->d.control = 0; /* FIS HOB bit clear */ 3886 fis->d.reserved5 = 0; 3887 3888 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 3889 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 3890 } 3891 3892 satIOContext->currentLBA = lba; 3893 satIOContext->OrgTL = tl; 3894 3895 /* 3896 computing number of loop and remainder for tl 3897 0xFF in case not ext 3898 0xFFFF in case EXT 3899 */ 3900 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 3901 { 3902 LoopNum = satComputeLoopNum(tl, 0xFF); 3903 } 3904 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 3905 fis->h.command == SAT_WRITE_DMA_EXT || 3906 fis->h.command == SAT_WRITE_DMA_FUA_EXT 3907 ) 3908 { 3909 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 3910 LoopNum = satComputeLoopNum(tl, 0xFFFF); 3911 } 3912 else 3913 { 3914 /* SAT_WRITE_FPDMA_QUEUEDK */ 3915 LoopNum = satComputeLoopNum(tl, 0xFFFF); 3916 } 3917 3918 satIOContext->LoopNum = LoopNum; 3919 3920 3921 if (LoopNum == 1) 3922 { 3923 TI_DBG5(("satWrite12: NON CHAINED data\n")); 3924 /* Initialize CB for SATA completion. 3925 */ 3926 satIOContext->satCompleteCB = &satNonChainedDataIOCB; 3927 } 3928 else 3929 { 3930 TI_DBG1(("satWrite12: CHAINED data\n")); 3931 /* re-setting tl */ 3932 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 3933 { 3934 fis->d.sectorCount = 0xFF; 3935 } 3936 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 3937 fis->h.command == SAT_WRITE_DMA_EXT || 3938 fis->h.command == SAT_WRITE_DMA_FUA_EXT 3939 ) 3940 { 3941 fis->d.sectorCount = 0xFF; 3942 fis->d.sectorCountExp = 0xFF; 3943 } 3944 else 3945 { 3946 /* SAT_WRITE_FPDMA_QUEUED */ 3947 fis->h.features = 0xFF; 3948 fis->d.featuresExp = 0xFF; 3949 } 3950 3951 /* Initialize CB for SATA completion. 3952 */ 3953 satIOContext->satCompleteCB = &satChainedDataIOCB; 3954 } 3955 3956 3957 /* 3958 * Prepare SGL and send FIS to LL layer. 3959 */ 3960 satIOContext->reqType = agRequestType; /* Save it */ 3961 3962 status = sataLLIOStart( tiRoot, 3963 tiIORequest, 3964 tiDeviceHandle, 3965 tiScsiRequest, 3966 satIOContext); 3967 return (status); 3968 } 3969 3970 /*****************************************************************************/ 3971 /*! \brief SAT implementation for SCSI WRITE10. 3972 * 3973 * SAT implementation for SCSI WRITE10 and send FIS request to LL layer. 3974 * 3975 * \param tiRoot: Pointer to TISA initiator driver/port instance. 3976 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 3977 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 3978 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 3979 * \param satIOContext_t: Pointer to the SAT IO Context 3980 * 3981 * \return If command is started successfully 3982 * - \e tiSuccess: I/O request successfully initiated. 3983 * - \e tiBusy: No resources available, try again later. 3984 * - \e tiIONoDevice: Invalid device handle. 3985 * - \e tiError: Other errors. 3986 */ 3987 /*****************************************************************************/ 3988 GLOBAL bit32 satWrite10( 3989 tiRoot_t *tiRoot, 3990 tiIORequest_t *tiIORequest, 3991 tiDeviceHandle_t *tiDeviceHandle, 3992 tiScsiInitiatorRequest_t *tiScsiRequest, 3993 satIOContext_t *satIOContext) 3994 { 3995 3996 bit32 status; 3997 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 3998 satDeviceData_t *pSatDevData; 3999 scsiRspSense_t *pSense; 4000 tiIniScsiCmnd_t *scsiCmnd; 4001 agsaFisRegHostToDevice_t *fis; 4002 bit32 lba = 0; 4003 bit32 tl = 0; 4004 bit32 LoopNum = 1; 4005 bit8 LBA[4]; 4006 bit8 TL[4]; 4007 bit32 rangeChk = agFALSE; /* lba and tl range check */ 4008 4009 pSense = satIOContext->pSense; 4010 pSatDevData = satIOContext->pSatDevData; 4011 scsiCmnd = &tiScsiRequest->scsiCmnd; 4012 fis = satIOContext->pFis; 4013 4014 TI_DBG5(("satWrite10: start\n")); 4015 4016 /* checking FUA_NV */ 4017 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 4018 { 4019 satSetSensePayload( pSense, 4020 SCSI_SNSKEY_ILLEGAL_REQUEST, 4021 0, 4022 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 4023 satIOContext); 4024 4025 ostiInitiatorIOCompleted( tiRoot, 4026 tiIORequest, 4027 tiIOSuccess, 4028 SCSI_STAT_CHECK_CONDITION, 4029 satIOContext->pTiSenseData, 4030 satIOContext->interruptContext ); 4031 4032 TI_DBG1(("satWrite10: return FUA_NV\n")); 4033 return tiSuccess; 4034 4035 } 4036 4037 /* checking CONTROL */ 4038 /* NACA == 1 or LINK == 1*/ 4039 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 4040 { 4041 satSetSensePayload( pSense, 4042 SCSI_SNSKEY_ILLEGAL_REQUEST, 4043 0, 4044 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 4045 satIOContext); 4046 4047 ostiInitiatorIOCompleted( tiRoot, 4048 tiIORequest, 4049 tiIOSuccess, 4050 SCSI_STAT_CHECK_CONDITION, 4051 satIOContext->pTiSenseData, 4052 satIOContext->interruptContext ); 4053 4054 TI_DBG1(("satWrite10: return control\n")); 4055 return tiSuccess; 4056 } 4057 4058 osti_memset(LBA, 0, sizeof(LBA)); 4059 osti_memset(TL, 0, sizeof(TL)); 4060 4061 /* do not use memcpy due to indexing in LBA and TL */ 4062 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 4063 LBA[1] = scsiCmnd->cdb[3]; 4064 LBA[2] = scsiCmnd->cdb[4]; 4065 LBA[3] = scsiCmnd->cdb[5]; /* LSB */ 4066 4067 TL[0] = 0; 4068 TL[1] = 0; 4069 TL[2] = scsiCmnd->cdb[7]; /* MSB */ 4070 TL[3] = scsiCmnd->cdb[8]; /* LSB */ 4071 4072 rangeChk = satAddNComparebit32(LBA, TL); 4073 4074 4075 /* cbd10; computing LBA and transfer length */ 4076 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 4077 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 4078 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 4079 4080 TI_DBG5(("satWrite10: lba %d functioned lba %d\n", lba, satComputeCDB10LBA(satIOContext))); 4081 TI_DBG5(("satWrite10: tl %d functioned tl %d\n", tl, satComputeCDB10TL(satIOContext))); 4082 4083 /* Table 34, 9.1, p 46 */ 4084 /* 4085 note: As of 2/10/2006, no support for DMA QUEUED 4086 */ 4087 4088 /* 4089 Table 34, 9.1, p 46, b 4090 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 4091 return check condition 4092 */ 4093 if (pSatDevData->satNCQ != agTRUE && 4094 pSatDevData->sat48BitSupport != agTRUE 4095 ) 4096 { 4097 if (lba > SAT_TR_LBA_LIMIT - 1) 4098 { 4099 satSetSensePayload( pSense, 4100 SCSI_SNSKEY_ILLEGAL_REQUEST, 4101 0, 4102 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 4103 satIOContext); 4104 4105 ostiInitiatorIOCompleted( tiRoot, 4106 tiIORequest, 4107 tiIOSuccess, 4108 SCSI_STAT_CHECK_CONDITION, 4109 satIOContext->pTiSenseData, 4110 satIOContext->interruptContext ); 4111 4112 TI_DBG1(("satWrite10: return LBA out of range, not EXT\n")); 4113 TI_DBG1(("satWrite10: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3], 4114 scsiCmnd->cdb[4], scsiCmnd->cdb[5])); 4115 TI_DBG1(("satWrite10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT)); 4116 return tiSuccess; 4117 } 4118 4119 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 4120 { 4121 TI_DBG1(("satWrite10: return LBA+TL out of range, not EXT\n")); 4122 satSetSensePayload( pSense, 4123 SCSI_SNSKEY_ILLEGAL_REQUEST, 4124 0, 4125 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 4126 satIOContext); 4127 4128 ostiInitiatorIOCompleted( tiRoot, 4129 tiIORequest, 4130 tiIOSuccess, 4131 SCSI_STAT_CHECK_CONDITION, 4132 satIOContext->pTiSenseData, 4133 satIOContext->interruptContext ); 4134 4135 return tiSuccess; 4136 } 4137 4138 } 4139 4140 4141 /* case 1 and 2 */ 4142 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT) 4143 { 4144 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 4145 { 4146 /* case 2 */ 4147 /* WRITE DMA*/ 4148 /* can't fit the transfer length */ 4149 TI_DBG5(("satWrite10: case 2\n")); 4150 fis->h.fisType = 0x27; /* Reg host to device */ 4151 fis->h.c_pmPort = 0x80; /* C bit is set */ 4152 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 4153 fis->h.features = 0; /* FIS reserve */ 4154 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 4155 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 4156 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 4157 4158 /* FIS LBA mode set LBA (27:24) */ 4159 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 4160 4161 fis->d.lbaLowExp = 0; 4162 fis->d.lbaMidExp = 0; 4163 fis->d.lbaHighExp = 0; 4164 fis->d.featuresExp = 0; 4165 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 4166 fis->d.sectorCountExp = 0; 4167 fis->d.reserved4 = 0; 4168 fis->d.control = 0; /* FIS HOB bit clear */ 4169 fis->d.reserved5 = 0; 4170 4171 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 4172 satIOContext->ATACmd = SAT_WRITE_DMA; 4173 } 4174 else 4175 { 4176 /* case 1 */ 4177 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 4178 /* WRITE SECTORS for easier implemetation */ 4179 /* can't fit the transfer length */ 4180 TI_DBG5(("satWrite10: case 1\n")); 4181 fis->h.fisType = 0x27; /* Reg host to device */ 4182 fis->h.c_pmPort = 0x80; /* C bit is set */ 4183 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 4184 fis->h.features = 0; /* FIS reserve */ 4185 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 4186 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 4187 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 4188 4189 /* FIS LBA mode set LBA (27:24) */ 4190 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 4191 4192 fis->d.lbaLowExp = 0; 4193 fis->d.lbaMidExp = 0; 4194 fis->d.lbaHighExp = 0; 4195 fis->d.featuresExp = 0; 4196 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 4197 fis->d.sectorCountExp = 0; 4198 fis->d.reserved4 = 0; 4199 fis->d.control = 0; /* FIS HOB bit clear */ 4200 fis->d.reserved5 = 0; 4201 4202 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 4203 satIOContext->ATACmd = SAT_WRITE_SECTORS; 4204 } 4205 } 4206 /* case 3 and 4 */ 4207 if (pSatDevData->sat48BitSupport == agTRUE) 4208 { 4209 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 4210 { 4211 /* case 3 */ 4212 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 4213 TI_DBG5(("satWrite10: case 3\n")); 4214 fis->h.fisType = 0x27; /* Reg host to device */ 4215 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4216 4217 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 4218 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 4219 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 4220 4221 fis->h.features = 0; /* FIS reserve */ 4222 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 4223 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 4224 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 4225 fis->d.device = 0x40; /* FIS LBA mode set */ 4226 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 4227 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4228 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4229 fis->d.featuresExp = 0; /* FIS reserve */ 4230 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 4231 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 4232 fis->d.reserved4 = 0; 4233 fis->d.control = 0; /* FIS HOB bit clear */ 4234 fis->d.reserved5 = 0; 4235 4236 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 4237 } 4238 else 4239 { 4240 /* case 4 */ 4241 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 4242 /* WRITE SECTORS EXT for easier implemetation */ 4243 TI_DBG5(("satWrite10: case 4\n")); 4244 fis->h.fisType = 0x27; /* Reg host to device */ 4245 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4246 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 4247 4248 fis->h.features = 0; /* FIS reserve */ 4249 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 4250 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 4251 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 4252 fis->d.device = 0x40; /* FIS LBA mode set */ 4253 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 4254 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4255 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4256 fis->d.featuresExp = 0; /* FIS reserve */ 4257 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 4258 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 4259 fis->d.reserved4 = 0; 4260 fis->d.control = 0; /* FIS HOB bit clear */ 4261 fis->d.reserved5 = 0; 4262 4263 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 4264 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 4265 } 4266 } 4267 /* case 5 */ 4268 if (pSatDevData->satNCQ == agTRUE) 4269 { 4270 /* WRITE FPDMA QUEUED */ 4271 if (pSatDevData->sat48BitSupport != agTRUE) 4272 { 4273 TI_DBG5(("satWrite10: case 5 !!! error NCQ but 28 bit address support \n")); 4274 satSetSensePayload( pSense, 4275 SCSI_SNSKEY_ILLEGAL_REQUEST, 4276 0, 4277 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 4278 satIOContext); 4279 4280 ostiInitiatorIOCompleted( tiRoot, 4281 tiIORequest, 4282 tiIOSuccess, 4283 SCSI_STAT_CHECK_CONDITION, 4284 satIOContext->pTiSenseData, 4285 satIOContext->interruptContext ); 4286 return tiSuccess; 4287 } 4288 TI_DBG6(("satWrite10: case 5\n")); 4289 4290 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 4291 4292 fis->h.fisType = 0x27; /* Reg host to device */ 4293 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4294 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 4295 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 4296 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 4297 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 4298 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 4299 4300 /* Check FUA bit */ 4301 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK) 4302 fis->d.device = 0xC0; /* FIS FUA set */ 4303 else 4304 fis->d.device = 0x40; /* FIS FUA clear */ 4305 4306 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 4307 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4308 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4309 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 4310 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 4311 fis->d.sectorCountExp = 0; 4312 fis->d.reserved4 = 0; 4313 fis->d.control = 0; /* FIS HOB bit clear */ 4314 fis->d.reserved5 = 0; 4315 4316 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 4317 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 4318 } 4319 4320 // tdhexdump("satWrite10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t)); 4321 4322 satIOContext->currentLBA = lba; 4323 satIOContext->OrgTL = tl; 4324 4325 /* 4326 computing number of loop and remainder for tl 4327 0xFF in case not ext 4328 0xFFFF in case EXT 4329 */ 4330 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 4331 { 4332 LoopNum = satComputeLoopNum(tl, 0xFF); 4333 } 4334 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 4335 fis->h.command == SAT_WRITE_DMA_EXT || 4336 fis->h.command == SAT_WRITE_DMA_FUA_EXT 4337 ) 4338 { 4339 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 4340 LoopNum = satComputeLoopNum(tl, 0xFFFF); 4341 } 4342 else 4343 { 4344 /* SAT_WRITE_FPDMA_QUEUEDK */ 4345 LoopNum = satComputeLoopNum(tl, 0xFFFF); 4346 } 4347 4348 satIOContext->LoopNum = LoopNum; 4349 4350 4351 if (LoopNum == 1) 4352 { 4353 TI_DBG5(("satWrite10: NON CHAINED data\n")); 4354 /* Initialize CB for SATA completion. 4355 */ 4356 satIOContext->satCompleteCB = &satNonChainedDataIOCB; 4357 } 4358 else 4359 { 4360 TI_DBG1(("satWrite10: CHAINED data\n")); 4361 /* re-setting tl */ 4362 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 4363 { 4364 fis->d.sectorCount = 0xFF; 4365 } 4366 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 4367 fis->h.command == SAT_WRITE_DMA_EXT || 4368 fis->h.command == SAT_WRITE_DMA_FUA_EXT 4369 ) 4370 { 4371 fis->d.sectorCount = 0xFF; 4372 fis->d.sectorCountExp = 0xFF; 4373 } 4374 else 4375 { 4376 /* SAT_WRITE_FPDMA_QUEUED */ 4377 fis->h.features = 0xFF; 4378 fis->d.featuresExp = 0xFF; 4379 } 4380 4381 /* Initialize CB for SATA completion. 4382 */ 4383 satIOContext->satCompleteCB = &satChainedDataIOCB; 4384 } 4385 4386 4387 /* 4388 * Prepare SGL and send FIS to LL layer. 4389 */ 4390 satIOContext->reqType = agRequestType; /* Save it */ 4391 4392 status = sataLLIOStart( tiRoot, 4393 tiIORequest, 4394 tiDeviceHandle, 4395 tiScsiRequest, 4396 satIOContext); 4397 return (status); 4398 } 4399 4400 /*****************************************************************************/ 4401 /*! \brief SAT implementation for SCSI satWrite_1. 4402 * 4403 * SAT implementation for SCSI WRITE10 and send FIS request to LL layer. 4404 * This is used when WRITE10 is divided into multiple ATA commands 4405 * 4406 * \param tiRoot: Pointer to TISA initiator driver/port instance. 4407 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 4408 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 4409 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 4410 * \param satIOContext_t: Pointer to the SAT IO Context 4411 * 4412 * \return If command is started successfully 4413 * - \e tiSuccess: I/O request successfully initiated. 4414 * - \e tiBusy: No resources available, try again later. 4415 * - \e tiIONoDevice: Invalid device handle. 4416 * - \e tiError: Other errors. 4417 */ 4418 /*****************************************************************************/ 4419 GLOBAL bit32 satWrite_1( 4420 tiRoot_t *tiRoot, 4421 tiIORequest_t *tiIORequest, 4422 tiDeviceHandle_t *tiDeviceHandle, 4423 tiScsiInitiatorRequest_t *tiScsiRequest, 4424 satIOContext_t *satIOContext) 4425 { 4426 /* 4427 Assumption: error check on lba and tl has been done in satWrite*() 4428 lba = lba + tl; 4429 */ 4430 bit32 status; 4431 satIOContext_t *satOrgIOContext = agNULL; 4432 tiIniScsiCmnd_t *scsiCmnd; 4433 agsaFisRegHostToDevice_t *fis; 4434 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 4435 bit32 lba = 0; 4436 bit32 DenomTL = 0xFF; 4437 bit32 Remainder = 0; 4438 bit8 LBA[4]; /* 0 MSB, 3 LSB */ 4439 4440 TI_DBG2(("satWrite_1: start\n")); 4441 4442 fis = satIOContext->pFis; 4443 satOrgIOContext = satIOContext->satOrgIOContext; 4444 scsiCmnd = satOrgIOContext->pScsiCmnd; 4445 4446 osti_memset(LBA,0, sizeof(LBA)); 4447 4448 switch (satOrgIOContext->ATACmd) 4449 { 4450 case SAT_WRITE_DMA: 4451 DenomTL = 0xFF; 4452 break; 4453 case SAT_WRITE_SECTORS: 4454 DenomTL = 0xFF; 4455 break; 4456 case SAT_WRITE_DMA_EXT: 4457 DenomTL = 0xFFFF; 4458 break; 4459 case SAT_WRITE_DMA_FUA_EXT: 4460 DenomTL = 0xFFFF; 4461 break; 4462 case SAT_WRITE_SECTORS_EXT: 4463 DenomTL = 0xFFFF; 4464 break; 4465 case SAT_WRITE_FPDMA_QUEUED: 4466 DenomTL = 0xFFFF; 4467 break; 4468 default: 4469 TI_DBG1(("satWrite_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd)); 4470 return tiError; 4471 break; 4472 } 4473 4474 Remainder = satOrgIOContext->OrgTL % DenomTL; 4475 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL; 4476 lba = satOrgIOContext->currentLBA; 4477 4478 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */ 4479 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2)); 4480 LBA[2] = (bit8)((lba & 0xF0) >> 8); 4481 LBA[3] = (bit8)(lba & 0xF); /* LSB */ 4482 4483 switch (satOrgIOContext->ATACmd) 4484 { 4485 case SAT_WRITE_DMA: 4486 fis->h.fisType = 0x27; /* Reg host to device */ 4487 fis->h.c_pmPort = 0x80; /* C bit is set */ 4488 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 4489 fis->h.features = 0; /* FIS reserve */ 4490 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 4491 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 4492 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 4493 4494 /* FIS LBA mode set LBA (27:24) */ 4495 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 4496 4497 fis->d.lbaLowExp = 0; 4498 fis->d.lbaMidExp = 0; 4499 fis->d.lbaHighExp = 0; 4500 fis->d.featuresExp = 0; 4501 if (satOrgIOContext->LoopNum == 1) 4502 { 4503 /* last loop */ 4504 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 4505 } 4506 else 4507 { 4508 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 4509 } 4510 fis->d.sectorCountExp = 0; 4511 fis->d.reserved4 = 0; 4512 fis->d.control = 0; /* FIS HOB bit clear */ 4513 fis->d.reserved5 = 0; 4514 4515 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 4516 4517 break; 4518 case SAT_WRITE_SECTORS: 4519 fis->h.fisType = 0x27; /* Reg host to device */ 4520 fis->h.c_pmPort = 0x80; /* C bit is set */ 4521 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 4522 fis->h.features = 0; /* FIS reserve */ 4523 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 4524 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 4525 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 4526 4527 /* FIS LBA mode set LBA (27:24) */ 4528 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 4529 4530 fis->d.lbaLowExp = 0; 4531 fis->d.lbaMidExp = 0; 4532 fis->d.lbaHighExp = 0; 4533 fis->d.featuresExp = 0; 4534 if (satOrgIOContext->LoopNum == 1) 4535 { 4536 /* last loop */ 4537 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 4538 } 4539 else 4540 { 4541 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 4542 } 4543 fis->d.sectorCountExp = 0; 4544 fis->d.reserved4 = 0; 4545 fis->d.control = 0; /* FIS HOB bit clear */ 4546 fis->d.reserved5 = 0; 4547 4548 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 4549 4550 break; 4551 case SAT_WRITE_DMA_EXT: 4552 fis->h.fisType = 0x27; /* Reg host to device */ 4553 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4554 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x3D */ 4555 fis->h.features = 0; /* FIS reserve */ 4556 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 4557 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 4558 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 4559 fis->d.device = 0x40; /* FIS LBA mode set */ 4560 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 4561 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4562 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4563 fis->d.featuresExp = 0; /* FIS reserve */ 4564 if (satOrgIOContext->LoopNum == 1) 4565 { 4566 /* last loop */ 4567 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 4568 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 4569 } 4570 else 4571 { 4572 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 4573 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 4574 } 4575 fis->d.reserved4 = 0; 4576 fis->d.control = 0; /* FIS HOB bit clear */ 4577 fis->d.reserved5 = 0; 4578 4579 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 4580 4581 break; 4582 case SAT_WRITE_SECTORS_EXT: 4583 fis->h.fisType = 0x27; /* Reg host to device */ 4584 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4585 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 4586 4587 fis->h.features = 0; /* FIS reserve */ 4588 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 4589 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 4590 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 4591 fis->d.device = 0x40; /* FIS LBA mode set */ 4592 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 4593 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4594 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4595 fis->d.featuresExp = 0; /* FIS reserve */ 4596 if (satOrgIOContext->LoopNum == 1) 4597 { 4598 /* last loop */ 4599 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 4600 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 4601 } 4602 else 4603 { 4604 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 4605 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 4606 } 4607 fis->d.reserved4 = 0; 4608 fis->d.control = 0; /* FIS HOB bit clear */ 4609 fis->d.reserved5 = 0; 4610 4611 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 4612 4613 break; 4614 case SAT_WRITE_FPDMA_QUEUED: 4615 fis->h.fisType = 0x27; /* Reg host to device */ 4616 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4617 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 4618 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 4619 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 4620 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 4621 4622 /* Check FUA bit */ 4623 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK) 4624 fis->d.device = 0xC0; /* FIS FUA set */ 4625 else 4626 fis->d.device = 0x40; /* FIS FUA clear */ 4627 4628 fis->d.lbaLowExp = LBA[0];; /* FIS LBA (31:24) */ 4629 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4630 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4631 if (satOrgIOContext->LoopNum == 1) 4632 { 4633 /* last loop */ 4634 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 4635 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 4636 } 4637 else 4638 { 4639 fis->h.features = 0xFF; /* FIS sector count (7:0) */ 4640 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */ 4641 } 4642 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 4643 fis->d.sectorCountExp = 0; 4644 fis->d.reserved4 = 0; 4645 fis->d.control = 0; /* FIS HOB bit clear */ 4646 fis->d.reserved5 = 0; 4647 4648 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 4649 break; 4650 4651 default: 4652 TI_DBG1(("satWrite_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd)); 4653 return tiError; 4654 break; 4655 } 4656 4657 /* Initialize CB for SATA completion. 4658 */ 4659 /* chained data */ 4660 satIOContext->satCompleteCB = &satChainedDataIOCB; 4661 4662 4663 /* 4664 * Prepare SGL and send FIS to LL layer. 4665 */ 4666 satIOContext->reqType = agRequestType; /* Save it */ 4667 4668 status = sataLLIOStart( tiRoot, 4669 tiIORequest, 4670 tiDeviceHandle, 4671 tiScsiRequest, 4672 satIOContext); 4673 4674 TI_DBG5(("satWrite_1: return\n")); 4675 return (status); 4676 } 4677 4678 /*****************************************************************************/ 4679 /*! \brief SAT implementation for SCSI WRITE6. 4680 * 4681 * SAT implementation for SCSI WRITE6 and send FIS request to LL layer. 4682 * 4683 * \param tiRoot: Pointer to TISA initiator driver/port instance. 4684 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 4685 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 4686 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 4687 * \param satIOContext_t: Pointer to the SAT IO Context 4688 * 4689 * \return If command is started successfully 4690 * - \e tiSuccess: I/O request successfully initiated. 4691 * - \e tiBusy: No resources available, try again later. 4692 * - \e tiIONoDevice: Invalid device handle. 4693 * - \e tiError: Other errors. 4694 */ 4695 /*****************************************************************************/ 4696 GLOBAL bit32 satWrite6( 4697 tiRoot_t *tiRoot, 4698 tiIORequest_t *tiIORequest, 4699 tiDeviceHandle_t *tiDeviceHandle, 4700 tiScsiInitiatorRequest_t *tiScsiRequest, 4701 satIOContext_t *satIOContext) 4702 { 4703 4704 bit32 status; 4705 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 4706 satDeviceData_t *pSatDevData; 4707 scsiRspSense_t *pSense; 4708 tiIniScsiCmnd_t *scsiCmnd; 4709 agsaFisRegHostToDevice_t *fis; 4710 bit32 lba = 0; 4711 bit16 tl = 0; 4712 4713 pSense = satIOContext->pSense; 4714 pSatDevData = satIOContext->pSatDevData; 4715 scsiCmnd = &tiScsiRequest->scsiCmnd; 4716 fis = satIOContext->pFis; 4717 4718 TI_DBG5(("satWrite6: start\n")); 4719 4720 /* checking CONTROL */ 4721 /* NACA == 1 or LINK == 1*/ 4722 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 4723 { 4724 satSetSensePayload( pSense, 4725 SCSI_SNSKEY_ILLEGAL_REQUEST, 4726 0, 4727 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 4728 satIOContext); 4729 4730 ostiInitiatorIOCompleted( tiRoot, 4731 tiIORequest, 4732 tiIOSuccess, 4733 SCSI_STAT_CHECK_CONDITION, 4734 satIOContext->pTiSenseData, 4735 satIOContext->interruptContext ); 4736 4737 TI_DBG1(("satWrite6: return control\n")); 4738 return tiSuccess; 4739 } 4740 4741 4742 /* cbd6; computing LBA and transfer length */ 4743 lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2)) 4744 + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3]; 4745 tl = scsiCmnd->cdb[4]; 4746 4747 4748 /* Table 34, 9.1, p 46 */ 4749 /* 4750 note: As of 2/10/2006, no support for DMA QUEUED 4751 */ 4752 4753 /* 4754 Table 34, 9.1, p 46, b 4755 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 4756 return check condition 4757 */ 4758 if (pSatDevData->satNCQ != agTRUE && 4759 pSatDevData->sat48BitSupport != agTRUE 4760 ) 4761 { 4762 if (lba > SAT_TR_LBA_LIMIT - 1) 4763 { 4764 satSetSensePayload( pSense, 4765 SCSI_SNSKEY_ILLEGAL_REQUEST, 4766 0, 4767 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 4768 satIOContext); 4769 4770 ostiInitiatorIOCompleted( tiRoot, 4771 tiIORequest, 4772 tiIOSuccess, 4773 SCSI_STAT_CHECK_CONDITION, 4774 satIOContext->pTiSenseData, 4775 satIOContext->interruptContext ); 4776 4777 TI_DBG1(("satWrite6: return LBA out of range\n")); 4778 return tiSuccess; 4779 } 4780 } 4781 4782 /* case 1 and 2 */ 4783 if (lba + tl <= SAT_TR_LBA_LIMIT) 4784 { 4785 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 4786 { 4787 /* case 2 */ 4788 /* WRITE DMA*/ 4789 TI_DBG5(("satWrite6: case 2\n")); 4790 4791 4792 fis->h.fisType = 0x27; /* Reg host to device */ 4793 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4794 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 4795 fis->h.features = 0; /* FIS reserve */ 4796 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 4797 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 4798 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 4799 fis->d.device = 0x40; /* FIS LBA mode */ 4800 fis->d.lbaLowExp = 0; 4801 fis->d.lbaMidExp = 0; 4802 fis->d.lbaHighExp = 0; 4803 fis->d.featuresExp = 0; 4804 if (tl == 0) 4805 { 4806 /* temporary fix */ 4807 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */ 4808 } 4809 else 4810 { 4811 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 4812 } 4813 fis->d.sectorCountExp = 0; 4814 fis->d.reserved4 = 0; 4815 fis->d.control = 0; /* FIS HOB bit clear */ 4816 fis->d.reserved5 = 0; 4817 4818 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 4819 } 4820 else 4821 { 4822 /* case 1 */ 4823 /* WRITE SECTORS for easier implemetation */ 4824 TI_DBG5(("satWrite6: case 1\n")); 4825 4826 fis->h.fisType = 0x27; /* Reg host to device */ 4827 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4828 fis->h.command = SAT_WRITE_SECTORS; /* 0xCA */ 4829 fis->h.features = 0; /* FIS reserve */ 4830 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 4831 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 4832 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 4833 fis->d.device = 0x40; /* FIS LBA mode */ 4834 fis->d.lbaLowExp = 0; 4835 fis->d.lbaMidExp = 0; 4836 fis->d.lbaHighExp = 0; 4837 fis->d.featuresExp = 0; 4838 if (tl == 0) 4839 { 4840 /* temporary fix */ 4841 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */ 4842 } 4843 else 4844 { 4845 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 4846 } 4847 fis->d.sectorCountExp = 0; 4848 fis->d.reserved4 = 0; 4849 fis->d.control = 0; /* FIS HOB bit clear */ 4850 fis->d.reserved5 = 0; 4851 4852 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 4853 4854 } 4855 } 4856 4857 /* case 3 and 4 */ 4858 if (pSatDevData->sat48BitSupport == agTRUE) 4859 { 4860 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 4861 { 4862 /* case 3 */ 4863 /* WRITE DMA EXT only */ 4864 TI_DBG5(("satWrite6: case 3\n")); 4865 fis->h.fisType = 0x27; /* Reg host to device */ 4866 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4867 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 4868 fis->h.features = 0; /* FIS reserve */ 4869 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 4870 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 4871 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 4872 fis->d.device = 0x40; /* FIS LBA mode set */ 4873 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 4874 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4875 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4876 fis->d.featuresExp = 0; /* FIS reserve */ 4877 if (tl == 0) 4878 { 4879 /* sector count is 256, 0x100*/ 4880 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 4881 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */ 4882 } 4883 else 4884 { 4885 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 4886 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 4887 } 4888 fis->d.reserved4 = 0; 4889 fis->d.control = 0; /* FIS HOB bit clear */ 4890 fis->d.reserved5 = 0; 4891 4892 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 4893 } 4894 else 4895 { 4896 /* case 4 */ 4897 /* WRITE SECTORS EXT for easier implemetation */ 4898 TI_DBG5(("satWrite6: case 4\n")); 4899 4900 fis->h.fisType = 0x27; /* Reg host to device */ 4901 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4902 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 4903 fis->h.features = 0; /* FIS reserve */ 4904 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 4905 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 4906 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 4907 fis->d.device = 0x40; /* FIS LBA mode set */ 4908 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 4909 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4910 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4911 fis->d.featuresExp = 0; /* FIS reserve */ 4912 if (tl == 0) 4913 { 4914 /* sector count is 256, 0x100*/ 4915 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 4916 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */ 4917 } 4918 else 4919 { 4920 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 4921 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 4922 } 4923 fis->d.reserved4 = 0; 4924 fis->d.control = 0; /* FIS HOB bit clear */ 4925 fis->d.reserved5 = 0; 4926 4927 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 4928 } 4929 } 4930 4931 /* case 5 */ 4932 if (pSatDevData->satNCQ == agTRUE) 4933 { 4934 /* WRITE FPDMA QUEUED */ 4935 if (pSatDevData->sat48BitSupport != agTRUE) 4936 { 4937 /* sanity check */ 4938 TI_DBG5(("satWrite6: case 5 !!! error NCQ but 28 bit address support \n")); 4939 satSetSensePayload( pSense, 4940 SCSI_SNSKEY_ILLEGAL_REQUEST, 4941 0, 4942 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 4943 satIOContext); 4944 4945 ostiInitiatorIOCompleted( tiRoot, 4946 tiIORequest, 4947 tiIOSuccess, 4948 SCSI_STAT_CHECK_CONDITION, 4949 satIOContext->pTiSenseData, 4950 satIOContext->interruptContext ); 4951 return tiSuccess; 4952 } 4953 TI_DBG5(("satWrite6: case 5\n")); 4954 4955 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 4956 4957 fis->h.fisType = 0x27; /* Reg host to device */ 4958 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4959 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 4960 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 4961 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 4962 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 4963 fis->d.device = 0x40; /* FIS FUA clear */ 4964 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 4965 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4966 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4967 if (tl == 0) 4968 { 4969 /* sector count is 256, 0x100*/ 4970 fis->h.features = 0; /* FIS sector count (7:0) */ 4971 fis->d.featuresExp = 0x01; /* FIS sector count (15:8) */ 4972 } 4973 else 4974 { 4975 fis->h.features = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 4976 fis->d.featuresExp = 0; /* FIS sector count (15:8) */ 4977 } 4978 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 4979 fis->d.sectorCountExp = 0; 4980 fis->d.reserved4 = 0; 4981 fis->d.control = 0; /* FIS HOB bit clear */ 4982 fis->d.reserved5 = 0; 4983 4984 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 4985 } 4986 4987 /* Initialize CB for SATA completion. 4988 */ 4989 satIOContext->satCompleteCB = &satNonChainedDataIOCB; 4990 4991 /* 4992 * Prepare SGL and send FIS to LL layer. 4993 */ 4994 satIOContext->reqType = agRequestType; /* Save it */ 4995 4996 status = sataLLIOStart( tiRoot, 4997 tiIORequest, 4998 tiDeviceHandle, 4999 tiScsiRequest, 5000 satIOContext); 5001 return (status); 5002 } 5003 5004 5005 /*****************************************************************************/ 5006 /*! \brief SAT implementation for SCSI TEST UNIT READY. 5007 * 5008 * SAT implementation for SCSI TUR and send FIS request to LL layer. 5009 * 5010 * \param tiRoot: Pointer to TISA initiator driver/port instance. 5011 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 5012 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 5013 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 5014 * \param satIOContext_t: Pointer to the SAT IO Context 5015 * 5016 * \return If command is started successfully 5017 * - \e tiSuccess: I/O request successfully initiated. 5018 * - \e tiBusy: No resources available, try again later. 5019 * - \e tiIONoDevice: Invalid device handle. 5020 * - \e tiError: Other errors. 5021 */ 5022 /*****************************************************************************/ 5023 GLOBAL bit32 satTestUnitReady( 5024 tiRoot_t *tiRoot, 5025 tiIORequest_t *tiIORequest, 5026 tiDeviceHandle_t *tiDeviceHandle, 5027 tiScsiInitiatorRequest_t *tiScsiRequest, 5028 satIOContext_t *satIOContext) 5029 { 5030 5031 bit32 status; 5032 bit32 agRequestType; 5033 satDeviceData_t *pSatDevData; 5034 scsiRspSense_t *pSense; 5035 tiIniScsiCmnd_t *scsiCmnd; 5036 agsaFisRegHostToDevice_t *fis; 5037 5038 pSense = satIOContext->pSense; 5039 pSatDevData = satIOContext->pSatDevData; 5040 scsiCmnd = &tiScsiRequest->scsiCmnd; 5041 fis = satIOContext->pFis; 5042 5043 TI_DBG6(("satTestUnitReady: entry tiDeviceHandle=%p tiIORequest=%p\n", 5044 tiDeviceHandle, tiIORequest)); 5045 5046 /* checking CONTROL */ 5047 /* NACA == 1 or LINK == 1*/ 5048 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 5049 { 5050 satSetSensePayload( pSense, 5051 SCSI_SNSKEY_ILLEGAL_REQUEST, 5052 0, 5053 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5054 satIOContext); 5055 5056 ostiInitiatorIOCompleted( tiRoot, 5057 tiIORequest, 5058 tiIOSuccess, 5059 SCSI_STAT_CHECK_CONDITION, 5060 satIOContext->pTiSenseData, 5061 satIOContext->interruptContext ); 5062 5063 TI_DBG1(("satTestUnitReady: return control\n")); 5064 return tiSuccess; 5065 } 5066 5067 /* SAT revision 8, 8.11.2, p42*/ 5068 if (pSatDevData->satStopState == agTRUE) 5069 { 5070 satSetSensePayload( pSense, 5071 SCSI_SNSKEY_NOT_READY, 5072 0, 5073 SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED, 5074 satIOContext); 5075 5076 ostiInitiatorIOCompleted( tiRoot, 5077 tiIORequest, 5078 tiIOSuccess, 5079 SCSI_STAT_CHECK_CONDITION, 5080 satIOContext->pTiSenseData, 5081 satIOContext->interruptContext ); 5082 TI_DBG1(("satTestUnitReady: stop state\n")); 5083 return tiSuccess; 5084 } 5085 5086 /* 5087 * Check if format is in progress 5088 */ 5089 5090 if (pSatDevData->satDriveState == SAT_DEV_STATE_FORMAT_IN_PROGRESS) 5091 { 5092 TI_DBG1(("satTestUnitReady() FORMAT_IN_PROGRESS tiDeviceHandle=%p tiIORequest=%p\n", 5093 tiDeviceHandle, tiIORequest)); 5094 5095 satSetSensePayload( pSense, 5096 SCSI_SNSKEY_NOT_READY, 5097 0, 5098 SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_FORMAT_IN_PROGRESS, 5099 satIOContext); 5100 5101 ostiInitiatorIOCompleted( tiRoot, 5102 tiIORequest, 5103 tiIOSuccess, 5104 SCSI_STAT_CHECK_CONDITION, 5105 satIOContext->pTiSenseData, 5106 satIOContext->interruptContext ); 5107 TI_DBG1(("satTestUnitReady: format in progress\n")); 5108 return tiSuccess; 5109 } 5110 5111 /* 5112 check previously issued ATA command 5113 */ 5114 if (pSatDevData->satPendingIO != 0) 5115 { 5116 if (pSatDevData->satDeviceFaultState == agTRUE) 5117 { 5118 satSetSensePayload( pSense, 5119 SCSI_SNSKEY_HARDWARE_ERROR, 5120 0, 5121 SCSI_SNSCODE_LOGICAL_UNIT_FAILURE, 5122 satIOContext); 5123 5124 ostiInitiatorIOCompleted( tiRoot, 5125 tiIORequest, 5126 tiIOSuccess, 5127 SCSI_STAT_CHECK_CONDITION, 5128 satIOContext->pTiSenseData, 5129 satIOContext->interruptContext ); 5130 TI_DBG1(("satTestUnitReady: previous command ended in error\n")); 5131 return tiSuccess; 5132 } 5133 } 5134 /* 5135 check removalbe media feature set 5136 */ 5137 if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled) 5138 { 5139 TI_DBG5(("satTestUnitReady: sending get media status cmnd\n")); 5140 /* send GET MEDIA STATUS command */ 5141 fis->h.fisType = 0x27; /* Reg host to device */ 5142 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5143 fis->h.command = SAT_GET_MEDIA_STATUS; /* 0xDA */ 5144 fis->h.features = 0; /* FIS features NA */ 5145 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 5146 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 5147 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 5148 fis->d.device = 0; /* FIS DEV is discared in SATA */ 5149 fis->d.lbaLowExp = 0; 5150 fis->d.lbaMidExp = 0; 5151 fis->d.lbaHighExp = 0; 5152 fis->d.featuresExp = 0; 5153 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 5154 fis->d.sectorCountExp = 0; 5155 fis->d.reserved4 = 0; 5156 fis->d.control = 0; /* FIS HOB bit clear */ 5157 fis->d.reserved5 = 0; 5158 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 5159 5160 /* Initialize CB for SATA completion. 5161 */ 5162 satIOContext->satCompleteCB = &satTestUnitReadyCB; 5163 5164 /* 5165 * Prepare SGL and send FIS to LL layer. 5166 */ 5167 satIOContext->reqType = agRequestType; /* Save it */ 5168 5169 status = sataLLIOStart( tiRoot, 5170 tiIORequest, 5171 tiDeviceHandle, 5172 tiScsiRequest, 5173 satIOContext); 5174 5175 return (status); 5176 } 5177 /* 5178 number 6) in SAT p42 5179 send ATA CHECK POWER MODE 5180 */ 5181 TI_DBG5(("satTestUnitReady: sending check power mode cmnd\n")); 5182 status = satTestUnitReady_1( tiRoot, 5183 tiIORequest, 5184 tiDeviceHandle, 5185 tiScsiRequest, 5186 satIOContext); 5187 return (status); 5188 } 5189 5190 5191 /*****************************************************************************/ 5192 /*! \brief SAT implementation for SCSI satTestUnitReady_1. 5193 * 5194 * SAT implementation for SCSI satTestUnitReady_1. 5195 * 5196 * \param tiRoot: Pointer to TISA initiator driver/port instance. 5197 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 5198 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 5199 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 5200 * \param satIOContext_t: Pointer to the SAT IO Context 5201 * 5202 * \return If command is started successfully 5203 * - \e tiSuccess: I/O request successfully initiated. 5204 * - \e tiBusy: No resources available, try again later. 5205 * - \e tiIONoDevice: Invalid device handle. 5206 * - \e tiError: Other errors. 5207 */ 5208 /*****************************************************************************/ 5209 GLOBAL bit32 satTestUnitReady_1( 5210 tiRoot_t *tiRoot, 5211 tiIORequest_t *tiIORequest, 5212 tiDeviceHandle_t *tiDeviceHandle, 5213 tiScsiInitiatorRequest_t *tiScsiRequest, 5214 satIOContext_t *satIOContext) 5215 { 5216 /* 5217 sends SAT_CHECK_POWER_MODE as a part of TESTUNITREADY 5218 internally generated - no directly corresponding scsi 5219 called in satIOCompleted as a part of satTestUnitReady(), SAT, revision8, 8.11.2, p42 5220 */ 5221 bit32 status; 5222 bit32 agRequestType; 5223 agsaFisRegHostToDevice_t *fis; 5224 5225 fis = satIOContext->pFis; 5226 5227 TI_DBG5(("satTestUnitReady_1: start\n")); 5228 5229 /* 5230 * Send the ATA CHECK POWER MODE command. 5231 */ 5232 fis->h.fisType = 0x27; /* Reg host to device */ 5233 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5234 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */ 5235 fis->h.features = 0; 5236 fis->d.lbaLow = 0; 5237 fis->d.lbaMid = 0; 5238 fis->d.lbaHigh = 0; 5239 fis->d.device = 0; 5240 fis->d.lbaLowExp = 0; 5241 fis->d.lbaMidExp = 0; 5242 fis->d.lbaHighExp = 0; 5243 fis->d.featuresExp = 0; 5244 fis->d.sectorCount = 0; 5245 fis->d.sectorCountExp = 0; 5246 fis->d.reserved4 = 0; 5247 fis->d.control = 0; /* FIS HOB bit clear */ 5248 fis->d.reserved5 = 0; 5249 5250 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 5251 5252 /* Initialize CB for SATA completion. 5253 */ 5254 satIOContext->satCompleteCB = &satTestUnitReadyCB; 5255 5256 /* 5257 * Prepare SGL and send FIS to LL layer. 5258 */ 5259 satIOContext->reqType = agRequestType; /* Save it */ 5260 5261 status = sataLLIOStart( tiRoot, 5262 tiIORequest, 5263 tiDeviceHandle, 5264 tiScsiRequest, 5265 satIOContext); 5266 5267 TI_DBG5(("satTestUnitReady_1: return\n")); 5268 5269 return status; 5270 } 5271 5272 5273 /*****************************************************************************/ 5274 /*! \brief SAT implementation for SCSI satReportLun. 5275 * 5276 * SAT implementation for SCSI satReportLun. Only LUN0 is reported. 5277 * 5278 * \param tiRoot: Pointer to TISA initiator driver/port instance. 5279 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 5280 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 5281 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 5282 * \param satIOContext_t: Pointer to the SAT IO Context 5283 * 5284 * \return If command is started successfully 5285 * - \e tiSuccess: I/O request successfully initiated. 5286 * - \e tiBusy: No resources available, try again later. 5287 * - \e tiIONoDevice: Invalid device handle. 5288 * - \e tiError: Other errors. 5289 */ 5290 /*****************************************************************************/ 5291 GLOBAL bit32 satReportLun( 5292 tiRoot_t *tiRoot, 5293 tiIORequest_t *tiIORequest, 5294 tiDeviceHandle_t *tiDeviceHandle, 5295 tiScsiInitiatorRequest_t *tiScsiRequest, 5296 satIOContext_t *satIOContext) 5297 { 5298 scsiRspSense_t *pSense; 5299 bit32 allocationLen; 5300 bit32 reportLunLen; 5301 scsiReportLun_t *pReportLun; 5302 tiIniScsiCmnd_t *scsiCmnd; 5303 5304 TI_DBG5(("satReportLun entry: tiDeviceHandle=%p tiIORequest=%p\n", 5305 tiDeviceHandle, tiIORequest)); 5306 5307 pSense = satIOContext->pSense; 5308 pReportLun = (scsiReportLun_t *) tiScsiRequest->sglVirtualAddr; 5309 scsiCmnd = &tiScsiRequest->scsiCmnd; 5310 5311 // tdhexdump("satReportLun cdb", (bit8 *)scsiCmnd, 16); 5312 5313 /* Find the buffer size allocated by Initiator */ 5314 allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) | 5315 (((bit32)scsiCmnd->cdb[7]) << 16) | 5316 (((bit32)scsiCmnd->cdb[8]) << 8 ) | 5317 (((bit32)scsiCmnd->cdb[9]) ); 5318 5319 reportLunLen = 16; /* 8 byte header and 8 bytes of LUN0 */ 5320 5321 if (allocationLen < reportLunLen) 5322 { 5323 TI_DBG1(("satReportLun *** ERROR *** insufficient len=0x%x tiDeviceHandle=%p tiIORequest=%p\n", 5324 reportLunLen, tiDeviceHandle, tiIORequest)); 5325 5326 satSetSensePayload( pSense, 5327 SCSI_SNSKEY_ILLEGAL_REQUEST, 5328 0, 5329 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5330 satIOContext); 5331 5332 ostiInitiatorIOCompleted( tiRoot, 5333 tiIORequest, 5334 tiIOSuccess, 5335 SCSI_STAT_CHECK_CONDITION, 5336 satIOContext->pTiSenseData, 5337 satIOContext->interruptContext ); 5338 return tiSuccess; 5339 5340 } 5341 5342 /* Set length to one entry */ 5343 pReportLun->len[0] = 0; 5344 pReportLun->len[1] = 0; 5345 pReportLun->len[2] = 0; 5346 pReportLun->len[3] = sizeof (tiLUN_t); 5347 5348 pReportLun->reserved = 0; 5349 5350 /* Set to LUN 0: 5351 * - address method to 0x00: Peripheral device addressing method, 5352 * - bus identifier to 0 5353 */ 5354 pReportLun->lunList[0].lun[0] = 0; 5355 pReportLun->lunList[0].lun[1] = 0; 5356 pReportLun->lunList[0].lun[2] = 0; 5357 pReportLun->lunList[0].lun[3] = 0; 5358 pReportLun->lunList[0].lun[4] = 0; 5359 pReportLun->lunList[0].lun[5] = 0; 5360 pReportLun->lunList[0].lun[6] = 0; 5361 pReportLun->lunList[0].lun[7] = 0; 5362 5363 if (allocationLen > reportLunLen) 5364 { 5365 /* underrun */ 5366 TI_DBG1(("satReportLun reporting underrun reportLunLen=0x%x allocationLen=0x%x \n", reportLunLen, allocationLen)); 5367 5368 ostiInitiatorIOCompleted( tiRoot, 5369 tiIORequest, 5370 tiIOUnderRun, 5371 allocationLen - reportLunLen, 5372 agNULL, 5373 satIOContext->interruptContext ); 5374 5375 5376 } 5377 else 5378 { 5379 ostiInitiatorIOCompleted( tiRoot, 5380 tiIORequest, 5381 tiIOSuccess, 5382 SCSI_STAT_GOOD, 5383 agNULL, 5384 satIOContext->interruptContext); 5385 } 5386 return tiSuccess; 5387 } 5388 5389 5390 /*****************************************************************************/ 5391 /*! \brief SAT implementation for SCSI REQUEST SENSE. 5392 * 5393 * SAT implementation for SCSI REQUEST SENSE. 5394 * 5395 * \param tiRoot: Pointer to TISA initiator driver/port instance. 5396 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 5397 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 5398 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 5399 * \param satIOContext_t: Pointer to the SAT IO Context 5400 * 5401 * \return If command is started successfully 5402 * - \e tiSuccess: I/O request successfully initiated. 5403 * - \e tiBusy: No resources available, try again later. 5404 * - \e tiIONoDevice: Invalid device handle. 5405 * - \e tiError: Other errors. 5406 */ 5407 /*****************************************************************************/ 5408 GLOBAL bit32 satRequestSense( 5409 tiRoot_t *tiRoot, 5410 tiIORequest_t *tiIORequest, 5411 tiDeviceHandle_t *tiDeviceHandle, 5412 tiScsiInitiatorRequest_t *tiScsiRequest, 5413 satIOContext_t *satIOContext) 5414 { 5415 /* 5416 SAT Rev 8 p38, Table25 5417 sending SMART RETURN STATUS 5418 Checking SMART Treshold Exceeded Condition is done in satRequestSenseCB() 5419 Only fixed format sense data is support. In other words, we don't support DESC bit is set 5420 in Request Sense 5421 */ 5422 bit32 status; 5423 bit32 agRequestType; 5424 scsiRspSense_t *pSense; 5425 satDeviceData_t *pSatDevData; 5426 tiIniScsiCmnd_t *scsiCmnd; 5427 agsaFisRegHostToDevice_t *fis; 5428 tdIORequestBody_t *tdIORequestBody; 5429 satInternalIo_t *satIntIo = agNULL; 5430 satIOContext_t *satIOContext2; 5431 5432 TI_DBG4(("satRequestSense entry: tiDeviceHandle=%p tiIORequest=%p\n", 5433 tiDeviceHandle, tiIORequest)); 5434 5435 pSense = (scsiRspSense_t *) tiScsiRequest->sglVirtualAddr; 5436 pSatDevData = satIOContext->pSatDevData; 5437 scsiCmnd = &tiScsiRequest->scsiCmnd; 5438 fis = satIOContext->pFis; 5439 5440 TI_DBG4(("satRequestSense: pSatDevData=%p\n", pSatDevData)); 5441 5442 /* checking CONTROL */ 5443 /* NACA == 1 or LINK == 1*/ 5444 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 5445 { 5446 satSetSensePayload( pSense, 5447 SCSI_SNSKEY_ILLEGAL_REQUEST, 5448 0, 5449 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5450 satIOContext); 5451 5452 ostiInitiatorIOCompleted( tiRoot, 5453 tiIORequest, 5454 tiIOSuccess, 5455 SCSI_STAT_CHECK_CONDITION, 5456 satIOContext->pTiSenseData, 5457 satIOContext->interruptContext ); 5458 5459 TI_DBG1(("satRequestSense: return control\n")); 5460 return tiSuccess; 5461 } 5462 5463 /* 5464 Only fixed format sense data is support. In other words, we don't support DESC bit is set 5465 in Request Sense 5466 */ 5467 if ( scsiCmnd->cdb[1] & ATA_REMOVABLE_MEDIA_DEVICE_MASK ) 5468 { 5469 satSetSensePayload( pSense, 5470 SCSI_SNSKEY_ILLEGAL_REQUEST, 5471 0, 5472 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5473 satIOContext); 5474 5475 ostiInitiatorIOCompleted( tiRoot, 5476 tiIORequest, 5477 tiIOSuccess, 5478 SCSI_STAT_CHECK_CONDITION, 5479 satIOContext->pTiSenseData, 5480 satIOContext->interruptContext ); 5481 5482 TI_DBG1(("satRequestSense: DESC bit is set, which we don't support\n")); 5483 return tiSuccess; 5484 } 5485 5486 5487 if (pSatDevData->satSMARTEnabled == agTRUE) 5488 { 5489 /* sends SMART RETURN STATUS */ 5490 fis->h.fisType = 0x27; /* Reg host to device */ 5491 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5492 5493 fis->h.command = SAT_SMART_RETURN_STATUS; /* 0xB0 */ 5494 fis->h.features = 0xDA; /* FIS features */ 5495 fis->d.featuresExp = 0; /* FIS reserve */ 5496 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 5497 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 5498 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 5499 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 5500 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 5501 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 5502 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 5503 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 5504 fis->d.device = 0; /* FIS DEV is discared in SATA */ 5505 fis->d.control = 0; /* FIS HOB bit clear */ 5506 fis->d.reserved4 = 0; 5507 fis->d.reserved5 = 0; 5508 5509 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 5510 /* Initialize CB for SATA completion. 5511 */ 5512 satIOContext->satCompleteCB = &satRequestSenseCB; 5513 5514 /* 5515 * Prepare SGL and send FIS to LL layer. 5516 */ 5517 satIOContext->reqType = agRequestType; /* Save it */ 5518 5519 status = sataLLIOStart( tiRoot, 5520 tiIORequest, 5521 tiDeviceHandle, 5522 tiScsiRequest, 5523 satIOContext); 5524 5525 TI_DBG4(("satRequestSense: if return, status %d\n", status)); 5526 return (status); 5527 } 5528 else 5529 { 5530 /*allocate iocontext for xmitting xmit SAT_CHECK_POWER_MODE 5531 then call satRequestSense2 */ 5532 5533 TI_DBG4(("satRequestSense: before satIntIo %p\n", satIntIo)); 5534 /* allocate iocontext */ 5535 satIntIo = satAllocIntIoResource( tiRoot, 5536 tiIORequest, /* original request */ 5537 pSatDevData, 5538 tiScsiRequest->scsiCmnd.expDataLength, 5539 satIntIo); 5540 5541 TI_DBG4(("satRequestSense: after satIntIo %p\n", satIntIo)); 5542 5543 if (satIntIo == agNULL) 5544 { 5545 /* memory allocation failure */ 5546 satFreeIntIoResource( tiRoot, 5547 pSatDevData, 5548 satIntIo); 5549 5550 /* failed during sending SMART RETURN STATUS */ 5551 satSetSensePayload( pSense, 5552 SCSI_SNSKEY_NO_SENSE, 5553 0, 5554 SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE, 5555 satIOContext); 5556 5557 ostiInitiatorIOCompleted( tiRoot, 5558 tiIORequest, 5559 tiIOSuccess, 5560 SCSI_STAT_GOOD, 5561 agNULL, 5562 satIOContext->interruptContext ); 5563 5564 TI_DBG4(("satRequestSense: else fail 1\n")); 5565 return tiSuccess; 5566 } /* end of memory allocation failure */ 5567 5568 5569 /* 5570 * Need to initialize all the fields within satIOContext except 5571 * reqType and satCompleteCB which will be set depending on cmd. 5572 */ 5573 5574 if (satIntIo == agNULL) 5575 { 5576 TI_DBG4(("satRequestSense: satIntIo is NULL\n")); 5577 } 5578 else 5579 { 5580 TI_DBG4(("satRequestSense: satIntIo is NOT NULL\n")); 5581 } 5582 /* use this --- tttttthe one the same */ 5583 5584 5585 satIntIo->satOrgTiIORequest = tiIORequest; 5586 tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody; 5587 satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext); 5588 5589 satIOContext2->pSatDevData = pSatDevData; 5590 satIOContext2->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 5591 satIOContext2->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd); 5592 satIOContext2->pSense = &(tdIORequestBody->transport.SATA.sensePayload); 5593 satIOContext2->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData); 5594 satIOContext2->pTiSenseData->senseData = satIOContext2->pSense; 5595 satIOContext2->tiRequestBody = satIntIo->satIntRequestBody; 5596 satIOContext2->interruptContext = satIOContext->interruptContext; 5597 satIOContext2->satIntIoContext = satIntIo; 5598 satIOContext2->ptiDeviceHandle = tiDeviceHandle; 5599 satIOContext2->satOrgIOContext = satIOContext; 5600 5601 TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.len %d\n", satIntIo->satIntTiScsiXchg.agSgl1.len)); 5602 5603 TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.upper %d\n", satIntIo->satIntTiScsiXchg.agSgl1.upper)); 5604 5605 TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.lower %d\n", satIntIo->satIntTiScsiXchg.agSgl1.lower)); 5606 5607 TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.type %d\n", satIntIo->satIntTiScsiXchg.agSgl1.type)); 5608 5609 status = satRequestSense_1( tiRoot, 5610 &(satIntIo->satIntTiIORequest), 5611 tiDeviceHandle, 5612 &(satIntIo->satIntTiScsiXchg), 5613 satIOContext2); 5614 5615 if (status != tiSuccess) 5616 { 5617 satFreeIntIoResource( tiRoot, 5618 pSatDevData, 5619 satIntIo); 5620 5621 /* failed during sending SMART RETURN STATUS */ 5622 satSetSensePayload( pSense, 5623 SCSI_SNSKEY_NO_SENSE, 5624 0, 5625 SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE, 5626 satIOContext); 5627 5628 ostiInitiatorIOCompleted( tiRoot, 5629 tiIORequest, 5630 tiIOSuccess, 5631 SCSI_STAT_CHECK_CONDITION, 5632 agNULL, 5633 satIOContext->interruptContext ); 5634 5635 TI_DBG1(("satRequestSense: else fail 2\n")); 5636 return tiSuccess; 5637 } 5638 TI_DBG4(("satRequestSense: else return success\n")); 5639 return tiSuccess; 5640 } 5641 } 5642 5643 5644 /*****************************************************************************/ 5645 /*! \brief SAT implementation for SCSI REQUEST SENSE. 5646 * 5647 * SAT implementation for SCSI REQUEST SENSE. 5648 * Sub function of satRequestSense 5649 * 5650 * \param tiRoot: Pointer to TISA initiator driver/port instance. 5651 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 5652 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 5653 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 5654 * \param satIOContext_t: Pointer to the SAT IO Context 5655 * 5656 * \return If command is started successfully 5657 * - \e tiSuccess: I/O request successfully initiated. 5658 * - \e tiBusy: No resources available, try again later. 5659 * - \e tiIONoDevice: Invalid device handle. 5660 * - \e tiError: Other errors. 5661 */ 5662 /*****************************************************************************/ 5663 GLOBAL bit32 satRequestSense_1( 5664 tiRoot_t *tiRoot, 5665 tiIORequest_t *tiIORequest, 5666 tiDeviceHandle_t *tiDeviceHandle, 5667 tiScsiInitiatorRequest_t *tiScsiRequest, 5668 satIOContext_t *satIOContext) 5669 { 5670 /* 5671 sends SAT_CHECK_POWER_MODE 5672 */ 5673 bit32 status; 5674 bit32 agRequestType; 5675 agsaFisRegHostToDevice_t *fis; 5676 5677 TI_DBG4(("satRequestSense_1 entry: tiDeviceHandle=%p tiIORequest=%p\n", 5678 tiDeviceHandle, tiIORequest)); 5679 5680 fis = satIOContext->pFis; 5681 /* 5682 * Send the ATA CHECK POWER MODE command. 5683 */ 5684 fis->h.fisType = 0x27; /* Reg host to device */ 5685 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5686 5687 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */ 5688 fis->h.features = 0; 5689 fis->d.lbaLow = 0; 5690 fis->d.lbaMid = 0; 5691 fis->d.lbaHigh = 0; 5692 fis->d.device = 0; 5693 fis->d.lbaLowExp = 0; 5694 fis->d.lbaMidExp = 0; 5695 fis->d.lbaHighExp = 0; 5696 fis->d.featuresExp = 0; 5697 fis->d.sectorCount = 0; 5698 fis->d.sectorCountExp = 0; 5699 fis->d.reserved4 = 0; 5700 fis->d.control = 0; /* FIS HOB bit clear */ 5701 fis->d.reserved5 = 0; 5702 5703 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 5704 5705 /* Initialize CB for SATA completion. 5706 */ 5707 satIOContext->satCompleteCB = &satRequestSenseCB; 5708 5709 /* 5710 * Prepare SGL and send FIS to LL layer. 5711 */ 5712 satIOContext->reqType = agRequestType; /* Save it */ 5713 5714 5715 TI_DBG4(("satRequestSense_1: agSgl1.len %d\n", tiScsiRequest->agSgl1.len)); 5716 5717 TI_DBG4(("satRequestSense_1: agSgl1.upper %d\n", tiScsiRequest->agSgl1.upper)); 5718 5719 TI_DBG4(("satRequestSense_1: agSgl1.lower %d\n", tiScsiRequest->agSgl1.lower)); 5720 5721 TI_DBG4(("satRequestSense_1: agSgl1.type %d\n", tiScsiRequest->agSgl1.type)); 5722 5723 // tdhexdump("satRequestSense_1", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t)); 5724 5725 status = sataLLIOStart( tiRoot, 5726 tiIORequest, 5727 tiDeviceHandle, 5728 tiScsiRequest, 5729 satIOContext); 5730 5731 5732 5733 return status; 5734 } 5735 5736 5737 /*****************************************************************************/ 5738 /*! \brief SAT implementation for SCSI INQUIRY. 5739 * 5740 * SAT implementation for SCSI INQUIRY. 5741 * 5742 * \param tiRoot: Pointer to TISA initiator driver/port instance. 5743 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 5744 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 5745 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 5746 * \param satIOContext_t: Pointer to the SAT IO Context 5747 * 5748 * \return If command is started successfully 5749 * - \e tiSuccess: I/O request successfully initiated. 5750 * - \e tiBusy: No resources available, try again later. 5751 * - \e tiIONoDevice: Invalid device handle. 5752 * - \e tiError: Other errors. 5753 */ 5754 /*****************************************************************************/ 5755 GLOBAL bit32 satInquiry( 5756 tiRoot_t *tiRoot, 5757 tiIORequest_t *tiIORequest, 5758 tiDeviceHandle_t *tiDeviceHandle, 5759 tiScsiInitiatorRequest_t *tiScsiRequest, 5760 satIOContext_t *satIOContext) 5761 { 5762 /* 5763 CMDDT bit is obsolete in SPC-3 and this is assumed in SAT revision 8 5764 */ 5765 scsiRspSense_t *pSense; 5766 tiIniScsiCmnd_t *scsiCmnd; 5767 satDeviceData_t *pSatDevData; 5768 bit32 status; 5769 5770 TI_DBG5(("satInquiry: start\n")); 5771 TI_DBG5(("satInquiry entry: tiDeviceHandle=%p tiIORequest=%p\n", 5772 tiDeviceHandle, tiIORequest)); 5773 pSense = satIOContext->pSense; 5774 scsiCmnd = &tiScsiRequest->scsiCmnd; 5775 pSatDevData = satIOContext->pSatDevData; 5776 TI_DBG5(("satInquiry: pSatDevData=%p\n", pSatDevData)); 5777 //tdhexdump("satInquiry", (bit8 *)scsiCmnd->cdb, 6); 5778 /* checking CONTROL */ 5779 /* NACA == 1 or LINK == 1*/ 5780 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 5781 { 5782 satSetSensePayload( pSense, 5783 SCSI_SNSKEY_ILLEGAL_REQUEST, 5784 0, 5785 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5786 satIOContext); 5787 ostiInitiatorIOCompleted( tiRoot, 5788 tiIORequest, 5789 tiIOSuccess, 5790 SCSI_STAT_CHECK_CONDITION, 5791 satIOContext->pTiSenseData, 5792 satIOContext->interruptContext ); 5793 TI_DBG2(("satInquiry: return control\n")); 5794 return tiSuccess; 5795 } 5796 5797 /* checking EVPD and Allocation Length */ 5798 /* SPC-4 spec 6.4 p141 */ 5799 /* EVPD bit == 0 && PAGE CODE != 0 */ 5800 if ( !(scsiCmnd->cdb[1] & SCSI_EVPD_MASK) && 5801 (scsiCmnd->cdb[2] != 0) 5802 ) 5803 { 5804 satSetSensePayload( pSense, 5805 SCSI_SNSKEY_ILLEGAL_REQUEST, 5806 0, 5807 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5808 satIOContext); 5809 ostiInitiatorIOCompleted( tiRoot, 5810 tiIORequest, 5811 tiIOSuccess, 5812 SCSI_STAT_CHECK_CONDITION, 5813 satIOContext->pTiSenseData, 5814 satIOContext->interruptContext ); 5815 TI_DBG1(("satInquiry: return EVPD and PAGE CODE\n")); 5816 return tiSuccess; 5817 } 5818 TI_DBG6(("satInquiry: allocation length 0x%x %d\n", ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4], ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4])); 5819 5820 /* convert OS IO to TD internal IO */ 5821 if ( pSatDevData->IDDeviceValid == agFALSE) 5822 { 5823 status = satStartIDDev( 5824 tiRoot, 5825 tiIORequest, 5826 tiDeviceHandle, 5827 tiScsiRequest, 5828 satIOContext 5829 ); 5830 TI_DBG6(("satInquiry: end status %d\n", status)); 5831 return status; 5832 } 5833 else 5834 { 5835 TI_DBG6(("satInquiry: calling satInquiryIntCB\n")); 5836 satInquiryIntCB( 5837 tiRoot, 5838 tiIORequest, 5839 tiDeviceHandle, 5840 tiScsiRequest, 5841 satIOContext 5842 ); 5843 5844 return tiSuccess; 5845 } 5846 5847 } 5848 5849 5850 /*****************************************************************************/ 5851 /*! \brief SAT implementation for SCSI satReadCapacity10. 5852 * 5853 * SAT implementation for SCSI satReadCapacity10. 5854 * 5855 * \param tiRoot: Pointer to TISA initiator driver/port instance. 5856 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 5857 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 5858 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 5859 * \param satIOContext_t: Pointer to the SAT IO Context 5860 * 5861 * \return If command is started successfully 5862 * - \e tiSuccess: I/O request successfully initiated. 5863 * - \e tiBusy: No resources available, try again later. 5864 * - \e tiIONoDevice: Invalid device handle. 5865 * - \e tiError: Other errors. 5866 */ 5867 /*****************************************************************************/ 5868 GLOBAL bit32 satReadCapacity10( 5869 tiRoot_t *tiRoot, 5870 tiIORequest_t *tiIORequest, 5871 tiDeviceHandle_t *tiDeviceHandle, 5872 tiScsiInitiatorRequest_t *tiScsiRequest, 5873 satIOContext_t *satIOContext) 5874 { 5875 scsiRspSense_t *pSense; 5876 tiIniScsiCmnd_t *scsiCmnd; 5877 bit8 *pVirtAddr; 5878 satDeviceData_t *pSatDevData; 5879 agsaSATAIdentifyData_t *pSATAIdData; 5880 bit32 lastLba; 5881 bit32 word117_118; 5882 bit32 word117; 5883 bit32 word118; 5884 TI_DBG5(("satReadCapacity10: start: tiDeviceHandle=%p tiIORequest=%p\n", 5885 tiDeviceHandle, tiIORequest)); 5886 5887 pSense = satIOContext->pSense; 5888 pVirtAddr = (bit8 *) tiScsiRequest->sglVirtualAddr; 5889 scsiCmnd = &tiScsiRequest->scsiCmnd; 5890 pSatDevData = satIOContext->pSatDevData; 5891 pSATAIdData = &pSatDevData->satIdentifyData; 5892 5893 5894 /* checking CONTROL */ 5895 /* NACA == 1 or LINK == 1*/ 5896 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 5897 { 5898 satSetSensePayload( pSense, 5899 SCSI_SNSKEY_ILLEGAL_REQUEST, 5900 0, 5901 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5902 satIOContext); 5903 5904 ostiInitiatorIOCompleted( tiRoot, 5905 tiIORequest, 5906 tiIOSuccess, 5907 SCSI_STAT_CHECK_CONDITION, 5908 satIOContext->pTiSenseData, 5909 satIOContext->interruptContext ); 5910 5911 TI_DBG1(("satReadCapacity10: return control\n")); 5912 return tiSuccess; 5913 } 5914 5915 5916 /* 5917 * If Logical block address is not set to zero, return error 5918 */ 5919 if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5])) 5920 { 5921 TI_DBG1(("satReadCapacity10 *** ERROR *** logical address non zero, tiDeviceHandle=%p tiIORequest=%p\n", 5922 tiDeviceHandle, tiIORequest)); 5923 5924 satSetSensePayload( pSense, 5925 SCSI_SNSKEY_ILLEGAL_REQUEST, 5926 0, 5927 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5928 satIOContext); 5929 5930 ostiInitiatorIOCompleted( tiRoot, 5931 tiIORequest, 5932 tiIOSuccess, 5933 SCSI_STAT_CHECK_CONDITION, 5934 satIOContext->pTiSenseData, 5935 satIOContext->interruptContext ); 5936 return tiSuccess; 5937 5938 } 5939 5940 /* 5941 * If PMI bit is not zero, return error 5942 */ 5943 if ( ((scsiCmnd->cdb[8]) & SCSI_READ_CAPACITY10_PMI_MASK) != 0 ) 5944 { 5945 TI_DBG1(("satReadCapacity10 *** ERROR *** PMI is not zero, tiDeviceHandle=%p tiIORequest=%p\n", 5946 tiDeviceHandle, tiIORequest)); 5947 5948 satSetSensePayload( pSense, 5949 SCSI_SNSKEY_ILLEGAL_REQUEST, 5950 0, 5951 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5952 satIOContext); 5953 5954 ostiInitiatorIOCompleted( tiRoot, 5955 tiIORequest, 5956 tiIOSuccess, 5957 SCSI_STAT_CHECK_CONDITION, 5958 satIOContext->pTiSenseData, 5959 satIOContext->interruptContext ); 5960 return tiSuccess; 5961 5962 } 5963 5964 /* 5965 filling in Read Capacity parameter data 5966 saved identify device has been already flipped 5967 See ATA spec p125 and p136 and SBC spec p54 5968 */ 5969 /* 5970 * If 48-bit addressing is supported, set capacity information from Identify 5971 * Device Word 100-103. 5972 */ 5973 if (pSatDevData->sat48BitSupport == agTRUE) 5974 { 5975 /* 5976 * Setting RETURNED LOGICAL BLOCK ADDRESS in READ CAPACITY(10) response data: 5977 * SBC-2 specifies that if the capacity exceeded the 4-byte RETURNED LOGICAL 5978 * BLOCK ADDRESS in READ CAPACITY(10) parameter data, the RETURNED LOGICAL 5979 * BLOCK ADDRESS should be set to 0xFFFFFFFF so the application client would 5980 * then issue a READ CAPACITY(16) command. 5981 */ 5982 /* ATA Identify Device information word 100 - 103 */ 5983 if ( (pSATAIdData->maxLBA32_47 != 0 ) || (pSATAIdData->maxLBA48_63 != 0)) 5984 { 5985 pVirtAddr[0] = 0xFF; /* MSB number of block */ 5986 pVirtAddr[1] = 0xFF; 5987 pVirtAddr[2] = 0xFF; 5988 pVirtAddr[3] = 0xFF; /* LSB number of block */ 5989 TI_DBG1(("satReadCapacity10: returns 0xFFFFFFFF\n")); 5990 } 5991 else /* Fit the Readcapacity10 4-bytes response length */ 5992 { 5993 lastLba = (((pSATAIdData->maxLBA16_31) << 16) ) | 5994 (pSATAIdData->maxLBA0_15); 5995 lastLba = lastLba - 1; /* LBA starts from zero */ 5996 5997 /* 5998 for testing 5999 lastLba = lastLba - (512*10) - 1; 6000 */ 6001 6002 6003 pVirtAddr[0] = (bit8)((lastLba >> 24) & 0xFF); /* MSB */ 6004 pVirtAddr[1] = (bit8)((lastLba >> 16) & 0xFF); 6005 pVirtAddr[2] = (bit8)((lastLba >> 8) & 0xFF); 6006 pVirtAddr[3] = (bit8)((lastLba ) & 0xFF); /* LSB */ 6007 6008 TI_DBG3(("satReadCapacity10: lastLba is 0x%x %d\n", lastLba, lastLba)); 6009 TI_DBG3(("satReadCapacity10: LBA 0 is 0x%x %d\n", pVirtAddr[0], pVirtAddr[0])); 6010 TI_DBG3(("satReadCapacity10: LBA 1 is 0x%x %d\n", pVirtAddr[1], pVirtAddr[1])); 6011 TI_DBG3(("satReadCapacity10: LBA 2 is 0x%x %d\n", pVirtAddr[2], pVirtAddr[2])); 6012 TI_DBG3(("satReadCapacity10: LBA 3 is 0x%x %d\n", pVirtAddr[3], pVirtAddr[3])); 6013 6014 } 6015 } 6016 6017 /* 6018 * For 28-bit addressing, set capacity information from Identify 6019 * Device Word 60-61. 6020 */ 6021 else 6022 { 6023 /* ATA Identify Device information word 60 - 61 */ 6024 lastLba = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) | 6025 (pSATAIdData->numOfUserAddressableSectorsLo); 6026 lastLba = lastLba - 1; /* LBA starts from zero */ 6027 6028 pVirtAddr[0] = (bit8)((lastLba >> 24) & 0xFF); /* MSB */ 6029 pVirtAddr[1] = (bit8)((lastLba >> 16) & 0xFF); 6030 pVirtAddr[2] = (bit8)((lastLba >> 8) & 0xFF); 6031 pVirtAddr[3] = (bit8)((lastLba ) & 0xFF); /* LSB */ 6032 } 6033 /* SAT Rev 8d */ 6034 if (((pSATAIdData->word104_107[2]) & 0x1000) == 0) 6035 { 6036 TI_DBG5(("satReadCapacity10: Default Block Length is 512\n")); 6037 /* 6038 * Set the block size, fixed at 512 bytes. 6039 */ 6040 pVirtAddr[4] = 0x00; /* MSB block size in bytes */ 6041 pVirtAddr[5] = 0x00; 6042 pVirtAddr[6] = 0x02; 6043 pVirtAddr[7] = 0x00; /* LSB block size in bytes */ 6044 } 6045 else 6046 { 6047 word118 = pSATAIdData->word112_126[6]; 6048 word117 = pSATAIdData->word112_126[5]; 6049 6050 word117_118 = (word118 << 16) + word117; 6051 word117_118 = word117_118 * 2; 6052 pVirtAddr[4] = (bit8)((word117_118 >> 24) & 0xFF); /* MSB block size in bytes */ 6053 pVirtAddr[5] = (bit8)((word117_118 >> 16) & 0xFF); 6054 pVirtAddr[6] = (bit8)((word117_118 >> 8) & 0xFF); 6055 pVirtAddr[7] = (bit8)(word117_118 & 0xFF); /* LSB block size in bytes */ 6056 6057 TI_DBG1(("satReadCapacity10: Nondefault word118 %d 0x%x \n", word118, word118)); 6058 TI_DBG1(("satReadCapacity10: Nondefault word117 %d 0x%x \n", word117, word117)); 6059 TI_DBG1(("satReadCapacity10: Nondefault Block Length is %d 0x%x \n",word117_118, word117_118)); 6060 6061 } 6062 6063 /* fill in MAX LBA, which is used in satSendDiagnostic_1() */ 6064 pSatDevData->satMaxLBA[0] = 0; /* MSB */ 6065 pSatDevData->satMaxLBA[1] = 0; 6066 pSatDevData->satMaxLBA[2] = 0; 6067 pSatDevData->satMaxLBA[3] = 0; 6068 pSatDevData->satMaxLBA[4] = pVirtAddr[0]; 6069 pSatDevData->satMaxLBA[5] = pVirtAddr[1]; 6070 pSatDevData->satMaxLBA[6] = pVirtAddr[2]; 6071 pSatDevData->satMaxLBA[7] = pVirtAddr[3]; /* LSB */ 6072 6073 6074 TI_DBG4(("satReadCapacity10 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , tiDeviceHandle=%p tiIORequest=%p\n", 6075 pVirtAddr[0], pVirtAddr[1], pVirtAddr[2], pVirtAddr[3], 6076 pVirtAddr[4], pVirtAddr[5], pVirtAddr[6], pVirtAddr[7], 6077 tiDeviceHandle, tiIORequest)); 6078 6079 6080 /* 6081 * Send the completion response now. 6082 */ 6083 ostiInitiatorIOCompleted( tiRoot, 6084 tiIORequest, 6085 tiIOSuccess, 6086 SCSI_STAT_GOOD, 6087 agNULL, 6088 satIOContext->interruptContext); 6089 return tiSuccess; 6090 } 6091 6092 6093 /*****************************************************************************/ 6094 /*! \brief SAT implementation for SCSI satReadCapacity16. 6095 * 6096 * SAT implementation for SCSI satReadCapacity16. 6097 * 6098 * \param tiRoot: Pointer to TISA initiator driver/port instance. 6099 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 6100 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 6101 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 6102 * \param satIOContext_t: Pointer to the SAT IO Context 6103 * 6104 * \return If command is started successfully 6105 * - \e tiSuccess: I/O request successfully initiated. 6106 * - \e tiBusy: No resources available, try again later. 6107 * - \e tiIONoDevice: Invalid device handle. 6108 * - \e tiError: Other errors. 6109 */ 6110 /*****************************************************************************/ 6111 GLOBAL bit32 satReadCapacity16( 6112 tiRoot_t *tiRoot, 6113 tiIORequest_t *tiIORequest, 6114 tiDeviceHandle_t *tiDeviceHandle, 6115 tiScsiInitiatorRequest_t *tiScsiRequest, 6116 satIOContext_t *satIOContext) 6117 { 6118 6119 scsiRspSense_t *pSense; 6120 tiIniScsiCmnd_t *scsiCmnd; 6121 bit8 *pVirtAddr; 6122 satDeviceData_t *pSatDevData; 6123 agsaSATAIdentifyData_t *pSATAIdData; 6124 bit32 lastLbaLo; 6125 bit32 allocationLen; 6126 bit32 readCapacityLen = 32; 6127 bit32 i = 0; 6128 TI_DBG5(("satReadCapacity16 start: tiDeviceHandle=%p tiIORequest=%p\n", 6129 tiDeviceHandle, tiIORequest)); 6130 6131 pSense = satIOContext->pSense; 6132 pVirtAddr = (bit8 *) tiScsiRequest->sglVirtualAddr; 6133 scsiCmnd = &tiScsiRequest->scsiCmnd; 6134 pSatDevData = satIOContext->pSatDevData; 6135 pSATAIdData = &pSatDevData->satIdentifyData; 6136 6137 /* Find the buffer size allocated by Initiator */ 6138 allocationLen = (((bit32)scsiCmnd->cdb[10]) << 24) | 6139 (((bit32)scsiCmnd->cdb[11]) << 16) | 6140 (((bit32)scsiCmnd->cdb[12]) << 8 ) | 6141 (((bit32)scsiCmnd->cdb[13]) ); 6142 6143 6144 if (allocationLen < readCapacityLen) 6145 { 6146 TI_DBG1(("satReadCapacity16 *** ERROR *** insufficient len=0x%x readCapacityLen=0x%x\n", allocationLen, readCapacityLen)); 6147 6148 satSetSensePayload( pSense, 6149 SCSI_SNSKEY_ILLEGAL_REQUEST, 6150 0, 6151 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6152 satIOContext); 6153 6154 ostiInitiatorIOCompleted( tiRoot, 6155 tiIORequest, 6156 tiIOSuccess, 6157 SCSI_STAT_CHECK_CONDITION, 6158 satIOContext->pTiSenseData, 6159 satIOContext->interruptContext ); 6160 return tiSuccess; 6161 6162 } 6163 6164 /* checking CONTROL */ 6165 /* NACA == 1 or LINK == 1*/ 6166 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 6167 { 6168 satSetSensePayload( pSense, 6169 SCSI_SNSKEY_ILLEGAL_REQUEST, 6170 0, 6171 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6172 satIOContext); 6173 6174 ostiInitiatorIOCompleted( tiRoot, 6175 tiIORequest, 6176 tiIOSuccess, 6177 SCSI_STAT_CHECK_CONDITION, 6178 satIOContext->pTiSenseData, 6179 satIOContext->interruptContext ); 6180 6181 TI_DBG1(("satReadCapacity16: return control\n")); 6182 return tiSuccess; 6183 } 6184 6185 /* 6186 * If Logical blcok address is not set to zero, return error 6187 */ 6188 if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]) || 6189 (scsiCmnd->cdb[6] || scsiCmnd->cdb[7] || scsiCmnd->cdb[8] || scsiCmnd->cdb[9]) ) 6190 { 6191 TI_DBG1(("satReadCapacity16 *** ERROR *** logical address non zero, tiDeviceHandle=%p tiIORequest=%p\n", 6192 tiDeviceHandle, tiIORequest)); 6193 6194 satSetSensePayload( pSense, 6195 SCSI_SNSKEY_ILLEGAL_REQUEST, 6196 0, 6197 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6198 satIOContext); 6199 6200 ostiInitiatorIOCompleted( tiRoot, 6201 tiIORequest, 6202 tiIOSuccess, 6203 SCSI_STAT_CHECK_CONDITION, 6204 satIOContext->pTiSenseData, 6205 satIOContext->interruptContext ); 6206 return tiSuccess; 6207 6208 } 6209 6210 /* 6211 * If PMI bit is not zero, return error 6212 */ 6213 if ( ((scsiCmnd->cdb[14]) & SCSI_READ_CAPACITY16_PMI_MASK) != 0 ) 6214 { 6215 TI_DBG1(("satReadCapacity16 *** ERROR *** PMI is not zero, tiDeviceHandle=%p tiIORequest=%p\n", 6216 tiDeviceHandle, tiIORequest)); 6217 6218 satSetSensePayload( pSense, 6219 SCSI_SNSKEY_ILLEGAL_REQUEST, 6220 0, 6221 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6222 satIOContext); 6223 6224 ostiInitiatorIOCompleted( tiRoot, 6225 tiIORequest, 6226 tiIOSuccess, 6227 SCSI_STAT_CHECK_CONDITION, 6228 satIOContext->pTiSenseData, 6229 satIOContext->interruptContext ); 6230 return tiSuccess; 6231 6232 } 6233 6234 /* 6235 filling in Read Capacity parameter data 6236 */ 6237 6238 /* 6239 * If 48-bit addressing is supported, set capacity information from Identify 6240 * Device Word 100-103. 6241 */ 6242 if (pSatDevData->sat48BitSupport == agTRUE) 6243 { 6244 pVirtAddr[0] = (bit8)(((pSATAIdData->maxLBA48_63) >> 8) & 0xff); /* MSB */ 6245 pVirtAddr[1] = (bit8)((pSATAIdData->maxLBA48_63) & 0xff); 6246 pVirtAddr[2] = (bit8)(((pSATAIdData->maxLBA32_47) >> 8) & 0xff); 6247 pVirtAddr[3] = (bit8)((pSATAIdData->maxLBA32_47) & 0xff); 6248 6249 lastLbaLo = (((pSATAIdData->maxLBA16_31) << 16) ) | (pSATAIdData->maxLBA0_15); 6250 lastLbaLo = lastLbaLo - 1; /* LBA starts from zero */ 6251 6252 pVirtAddr[4] = (bit8)((lastLbaLo >> 24) & 0xFF); 6253 pVirtAddr[5] = (bit8)((lastLbaLo >> 16) & 0xFF); 6254 pVirtAddr[6] = (bit8)((lastLbaLo >> 8) & 0xFF); 6255 pVirtAddr[7] = (bit8)((lastLbaLo ) & 0xFF); /* LSB */ 6256 6257 } 6258 6259 /* 6260 * For 28-bit addressing, set capacity information from Identify 6261 * Device Word 60-61. 6262 */ 6263 else 6264 { 6265 pVirtAddr[0] = 0; /* MSB */ 6266 pVirtAddr[1] = 0; 6267 pVirtAddr[2] = 0; 6268 pVirtAddr[3] = 0; 6269 6270 lastLbaLo = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) | 6271 (pSATAIdData->numOfUserAddressableSectorsLo); 6272 lastLbaLo = lastLbaLo - 1; /* LBA starts from zero */ 6273 6274 pVirtAddr[4] = (bit8)((lastLbaLo >> 24) & 0xFF); 6275 pVirtAddr[5] = (bit8)((lastLbaLo >> 16) & 0xFF); 6276 pVirtAddr[6] = (bit8)((lastLbaLo >> 8) & 0xFF); 6277 pVirtAddr[7] = (bit8)((lastLbaLo ) & 0xFF); /* LSB */ 6278 6279 } 6280 6281 /* 6282 * Set the block size, fixed at 512 bytes. 6283 */ 6284 pVirtAddr[8] = 0x00; /* MSB block size in bytes */ 6285 pVirtAddr[9] = 0x00; 6286 pVirtAddr[10] = 0x02; 6287 pVirtAddr[11] = 0x00; /* LSB block size in bytes */ 6288 6289 6290 /* fill in MAX LBA, which is used in satSendDiagnostic_1() */ 6291 pSatDevData->satMaxLBA[0] = pVirtAddr[0]; /* MSB */ 6292 pSatDevData->satMaxLBA[1] = pVirtAddr[1]; 6293 pSatDevData->satMaxLBA[2] = pVirtAddr[2]; 6294 pSatDevData->satMaxLBA[3] = pVirtAddr[3]; 6295 pSatDevData->satMaxLBA[4] = pVirtAddr[4]; 6296 pSatDevData->satMaxLBA[5] = pVirtAddr[5]; 6297 pSatDevData->satMaxLBA[6] = pVirtAddr[6]; 6298 pSatDevData->satMaxLBA[7] = pVirtAddr[7]; /* LSB */ 6299 6300 TI_DBG5(("satReadCapacity16 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , tiDeviceHandle=%p tiIORequest=%p\n", 6301 pVirtAddr[0], pVirtAddr[1], pVirtAddr[2], pVirtAddr[3], 6302 pVirtAddr[4], pVirtAddr[5], pVirtAddr[6], pVirtAddr[7], 6303 pVirtAddr[8], pVirtAddr[9], pVirtAddr[10], pVirtAddr[11], 6304 tiDeviceHandle, tiIORequest)); 6305 6306 for(i=12;i<=31;i++) 6307 { 6308 pVirtAddr[i] = 0x00; 6309 } 6310 6311 /* 6312 * Send the completion response now. 6313 */ 6314 if (allocationLen > readCapacityLen) 6315 { 6316 /* underrun */ 6317 TI_DBG1(("satReadCapacity16 reporting underrun readCapacityLen=0x%x allocationLen=0x%x \n", readCapacityLen, allocationLen)); 6318 6319 ostiInitiatorIOCompleted( tiRoot, 6320 tiIORequest, 6321 tiIOUnderRun, 6322 allocationLen - readCapacityLen, 6323 agNULL, 6324 satIOContext->interruptContext ); 6325 6326 6327 } 6328 else 6329 { 6330 ostiInitiatorIOCompleted( tiRoot, 6331 tiIORequest, 6332 tiIOSuccess, 6333 SCSI_STAT_GOOD, 6334 agNULL, 6335 satIOContext->interruptContext); 6336 } 6337 return tiSuccess; 6338 6339 } 6340 6341 6342 /*****************************************************************************/ 6343 /*! \brief SAT implementation for SCSI MODE SENSE (6). 6344 * 6345 * SAT implementation for SCSI MODE SENSE (6). 6346 * 6347 * \param tiRoot: Pointer to TISA initiator driver/port instance. 6348 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 6349 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 6350 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 6351 * \param satIOContext_t: Pointer to the SAT IO Context 6352 * 6353 * \return If command is started successfully 6354 * - \e tiSuccess: I/O request successfully initiated. 6355 * - \e tiBusy: No resources available, try again later. 6356 * - \e tiIONoDevice: Invalid device handle. 6357 * - \e tiError: Other errors. 6358 */ 6359 /*****************************************************************************/ 6360 GLOBAL bit32 satModeSense6( 6361 tiRoot_t *tiRoot, 6362 tiIORequest_t *tiIORequest, 6363 tiDeviceHandle_t *tiDeviceHandle, 6364 tiScsiInitiatorRequest_t *tiScsiRequest, 6365 satIOContext_t *satIOContext) 6366 { 6367 6368 scsiRspSense_t *pSense; 6369 bit32 requestLen; 6370 tiIniScsiCmnd_t *scsiCmnd; 6371 bit32 pageSupported; 6372 bit8 page; 6373 bit8 *pModeSense; /* Mode Sense data buffer */ 6374 satDeviceData_t *pSatDevData; 6375 bit8 PC; 6376 bit8 AllPages[MODE_SENSE6_RETURN_ALL_PAGES_LEN]; 6377 bit8 Control[MODE_SENSE6_CONTROL_PAGE_LEN]; 6378 bit8 RWErrorRecovery[MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN]; 6379 bit8 Caching[MODE_SENSE6_CACHING_LEN]; 6380 bit8 InfoExceptionCtrl[MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN]; 6381 bit8 lenRead = 0; 6382 6383 6384 TI_DBG5(("satModeSense6 entry: tiDeviceHandle=%p tiIORequest=%p\n", 6385 tiDeviceHandle, tiIORequest)); 6386 6387 pSense = satIOContext->pSense; 6388 scsiCmnd = &tiScsiRequest->scsiCmnd; 6389 pModeSense = (bit8 *) tiScsiRequest->sglVirtualAddr; 6390 pSatDevData = satIOContext->pSatDevData; 6391 6392 //tdhexdump("satModeSense6", (bit8 *)scsiCmnd->cdb, 6); 6393 /* checking CONTROL */ 6394 /* NACA == 1 or LINK == 1*/ 6395 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 6396 { 6397 satSetSensePayload( pSense, 6398 SCSI_SNSKEY_ILLEGAL_REQUEST, 6399 0, 6400 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6401 satIOContext); 6402 6403 ostiInitiatorIOCompleted( tiRoot, 6404 tiIORequest, 6405 tiIOSuccess, 6406 SCSI_STAT_CHECK_CONDITION, 6407 satIOContext->pTiSenseData, 6408 satIOContext->interruptContext ); 6409 6410 TI_DBG2(("satModeSense6: return control\n")); 6411 return tiSuccess; 6412 } 6413 6414 /* checking PC(Page Control) 6415 SAT revion 8, 8.5.3 p33 and 10.1.2, p66 6416 */ 6417 PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PC_MASK); 6418 if (PC != 0) 6419 { 6420 satSetSensePayload( pSense, 6421 SCSI_SNSKEY_ILLEGAL_REQUEST, 6422 0, 6423 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6424 satIOContext); 6425 6426 ostiInitiatorIOCompleted( tiRoot, 6427 tiIORequest, 6428 tiIOSuccess, 6429 SCSI_STAT_CHECK_CONDITION, 6430 satIOContext->pTiSenseData, 6431 satIOContext->interruptContext ); 6432 6433 TI_DBG1(("satModeSense6: return due to PC value pc 0x%x\n", PC >> 6)); 6434 return tiSuccess; 6435 } 6436 6437 /* reading PAGE CODE */ 6438 page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PAGE_CODE_MASK); 6439 6440 6441 TI_DBG5(("satModeSense6: page=0x%x, tiDeviceHandle=%p tiIORequest=%p\n", 6442 page, tiDeviceHandle, tiIORequest)); 6443 6444 requestLen = scsiCmnd->cdb[4]; 6445 6446 /* 6447 Based on page code value, returns a corresponding mode page 6448 note: no support for subpage 6449 */ 6450 6451 switch(page) 6452 { 6453 case MODESENSE_RETURN_ALL_PAGES: 6454 case MODESENSE_CONTROL_PAGE: /* control */ 6455 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */ 6456 case MODESENSE_CACHING: /* caching */ 6457 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/ 6458 pageSupported = agTRUE; 6459 break; 6460 case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */ 6461 default: 6462 pageSupported = agFALSE; 6463 break; 6464 } 6465 6466 if (pageSupported == agFALSE) 6467 { 6468 6469 TI_DBG1(("satModeSense6 *** ERROR *** not supported page 0x%x tiDeviceHandle=%p tiIORequest=%p\n", 6470 page, tiDeviceHandle, tiIORequest)); 6471 6472 satSetSensePayload( pSense, 6473 SCSI_SNSKEY_ILLEGAL_REQUEST, 6474 0, 6475 SCSI_SNSCODE_INVALID_COMMAND, 6476 satIOContext); 6477 6478 ostiInitiatorIOCompleted( tiRoot, 6479 tiIORequest, 6480 tiIOSuccess, 6481 SCSI_STAT_CHECK_CONDITION, 6482 satIOContext->pTiSenseData, 6483 satIOContext->interruptContext ); 6484 return tiSuccess; 6485 } 6486 6487 switch(page) 6488 { 6489 case MODESENSE_RETURN_ALL_PAGES: 6490 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_RETURN_ALL_PAGES_LEN); 6491 break; 6492 case MODESENSE_CONTROL_PAGE: /* control */ 6493 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_CONTROL_PAGE_LEN); 6494 break; 6495 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */ 6496 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN); 6497 break; 6498 case MODESENSE_CACHING: /* caching */ 6499 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_CACHING_LEN); 6500 break; 6501 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/ 6502 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN); 6503 break; 6504 default: 6505 TI_DBG1(("satModeSense6: default error page %d\n", page)); 6506 break; 6507 } 6508 6509 if (page == MODESENSE_RETURN_ALL_PAGES) 6510 { 6511 TI_DBG5(("satModeSense6: MODESENSE_RETURN_ALL_PAGES\n")); 6512 AllPages[0] = (bit8)(lenRead - 1); 6513 AllPages[1] = 0x00; /* default medium type (currently mounted medium type) */ 6514 AllPages[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 6515 AllPages[3] = 0x08; /* block descriptor length */ 6516 6517 /* 6518 * Fill-up direct-access device block-descriptor, SAT, Table 19 6519 */ 6520 6521 /* density code */ 6522 AllPages[4] = 0x04; /* density-code : reserved for direct-access */ 6523 /* number of blocks */ 6524 AllPages[5] = 0x00; /* unspecified */ 6525 AllPages[6] = 0x00; /* unspecified */ 6526 AllPages[7] = 0x00; /* unspecified */ 6527 /* reserved */ 6528 AllPages[8] = 0x00; /* reserved */ 6529 /* Block size */ 6530 AllPages[9] = 0x00; 6531 AllPages[10] = 0x02; /* Block size is always 512 bytes */ 6532 AllPages[11] = 0x00; 6533 6534 /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */ 6535 AllPages[12] = 0x01; /* page code */ 6536 AllPages[13] = 0x0A; /* page length */ 6537 AllPages[14] = 0x40; /* ARRE is set */ 6538 AllPages[15] = 0x00; 6539 AllPages[16] = 0x00; 6540 AllPages[17] = 0x00; 6541 AllPages[18] = 0x00; 6542 AllPages[19] = 0x00; 6543 AllPages[20] = 0x00; 6544 AllPages[21] = 0x00; 6545 AllPages[22] = 0x00; 6546 AllPages[23] = 0x00; 6547 /* MODESENSE_CACHING */ 6548 AllPages[24] = 0x08; /* page code */ 6549 AllPages[25] = 0x12; /* page length */ 6550 #ifdef NOT_YET 6551 if (pSatDevData->satWriteCacheEnabled == agTRUE) 6552 { 6553 AllPages[26] = 0x04;/* WCE bit is set */ 6554 } 6555 else 6556 { 6557 AllPages[26] = 0x00;/* WCE bit is NOT set */ 6558 } 6559 #endif 6560 AllPages[26] = 0x00;/* WCE bit is NOT set */ 6561 6562 AllPages[27] = 0x00; 6563 AllPages[28] = 0x00; 6564 AllPages[29] = 0x00; 6565 AllPages[30] = 0x00; 6566 AllPages[31] = 0x00; 6567 AllPages[32] = 0x00; 6568 AllPages[33] = 0x00; 6569 AllPages[34] = 0x00; 6570 AllPages[35] = 0x00; 6571 if (pSatDevData->satLookAheadEnabled == agTRUE) 6572 { 6573 AllPages[36] = 0x00;/* DRA bit is NOT set */ 6574 } 6575 else 6576 { 6577 AllPages[36] = 0x20;/* DRA bit is set */ 6578 } 6579 AllPages[37] = 0x00; 6580 AllPages[38] = 0x00; 6581 AllPages[39] = 0x00; 6582 AllPages[40] = 0x00; 6583 AllPages[41] = 0x00; 6584 AllPages[42] = 0x00; 6585 AllPages[43] = 0x00; 6586 /* MODESENSE_CONTROL_PAGE */ 6587 AllPages[44] = 0x0A; /* page code */ 6588 AllPages[45] = 0x0A; /* page length */ 6589 AllPages[46] = 0x02; /* only GLTSD bit is set */ 6590 if (pSatDevData->satNCQ == agTRUE) 6591 { 6592 AllPages[47] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/ 6593 } 6594 else 6595 { 6596 AllPages[47] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */ 6597 } 6598 AllPages[48] = 0x00; 6599 AllPages[49] = 0x00; 6600 AllPages[50] = 0x00; /* obsolete */ 6601 AllPages[51] = 0x00; /* obsolete */ 6602 AllPages[52] = 0xFF; /* Busy Timeout Period */ 6603 AllPages[53] = 0xFF; /* Busy Timeout Period */ 6604 AllPages[54] = 0x00; /* we don't support non-000b value for the self-test code */ 6605 AllPages[55] = 0x00; /* we don't support non-000b value for the self-test code */ 6606 /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */ 6607 AllPages[56] = 0x1C; /* page code */ 6608 AllPages[57] = 0x0A; /* page length */ 6609 if (pSatDevData->satSMARTEnabled == agTRUE) 6610 { 6611 AllPages[58] = 0x00;/* DEXCPT bit is NOT set */ 6612 } 6613 else 6614 { 6615 AllPages[58] = 0x08;/* DEXCPT bit is set */ 6616 } 6617 AllPages[59] = 0x00; /* We don't support MRIE */ 6618 AllPages[60] = 0x00; /* Interval timer vendor-specific */ 6619 AllPages[61] = 0x00; 6620 AllPages[62] = 0x00; 6621 AllPages[63] = 0x00; 6622 AllPages[64] = 0x00; /* REPORT-COUNT */ 6623 AllPages[65] = 0x00; 6624 AllPages[66] = 0x00; 6625 AllPages[67] = 0x00; 6626 6627 osti_memcpy(pModeSense, &AllPages, lenRead); 6628 } 6629 else if (page == MODESENSE_CONTROL_PAGE) 6630 { 6631 TI_DBG5(("satModeSense6: MODESENSE_CONTROL_PAGE\n")); 6632 Control[0] = MODE_SENSE6_CONTROL_PAGE_LEN - 1; 6633 Control[1] = 0x00; /* default medium type (currently mounted medium type) */ 6634 Control[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 6635 Control[3] = 0x08; /* block descriptor length */ 6636 /* 6637 * Fill-up direct-access device block-descriptor, SAT, Table 19 6638 */ 6639 6640 /* density code */ 6641 Control[4] = 0x04; /* density-code : reserved for direct-access */ 6642 /* number of blocks */ 6643 Control[5] = 0x00; /* unspecified */ 6644 Control[6] = 0x00; /* unspecified */ 6645 Control[7] = 0x00; /* unspecified */ 6646 /* reserved */ 6647 Control[8] = 0x00; /* reserved */ 6648 /* Block size */ 6649 Control[9] = 0x00; 6650 Control[10] = 0x02; /* Block size is always 512 bytes */ 6651 Control[11] = 0x00; 6652 /* 6653 * Fill-up control mode page, SAT, Table 65 6654 */ 6655 Control[12] = 0x0A; /* page code */ 6656 Control[13] = 0x0A; /* page length */ 6657 Control[14] = 0x02; /* only GLTSD bit is set */ 6658 if (pSatDevData->satNCQ == agTRUE) 6659 { 6660 Control[15] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/ 6661 } 6662 else 6663 { 6664 Control[15] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */ 6665 } 6666 Control[16] = 0x00; 6667 Control[17] = 0x00; 6668 Control[18] = 0x00; /* obsolete */ 6669 Control[19] = 0x00; /* obsolete */ 6670 Control[20] = 0xFF; /* Busy Timeout Period */ 6671 Control[21] = 0xFF; /* Busy Timeout Period */ 6672 Control[22] = 0x00; /* we don't support non-000b value for the self-test code */ 6673 Control[23] = 0x00; /* we don't support non-000b value for the self-test code */ 6674 6675 osti_memcpy(pModeSense, &Control, lenRead); 6676 6677 } 6678 else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE) 6679 { 6680 TI_DBG5(("satModeSense6: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n")); 6681 RWErrorRecovery[0] = MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN - 1; 6682 RWErrorRecovery[1] = 0x00; /* default medium type (currently mounted medium type) */ 6683 RWErrorRecovery[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 6684 RWErrorRecovery[3] = 0x08; /* block descriptor length */ 6685 /* 6686 * Fill-up direct-access device block-descriptor, SAT, Table 19 6687 */ 6688 6689 /* density code */ 6690 RWErrorRecovery[4] = 0x04; /* density-code : reserved for direct-access */ 6691 /* number of blocks */ 6692 RWErrorRecovery[5] = 0x00; /* unspecified */ 6693 RWErrorRecovery[6] = 0x00; /* unspecified */ 6694 RWErrorRecovery[7] = 0x00; /* unspecified */ 6695 /* reserved */ 6696 RWErrorRecovery[8] = 0x00; /* reserved */ 6697 /* Block size */ 6698 RWErrorRecovery[9] = 0x00; 6699 RWErrorRecovery[10] = 0x02; /* Block size is always 512 bytes */ 6700 RWErrorRecovery[11] = 0x00; 6701 /* 6702 * Fill-up Read-Write Error Recovery mode page, SAT, Table 66 6703 */ 6704 RWErrorRecovery[12] = 0x01; /* page code */ 6705 RWErrorRecovery[13] = 0x0A; /* page length */ 6706 RWErrorRecovery[14] = 0x40; /* ARRE is set */ 6707 RWErrorRecovery[15] = 0x00; 6708 RWErrorRecovery[16] = 0x00; 6709 RWErrorRecovery[17] = 0x00; 6710 RWErrorRecovery[18] = 0x00; 6711 RWErrorRecovery[19] = 0x00; 6712 RWErrorRecovery[20] = 0x00; 6713 RWErrorRecovery[21] = 0x00; 6714 RWErrorRecovery[22] = 0x00; 6715 RWErrorRecovery[23] = 0x00; 6716 6717 osti_memcpy(pModeSense, &RWErrorRecovery, lenRead); 6718 6719 } 6720 else if (page == MODESENSE_CACHING) 6721 { 6722 TI_DBG5(("satModeSense6: MODESENSE_CACHING\n")); 6723 /* special case */ 6724 if (requestLen == 4 && page == MODESENSE_CACHING) 6725 { 6726 TI_DBG5(("satModeSense6: linux 2.6.8.24 support\n")); 6727 6728 pModeSense[0] = 0x20 - 1; /* 32 - 1 */ 6729 pModeSense[1] = 0x00; /* default medium type (currently mounted medium type) */ 6730 pModeSense[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 6731 pModeSense[3] = 0x08; /* block descriptor length */ 6732 ostiInitiatorIOCompleted( tiRoot, 6733 tiIORequest, 6734 tiIOSuccess, 6735 SCSI_STAT_GOOD, 6736 agNULL, 6737 satIOContext->interruptContext); 6738 return tiSuccess; 6739 } 6740 Caching[0] = MODE_SENSE6_CACHING_LEN - 1; 6741 Caching[1] = 0x00; /* default medium type (currently mounted medium type) */ 6742 Caching[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 6743 Caching[3] = 0x08; /* block descriptor length */ 6744 /* 6745 * Fill-up direct-access device block-descriptor, SAT, Table 19 6746 */ 6747 6748 /* density code */ 6749 Caching[4] = 0x04; /* density-code : reserved for direct-access */ 6750 /* number of blocks */ 6751 Caching[5] = 0x00; /* unspecified */ 6752 Caching[6] = 0x00; /* unspecified */ 6753 Caching[7] = 0x00; /* unspecified */ 6754 /* reserved */ 6755 Caching[8] = 0x00; /* reserved */ 6756 /* Block size */ 6757 Caching[9] = 0x00; 6758 Caching[10] = 0x02; /* Block size is always 512 bytes */ 6759 Caching[11] = 0x00; 6760 /* 6761 * Fill-up Caching mode page, SAT, Table 67 6762 */ 6763 /* length 20 */ 6764 Caching[12] = 0x08; /* page code */ 6765 Caching[13] = 0x12; /* page length */ 6766 #ifdef NOT_YET 6767 if (pSatDevData->satWriteCacheEnabled == agTRUE) 6768 { 6769 Caching[14] = 0x04;/* WCE bit is set */ 6770 } 6771 else 6772 { 6773 Caching[14] = 0x00;/* WCE bit is NOT set */ 6774 } 6775 #endif 6776 Caching[14] = 0x00;/* WCE bit is NOT set */ 6777 6778 Caching[15] = 0x00; 6779 Caching[16] = 0x00; 6780 Caching[17] = 0x00; 6781 Caching[18] = 0x00; 6782 Caching[19] = 0x00; 6783 Caching[20] = 0x00; 6784 Caching[21] = 0x00; 6785 Caching[22] = 0x00; 6786 Caching[23] = 0x00; 6787 if (pSatDevData->satLookAheadEnabled == agTRUE) 6788 { 6789 Caching[24] = 0x00;/* DRA bit is NOT set */ 6790 } 6791 else 6792 { 6793 Caching[24] = 0x20;/* DRA bit is set */ 6794 } 6795 Caching[25] = 0x00; 6796 Caching[26] = 0x00; 6797 Caching[27] = 0x00; 6798 Caching[28] = 0x00; 6799 Caching[29] = 0x00; 6800 Caching[30] = 0x00; 6801 Caching[31] = 0x00; 6802 6803 osti_memcpy(pModeSense, &Caching, lenRead); 6804 6805 } 6806 else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE) 6807 { 6808 TI_DBG5(("satModeSense6: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n")); 6809 InfoExceptionCtrl[0] = MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN - 1; 6810 InfoExceptionCtrl[1] = 0x00; /* default medium type (currently mounted medium type) */ 6811 InfoExceptionCtrl[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 6812 InfoExceptionCtrl[3] = 0x08; /* block descriptor length */ 6813 /* 6814 * Fill-up direct-access device block-descriptor, SAT, Table 19 6815 */ 6816 6817 /* density code */ 6818 InfoExceptionCtrl[4] = 0x04; /* density-code : reserved for direct-access */ 6819 /* number of blocks */ 6820 InfoExceptionCtrl[5] = 0x00; /* unspecified */ 6821 InfoExceptionCtrl[6] = 0x00; /* unspecified */ 6822 InfoExceptionCtrl[7] = 0x00; /* unspecified */ 6823 /* reserved */ 6824 InfoExceptionCtrl[8] = 0x00; /* reserved */ 6825 /* Block size */ 6826 InfoExceptionCtrl[9] = 0x00; 6827 InfoExceptionCtrl[10] = 0x02; /* Block size is always 512 bytes */ 6828 InfoExceptionCtrl[11] = 0x00; 6829 /* 6830 * Fill-up informational-exceptions control mode page, SAT, Table 68 6831 */ 6832 InfoExceptionCtrl[12] = 0x1C; /* page code */ 6833 InfoExceptionCtrl[13] = 0x0A; /* page length */ 6834 if (pSatDevData->satSMARTEnabled == agTRUE) 6835 { 6836 InfoExceptionCtrl[14] = 0x00;/* DEXCPT bit is NOT set */ 6837 } 6838 else 6839 { 6840 InfoExceptionCtrl[14] = 0x08;/* DEXCPT bit is set */ 6841 } 6842 InfoExceptionCtrl[15] = 0x00; /* We don't support MRIE */ 6843 InfoExceptionCtrl[16] = 0x00; /* Interval timer vendor-specific */ 6844 InfoExceptionCtrl[17] = 0x00; 6845 InfoExceptionCtrl[18] = 0x00; 6846 InfoExceptionCtrl[19] = 0x00; 6847 InfoExceptionCtrl[20] = 0x00; /* REPORT-COUNT */ 6848 InfoExceptionCtrl[21] = 0x00; 6849 InfoExceptionCtrl[22] = 0x00; 6850 InfoExceptionCtrl[23] = 0x00; 6851 osti_memcpy(pModeSense, &InfoExceptionCtrl, lenRead); 6852 6853 } 6854 else 6855 { 6856 /* Error */ 6857 TI_DBG1(("satModeSense6: Error page %d\n", page)); 6858 satSetSensePayload( pSense, 6859 SCSI_SNSKEY_ILLEGAL_REQUEST, 6860 0, 6861 SCSI_SNSCODE_INVALID_COMMAND, 6862 satIOContext); 6863 6864 ostiInitiatorIOCompleted( tiRoot, 6865 tiIORequest, 6866 tiIOSuccess, 6867 SCSI_STAT_CHECK_CONDITION, 6868 satIOContext->pTiSenseData, 6869 satIOContext->interruptContext ); 6870 return tiSuccess; 6871 } 6872 6873 /* there can be only underrun not overrun in error case */ 6874 if (requestLen > lenRead) 6875 { 6876 TI_DBG6(("satModeSense6 reporting underrun lenRead=0x%x requestLen=0x%x tiIORequest=%p\n", lenRead, requestLen, tiIORequest)); 6877 6878 ostiInitiatorIOCompleted( tiRoot, 6879 tiIORequest, 6880 tiIOUnderRun, 6881 requestLen - lenRead, 6882 agNULL, 6883 satIOContext->interruptContext ); 6884 6885 6886 } 6887 else 6888 { 6889 ostiInitiatorIOCompleted( tiRoot, 6890 tiIORequest, 6891 tiIOSuccess, 6892 SCSI_STAT_GOOD, 6893 agNULL, 6894 satIOContext->interruptContext); 6895 } 6896 6897 return tiSuccess; 6898 6899 } 6900 6901 /*****************************************************************************/ 6902 /*! \brief SAT implementation for SCSI MODE SENSE (10). 6903 * 6904 * SAT implementation for SCSI MODE SENSE (10). 6905 * 6906 * \param tiRoot: Pointer to TISA initiator driver/port instance. 6907 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 6908 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 6909 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 6910 * \param satIOContext_t: Pointer to the SAT IO Context 6911 * 6912 * \return If command is started successfully 6913 * - \e tiSuccess: I/O request successfully initiated. 6914 * - \e tiBusy: No resources available, try again later. 6915 * - \e tiIONoDevice: Invalid device handle. 6916 * - \e tiError: Other errors. 6917 */ 6918 /*****************************************************************************/ 6919 GLOBAL bit32 satModeSense10( 6920 tiRoot_t *tiRoot, 6921 tiIORequest_t *tiIORequest, 6922 tiDeviceHandle_t *tiDeviceHandle, 6923 tiScsiInitiatorRequest_t *tiScsiRequest, 6924 satIOContext_t *satIOContext) 6925 { 6926 6927 scsiRspSense_t *pSense; 6928 bit32 requestLen; 6929 tiIniScsiCmnd_t *scsiCmnd; 6930 bit32 pageSupported; 6931 bit8 page; 6932 bit8 *pModeSense; /* Mode Sense data buffer */ 6933 satDeviceData_t *pSatDevData; 6934 bit8 PC; /* page control */ 6935 bit8 LLBAA; /* Long LBA Accepted */ 6936 bit32 index; 6937 bit8 AllPages[MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN]; 6938 bit8 Control[MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN]; 6939 bit8 RWErrorRecovery[MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN]; 6940 bit8 Caching[MODE_SENSE10_CACHING_LLBAA_LEN]; 6941 bit8 InfoExceptionCtrl[MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN]; 6942 bit8 lenRead = 0; 6943 6944 TI_DBG5(("satModeSense10 entry: tiDeviceHandle=%p tiIORequest=%p\n", 6945 tiDeviceHandle, tiIORequest)); 6946 6947 pSense = satIOContext->pSense; 6948 scsiCmnd = &tiScsiRequest->scsiCmnd; 6949 pModeSense = (bit8 *) tiScsiRequest->sglVirtualAddr; 6950 pSatDevData = satIOContext->pSatDevData; 6951 6952 /* checking CONTROL */ 6953 /* NACA == 1 or LINK == 1*/ 6954 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 6955 { 6956 satSetSensePayload( pSense, 6957 SCSI_SNSKEY_ILLEGAL_REQUEST, 6958 0, 6959 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6960 satIOContext); 6961 6962 ostiInitiatorIOCompleted( tiRoot, 6963 tiIORequest, 6964 tiIOSuccess, 6965 SCSI_STAT_CHECK_CONDITION, 6966 satIOContext->pTiSenseData, 6967 satIOContext->interruptContext ); 6968 6969 TI_DBG2(("satModeSense10: return control\n")); 6970 return tiSuccess; 6971 } 6972 6973 /* checking PC(Page Control) 6974 SAT revion 8, 8.5.3 p33 and 10.1.2, p66 6975 */ 6976 PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PC_MASK); 6977 if (PC != 0) 6978 { 6979 satSetSensePayload( pSense, 6980 SCSI_SNSKEY_ILLEGAL_REQUEST, 6981 0, 6982 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6983 satIOContext); 6984 6985 ostiInitiatorIOCompleted( tiRoot, 6986 tiIORequest, 6987 tiIOSuccess, 6988 SCSI_STAT_CHECK_CONDITION, 6989 satIOContext->pTiSenseData, 6990 satIOContext->interruptContext ); 6991 6992 TI_DBG1(("satModeSense10: return due to PC value pc 0x%x\n", PC)); 6993 return tiSuccess; 6994 } 6995 /* finding LLBAA bit */ 6996 LLBAA = (bit8)((scsiCmnd->cdb[1]) & SCSI_MODE_SENSE10_LLBAA_MASK); 6997 /* reading PAGE CODE */ 6998 page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PAGE_CODE_MASK); 6999 7000 TI_DBG5(("satModeSense10: page=0x%x, tiDeviceHandle=%p tiIORequest=%p\n", 7001 page, tiDeviceHandle, tiIORequest)); 7002 requestLen = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 7003 7004 /* 7005 Based on page code value, returns a corresponding mode page 7006 note: no support for subpage 7007 */ 7008 switch(page) 7009 { 7010 case MODESENSE_RETURN_ALL_PAGES: /* return all pages */ 7011 case MODESENSE_CONTROL_PAGE: /* control */ 7012 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */ 7013 case MODESENSE_CACHING: /* caching */ 7014 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/ 7015 pageSupported = agTRUE; 7016 break; 7017 case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */ 7018 default: 7019 pageSupported = agFALSE; 7020 break; 7021 } 7022 7023 if (pageSupported == agFALSE) 7024 { 7025 7026 TI_DBG1(("satModeSense10 *** ERROR *** not supported page 0x%x tiDeviceHandle=%p tiIORequest=%p\n", 7027 page, tiDeviceHandle, tiIORequest)); 7028 7029 satSetSensePayload( pSense, 7030 SCSI_SNSKEY_ILLEGAL_REQUEST, 7031 0, 7032 SCSI_SNSCODE_INVALID_COMMAND, 7033 satIOContext); 7034 7035 ostiInitiatorIOCompleted( tiRoot, 7036 tiIORequest, 7037 tiIOSuccess, 7038 SCSI_STAT_CHECK_CONDITION, 7039 satIOContext->pTiSenseData, 7040 satIOContext->interruptContext ); 7041 return tiSuccess; 7042 } 7043 7044 switch(page) 7045 { 7046 case MODESENSE_RETURN_ALL_PAGES: 7047 if (LLBAA) 7048 { 7049 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN); 7050 } 7051 else 7052 { 7053 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_RETURN_ALL_PAGES_LEN); 7054 } 7055 break; 7056 case MODESENSE_CONTROL_PAGE: /* control */ 7057 if (LLBAA) 7058 { 7059 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN); 7060 } 7061 else 7062 { 7063 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CONTROL_PAGE_LEN); 7064 } 7065 break; 7066 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */ 7067 if (LLBAA) 7068 { 7069 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN); 7070 } 7071 else 7072 { 7073 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LEN); 7074 } 7075 break; 7076 case MODESENSE_CACHING: /* caching */ 7077 if (LLBAA) 7078 { 7079 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CACHING_LLBAA_LEN); 7080 } 7081 else 7082 { 7083 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CACHING_LEN); 7084 } 7085 break; 7086 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/ 7087 if (LLBAA) 7088 { 7089 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN); 7090 } 7091 else 7092 { 7093 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN); 7094 } 7095 break; 7096 default: 7097 TI_DBG1(("satModeSense10: default error page %d\n", page)); 7098 break; 7099 } 7100 7101 if (page == MODESENSE_RETURN_ALL_PAGES) 7102 { 7103 TI_DBG5(("satModeSense10: MODESENSE_RETURN_ALL_PAGES\n")); 7104 AllPages[0] = 0; 7105 AllPages[1] = (bit8)(lenRead - 2); 7106 AllPages[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */ 7107 AllPages[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */ 7108 if (LLBAA) 7109 { 7110 AllPages[4] = 0x00; /* reserved and LONGLBA */ 7111 AllPages[4] = (bit8)(AllPages[4] | 0x1); /* LONGLBA is set */ 7112 } 7113 else 7114 { 7115 AllPages[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */ 7116 } 7117 AllPages[5] = 0x00; /* reserved */ 7118 AllPages[6] = 0x00; /* block descriptot length */ 7119 if (LLBAA) 7120 { 7121 AllPages[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */ 7122 } 7123 else 7124 { 7125 AllPages[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */ 7126 } 7127 7128 /* 7129 * Fill-up direct-access device block-descriptor, SAT, Table 19 7130 */ 7131 7132 if (LLBAA) 7133 { 7134 /* density code */ 7135 AllPages[8] = 0x04; /* density-code : reserved for direct-access */ 7136 /* number of blocks */ 7137 AllPages[9] = 0x00; /* unspecified */ 7138 AllPages[10] = 0x00; /* unspecified */ 7139 AllPages[11] = 0x00; /* unspecified */ 7140 AllPages[12] = 0x00; /* unspecified */ 7141 AllPages[13] = 0x00; /* unspecified */ 7142 AllPages[14] = 0x00; /* unspecified */ 7143 AllPages[15] = 0x00; /* unspecified */ 7144 /* reserved */ 7145 AllPages[16] = 0x00; /* reserved */ 7146 AllPages[17] = 0x00; /* reserved */ 7147 AllPages[18] = 0x00; /* reserved */ 7148 AllPages[19] = 0x00; /* reserved */ 7149 /* Block size */ 7150 AllPages[20] = 0x00; 7151 AllPages[21] = 0x00; 7152 AllPages[22] = 0x02; /* Block size is always 512 bytes */ 7153 AllPages[23] = 0x00; 7154 } 7155 else 7156 { 7157 /* density code */ 7158 AllPages[8] = 0x04; /* density-code : reserved for direct-access */ 7159 /* number of blocks */ 7160 AllPages[9] = 0x00; /* unspecified */ 7161 AllPages[10] = 0x00; /* unspecified */ 7162 AllPages[11] = 0x00; /* unspecified */ 7163 /* reserved */ 7164 AllPages[12] = 0x00; /* reserved */ 7165 /* Block size */ 7166 AllPages[13] = 0x00; 7167 AllPages[14] = 0x02; /* Block size is always 512 bytes */ 7168 AllPages[15] = 0x00; 7169 } 7170 7171 if (LLBAA) 7172 { 7173 index = 24; 7174 } 7175 else 7176 { 7177 index = 16; 7178 } 7179 /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */ 7180 AllPages[index+0] = 0x01; /* page code */ 7181 AllPages[index+1] = 0x0A; /* page length */ 7182 AllPages[index+2] = 0x40; /* ARRE is set */ 7183 AllPages[index+3] = 0x00; 7184 AllPages[index+4] = 0x00; 7185 AllPages[index+5] = 0x00; 7186 AllPages[index+6] = 0x00; 7187 AllPages[index+7] = 0x00; 7188 AllPages[index+8] = 0x00; 7189 AllPages[index+9] = 0x00; 7190 AllPages[index+10] = 0x00; 7191 AllPages[index+11] = 0x00; 7192 7193 /* MODESENSE_CACHING */ 7194 /* 7195 * Fill-up Caching mode page, SAT, Table 67 7196 */ 7197 /* length 20 */ 7198 AllPages[index+12] = 0x08; /* page code */ 7199 AllPages[index+13] = 0x12; /* page length */ 7200 #ifdef NOT_YET 7201 if (pSatDevData->satWriteCacheEnabled == agTRUE) 7202 { 7203 AllPages[index+14] = 0x04;/* WCE bit is set */ 7204 } 7205 else 7206 { 7207 AllPages[index+14] = 0x00;/* WCE bit is NOT set */ 7208 } 7209 #endif 7210 AllPages[index+14] = 0x00;/* WCE bit is NOT set */ 7211 AllPages[index+15] = 0x00; 7212 AllPages[index+16] = 0x00; 7213 AllPages[index+17] = 0x00; 7214 AllPages[index+18] = 0x00; 7215 AllPages[index+19] = 0x00; 7216 AllPages[index+20] = 0x00; 7217 AllPages[index+21] = 0x00; 7218 AllPages[index+22] = 0x00; 7219 AllPages[index+23] = 0x00; 7220 if (pSatDevData->satLookAheadEnabled == agTRUE) 7221 { 7222 AllPages[index+24] = 0x00;/* DRA bit is NOT set */ 7223 } 7224 else 7225 { 7226 AllPages[index+24] = 0x20;/* DRA bit is set */ 7227 } 7228 AllPages[index+25] = 0x00; 7229 AllPages[index+26] = 0x00; 7230 AllPages[index+27] = 0x00; 7231 AllPages[index+28] = 0x00; 7232 AllPages[index+29] = 0x00; 7233 AllPages[index+30] = 0x00; 7234 AllPages[index+31] = 0x00; 7235 7236 /* MODESENSE_CONTROL_PAGE */ 7237 /* 7238 * Fill-up control mode page, SAT, Table 65 7239 */ 7240 AllPages[index+32] = 0x0A; /* page code */ 7241 AllPages[index+33] = 0x0A; /* page length */ 7242 AllPages[index+34] = 0x02; /* only GLTSD bit is set */ 7243 if (pSatDevData->satNCQ == agTRUE) 7244 { 7245 AllPages[index+35] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/ 7246 } 7247 else 7248 { 7249 AllPages[index+35] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */ 7250 } 7251 AllPages[index+36] = 0x00; 7252 AllPages[index+37] = 0x00; 7253 AllPages[index+38] = 0x00; /* obsolete */ 7254 AllPages[index+39] = 0x00; /* obsolete */ 7255 AllPages[index+40] = 0xFF; /* Busy Timeout Period */ 7256 AllPages[index+41] = 0xFF; /* Busy Timeout Period */ 7257 AllPages[index+42] = 0x00; /* we don't support non-000b value for the self-test code */ 7258 AllPages[index+43] = 0x00; /* we don't support non-000b value for the self-test code */ 7259 7260 /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */ 7261 /* 7262 * Fill-up informational-exceptions control mode page, SAT, Table 68 7263 */ 7264 AllPages[index+44] = 0x1C; /* page code */ 7265 AllPages[index+45] = 0x0A; /* page length */ 7266 if (pSatDevData->satSMARTEnabled == agTRUE) 7267 { 7268 AllPages[index+46] = 0x00;/* DEXCPT bit is NOT set */ 7269 } 7270 else 7271 { 7272 AllPages[index+46] = 0x08;/* DEXCPT bit is set */ 7273 } 7274 AllPages[index+47] = 0x00; /* We don't support MRIE */ 7275 AllPages[index+48] = 0x00; /* Interval timer vendor-specific */ 7276 AllPages[index+49] = 0x00; 7277 AllPages[index+50] = 0x00; 7278 AllPages[index+51] = 0x00; 7279 AllPages[index+52] = 0x00; /* REPORT-COUNT */ 7280 AllPages[index+53] = 0x00; 7281 AllPages[index+54] = 0x00; 7282 AllPages[index+55] = 0x00; 7283 7284 osti_memcpy(pModeSense, &AllPages, lenRead); 7285 } 7286 else if (page == MODESENSE_CONTROL_PAGE) 7287 { 7288 TI_DBG5(("satModeSense10: MODESENSE_CONTROL_PAGE\n")); 7289 Control[0] = 0; 7290 Control[1] = (bit8)(lenRead - 2); 7291 Control[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */ 7292 Control[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */ 7293 if (LLBAA) 7294 { 7295 Control[4] = 0x00; /* reserved and LONGLBA */ 7296 Control[4] = (bit8)(Control[4] | 0x1); /* LONGLBA is set */ 7297 } 7298 else 7299 { 7300 Control[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */ 7301 } 7302 Control[5] = 0x00; /* reserved */ 7303 Control[6] = 0x00; /* block descriptot length */ 7304 if (LLBAA) 7305 { 7306 Control[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */ 7307 } 7308 else 7309 { 7310 Control[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */ 7311 } 7312 7313 /* 7314 * Fill-up direct-access device block-descriptor, SAT, Table 19 7315 */ 7316 7317 if (LLBAA) 7318 { 7319 /* density code */ 7320 Control[8] = 0x04; /* density-code : reserved for direct-access */ 7321 /* number of blocks */ 7322 Control[9] = 0x00; /* unspecified */ 7323 Control[10] = 0x00; /* unspecified */ 7324 Control[11] = 0x00; /* unspecified */ 7325 Control[12] = 0x00; /* unspecified */ 7326 Control[13] = 0x00; /* unspecified */ 7327 Control[14] = 0x00; /* unspecified */ 7328 Control[15] = 0x00; /* unspecified */ 7329 /* reserved */ 7330 Control[16] = 0x00; /* reserved */ 7331 Control[17] = 0x00; /* reserved */ 7332 Control[18] = 0x00; /* reserved */ 7333 Control[19] = 0x00; /* reserved */ 7334 /* Block size */ 7335 Control[20] = 0x00; 7336 Control[21] = 0x00; 7337 Control[22] = 0x02; /* Block size is always 512 bytes */ 7338 Control[23] = 0x00; 7339 } 7340 else 7341 { 7342 /* density code */ 7343 Control[8] = 0x04; /* density-code : reserved for direct-access */ 7344 /* number of blocks */ 7345 Control[9] = 0x00; /* unspecified */ 7346 Control[10] = 0x00; /* unspecified */ 7347 Control[11] = 0x00; /* unspecified */ 7348 /* reserved */ 7349 Control[12] = 0x00; /* reserved */ 7350 /* Block size */ 7351 Control[13] = 0x00; 7352 Control[14] = 0x02; /* Block size is always 512 bytes */ 7353 Control[15] = 0x00; 7354 } 7355 7356 if (LLBAA) 7357 { 7358 index = 24; 7359 } 7360 else 7361 { 7362 index = 16; 7363 } 7364 /* 7365 * Fill-up control mode page, SAT, Table 65 7366 */ 7367 Control[index+0] = 0x0A; /* page code */ 7368 Control[index+1] = 0x0A; /* page length */ 7369 Control[index+2] = 0x02; /* only GLTSD bit is set */ 7370 if (pSatDevData->satNCQ == agTRUE) 7371 { 7372 Control[index+3] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/ 7373 } 7374 else 7375 { 7376 Control[index+3] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */ 7377 } 7378 Control[index+4] = 0x00; 7379 Control[index+5] = 0x00; 7380 Control[index+6] = 0x00; /* obsolete */ 7381 Control[index+7] = 0x00; /* obsolete */ 7382 Control[index+8] = 0xFF; /* Busy Timeout Period */ 7383 Control[index+9] = 0xFF; /* Busy Timeout Period */ 7384 Control[index+10] = 0x00; /* we don't support non-000b value for the self-test code */ 7385 Control[index+11] = 0x00; /* we don't support non-000b value for the self-test code */ 7386 7387 osti_memcpy(pModeSense, &Control, lenRead); 7388 } 7389 else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE) 7390 { 7391 TI_DBG5(("satModeSense10: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n")); 7392 RWErrorRecovery[0] = 0; 7393 RWErrorRecovery[1] = (bit8)(lenRead - 2); 7394 RWErrorRecovery[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */ 7395 RWErrorRecovery[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */ 7396 if (LLBAA) 7397 { 7398 RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA */ 7399 RWErrorRecovery[4] = (bit8)(RWErrorRecovery[4] | 0x1); /* LONGLBA is set */ 7400 } 7401 else 7402 { 7403 RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */ 7404 } 7405 RWErrorRecovery[5] = 0x00; /* reserved */ 7406 RWErrorRecovery[6] = 0x00; /* block descriptot length */ 7407 if (LLBAA) 7408 { 7409 RWErrorRecovery[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */ 7410 } 7411 else 7412 { 7413 RWErrorRecovery[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */ 7414 } 7415 7416 /* 7417 * Fill-up direct-access device block-descriptor, SAT, Table 19 7418 */ 7419 7420 if (LLBAA) 7421 { 7422 /* density code */ 7423 RWErrorRecovery[8] = 0x04; /* density-code : reserved for direct-access */ 7424 /* number of blocks */ 7425 RWErrorRecovery[9] = 0x00; /* unspecified */ 7426 RWErrorRecovery[10] = 0x00; /* unspecified */ 7427 RWErrorRecovery[11] = 0x00; /* unspecified */ 7428 RWErrorRecovery[12] = 0x00; /* unspecified */ 7429 RWErrorRecovery[13] = 0x00; /* unspecified */ 7430 RWErrorRecovery[14] = 0x00; /* unspecified */ 7431 RWErrorRecovery[15] = 0x00; /* unspecified */ 7432 /* reserved */ 7433 RWErrorRecovery[16] = 0x00; /* reserved */ 7434 RWErrorRecovery[17] = 0x00; /* reserved */ 7435 RWErrorRecovery[18] = 0x00; /* reserved */ 7436 RWErrorRecovery[19] = 0x00; /* reserved */ 7437 /* Block size */ 7438 RWErrorRecovery[20] = 0x00; 7439 RWErrorRecovery[21] = 0x00; 7440 RWErrorRecovery[22] = 0x02; /* Block size is always 512 bytes */ 7441 RWErrorRecovery[23] = 0x00; 7442 } 7443 else 7444 { 7445 /* density code */ 7446 RWErrorRecovery[8] = 0x04; /* density-code : reserved for direct-access */ 7447 /* number of blocks */ 7448 RWErrorRecovery[9] = 0x00; /* unspecified */ 7449 RWErrorRecovery[10] = 0x00; /* unspecified */ 7450 RWErrorRecovery[11] = 0x00; /* unspecified */ 7451 /* reserved */ 7452 RWErrorRecovery[12] = 0x00; /* reserved */ 7453 /* Block size */ 7454 RWErrorRecovery[13] = 0x00; 7455 RWErrorRecovery[14] = 0x02; /* Block size is always 512 bytes */ 7456 RWErrorRecovery[15] = 0x00; 7457 } 7458 7459 if (LLBAA) 7460 { 7461 index = 24; 7462 } 7463 else 7464 { 7465 index = 16; 7466 } 7467 /* 7468 * Fill-up Read-Write Error Recovery mode page, SAT, Table 66 7469 */ 7470 RWErrorRecovery[index+0] = 0x01; /* page code */ 7471 RWErrorRecovery[index+1] = 0x0A; /* page length */ 7472 RWErrorRecovery[index+2] = 0x40; /* ARRE is set */ 7473 RWErrorRecovery[index+3] = 0x00; 7474 RWErrorRecovery[index+4] = 0x00; 7475 RWErrorRecovery[index+5] = 0x00; 7476 RWErrorRecovery[index+6] = 0x00; 7477 RWErrorRecovery[index+7] = 0x00; 7478 RWErrorRecovery[index+8] = 0x00; 7479 RWErrorRecovery[index+9] = 0x00; 7480 RWErrorRecovery[index+10] = 0x00; 7481 RWErrorRecovery[index+11] = 0x00; 7482 7483 osti_memcpy(pModeSense, &RWErrorRecovery, lenRead); 7484 } 7485 else if (page == MODESENSE_CACHING) 7486 { 7487 TI_DBG5(("satModeSense10: MODESENSE_CACHING\n")); 7488 Caching[0] = 0; 7489 Caching[1] = (bit8)(lenRead - 2); 7490 Caching[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */ 7491 Caching[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */ 7492 if (LLBAA) 7493 { 7494 Caching[4] = 0x00; /* reserved and LONGLBA */ 7495 Caching[4] = (bit8)(Caching[4] | 0x1); /* LONGLBA is set */ 7496 } 7497 else 7498 { 7499 Caching[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */ 7500 } 7501 Caching[5] = 0x00; /* reserved */ 7502 Caching[6] = 0x00; /* block descriptot length */ 7503 if (LLBAA) 7504 { 7505 Caching[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */ 7506 } 7507 else 7508 { 7509 Caching[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */ 7510 } 7511 7512 /* 7513 * Fill-up direct-access device block-descriptor, SAT, Table 19 7514 */ 7515 7516 if (LLBAA) 7517 { 7518 /* density code */ 7519 Caching[8] = 0x04; /* density-code : reserved for direct-access */ 7520 /* number of blocks */ 7521 Caching[9] = 0x00; /* unspecified */ 7522 Caching[10] = 0x00; /* unspecified */ 7523 Caching[11] = 0x00; /* unspecified */ 7524 Caching[12] = 0x00; /* unspecified */ 7525 Caching[13] = 0x00; /* unspecified */ 7526 Caching[14] = 0x00; /* unspecified */ 7527 Caching[15] = 0x00; /* unspecified */ 7528 /* reserved */ 7529 Caching[16] = 0x00; /* reserved */ 7530 Caching[17] = 0x00; /* reserved */ 7531 Caching[18] = 0x00; /* reserved */ 7532 Caching[19] = 0x00; /* reserved */ 7533 /* Block size */ 7534 Caching[20] = 0x00; 7535 Caching[21] = 0x00; 7536 Caching[22] = 0x02; /* Block size is always 512 bytes */ 7537 Caching[23] = 0x00; 7538 } 7539 else 7540 { 7541 /* density code */ 7542 Caching[8] = 0x04; /* density-code : reserved for direct-access */ 7543 /* number of blocks */ 7544 Caching[9] = 0x00; /* unspecified */ 7545 Caching[10] = 0x00; /* unspecified */ 7546 Caching[11] = 0x00; /* unspecified */ 7547 /* reserved */ 7548 Caching[12] = 0x00; /* reserved */ 7549 /* Block size */ 7550 Caching[13] = 0x00; 7551 Caching[14] = 0x02; /* Block size is always 512 bytes */ 7552 Caching[15] = 0x00; 7553 } 7554 7555 if (LLBAA) 7556 { 7557 index = 24; 7558 } 7559 else 7560 { 7561 index = 16; 7562 } 7563 /* 7564 * Fill-up Caching mode page, SAT, Table 67 7565 */ 7566 /* length 20 */ 7567 Caching[index+0] = 0x08; /* page code */ 7568 Caching[index+1] = 0x12; /* page length */ 7569 #ifdef NOT_YET 7570 if (pSatDevData->satWriteCacheEnabled == agTRUE) 7571 { 7572 Caching[index+2] = 0x04;/* WCE bit is set */ 7573 } 7574 else 7575 { 7576 Caching[index+2] = 0x00;/* WCE bit is NOT set */ 7577 } 7578 #endif 7579 Caching[index+2] = 0x00;/* WCE bit is NOT set */ 7580 Caching[index+3] = 0x00; 7581 Caching[index+4] = 0x00; 7582 Caching[index+5] = 0x00; 7583 Caching[index+6] = 0x00; 7584 Caching[index+7] = 0x00; 7585 Caching[index+8] = 0x00; 7586 Caching[index+9] = 0x00; 7587 Caching[index+10] = 0x00; 7588 Caching[index+11] = 0x00; 7589 if (pSatDevData->satLookAheadEnabled == agTRUE) 7590 { 7591 Caching[index+12] = 0x00;/* DRA bit is NOT set */ 7592 } 7593 else 7594 { 7595 Caching[index+12] = 0x20;/* DRA bit is set */ 7596 } 7597 Caching[index+13] = 0x00; 7598 Caching[index+14] = 0x00; 7599 Caching[index+15] = 0x00; 7600 Caching[index+16] = 0x00; 7601 Caching[index+17] = 0x00; 7602 Caching[index+18] = 0x00; 7603 Caching[index+19] = 0x00; 7604 osti_memcpy(pModeSense, &Caching, lenRead); 7605 7606 } 7607 else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE) 7608 { 7609 TI_DBG5(("satModeSense10: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n")); 7610 InfoExceptionCtrl[0] = 0; 7611 InfoExceptionCtrl[1] = (bit8)(lenRead - 2); 7612 InfoExceptionCtrl[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */ 7613 InfoExceptionCtrl[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */ 7614 if (LLBAA) 7615 { 7616 InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA */ 7617 InfoExceptionCtrl[4] = (bit8)(InfoExceptionCtrl[4] | 0x1); /* LONGLBA is set */ 7618 } 7619 else 7620 { 7621 InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */ 7622 } 7623 InfoExceptionCtrl[5] = 0x00; /* reserved */ 7624 InfoExceptionCtrl[6] = 0x00; /* block descriptot length */ 7625 if (LLBAA) 7626 { 7627 InfoExceptionCtrl[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */ 7628 } 7629 else 7630 { 7631 InfoExceptionCtrl[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */ 7632 } 7633 7634 /* 7635 * Fill-up direct-access device block-descriptor, SAT, Table 19 7636 */ 7637 7638 if (LLBAA) 7639 { 7640 /* density code */ 7641 InfoExceptionCtrl[8] = 0x04; /* density-code : reserved for direct-access */ 7642 /* number of blocks */ 7643 InfoExceptionCtrl[9] = 0x00; /* unspecified */ 7644 InfoExceptionCtrl[10] = 0x00; /* unspecified */ 7645 InfoExceptionCtrl[11] = 0x00; /* unspecified */ 7646 InfoExceptionCtrl[12] = 0x00; /* unspecified */ 7647 InfoExceptionCtrl[13] = 0x00; /* unspecified */ 7648 InfoExceptionCtrl[14] = 0x00; /* unspecified */ 7649 InfoExceptionCtrl[15] = 0x00; /* unspecified */ 7650 /* reserved */ 7651 InfoExceptionCtrl[16] = 0x00; /* reserved */ 7652 InfoExceptionCtrl[17] = 0x00; /* reserved */ 7653 InfoExceptionCtrl[18] = 0x00; /* reserved */ 7654 InfoExceptionCtrl[19] = 0x00; /* reserved */ 7655 /* Block size */ 7656 InfoExceptionCtrl[20] = 0x00; 7657 InfoExceptionCtrl[21] = 0x00; 7658 InfoExceptionCtrl[22] = 0x02; /* Block size is always 512 bytes */ 7659 InfoExceptionCtrl[23] = 0x00; 7660 } 7661 else 7662 { 7663 /* density code */ 7664 InfoExceptionCtrl[8] = 0x04; /* density-code : reserved for direct-access */ 7665 /* number of blocks */ 7666 InfoExceptionCtrl[9] = 0x00; /* unspecified */ 7667 InfoExceptionCtrl[10] = 0x00; /* unspecified */ 7668 InfoExceptionCtrl[11] = 0x00; /* unspecified */ 7669 /* reserved */ 7670 InfoExceptionCtrl[12] = 0x00; /* reserved */ 7671 /* Block size */ 7672 InfoExceptionCtrl[13] = 0x00; 7673 InfoExceptionCtrl[14] = 0x02; /* Block size is always 512 bytes */ 7674 InfoExceptionCtrl[15] = 0x00; 7675 } 7676 7677 if (LLBAA) 7678 { 7679 index = 24; 7680 } 7681 else 7682 { 7683 index = 16; 7684 } 7685 /* 7686 * Fill-up informational-exceptions control mode page, SAT, Table 68 7687 */ 7688 InfoExceptionCtrl[index+0] = 0x1C; /* page code */ 7689 InfoExceptionCtrl[index+1] = 0x0A; /* page length */ 7690 if (pSatDevData->satSMARTEnabled == agTRUE) 7691 { 7692 InfoExceptionCtrl[index+2] = 0x00;/* DEXCPT bit is NOT set */ 7693 } 7694 else 7695 { 7696 InfoExceptionCtrl[index+2] = 0x08;/* DEXCPT bit is set */ 7697 } 7698 InfoExceptionCtrl[index+3] = 0x00; /* We don't support MRIE */ 7699 InfoExceptionCtrl[index+4] = 0x00; /* Interval timer vendor-specific */ 7700 InfoExceptionCtrl[index+5] = 0x00; 7701 InfoExceptionCtrl[index+6] = 0x00; 7702 InfoExceptionCtrl[index+7] = 0x00; 7703 InfoExceptionCtrl[index+8] = 0x00; /* REPORT-COUNT */ 7704 InfoExceptionCtrl[index+9] = 0x00; 7705 InfoExceptionCtrl[index+10] = 0x00; 7706 InfoExceptionCtrl[index+11] = 0x00; 7707 osti_memcpy(pModeSense, &InfoExceptionCtrl, lenRead); 7708 7709 } 7710 else 7711 { 7712 /* Error */ 7713 TI_DBG1(("satModeSense10: Error page %d\n", page)); 7714 satSetSensePayload( pSense, 7715 SCSI_SNSKEY_ILLEGAL_REQUEST, 7716 0, 7717 SCSI_SNSCODE_INVALID_COMMAND, 7718 satIOContext); 7719 7720 ostiInitiatorIOCompleted( tiRoot, 7721 tiIORequest, 7722 tiIOSuccess, 7723 SCSI_STAT_CHECK_CONDITION, 7724 satIOContext->pTiSenseData, 7725 satIOContext->interruptContext ); 7726 return tiSuccess; 7727 } 7728 7729 if (requestLen > lenRead) 7730 { 7731 TI_DBG1(("satModeSense10 reporting underrun lenRead=0x%x requestLen=0x%x tiIORequest=%p\n", lenRead, requestLen, tiIORequest)); 7732 7733 ostiInitiatorIOCompleted( tiRoot, 7734 tiIORequest, 7735 tiIOUnderRun, 7736 requestLen - lenRead, 7737 agNULL, 7738 satIOContext->interruptContext ); 7739 7740 7741 } 7742 else 7743 { 7744 ostiInitiatorIOCompleted( tiRoot, 7745 tiIORequest, 7746 tiIOSuccess, 7747 SCSI_STAT_GOOD, 7748 agNULL, 7749 satIOContext->interruptContext); 7750 } 7751 7752 return tiSuccess; 7753 } 7754 7755 7756 /*****************************************************************************/ 7757 /*! \brief SAT implementation for SCSI VERIFY (10). 7758 * 7759 * SAT implementation for SCSI VERIFY (10). 7760 * 7761 * \param tiRoot: Pointer to TISA initiator driver/port instance. 7762 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 7763 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 7764 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 7765 * \param satIOContext_t: Pointer to the SAT IO Context 7766 * 7767 * \return If command is started successfully 7768 * - \e tiSuccess: I/O request successfully initiated. 7769 * - \e tiBusy: No resources available, try again later. 7770 * - \e tiIONoDevice: Invalid device handle. 7771 * - \e tiError: Other errors. 7772 */ 7773 /*****************************************************************************/ 7774 GLOBAL bit32 satVerify10( 7775 tiRoot_t *tiRoot, 7776 tiIORequest_t *tiIORequest, 7777 tiDeviceHandle_t *tiDeviceHandle, 7778 tiScsiInitiatorRequest_t *tiScsiRequest, 7779 satIOContext_t *satIOContext) 7780 { 7781 /* 7782 For simple implementation, 7783 no byte comparison supported as of 4/5/06 7784 */ 7785 scsiRspSense_t *pSense; 7786 tiIniScsiCmnd_t *scsiCmnd; 7787 satDeviceData_t *pSatDevData; 7788 agsaFisRegHostToDevice_t *fis; 7789 bit32 status; 7790 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 7791 bit32 lba = 0; 7792 bit32 tl = 0; 7793 bit32 LoopNum = 1; 7794 bit8 LBA[4]; 7795 bit8 TL[4]; 7796 bit32 rangeChk = agFALSE; /* lba and tl range check */ 7797 7798 7799 TI_DBG5(("satVerify10 entry: tiDeviceHandle=%p tiIORequest=%p\n", 7800 tiDeviceHandle, tiIORequest)); 7801 7802 pSense = satIOContext->pSense; 7803 scsiCmnd = &tiScsiRequest->scsiCmnd; 7804 pSatDevData = satIOContext->pSatDevData; 7805 fis = satIOContext->pFis; 7806 7807 /* checking BYTCHK */ 7808 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK) 7809 { 7810 /* 7811 should do the byte check 7812 but not supported in this version 7813 */ 7814 satSetSensePayload( pSense, 7815 SCSI_SNSKEY_ILLEGAL_REQUEST, 7816 0, 7817 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 7818 satIOContext); 7819 7820 ostiInitiatorIOCompleted( tiRoot, 7821 tiIORequest, 7822 tiIOSuccess, 7823 SCSI_STAT_CHECK_CONDITION, 7824 satIOContext->pTiSenseData, 7825 satIOContext->interruptContext ); 7826 7827 TI_DBG1(("satVerify10: no byte checking \n")); 7828 return tiSuccess; 7829 } 7830 7831 /* checking CONTROL */ 7832 /* NACA == 1 or LINK == 1*/ 7833 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 7834 { 7835 satSetSensePayload( pSense, 7836 SCSI_SNSKEY_ILLEGAL_REQUEST, 7837 0, 7838 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 7839 satIOContext); 7840 7841 ostiInitiatorIOCompleted( tiRoot, 7842 tiIORequest, 7843 tiIOSuccess, 7844 SCSI_STAT_CHECK_CONDITION, 7845 satIOContext->pTiSenseData, 7846 satIOContext->interruptContext ); 7847 7848 TI_DBG2(("satVerify10: return control\n")); 7849 return tiSuccess; 7850 } 7851 7852 osti_memset(LBA, 0, sizeof(LBA)); 7853 osti_memset(TL, 0, sizeof(TL)); 7854 7855 /* do not use memcpy due to indexing in LBA and TL */ 7856 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 7857 LBA[1] = scsiCmnd->cdb[3]; 7858 LBA[2] = scsiCmnd->cdb[4]; 7859 LBA[3] = scsiCmnd->cdb[5]; /* LSB */ 7860 7861 TL[0] = 0; 7862 TL[1] = 0; 7863 TL[2] = scsiCmnd->cdb[7]; /* MSB */ 7864 TL[3] = scsiCmnd->cdb[8]; /* LSB */ 7865 7866 rangeChk = satAddNComparebit32(LBA, TL); 7867 7868 /* cbd10; computing LBA and transfer length */ 7869 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 7870 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 7871 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 7872 7873 if (pSatDevData->satNCQ != agTRUE && 7874 pSatDevData->sat48BitSupport != agTRUE 7875 ) 7876 { 7877 if (lba > SAT_TR_LBA_LIMIT - 1) 7878 { 7879 satSetSensePayload( pSense, 7880 SCSI_SNSKEY_ILLEGAL_REQUEST, 7881 0, 7882 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 7883 satIOContext); 7884 7885 ostiInitiatorIOCompleted( tiRoot, 7886 tiIORequest, 7887 tiIOSuccess, 7888 SCSI_STAT_CHECK_CONDITION, 7889 satIOContext->pTiSenseData, 7890 satIOContext->interruptContext ); 7891 7892 TI_DBG1(("satVerify10: return LBA out of range, not EXT\n")); 7893 TI_DBG1(("satVerify10: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3], 7894 scsiCmnd->cdb[4], scsiCmnd->cdb[5])); 7895 TI_DBG1(("satVerify10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT)); 7896 return tiSuccess; 7897 } 7898 7899 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 7900 { 7901 TI_DBG1(("satVerify10: return LBA+TL out of range, not EXT\n")); 7902 satSetSensePayload( pSense, 7903 SCSI_SNSKEY_ILLEGAL_REQUEST, 7904 0, 7905 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 7906 satIOContext); 7907 7908 ostiInitiatorIOCompleted( tiRoot, 7909 tiIORequest, 7910 tiIOSuccess, 7911 SCSI_STAT_CHECK_CONDITION, 7912 satIOContext->pTiSenseData, 7913 satIOContext->interruptContext ); 7914 7915 return tiSuccess; 7916 } 7917 } 7918 7919 if (pSatDevData->sat48BitSupport == agTRUE) 7920 { 7921 TI_DBG5(("satVerify10: SAT_READ_VERIFY_SECTORS_EXT\n")); 7922 fis->h.fisType = 0x27; /* Reg host to device */ 7923 fis->h.c_pmPort = 0x80; /* C Bit is set */ 7924 7925 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 7926 fis->h.features = 0; /* FIS reserve */ 7927 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 7928 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 7929 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 7930 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 7931 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 7932 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 7933 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 7934 fis->d.featuresExp = 0; /* FIS reserve */ 7935 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 7936 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 7937 7938 fis->d.reserved4 = 0; 7939 fis->d.control = 0; /* FIS HOB bit clear */ 7940 fis->d.reserved5 = 0; 7941 7942 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 7943 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT; 7944 } 7945 else 7946 { 7947 TI_DBG5(("satVerify10: SAT_READ_VERIFY_SECTORS\n")); 7948 fis->h.fisType = 0x27; /* Reg host to device */ 7949 fis->h.c_pmPort = 0x80; /* C bit is set */ 7950 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 7951 fis->h.features = 0; /* FIS reserve */ 7952 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 7953 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 7954 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 7955 /* FIS LBA mode set LBA (27:24) */ 7956 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 7957 fis->d.lbaLowExp = 0; 7958 fis->d.lbaMidExp = 0; 7959 fis->d.lbaHighExp = 0; 7960 fis->d.featuresExp = 0; 7961 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 7962 fis->d.sectorCountExp = 0; 7963 fis->d.reserved4 = 0; 7964 fis->d.control = 0; /* FIS HOB bit clear */ 7965 fis->d.reserved5 = 0; 7966 7967 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 7968 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS; 7969 7970 } 7971 7972 satIOContext->currentLBA = lba; 7973 satIOContext->OrgTL = tl; 7974 7975 /* 7976 computing number of loop and remainder for tl 7977 0xFF in case not ext 7978 0xFFFF in case EXT 7979 */ 7980 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 7981 { 7982 LoopNum = satComputeLoopNum(tl, 0xFF); 7983 } 7984 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 7985 { 7986 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 7987 LoopNum = satComputeLoopNum(tl, 0xFFFF); 7988 } 7989 else 7990 { 7991 TI_DBG1(("satVerify10: error case 1!!!\n")); 7992 LoopNum = 1; 7993 } 7994 7995 satIOContext->LoopNum = LoopNum; 7996 7997 if (LoopNum == 1) 7998 { 7999 TI_DBG5(("satVerify10: NON CHAINED data\n")); 8000 /* Initialize CB for SATA completion. 8001 */ 8002 satIOContext->satCompleteCB = &satNonChainedVerifyCB; 8003 } 8004 else 8005 { 8006 TI_DBG1(("satVerify10: CHAINED data\n")); 8007 /* re-setting tl */ 8008 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 8009 { 8010 fis->d.sectorCount = 0xFF; 8011 } 8012 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 8013 { 8014 fis->d.sectorCount = 0xFF; 8015 fis->d.sectorCountExp = 0xFF; 8016 } 8017 else 8018 { 8019 TI_DBG1(("satVerify10: error case 2!!!\n")); 8020 } 8021 8022 /* Initialize CB for SATA completion. 8023 */ 8024 satIOContext->satCompleteCB = &satChainedVerifyCB; 8025 } 8026 8027 8028 /* 8029 * Prepare SGL and send FIS to LL layer. 8030 */ 8031 satIOContext->reqType = agRequestType; /* Save it */ 8032 8033 status = sataLLIOStart( tiRoot, 8034 tiIORequest, 8035 tiDeviceHandle, 8036 tiScsiRequest, 8037 satIOContext); 8038 return (status); 8039 } 8040 8041 GLOBAL bit32 satChainedVerify( 8042 tiRoot_t *tiRoot, 8043 tiIORequest_t *tiIORequest, 8044 tiDeviceHandle_t *tiDeviceHandle, 8045 tiScsiInitiatorRequest_t *tiScsiRequest, 8046 satIOContext_t *satIOContext) 8047 { 8048 bit32 status; 8049 satIOContext_t *satOrgIOContext = agNULL; 8050 agsaFisRegHostToDevice_t *fis; 8051 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8052 bit32 lba = 0; 8053 bit32 DenomTL = 0xFF; 8054 bit32 Remainder = 0; 8055 bit8 LBA[4]; /* 0 MSB, 3 LSB */ 8056 8057 TI_DBG2(("satChainedVerify: start\n")); 8058 8059 fis = satIOContext->pFis; 8060 satOrgIOContext = satIOContext->satOrgIOContext; 8061 osti_memset(LBA,0, sizeof(LBA)); 8062 8063 switch (satOrgIOContext->ATACmd) 8064 { 8065 case SAT_READ_VERIFY_SECTORS: 8066 DenomTL = 0xFF; 8067 break; 8068 case SAT_READ_VERIFY_SECTORS_EXT: 8069 DenomTL = 0xFFFF; 8070 break; 8071 default: 8072 TI_DBG1(("satChainedVerify: error incorrect ata command 0x%x\n", satIOContext->ATACmd)); 8073 return tiError; 8074 break; 8075 } 8076 8077 Remainder = satOrgIOContext->OrgTL % DenomTL; 8078 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL; 8079 lba = satOrgIOContext->currentLBA; 8080 8081 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */ 8082 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2)); 8083 LBA[2] = (bit8)((lba & 0xF0) >> 8); 8084 LBA[3] = (bit8)(lba & 0xF); /* LSB */ 8085 8086 switch (satOrgIOContext->ATACmd) 8087 { 8088 case SAT_READ_VERIFY_SECTORS: 8089 fis->h.fisType = 0x27; /* Reg host to device */ 8090 fis->h.c_pmPort = 0x80; /* C bit is set */ 8091 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 8092 fis->h.features = 0; /* FIS reserve */ 8093 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 8094 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 8095 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 8096 8097 /* FIS LBA mode set LBA (27:24) */ 8098 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 8099 8100 fis->d.lbaLowExp = 0; 8101 fis->d.lbaMidExp = 0; 8102 fis->d.lbaHighExp = 0; 8103 fis->d.featuresExp = 0; 8104 if (satOrgIOContext->LoopNum == 1) 8105 { 8106 /* last loop */ 8107 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 8108 } 8109 else 8110 { 8111 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 8112 } 8113 fis->d.sectorCountExp = 0; 8114 fis->d.reserved4 = 0; 8115 fis->d.control = 0; /* FIS HOB bit clear */ 8116 fis->d.reserved5 = 0; 8117 8118 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8119 8120 break; 8121 case SAT_READ_VERIFY_SECTORS_EXT: 8122 fis->h.fisType = 0x27; /* Reg host to device */ 8123 fis->h.c_pmPort = 0x80; /* C Bit is set */ 8124 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT; /* 0x42 */ 8125 fis->h.features = 0; /* FIS reserve */ 8126 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 8127 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 8128 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 8129 fis->d.device = 0x40; /* FIS LBA mode set */ 8130 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 8131 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 8132 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 8133 fis->d.featuresExp = 0; /* FIS reserve */ 8134 if (satOrgIOContext->LoopNum == 1) 8135 { 8136 /* last loop */ 8137 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 8138 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 8139 } 8140 else 8141 { 8142 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 8143 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 8144 } 8145 fis->d.reserved4 = 0; 8146 fis->d.control = 0; /* FIS HOB bit clear */ 8147 fis->d.reserved5 = 0; 8148 8149 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8150 8151 break; 8152 8153 default: 8154 TI_DBG1(("satChainedVerify: error incorrect ata command 0x%x\n", satIOContext->ATACmd)); 8155 return tiError; 8156 break; 8157 } 8158 8159 /* Initialize CB for SATA completion. 8160 */ 8161 /* chained data */ 8162 satIOContext->satCompleteCB = &satChainedVerifyCB; 8163 8164 8165 /* 8166 * Prepare SGL and send FIS to LL layer. 8167 */ 8168 satIOContext->reqType = agRequestType; /* Save it */ 8169 8170 status = sataLLIOStart( tiRoot, 8171 tiIORequest, 8172 tiDeviceHandle, 8173 tiScsiRequest, 8174 satIOContext); 8175 8176 TI_DBG5(("satChainedVerify: return\n")); 8177 return (status); 8178 8179 } 8180 8181 8182 /*****************************************************************************/ 8183 /*! \brief SAT implementation for SCSI VERIFY (12). 8184 * 8185 * SAT implementation for SCSI VERIFY (12). 8186 * 8187 * \param tiRoot: Pointer to TISA initiator driver/port instance. 8188 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 8189 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 8190 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 8191 * \param satIOContext_t: Pointer to the SAT IO Context 8192 * 8193 * \return If command is started successfully 8194 * - \e tiSuccess: I/O request successfully initiated. 8195 * - \e tiBusy: No resources available, try again later. 8196 * - \e tiIONoDevice: Invalid device handle. 8197 * - \e tiError: Other errors. 8198 */ 8199 /*****************************************************************************/ 8200 GLOBAL bit32 satVerify12( 8201 tiRoot_t *tiRoot, 8202 tiIORequest_t *tiIORequest, 8203 tiDeviceHandle_t *tiDeviceHandle, 8204 tiScsiInitiatorRequest_t *tiScsiRequest, 8205 satIOContext_t *satIOContext) 8206 { 8207 /* 8208 For simple implementation, 8209 no byte comparison supported as of 4/5/06 8210 */ 8211 scsiRspSense_t *pSense; 8212 tiIniScsiCmnd_t *scsiCmnd; 8213 satDeviceData_t *pSatDevData; 8214 agsaFisRegHostToDevice_t *fis; 8215 bit32 status; 8216 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8217 bit32 lba = 0; 8218 bit32 tl = 0; 8219 bit32 LoopNum = 1; 8220 bit8 LBA[4]; 8221 bit8 TL[4]; 8222 bit32 rangeChk = agFALSE; /* lba and tl range check */ 8223 8224 TI_DBG5(("satVerify12 entry: tiDeviceHandle=%p tiIORequest=%p\n", 8225 tiDeviceHandle, tiIORequest)); 8226 8227 pSense = satIOContext->pSense; 8228 scsiCmnd = &tiScsiRequest->scsiCmnd; 8229 pSatDevData = satIOContext->pSatDevData; 8230 fis = satIOContext->pFis; 8231 8232 8233 /* checking BYTCHK */ 8234 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK) 8235 { 8236 /* 8237 should do the byte check 8238 but not supported in this version 8239 */ 8240 satSetSensePayload( pSense, 8241 SCSI_SNSKEY_ILLEGAL_REQUEST, 8242 0, 8243 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8244 satIOContext); 8245 8246 ostiInitiatorIOCompleted( tiRoot, 8247 tiIORequest, 8248 tiIOSuccess, 8249 SCSI_STAT_CHECK_CONDITION, 8250 satIOContext->pTiSenseData, 8251 satIOContext->interruptContext ); 8252 8253 TI_DBG1(("satVerify12: no byte checking \n")); 8254 return tiSuccess; 8255 } 8256 8257 /* checking CONTROL */ 8258 /* NACA == 1 or LINK == 1*/ 8259 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) ) 8260 { 8261 satSetSensePayload( pSense, 8262 SCSI_SNSKEY_ILLEGAL_REQUEST, 8263 0, 8264 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8265 satIOContext); 8266 8267 ostiInitiatorIOCompleted( tiRoot, 8268 tiIORequest, 8269 tiIOSuccess, 8270 SCSI_STAT_CHECK_CONDITION, 8271 satIOContext->pTiSenseData, 8272 satIOContext->interruptContext ); 8273 8274 TI_DBG1(("satVerify12: return control\n")); 8275 return tiSuccess; 8276 } 8277 8278 osti_memset(LBA, 0, sizeof(LBA)); 8279 osti_memset(TL, 0, sizeof(TL)); 8280 8281 /* do not use memcpy due to indexing in LBA and TL */ 8282 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 8283 LBA[1] = scsiCmnd->cdb[3]; 8284 LBA[2] = scsiCmnd->cdb[4]; 8285 LBA[3] = scsiCmnd->cdb[5]; /* LSB */ 8286 8287 TL[0] = scsiCmnd->cdb[6]; /* MSB */ 8288 TL[1] = scsiCmnd->cdb[7]; 8289 TL[2] = scsiCmnd->cdb[7]; 8290 TL[3] = scsiCmnd->cdb[8]; /* LSB */ 8291 8292 rangeChk = satAddNComparebit32(LBA, TL); 8293 8294 lba = satComputeCDB12LBA(satIOContext); 8295 tl = satComputeCDB12TL(satIOContext); 8296 8297 if (pSatDevData->satNCQ != agTRUE && 8298 pSatDevData->sat48BitSupport != agTRUE 8299 ) 8300 { 8301 if (lba > SAT_TR_LBA_LIMIT - 1) 8302 { 8303 satSetSensePayload( pSense, 8304 SCSI_SNSKEY_ILLEGAL_REQUEST, 8305 0, 8306 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 8307 satIOContext); 8308 8309 ostiInitiatorIOCompleted( tiRoot, 8310 tiIORequest, 8311 tiIOSuccess, 8312 SCSI_STAT_CHECK_CONDITION, 8313 satIOContext->pTiSenseData, 8314 satIOContext->interruptContext ); 8315 8316 TI_DBG1(("satVerify12: return LBA out of range, not EXT\n")); 8317 TI_DBG1(("satVerify12: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3], 8318 scsiCmnd->cdb[4], scsiCmnd->cdb[5])); 8319 TI_DBG1(("satVerify12: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT)); 8320 return tiSuccess; 8321 } 8322 8323 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 8324 { 8325 TI_DBG1(("satVerify12: return LBA+TL out of range, not EXT\n")); 8326 satSetSensePayload( pSense, 8327 SCSI_SNSKEY_ILLEGAL_REQUEST, 8328 0, 8329 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 8330 satIOContext); 8331 8332 ostiInitiatorIOCompleted( tiRoot, 8333 tiIORequest, 8334 tiIOSuccess, 8335 SCSI_STAT_CHECK_CONDITION, 8336 satIOContext->pTiSenseData, 8337 satIOContext->interruptContext ); 8338 8339 return tiSuccess; 8340 } 8341 } 8342 8343 if (pSatDevData->sat48BitSupport == agTRUE) 8344 { 8345 TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS_EXT\n")); 8346 fis->h.fisType = 0x27; /* Reg host to device */ 8347 fis->h.c_pmPort = 0x80; /* C Bit is set */ 8348 8349 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 8350 fis->h.features = 0; /* FIS reserve */ 8351 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 8352 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 8353 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 8354 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 8355 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 8356 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 8357 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 8358 fis->d.featuresExp = 0; /* FIS reserve */ 8359 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 8360 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 8361 8362 fis->d.reserved4 = 0; 8363 fis->d.control = 0; /* FIS HOB bit clear */ 8364 fis->d.reserved5 = 0; 8365 8366 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8367 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT; 8368 } 8369 else 8370 { 8371 TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS\n")); 8372 fis->h.fisType = 0x27; /* Reg host to device */ 8373 fis->h.c_pmPort = 0x80; /* C bit is set */ 8374 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 8375 fis->h.features = 0; /* FIS reserve */ 8376 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 8377 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 8378 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 8379 /* FIS LBA mode set LBA (27:24) */ 8380 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 8381 fis->d.lbaLowExp = 0; 8382 fis->d.lbaMidExp = 0; 8383 fis->d.lbaHighExp = 0; 8384 fis->d.featuresExp = 0; 8385 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 8386 fis->d.sectorCountExp = 0; 8387 fis->d.reserved4 = 0; 8388 fis->d.control = 0; /* FIS HOB bit clear */ 8389 fis->d.reserved5 = 0; 8390 8391 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8392 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS; 8393 8394 } 8395 8396 satIOContext->currentLBA = lba; 8397 satIOContext->OrgTL = tl; 8398 8399 /* 8400 computing number of loop and remainder for tl 8401 0xFF in case not ext 8402 0xFFFF in case EXT 8403 */ 8404 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 8405 { 8406 LoopNum = satComputeLoopNum(tl, 0xFF); 8407 } 8408 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 8409 { 8410 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 8411 LoopNum = satComputeLoopNum(tl, 0xFFFF); 8412 } 8413 else 8414 { 8415 TI_DBG1(("satVerify12: error case 1!!!\n")); 8416 LoopNum = 1; 8417 } 8418 8419 satIOContext->LoopNum = LoopNum; 8420 8421 if (LoopNum == 1) 8422 { 8423 TI_DBG5(("satVerify12: NON CHAINED data\n")); 8424 /* Initialize CB for SATA completion. 8425 */ 8426 satIOContext->satCompleteCB = &satNonChainedVerifyCB; 8427 } 8428 else 8429 { 8430 TI_DBG1(("satVerify12: CHAINED data\n")); 8431 /* re-setting tl */ 8432 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 8433 { 8434 fis->d.sectorCount = 0xFF; 8435 } 8436 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 8437 { 8438 fis->d.sectorCount = 0xFF; 8439 fis->d.sectorCountExp = 0xFF; 8440 } 8441 else 8442 { 8443 TI_DBG1(("satVerify10: error case 2!!!\n")); 8444 } 8445 8446 /* Initialize CB for SATA completion. 8447 */ 8448 satIOContext->satCompleteCB = &satChainedVerifyCB; 8449 } 8450 8451 8452 /* 8453 * Prepare SGL and send FIS to LL layer. 8454 */ 8455 satIOContext->reqType = agRequestType; /* Save it */ 8456 8457 status = sataLLIOStart( tiRoot, 8458 tiIORequest, 8459 tiDeviceHandle, 8460 tiScsiRequest, 8461 satIOContext); 8462 return (status); 8463 } 8464 /*****************************************************************************/ 8465 /*! \brief SAT implementation for SCSI VERIFY (16). 8466 * 8467 * SAT implementation for SCSI VERIFY (16). 8468 * 8469 * \param tiRoot: Pointer to TISA initiator driver/port instance. 8470 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 8471 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 8472 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 8473 * \param satIOContext_t: Pointer to the SAT IO Context 8474 * 8475 * \return If command is started successfully 8476 * - \e tiSuccess: I/O request successfully initiated. 8477 * - \e tiBusy: No resources available, try again later. 8478 * - \e tiIONoDevice: Invalid device handle. 8479 * - \e tiError: Other errors. 8480 */ 8481 /*****************************************************************************/ 8482 GLOBAL bit32 satVerify16( 8483 tiRoot_t *tiRoot, 8484 tiIORequest_t *tiIORequest, 8485 tiDeviceHandle_t *tiDeviceHandle, 8486 tiScsiInitiatorRequest_t *tiScsiRequest, 8487 satIOContext_t *satIOContext) 8488 { 8489 /* 8490 For simple implementation, 8491 no byte comparison supported as of 4/5/06 8492 */ 8493 scsiRspSense_t *pSense; 8494 tiIniScsiCmnd_t *scsiCmnd; 8495 satDeviceData_t *pSatDevData; 8496 agsaFisRegHostToDevice_t *fis; 8497 bit32 status; 8498 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8499 bit32 lba = 0; 8500 bit32 tl = 0; 8501 bit32 LoopNum = 1; 8502 bit8 LBA[8]; 8503 bit8 TL[8]; 8504 bit32 rangeChk = agFALSE; /* lba and tl range check */ 8505 bit32 limitChk = agFALSE; /* lba and tl range check */ 8506 8507 TI_DBG5(("satVerify16 entry: tiDeviceHandle=%p tiIORequest=%p\n", 8508 tiDeviceHandle, tiIORequest)); 8509 8510 pSense = satIOContext->pSense; 8511 scsiCmnd = &tiScsiRequest->scsiCmnd; 8512 pSatDevData = satIOContext->pSatDevData; 8513 fis = satIOContext->pFis; 8514 8515 /* checking BYTCHK */ 8516 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK) 8517 { 8518 /* 8519 should do the byte check 8520 but not supported in this version 8521 */ 8522 satSetSensePayload( pSense, 8523 SCSI_SNSKEY_ILLEGAL_REQUEST, 8524 0, 8525 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8526 satIOContext); 8527 8528 ostiInitiatorIOCompleted( tiRoot, 8529 tiIORequest, 8530 tiIOSuccess, 8531 SCSI_STAT_CHECK_CONDITION, 8532 satIOContext->pTiSenseData, 8533 satIOContext->interruptContext ); 8534 8535 TI_DBG1(("satVerify16: no byte checking \n")); 8536 return tiSuccess; 8537 } 8538 8539 /* checking CONTROL */ 8540 /* NACA == 1 or LINK == 1*/ 8541 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 8542 { 8543 satSetSensePayload( pSense, 8544 SCSI_SNSKEY_ILLEGAL_REQUEST, 8545 0, 8546 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8547 satIOContext); 8548 8549 ostiInitiatorIOCompleted( tiRoot, 8550 tiIORequest, 8551 tiIOSuccess, 8552 SCSI_STAT_CHECK_CONDITION, 8553 satIOContext->pTiSenseData, 8554 satIOContext->interruptContext ); 8555 8556 TI_DBG2(("satVerify16: return control\n")); 8557 return tiSuccess; 8558 } 8559 8560 osti_memset(LBA, 0, sizeof(LBA)); 8561 osti_memset(TL, 0, sizeof(TL)); 8562 8563 8564 /* do not use memcpy due to indexing in LBA and TL */ 8565 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 8566 LBA[1] = scsiCmnd->cdb[3]; 8567 LBA[2] = scsiCmnd->cdb[4]; 8568 LBA[3] = scsiCmnd->cdb[5]; 8569 LBA[4] = scsiCmnd->cdb[6]; 8570 LBA[5] = scsiCmnd->cdb[7]; 8571 LBA[6] = scsiCmnd->cdb[8]; 8572 LBA[7] = scsiCmnd->cdb[9]; /* LSB */ 8573 8574 TL[0] = 0; 8575 TL[1] = 0; 8576 TL[2] = 0; 8577 TL[3] = 0; 8578 TL[4] = scsiCmnd->cdb[10]; /* MSB */ 8579 TL[5] = scsiCmnd->cdb[11]; 8580 TL[6] = scsiCmnd->cdb[12]; 8581 TL[7] = scsiCmnd->cdb[13]; /* LSB */ 8582 8583 rangeChk = satAddNComparebit64(LBA, TL); 8584 8585 limitChk = satCompareLBALimitbit(LBA); 8586 8587 lba = satComputeCDB16LBA(satIOContext); 8588 tl = satComputeCDB16TL(satIOContext); 8589 8590 if (pSatDevData->satNCQ != agTRUE && 8591 pSatDevData->sat48BitSupport != agTRUE 8592 ) 8593 { 8594 if (limitChk) 8595 { 8596 TI_DBG1(("satVerify16: return LBA out of range, not EXT\n")); 8597 satSetSensePayload( pSense, 8598 SCSI_SNSKEY_ILLEGAL_REQUEST, 8599 0, 8600 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 8601 satIOContext); 8602 8603 ostiInitiatorIOCompleted( tiRoot, 8604 tiIORequest, 8605 tiIOSuccess, 8606 SCSI_STAT_CHECK_CONDITION, 8607 satIOContext->pTiSenseData, 8608 satIOContext->interruptContext ); 8609 8610 return tiSuccess; 8611 } 8612 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 8613 { 8614 TI_DBG1(("satVerify16: return LBA+TL out of range, not EXT\n")); 8615 satSetSensePayload( pSense, 8616 SCSI_SNSKEY_ILLEGAL_REQUEST, 8617 0, 8618 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 8619 satIOContext); 8620 8621 ostiInitiatorIOCompleted( tiRoot, 8622 tiIORequest, 8623 tiIOSuccess, 8624 SCSI_STAT_CHECK_CONDITION, 8625 satIOContext->pTiSenseData, 8626 satIOContext->interruptContext ); 8627 8628 return tiSuccess; 8629 } 8630 } 8631 8632 if (pSatDevData->sat48BitSupport == agTRUE) 8633 { 8634 TI_DBG5(("satVerify16: SAT_READ_VERIFY_SECTORS_EXT\n")); 8635 fis->h.fisType = 0x27; /* Reg host to device */ 8636 fis->h.c_pmPort = 0x80; /* C Bit is set */ 8637 8638 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 8639 fis->h.features = 0; /* FIS reserve */ 8640 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 8641 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 8642 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 8643 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 8644 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 8645 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 8646 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 8647 fis->d.featuresExp = 0; /* FIS reserve */ 8648 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 8649 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 8650 8651 fis->d.reserved4 = 0; 8652 fis->d.control = 0; /* FIS HOB bit clear */ 8653 fis->d.reserved5 = 0; 8654 8655 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8656 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT; 8657 } 8658 else 8659 { 8660 TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS\n")); 8661 fis->h.fisType = 0x27; /* Reg host to device */ 8662 fis->h.c_pmPort = 0x80; /* C bit is set */ 8663 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 8664 fis->h.features = 0; /* FIS reserve */ 8665 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 8666 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 8667 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 8668 /* FIS LBA mode set LBA (27:24) */ 8669 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); 8670 fis->d.lbaLowExp = 0; 8671 fis->d.lbaMidExp = 0; 8672 fis->d.lbaHighExp = 0; 8673 fis->d.featuresExp = 0; 8674 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 8675 fis->d.sectorCountExp = 0; 8676 fis->d.reserved4 = 0; 8677 fis->d.control = 0; /* FIS HOB bit clear */ 8678 fis->d.reserved5 = 0; 8679 8680 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8681 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS; 8682 8683 } 8684 8685 satIOContext->currentLBA = lba; 8686 satIOContext->OrgTL = tl; 8687 8688 /* 8689 computing number of loop and remainder for tl 8690 0xFF in case not ext 8691 0xFFFF in case EXT 8692 */ 8693 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 8694 { 8695 LoopNum = satComputeLoopNum(tl, 0xFF); 8696 } 8697 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 8698 { 8699 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 8700 LoopNum = satComputeLoopNum(tl, 0xFFFF); 8701 } 8702 else 8703 { 8704 TI_DBG1(("satVerify12: error case 1!!!\n")); 8705 LoopNum = 1; 8706 } 8707 8708 satIOContext->LoopNum = LoopNum; 8709 8710 if (LoopNum == 1) 8711 { 8712 TI_DBG5(("satVerify12: NON CHAINED data\n")); 8713 /* Initialize CB for SATA completion. 8714 */ 8715 satIOContext->satCompleteCB = &satNonChainedVerifyCB; 8716 } 8717 else 8718 { 8719 TI_DBG1(("satVerify12: CHAINED data\n")); 8720 /* re-setting tl */ 8721 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 8722 { 8723 fis->d.sectorCount = 0xFF; 8724 } 8725 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 8726 { 8727 fis->d.sectorCount = 0xFF; 8728 fis->d.sectorCountExp = 0xFF; 8729 } 8730 else 8731 { 8732 TI_DBG1(("satVerify10: error case 2!!!\n")); 8733 } 8734 8735 /* Initialize CB for SATA completion. 8736 */ 8737 satIOContext->satCompleteCB = &satChainedVerifyCB; 8738 } 8739 8740 8741 /* 8742 * Prepare SGL and send FIS to LL layer. 8743 */ 8744 satIOContext->reqType = agRequestType; /* Save it */ 8745 8746 status = sataLLIOStart( tiRoot, 8747 tiIORequest, 8748 tiDeviceHandle, 8749 tiScsiRequest, 8750 satIOContext); 8751 return (status); 8752 } 8753 /*****************************************************************************/ 8754 /*! \brief SAT implementation for SCSI satFormatUnit. 8755 * 8756 * SAT implementation for SCSI satFormatUnit. 8757 * 8758 * \param tiRoot: Pointer to TISA initiator driver/port instance. 8759 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 8760 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 8761 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 8762 * \param satIOContext_t: Pointer to the SAT IO Context 8763 * 8764 * \return If command is started successfully 8765 * - \e tiSuccess: I/O request successfully initiated. 8766 * - \e tiBusy: No resources available, try again later. 8767 * - \e tiIONoDevice: Invalid device handle. 8768 * - \e tiError: Other errors. 8769 */ 8770 /*****************************************************************************/ 8771 GLOBAL bit32 satFormatUnit( 8772 tiRoot_t *tiRoot, 8773 tiIORequest_t *tiIORequest, 8774 tiDeviceHandle_t *tiDeviceHandle, 8775 tiScsiInitiatorRequest_t *tiScsiRequest, 8776 satIOContext_t *satIOContext) 8777 { 8778 /* 8779 note: we don't support media certification in this version and IP bit 8780 satDevData->satFormatState will be agFalse since SAT does not actually sends 8781 any ATA command 8782 */ 8783 8784 scsiRspSense_t *pSense; 8785 tiIniScsiCmnd_t *scsiCmnd; 8786 bit32 index = 0; 8787 8788 pSense = satIOContext->pSense; 8789 scsiCmnd = &tiScsiRequest->scsiCmnd; 8790 8791 TI_DBG5(("satFormatUnit:start\n")); 8792 8793 /* 8794 checking opcode 8795 1. FMTDATA bit == 0(no defect list header) 8796 2. FMTDATA bit == 1 and DCRT bit == 1(defect list header is provided 8797 with DCRT bit set) 8798 */ 8799 if ( ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) == 0) || 8800 ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) && 8801 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK)) 8802 ) 8803 { 8804 ostiInitiatorIOCompleted( tiRoot, 8805 tiIORequest, 8806 tiIOSuccess, 8807 SCSI_STAT_GOOD, 8808 agNULL, 8809 satIOContext->interruptContext); 8810 8811 TI_DBG2(("satFormatUnit: return opcode\n")); 8812 return tiSuccess; 8813 } 8814 8815 /* 8816 checking DEFECT LIST FORMAT and defect list length 8817 */ 8818 if ( (((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x00) || 8819 ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x06)) ) 8820 { 8821 /* short parameter header */ 8822 if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x00) 8823 { 8824 index = 8; 8825 } 8826 /* long parameter header */ 8827 if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x01) 8828 { 8829 index = 10; 8830 } 8831 /* defect list length */ 8832 if ((scsiCmnd->cdb[index] != 0) || (scsiCmnd->cdb[index+1] != 0)) 8833 { 8834 satSetSensePayload( pSense, 8835 SCSI_SNSKEY_ILLEGAL_REQUEST, 8836 0, 8837 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8838 satIOContext); 8839 8840 ostiInitiatorIOCompleted( tiRoot, 8841 tiIORequest, 8842 tiIOSuccess, 8843 SCSI_STAT_CHECK_CONDITION, 8844 satIOContext->pTiSenseData, 8845 satIOContext->interruptContext ); 8846 8847 TI_DBG1(("satFormatUnit: return defect list format\n")); 8848 return tiSuccess; 8849 } 8850 } 8851 8852 /* FMTDATA == 1 && CMPLIST == 1*/ 8853 if ( (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) && 8854 (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_CMPLIST_MASK) ) 8855 { 8856 satSetSensePayload( pSense, 8857 SCSI_SNSKEY_ILLEGAL_REQUEST, 8858 0, 8859 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8860 satIOContext); 8861 8862 ostiInitiatorIOCompleted( tiRoot, 8863 tiIORequest, 8864 tiIOSuccess, 8865 SCSI_STAT_CHECK_CONDITION, 8866 satIOContext->pTiSenseData, 8867 satIOContext->interruptContext ); 8868 8869 TI_DBG1(("satFormatUnit: return cmplist\n")); 8870 return tiSuccess; 8871 8872 } 8873 8874 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 8875 { 8876 satSetSensePayload( pSense, 8877 SCSI_SNSKEY_ILLEGAL_REQUEST, 8878 0, 8879 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8880 satIOContext); 8881 8882 ostiInitiatorIOCompleted( tiRoot, 8883 tiIORequest, 8884 tiIOSuccess, 8885 SCSI_STAT_CHECK_CONDITION, 8886 satIOContext->pTiSenseData, 8887 satIOContext->interruptContext ); 8888 8889 TI_DBG1(("satFormatUnit: return control\n")); 8890 return tiSuccess; 8891 } 8892 8893 /* defect list header filed, if exists, SAT rev8, Table 37, p48 */ 8894 if (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) 8895 { 8896 /* case 1,2,3 */ 8897 /* IMMED 1; FOV 0; FOV 1, DCRT 1, IP 0 */ 8898 if ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) || 8899 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK)) || 8900 ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) && 8901 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) && 8902 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK)) 8903 ) 8904 { 8905 ostiInitiatorIOCompleted( tiRoot, 8906 tiIORequest, 8907 tiIOSuccess, 8908 SCSI_STAT_GOOD, 8909 agNULL, 8910 satIOContext->interruptContext); 8911 8912 TI_DBG5(("satFormatUnit: return defect list case 1\n")); 8913 return tiSuccess; 8914 } 8915 /* case 4,5,6 */ 8916 /* 8917 1. IMMED 0, FOV 1, DCRT 0, IP 0 8918 2. IMMED 0, FOV 1, DCRT 0, IP 1 8919 3. IMMED 0, FOV 1, DCRT 1, IP 1 8920 */ 8921 8922 if ( ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) && 8923 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) && 8924 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) && 8925 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) ) 8926 || 8927 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) && 8928 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) && 8929 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) && 8930 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) ) 8931 || 8932 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) && 8933 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) && 8934 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) && 8935 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) ) 8936 ) 8937 { 8938 8939 satSetSensePayload( pSense, 8940 SCSI_SNSKEY_ILLEGAL_REQUEST, 8941 0, 8942 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 8943 satIOContext); 8944 8945 ostiInitiatorIOCompleted( tiRoot, 8946 tiIORequest, 8947 tiIOSuccess, 8948 SCSI_STAT_CHECK_CONDITION, 8949 satIOContext->pTiSenseData, 8950 satIOContext->interruptContext ); 8951 8952 TI_DBG5(("satFormatUnit: return defect list case 2\n")); 8953 return tiSuccess; 8954 8955 } 8956 } 8957 8958 8959 /* 8960 * Send the completion response now. 8961 */ 8962 ostiInitiatorIOCompleted( tiRoot, 8963 tiIORequest, 8964 tiIOSuccess, 8965 SCSI_STAT_GOOD, 8966 agNULL, 8967 satIOContext->interruptContext); 8968 8969 TI_DBG5(("satFormatUnit: return last\n")); 8970 return tiSuccess; 8971 } 8972 8973 8974 /*****************************************************************************/ 8975 /*! \brief SAT implementation for SCSI satSendDiagnostic. 8976 * 8977 * SAT implementation for SCSI satSendDiagnostic. 8978 * 8979 * \param tiRoot: Pointer to TISA initiator driver/port instance. 8980 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 8981 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 8982 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 8983 * \param satIOContext_t: Pointer to the SAT IO Context 8984 * 8985 * \return If command is started successfully 8986 * - \e tiSuccess: I/O request successfully initiated. 8987 * - \e tiBusy: No resources available, try again later. 8988 * - \e tiIONoDevice: Invalid device handle. 8989 * - \e tiError: Other errors. 8990 */ 8991 /*****************************************************************************/ 8992 GLOBAL bit32 satSendDiagnostic( 8993 tiRoot_t *tiRoot, 8994 tiIORequest_t *tiIORequest, 8995 tiDeviceHandle_t *tiDeviceHandle, 8996 tiScsiInitiatorRequest_t *tiScsiRequest, 8997 satIOContext_t *satIOContext) 8998 { 8999 bit32 status; 9000 bit32 agRequestType; 9001 satDeviceData_t *pSatDevData; 9002 scsiRspSense_t *pSense; 9003 tiIniScsiCmnd_t *scsiCmnd; 9004 agsaFisRegHostToDevice_t *fis; 9005 bit32 parmLen; 9006 9007 pSense = satIOContext->pSense; 9008 pSatDevData = satIOContext->pSatDevData; 9009 scsiCmnd = &tiScsiRequest->scsiCmnd; 9010 fis = satIOContext->pFis; 9011 9012 TI_DBG5(("satSendDiagnostic:start\n")); 9013 9014 /* reset satVerifyState */ 9015 pSatDevData->satVerifyState = 0; 9016 /* no pending diagnostic in background */ 9017 pSatDevData->satBGPendingDiag = agFALSE; 9018 9019 /* table 27, 8.10 p39 SAT Rev8 */ 9020 /* 9021 1. checking PF == 1 9022 2. checking DEVOFFL == 1 9023 3. checking UNITOFFL == 1 9024 4. checking PARAMETER LIST LENGTH != 0 9025 9026 */ 9027 if ( (scsiCmnd->cdb[1] & SCSI_PF_MASK) || 9028 (scsiCmnd->cdb[1] & SCSI_DEVOFFL_MASK) || 9029 (scsiCmnd->cdb[1] & SCSI_UNITOFFL_MASK) || 9030 ( (scsiCmnd->cdb[3] != 0) || (scsiCmnd->cdb[4] != 0) ) 9031 ) 9032 { 9033 satSetSensePayload( pSense, 9034 SCSI_SNSKEY_ILLEGAL_REQUEST, 9035 0, 9036 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9037 satIOContext); 9038 9039 ostiInitiatorIOCompleted( tiRoot, 9040 tiIORequest, 9041 tiIOSuccess, 9042 SCSI_STAT_CHECK_CONDITION, 9043 satIOContext->pTiSenseData, 9044 satIOContext->interruptContext ); 9045 9046 TI_DBG1(("satSendDiagnostic: return PF, DEVOFFL, UNITOFFL, PARAM LIST\n")); 9047 return tiSuccess; 9048 } 9049 9050 /* checking CONTROL */ 9051 /* NACA == 1 or LINK == 1*/ 9052 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 9053 { 9054 satSetSensePayload( pSense, 9055 SCSI_SNSKEY_ILLEGAL_REQUEST, 9056 0, 9057 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9058 satIOContext); 9059 9060 ostiInitiatorIOCompleted( tiRoot, 9061 tiIORequest, 9062 tiIOSuccess, 9063 SCSI_STAT_CHECK_CONDITION, 9064 satIOContext->pTiSenseData, 9065 satIOContext->interruptContext ); 9066 9067 TI_DBG2(("satSendDiagnostic: return control\n")); 9068 return tiSuccess; 9069 } 9070 9071 parmLen = (scsiCmnd->cdb[3] << 8) + scsiCmnd->cdb[4]; 9072 9073 /* checking SELFTEST bit*/ 9074 /* table 29, 8.10.3, p41 SAT Rev8 */ 9075 /* case 1 */ 9076 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 9077 (pSatDevData->satSMARTSelfTest == agFALSE) 9078 ) 9079 { 9080 satSetSensePayload( pSense, 9081 SCSI_SNSKEY_ILLEGAL_REQUEST, 9082 0, 9083 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9084 satIOContext); 9085 9086 ostiInitiatorIOCompleted( tiRoot, 9087 tiIORequest, 9088 tiIOSuccess, 9089 SCSI_STAT_CHECK_CONDITION, 9090 satIOContext->pTiSenseData, 9091 satIOContext->interruptContext ); 9092 9093 TI_DBG1(("satSendDiagnostic: return Table 29 case 1\n")); 9094 return tiSuccess; 9095 } 9096 9097 /* case 2 */ 9098 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 9099 (pSatDevData->satSMARTSelfTest == agTRUE) && 9100 (pSatDevData->satSMARTEnabled == agFALSE) 9101 ) 9102 { 9103 satSetSensePayload( pSense, 9104 SCSI_SNSKEY_ABORTED_COMMAND, 9105 0, 9106 SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED, 9107 satIOContext); 9108 9109 ostiInitiatorIOCompleted( tiRoot, 9110 tiIORequest, 9111 tiIOSuccess, 9112 SCSI_STAT_CHECK_CONDITION, 9113 satIOContext->pTiSenseData, 9114 satIOContext->interruptContext ); 9115 9116 TI_DBG5(("satSendDiagnostic: return Table 29 case 2\n")); 9117 return tiSuccess; 9118 } 9119 /* 9120 case 3 9121 see SELF TEST CODE later 9122 */ 9123 9124 9125 9126 /* case 4 */ 9127 9128 /* 9129 sends three ATA verify commands 9130 9131 */ 9132 if ( ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 9133 (pSatDevData->satSMARTSelfTest == agFALSE)) 9134 || 9135 ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 9136 (pSatDevData->satSMARTSelfTest == agTRUE) && 9137 (pSatDevData->satSMARTEnabled == agFALSE)) 9138 ) 9139 { 9140 /* 9141 sector count 1, LBA 0 9142 sector count 1, LBA MAX 9143 sector count 1, LBA random 9144 */ 9145 if (pSatDevData->sat48BitSupport == agTRUE) 9146 { 9147 /* sends READ VERIFY SECTOR(S) EXT*/ 9148 fis->h.fisType = 0x27; /* Reg host to device */ 9149 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9150 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 9151 fis->h.features = 0; /* FIS reserve */ 9152 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 9153 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 9154 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 9155 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 9156 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 9157 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 9158 fis->d.featuresExp = 0; /* FIS reserve */ 9159 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 9160 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 9161 fis->d.reserved4 = 0; 9162 fis->d.device = 0x40; /* 01000000 */ 9163 fis->d.control = 0; /* FIS HOB bit clear */ 9164 fis->d.reserved5 = 0; 9165 9166 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9167 } 9168 else 9169 { 9170 /* READ VERIFY SECTOR(S)*/ 9171 fis->h.fisType = 0x27; /* Reg host to device */ 9172 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9173 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 9174 fis->h.features = 0; /* FIS features NA */ 9175 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 9176 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 9177 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 9178 fis->d.lbaLowExp = 0; 9179 fis->d.lbaMidExp = 0; 9180 fis->d.lbaHighExp = 0; 9181 fis->d.featuresExp = 0; 9182 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 9183 fis->d.sectorCountExp = 0; 9184 fis->d.reserved4 = 0; 9185 fis->d.device = 0x40; /* 01000000 */ 9186 fis->d.control = 0; /* FIS HOB bit clear */ 9187 fis->d.reserved5 = 0; 9188 9189 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9190 } 9191 9192 /* Initialize CB for SATA completion. 9193 */ 9194 satIOContext->satCompleteCB = &satSendDiagnosticCB; 9195 9196 /* 9197 * Prepare SGL and send FIS to LL layer. 9198 */ 9199 satIOContext->reqType = agRequestType; /* Save it */ 9200 9201 status = sataLLIOStart( tiRoot, 9202 tiIORequest, 9203 tiDeviceHandle, 9204 tiScsiRequest, 9205 satIOContext); 9206 9207 9208 TI_DBG5(("satSendDiagnostic: return Table 29 case 4\n")); 9209 return (status); 9210 } 9211 /* case 5 */ 9212 if ( (scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 9213 (pSatDevData->satSMARTSelfTest == agTRUE) && 9214 (pSatDevData->satSMARTEnabled == agTRUE) 9215 ) 9216 { 9217 /* sends SMART EXECUTE OFF-LINE IMMEDIATE */ 9218 fis->h.fisType = 0x27; /* Reg host to device */ 9219 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9220 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0xB0 */ 9221 fis->h.features = 0xD4; /* FIS features NA */ 9222 fis->d.lbaLow = 0x81; /* FIS LBA (7 :0 ) */ 9223 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 9224 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 9225 fis->d.lbaLowExp = 0; 9226 fis->d.lbaMidExp = 0; 9227 fis->d.lbaHighExp = 0; 9228 fis->d.featuresExp = 0; 9229 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 9230 fis->d.sectorCountExp = 0; 9231 fis->d.reserved4 = 0; 9232 fis->d.device = 0; /* FIS DEV is discared in SATA */ 9233 fis->d.control = 0; /* FIS HOB bit clear */ 9234 fis->d.reserved5 = 0; 9235 9236 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9237 9238 /* Initialize CB for SATA completion. 9239 */ 9240 satIOContext->satCompleteCB = &satSendDiagnosticCB; 9241 9242 /* 9243 * Prepare SGL and send FIS to LL layer. 9244 */ 9245 satIOContext->reqType = agRequestType; /* Save it */ 9246 9247 status = sataLLIOStart( tiRoot, 9248 tiIORequest, 9249 tiDeviceHandle, 9250 tiScsiRequest, 9251 satIOContext); 9252 9253 9254 TI_DBG5(("satSendDiagnostic: return Table 29 case 5\n")); 9255 return (status); 9256 } 9257 9258 9259 9260 9261 /* SAT rev8 Table29 p41 case 3*/ 9262 /* checking SELF TEST CODE*/ 9263 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 9264 (pSatDevData->satSMARTSelfTest == agTRUE) && 9265 (pSatDevData->satSMARTEnabled == agTRUE) 9266 ) 9267 { 9268 /* SAT rev8 Table28 p40 */ 9269 /* finding self-test code */ 9270 switch ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_TEST_CODE_MASK) >> 5) 9271 { 9272 case 1: 9273 pSatDevData->satBGPendingDiag = agTRUE; 9274 9275 ostiInitiatorIOCompleted( tiRoot, 9276 tiIORequest, 9277 tiIOSuccess, 9278 SCSI_STAT_GOOD, 9279 agNULL, 9280 satIOContext->interruptContext ); 9281 /* sends SMART EXECUTE OFF-LINE IMMEDIATE */ 9282 fis->h.fisType = 0x27; /* Reg host to device */ 9283 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9284 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */ 9285 fis->h.features = 0xD4; /* FIS features NA */ 9286 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */ 9287 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 9288 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 9289 9290 fis->d.lbaLowExp = 0; 9291 fis->d.lbaMidExp = 0; 9292 fis->d.lbaHighExp = 0; 9293 fis->d.featuresExp = 0; 9294 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 9295 fis->d.sectorCountExp = 0; 9296 fis->d.reserved4 = 0; 9297 fis->d.device = 0; /* FIS DEV is discared in SATA */ 9298 fis->d.control = 0; /* FIS HOB bit clear */ 9299 fis->d.reserved5 = 0; 9300 9301 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9302 9303 /* Initialize CB for SATA completion. 9304 */ 9305 satIOContext->satCompleteCB = &satSendDiagnosticCB; 9306 9307 /* 9308 * Prepare SGL and send FIS to LL layer. 9309 */ 9310 satIOContext->reqType = agRequestType; /* Save it */ 9311 9312 status = sataLLIOStart( tiRoot, 9313 tiIORequest, 9314 tiDeviceHandle, 9315 tiScsiRequest, 9316 satIOContext); 9317 9318 9319 TI_DBG5(("satSendDiagnostic: return Table 28 case 1\n")); 9320 return (status); 9321 case 2: 9322 pSatDevData->satBGPendingDiag = agTRUE; 9323 9324 ostiInitiatorIOCompleted( tiRoot, 9325 tiIORequest, 9326 tiIOSuccess, 9327 SCSI_STAT_GOOD, 9328 agNULL, 9329 satIOContext->interruptContext ); 9330 9331 9332 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */ 9333 fis->h.fisType = 0x27; /* Reg host to device */ 9334 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9335 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */ 9336 fis->h.features = 0xD4; /* FIS features NA */ 9337 fis->d.lbaLow = 0x02; /* FIS LBA (7 :0 ) */ 9338 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 9339 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 9340 fis->d.lbaLowExp = 0; 9341 fis->d.lbaMidExp = 0; 9342 fis->d.lbaHighExp = 0; 9343 fis->d.featuresExp = 0; 9344 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 9345 fis->d.sectorCountExp = 0; 9346 fis->d.reserved4 = 0; 9347 fis->d.device = 0; /* FIS DEV is discared in SATA */ 9348 fis->d.control = 0; /* FIS HOB bit clear */ 9349 fis->d.reserved5 = 0; 9350 9351 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9352 9353 /* Initialize CB for SATA completion. 9354 */ 9355 satIOContext->satCompleteCB = &satSendDiagnosticCB; 9356 9357 /* 9358 * Prepare SGL and send FIS to LL layer. 9359 */ 9360 satIOContext->reqType = agRequestType; /* Save it */ 9361 9362 status = sataLLIOStart( tiRoot, 9363 tiIORequest, 9364 tiDeviceHandle, 9365 tiScsiRequest, 9366 satIOContext); 9367 9368 9369 TI_DBG5(("satSendDiagnostic: return Table 28 case 2\n")); 9370 return (status); 9371 case 4: 9372 /* For simplicity, no abort is supported 9373 Returns good status 9374 need a flag in device data for previously sent background Send Diagnostic 9375 */ 9376 if (parmLen != 0) 9377 { 9378 /* check condition */ 9379 satSetSensePayload( pSense, 9380 SCSI_SNSKEY_ILLEGAL_REQUEST, 9381 0, 9382 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9383 satIOContext); 9384 9385 ostiInitiatorIOCompleted( tiRoot, 9386 tiIORequest, 9387 tiIOSuccess, 9388 SCSI_STAT_CHECK_CONDITION, 9389 satIOContext->pTiSenseData, 9390 satIOContext->interruptContext ); 9391 9392 TI_DBG1(("satSendDiagnostic: case 4, non zero ParmLen %d\n", parmLen)); 9393 return tiSuccess; 9394 } 9395 if (pSatDevData->satBGPendingDiag == agTRUE) 9396 { 9397 /* sends SMART EXECUTE OFF-LINE IMMEDIATE abort */ 9398 fis->h.fisType = 0x27; /* Reg host to device */ 9399 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9400 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */ 9401 fis->h.features = 0xD4; /* FIS features NA */ 9402 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */ 9403 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 9404 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 9405 9406 fis->d.lbaLowExp = 0; 9407 fis->d.lbaMidExp = 0; 9408 fis->d.lbaHighExp = 0; 9409 fis->d.featuresExp = 0; 9410 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 9411 fis->d.sectorCountExp = 0; 9412 fis->d.reserved4 = 0; 9413 fis->d.device = 0; /* FIS DEV is discared in SATA */ 9414 fis->d.control = 0; /* FIS HOB bit clear */ 9415 fis->d.reserved5 = 0; 9416 9417 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9418 9419 /* Initialize CB for SATA completion. 9420 */ 9421 satIOContext->satCompleteCB = &satSendDiagnosticCB; 9422 9423 /* 9424 * Prepare SGL and send FIS to LL layer. 9425 */ 9426 satIOContext->reqType = agRequestType; /* Save it */ 9427 9428 status = sataLLIOStart( tiRoot, 9429 tiIORequest, 9430 tiDeviceHandle, 9431 tiScsiRequest, 9432 satIOContext); 9433 9434 9435 TI_DBG5(("satSendDiagnostic: send SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE case 3\n")); 9436 TI_DBG5(("satSendDiagnostic: Table 28 case 4\n")); 9437 return (status); 9438 } 9439 else 9440 { 9441 /* check condition */ 9442 satSetSensePayload( pSense, 9443 SCSI_SNSKEY_ILLEGAL_REQUEST, 9444 0, 9445 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9446 satIOContext); 9447 9448 ostiInitiatorIOCompleted( tiRoot, 9449 tiIORequest, 9450 tiIOSuccess, 9451 SCSI_STAT_CHECK_CONDITION, 9452 satIOContext->pTiSenseData, 9453 satIOContext->interruptContext ); 9454 9455 TI_DBG1(("satSendDiagnostic: case 4, no pending diagnostic in background\n")); 9456 TI_DBG5(("satSendDiagnostic: Table 28 case 4\n")); 9457 return tiSuccess; 9458 } 9459 break; 9460 case 5: 9461 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */ 9462 fis->h.fisType = 0x27; /* Reg host to device */ 9463 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9464 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */ 9465 fis->h.features = 0xD4; /* FIS features NA */ 9466 fis->d.lbaLow = 0x81; /* FIS LBA (7 :0 ) */ 9467 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 9468 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 9469 fis->d.lbaLowExp = 0; 9470 fis->d.lbaMidExp = 0; 9471 fis->d.lbaHighExp = 0; 9472 fis->d.featuresExp = 0; 9473 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 9474 fis->d.sectorCountExp = 0; 9475 fis->d.reserved4 = 0; 9476 fis->d.device = 0; /* FIS DEV is discared in SATA */ 9477 fis->d.control = 0; /* FIS HOB bit clear */ 9478 fis->d.reserved5 = 0; 9479 9480 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9481 9482 /* Initialize CB for SATA completion. 9483 */ 9484 satIOContext->satCompleteCB = &satSendDiagnosticCB; 9485 9486 /* 9487 * Prepare SGL and send FIS to LL layer. 9488 */ 9489 satIOContext->reqType = agRequestType; /* Save it */ 9490 9491 status = sataLLIOStart( tiRoot, 9492 tiIORequest, 9493 tiDeviceHandle, 9494 tiScsiRequest, 9495 satIOContext); 9496 9497 9498 TI_DBG5(("satSendDiagnostic: return Table 28 case 5\n")); 9499 return (status); 9500 case 6: 9501 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */ 9502 fis->h.fisType = 0x27; /* Reg host to device */ 9503 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9504 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */ 9505 fis->h.features = 0xD4; /* FIS features NA */ 9506 fis->d.lbaLow = 0x82; /* FIS LBA (7 :0 ) */ 9507 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 9508 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 9509 fis->d.lbaLowExp = 0; 9510 fis->d.lbaMidExp = 0; 9511 fis->d.lbaHighExp = 0; 9512 fis->d.featuresExp = 0; 9513 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 9514 fis->d.sectorCountExp = 0; 9515 fis->d.reserved4 = 0; 9516 fis->d.device = 0; /* FIS DEV is discared in SATA */ 9517 fis->d.control = 0; /* FIS HOB bit clear */ 9518 fis->d.reserved5 = 0; 9519 9520 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9521 9522 /* Initialize CB for SATA completion. 9523 */ 9524 satIOContext->satCompleteCB = &satSendDiagnosticCB; 9525 9526 /* 9527 * Prepare SGL and send FIS to LL layer. 9528 */ 9529 satIOContext->reqType = agRequestType; /* Save it */ 9530 9531 status = sataLLIOStart( tiRoot, 9532 tiIORequest, 9533 tiDeviceHandle, 9534 tiScsiRequest, 9535 satIOContext); 9536 9537 9538 TI_DBG5(("satSendDiagnostic: return Table 28 case 6\n")); 9539 return (status); 9540 case 0: 9541 case 3: /* fall through */ 9542 case 7: /* fall through */ 9543 default: 9544 break; 9545 }/* switch */ 9546 9547 /* returns the results of default self-testing, which is good */ 9548 ostiInitiatorIOCompleted( tiRoot, 9549 tiIORequest, 9550 tiIOSuccess, 9551 SCSI_STAT_GOOD, 9552 agNULL, 9553 satIOContext->interruptContext ); 9554 9555 TI_DBG5(("satSendDiagnostic: return Table 28 case 0,3,7 and default\n")); 9556 return tiSuccess; 9557 } 9558 9559 9560 ostiInitiatorIOCompleted( tiRoot, 9561 tiIORequest, 9562 tiIOSuccess, 9563 SCSI_STAT_GOOD, 9564 agNULL, 9565 satIOContext->interruptContext ); 9566 9567 9568 TI_DBG5(("satSendDiagnostic: return last\n")); 9569 return tiSuccess; 9570 } 9571 9572 /*****************************************************************************/ 9573 /*! \brief SAT implementation for SCSI satSendDiagnostic_1. 9574 * 9575 * SAT implementation for SCSI satSendDiagnostic_1. 9576 * Sub function of satSendDiagnostic. 9577 * 9578 * \param tiRoot: Pointer to TISA initiator driver/port instance. 9579 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 9580 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 9581 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 9582 * \param satIOContext_t: Pointer to the SAT IO Context 9583 * 9584 * \return If command is started successfully 9585 * - \e tiSuccess: I/O request successfully initiated. 9586 * - \e tiBusy: No resources available, try again later. 9587 * - \e tiIONoDevice: Invalid device handle. 9588 * - \e tiError: Other errors. 9589 */ 9590 /*****************************************************************************/ 9591 GLOBAL bit32 satSendDiagnostic_1( 9592 tiRoot_t *tiRoot, 9593 tiIORequest_t *tiIORequest, 9594 tiDeviceHandle_t *tiDeviceHandle, 9595 tiScsiInitiatorRequest_t *tiScsiRequest, 9596 satIOContext_t *satIOContext) 9597 { 9598 /* 9599 SAT Rev9, Table29, p41 9600 send 2nd SAT_READ_VERIFY_SECTORS(_EXT) 9601 */ 9602 bit32 status; 9603 bit32 agRequestType; 9604 satDeviceData_t *pSatDevData; 9605 agsaFisRegHostToDevice_t *fis; 9606 9607 TI_DBG5(("satSendDiagnostic_1 entry: tiDeviceHandle=%p tiIORequest=%p\n", 9608 tiDeviceHandle, tiIORequest)); 9609 9610 pSatDevData = satIOContext->pSatDevData; 9611 fis = satIOContext->pFis; 9612 9613 /* 9614 sector count 1, LBA MAX 9615 */ 9616 if (pSatDevData->sat48BitSupport == agTRUE) 9617 { 9618 /* sends READ VERIFY SECTOR(S) EXT*/ 9619 fis->h.fisType = 0x27; /* Reg host to device */ 9620 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9621 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 9622 fis->h.features = 0; /* FIS reserve */ 9623 fis->d.lbaLow = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */ 9624 fis->d.lbaMid = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */ 9625 fis->d.lbaHigh = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */ 9626 fis->d.lbaLowExp = pSatDevData->satMaxLBA[4]; /* FIS LBA (31:24) */ 9627 fis->d.lbaMidExp = pSatDevData->satMaxLBA[3]; /* FIS LBA (39:32) */ 9628 fis->d.lbaHighExp = pSatDevData->satMaxLBA[2]; /* FIS LBA (47:40) */ 9629 fis->d.featuresExp = 0; /* FIS reserve */ 9630 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 9631 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 9632 fis->d.reserved4 = 0; 9633 fis->d.device = 0x40; /* 01000000 */ 9634 fis->d.control = 0; /* FIS HOB bit clear */ 9635 fis->d.reserved5 = 0; 9636 9637 } 9638 else 9639 { 9640 /* READ VERIFY SECTOR(S)*/ 9641 fis->h.fisType = 0x27; /* Reg host to device */ 9642 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9643 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 9644 fis->h.features = 0; /* FIS features NA */ 9645 fis->d.lbaLow = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */ 9646 fis->d.lbaMid = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */ 9647 fis->d.lbaHigh = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */ 9648 fis->d.lbaLowExp = 0; 9649 fis->d.lbaMidExp = 0; 9650 fis->d.lbaHighExp = 0; 9651 fis->d.featuresExp = 0; 9652 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 9653 fis->d.sectorCountExp = 0; 9654 fis->d.reserved4 = 0; 9655 fis->d.device = (bit8)((0x4 << 4) | (pSatDevData->satMaxLBA[4] & 0xF)); 9656 /* DEV and LBA 27:24 */ 9657 fis->d.control = 0; /* FIS HOB bit clear */ 9658 fis->d.reserved5 = 0; 9659 9660 } 9661 9662 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9663 9664 /* Initialize CB for SATA completion. 9665 */ 9666 satIOContext->satCompleteCB = &satSendDiagnosticCB; 9667 9668 /* 9669 * Prepare SGL and send FIS to LL layer. 9670 */ 9671 satIOContext->reqType = agRequestType; /* Save it */ 9672 9673 status = sataLLIOStart( tiRoot, 9674 tiIORequest, 9675 tiDeviceHandle, 9676 tiScsiRequest, 9677 satIOContext); 9678 9679 9680 return status; 9681 } 9682 9683 /*****************************************************************************/ 9684 /*! \brief SAT implementation for SCSI satSendDiagnostic_2. 9685 * 9686 * SAT implementation for SCSI satSendDiagnostic_2. 9687 * Sub function of satSendDiagnostic. 9688 * 9689 * \param tiRoot: Pointer to TISA initiator driver/port instance. 9690 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 9691 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 9692 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 9693 * \param satIOContext_t: Pointer to the SAT IO Context 9694 * 9695 * \return If command is started successfully 9696 * - \e tiSuccess: I/O request successfully initiated. 9697 * - \e tiBusy: No resources available, try again later. 9698 * - \e tiIONoDevice: Invalid device handle. 9699 * - \e tiError: Other errors. 9700 */ 9701 /*****************************************************************************/ 9702 GLOBAL bit32 satSendDiagnostic_2( 9703 tiRoot_t *tiRoot, 9704 tiIORequest_t *tiIORequest, 9705 tiDeviceHandle_t *tiDeviceHandle, 9706 tiScsiInitiatorRequest_t *tiScsiRequest, 9707 satIOContext_t *satIOContext) 9708 { 9709 /* 9710 SAT Rev9, Table29, p41 9711 send 3rd SAT_READ_VERIFY_SECTORS(_EXT) 9712 */ 9713 bit32 status; 9714 bit32 agRequestType; 9715 satDeviceData_t *pSatDevData; 9716 agsaFisRegHostToDevice_t *fis; 9717 9718 TI_DBG5(("satSendDiagnostic_2 entry: tiDeviceHandle=%p tiIORequest=%p\n", 9719 tiDeviceHandle, tiIORequest)); 9720 9721 pSatDevData = satIOContext->pSatDevData; 9722 fis = satIOContext->pFis; 9723 9724 /* 9725 sector count 1, LBA Random 9726 */ 9727 if (pSatDevData->sat48BitSupport == agTRUE) 9728 { 9729 /* sends READ VERIFY SECTOR(S) EXT*/ 9730 fis->h.fisType = 0x27; /* Reg host to device */ 9731 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9732 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 9733 fis->h.features = 0; /* FIS reserve */ 9734 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */ 9735 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 9736 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 9737 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 9738 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 9739 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 9740 fis->d.featuresExp = 0; /* FIS reserve */ 9741 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 9742 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 9743 fis->d.reserved4 = 0; 9744 fis->d.device = 0x40; /* 01000000 */ 9745 fis->d.control = 0; /* FIS HOB bit clear */ 9746 fis->d.reserved5 = 0; 9747 9748 } 9749 else 9750 { 9751 /* READ VERIFY SECTOR(S)*/ 9752 fis->h.fisType = 0x27; /* Reg host to device */ 9753 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9754 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 9755 fis->h.features = 0; /* FIS features NA */ 9756 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */ 9757 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 9758 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 9759 fis->d.lbaLowExp = 0; 9760 fis->d.lbaMidExp = 0; 9761 fis->d.lbaHighExp = 0; 9762 fis->d.featuresExp = 0; 9763 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 9764 fis->d.sectorCountExp = 0; 9765 fis->d.reserved4 = 0; 9766 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 9767 fis->d.control = 0; /* FIS HOB bit clear */ 9768 fis->d.reserved5 = 0; 9769 9770 } 9771 9772 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9773 9774 /* Initialize CB for SATA completion. 9775 */ 9776 satIOContext->satCompleteCB = &satSendDiagnosticCB; 9777 9778 /* 9779 * Prepare SGL and send FIS to LL layer. 9780 */ 9781 satIOContext->reqType = agRequestType; /* Save it */ 9782 9783 status = sataLLIOStart( tiRoot, 9784 tiIORequest, 9785 tiDeviceHandle, 9786 tiScsiRequest, 9787 satIOContext); 9788 9789 9790 return status; 9791 } 9792 /*****************************************************************************/ 9793 /*! \brief SAT implementation for SCSI satStartStopUnit. 9794 * 9795 * SAT implementation for SCSI satStartStopUnit. 9796 * 9797 * \param tiRoot: Pointer to TISA initiator driver/port instance. 9798 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 9799 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 9800 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 9801 * \param satIOContext_t: Pointer to the SAT IO Context 9802 * 9803 * \return If command is started successfully 9804 * - \e tiSuccess: I/O request successfully initiated. 9805 * - \e tiBusy: No resources available, try again later. 9806 * - \e tiIONoDevice: Invalid device handle. 9807 * - \e tiError: Other errors. 9808 */ 9809 /*****************************************************************************/ 9810 GLOBAL bit32 satStartStopUnit( 9811 tiRoot_t *tiRoot, 9812 tiIORequest_t *tiIORequest, 9813 tiDeviceHandle_t *tiDeviceHandle, 9814 tiScsiInitiatorRequest_t *tiScsiRequest, 9815 satIOContext_t *satIOContext) 9816 { 9817 bit32 status; 9818 bit32 agRequestType; 9819 satDeviceData_t *pSatDevData; 9820 scsiRspSense_t *pSense; 9821 tiIniScsiCmnd_t *scsiCmnd; 9822 agsaFisRegHostToDevice_t *fis; 9823 9824 pSense = satIOContext->pSense; 9825 pSatDevData = satIOContext->pSatDevData; 9826 scsiCmnd = &tiScsiRequest->scsiCmnd; 9827 fis = satIOContext->pFis; 9828 9829 TI_DBG5(("satStartStopUnit:start\n")); 9830 9831 /* checking CONTROL */ 9832 /* NACA == 1 or LINK == 1*/ 9833 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 9834 { 9835 satSetSensePayload( pSense, 9836 SCSI_SNSKEY_ILLEGAL_REQUEST, 9837 0, 9838 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9839 satIOContext); 9840 9841 ostiInitiatorIOCompleted( tiRoot, 9842 tiIORequest, 9843 tiIOSuccess, 9844 SCSI_STAT_CHECK_CONDITION, 9845 satIOContext->pTiSenseData, 9846 satIOContext->interruptContext ); 9847 9848 TI_DBG1(("satStartStopUnit: return control\n")); 9849 return tiSuccess; 9850 } 9851 9852 /* Spec p55, Table 48 checking START and LOEJ bit */ 9853 /* case 1 */ 9854 if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) 9855 { 9856 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) ) 9857 { 9858 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/ 9859 ostiInitiatorIOCompleted( tiRoot, 9860 tiIORequest, 9861 tiIOSuccess, 9862 SCSI_STAT_GOOD, 9863 agNULL, 9864 satIOContext->interruptContext ); 9865 TI_DBG5(("satStartStopUnit: return table48 case 1-1\n")); 9866 return tiSuccess; 9867 } 9868 /* sends FLUSH CACHE or FLUSH CACHE EXT */ 9869 if (pSatDevData->sat48BitSupport == agTRUE) 9870 { 9871 /* FLUSH CACHE EXT */ 9872 fis->h.fisType = 0x27; /* Reg host to device */ 9873 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9874 9875 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */ 9876 fis->h.features = 0; /* FIS reserve */ 9877 fis->d.featuresExp = 0; /* FIS reserve */ 9878 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 9879 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 9880 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 9881 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 9882 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 9883 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 9884 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 9885 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 9886 fis->d.device = 0; /* FIS DEV is discared in SATA */ 9887 fis->d.control = 0; /* FIS HOB bit clear */ 9888 fis->d.reserved4 = 0; 9889 fis->d.reserved5 = 0; 9890 9891 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9892 } 9893 else 9894 { 9895 /* FLUSH CACHE */ 9896 fis->h.fisType = 0x27; /* Reg host to device */ 9897 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9898 9899 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */ 9900 fis->h.features = 0; /* FIS features NA */ 9901 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 9902 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 9903 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 9904 fis->d.lbaLowExp = 0; 9905 fis->d.lbaMidExp = 0; 9906 fis->d.lbaHighExp = 0; 9907 fis->d.featuresExp = 0; 9908 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 9909 fis->d.sectorCountExp = 0; 9910 fis->d.device = 0; /* FIS DEV is discared in SATA */ 9911 fis->d.control = 0; /* FIS HOB bit clear */ 9912 fis->d.reserved4 = 0; 9913 fis->d.reserved5 = 0; 9914 9915 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9916 } 9917 9918 /* Initialize CB for SATA completion. 9919 */ 9920 satIOContext->satCompleteCB = &satStartStopUnitCB; 9921 9922 /* 9923 * Prepare SGL and send FIS to LL layer. 9924 */ 9925 satIOContext->reqType = agRequestType; /* Save it */ 9926 9927 status = sataLLIOStart( tiRoot, 9928 tiIORequest, 9929 tiDeviceHandle, 9930 tiScsiRequest, 9931 satIOContext); 9932 9933 9934 TI_DBG5(("satStartStopUnit: return table48 case 1\n")); 9935 return (status); 9936 } 9937 /* case 2 */ 9938 else if ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) 9939 { 9940 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/ 9941 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) ) 9942 { 9943 ostiInitiatorIOCompleted( tiRoot, 9944 tiIORequest, 9945 tiIOSuccess, 9946 SCSI_STAT_GOOD, 9947 agNULL, 9948 satIOContext->interruptContext ); 9949 9950 TI_DBG5(("satStartStopUnit: return table48 case 2 1\n")); 9951 return tiSuccess; 9952 } 9953 /* 9954 sends READ_VERIFY_SECTORS(_EXT) 9955 sector count 1, any LBA between zero to Maximum 9956 */ 9957 if (pSatDevData->sat48BitSupport == agTRUE) 9958 { 9959 /* READ VERIFY SECTOR(S) EXT*/ 9960 fis->h.fisType = 0x27; /* Reg host to device */ 9961 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9962 9963 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 9964 fis->h.features = 0; /* FIS reserve */ 9965 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */ 9966 fis->d.lbaMid = 0x00; /* FIS LBA (15:8 ) */ 9967 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */ 9968 fis->d.lbaLowExp = 0x00; /* FIS LBA (31:24) */ 9969 fis->d.lbaMidExp = 0x00; /* FIS LBA (39:32) */ 9970 fis->d.lbaHighExp = 0x00; /* FIS LBA (47:40) */ 9971 fis->d.featuresExp = 0; /* FIS reserve */ 9972 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 9973 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 9974 fis->d.reserved4 = 0; 9975 fis->d.device = 0x40; /* 01000000 */ 9976 fis->d.control = 0; /* FIS HOB bit clear */ 9977 fis->d.reserved5 = 0; 9978 9979 } 9980 else 9981 { 9982 /* READ VERIFY SECTOR(S)*/ 9983 fis->h.fisType = 0x27; /* Reg host to device */ 9984 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9985 9986 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 9987 fis->h.features = 0; /* FIS features NA */ 9988 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */ 9989 fis->d.lbaMid = 0x00; /* FIS LBA (15:8 ) */ 9990 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */ 9991 fis->d.lbaLowExp = 0; 9992 fis->d.lbaMidExp = 0; 9993 fis->d.lbaHighExp = 0; 9994 fis->d.featuresExp = 0; 9995 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 9996 fis->d.sectorCountExp = 0; 9997 fis->d.reserved4 = 0; 9998 fis->d.device = 0x40; /* 01000000 */ 9999 fis->d.control = 0; /* FIS HOB bit clear */ 10000 fis->d.reserved5 = 0; 10001 10002 } 10003 10004 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 10005 10006 /* Initialize CB for SATA completion. 10007 */ 10008 satIOContext->satCompleteCB = &satStartStopUnitCB; 10009 10010 /* 10011 * Prepare SGL and send FIS to LL layer. 10012 */ 10013 satIOContext->reqType = agRequestType; /* Save it */ 10014 10015 status = sataLLIOStart( tiRoot, 10016 tiIORequest, 10017 tiDeviceHandle, 10018 tiScsiRequest, 10019 satIOContext); 10020 10021 TI_DBG5(("satStartStopUnit: return table48 case 2 2\n")); 10022 return status; 10023 } 10024 /* case 3 */ 10025 else if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) 10026 { 10027 if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled) 10028 { 10029 /* support for removal media */ 10030 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/ 10031 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) ) 10032 { 10033 ostiInitiatorIOCompleted( tiRoot, 10034 tiIORequest, 10035 tiIOSuccess, 10036 SCSI_STAT_GOOD, 10037 agNULL, 10038 satIOContext->interruptContext ); 10039 10040 TI_DBG5(("satStartStopUnit: return table48 case 3 1\n")); 10041 return tiSuccess; 10042 } 10043 /* 10044 sends MEDIA EJECT 10045 */ 10046 /* Media Eject fis */ 10047 fis->h.fisType = 0x27; /* Reg host to device */ 10048 fis->h.c_pmPort = 0x80; /* C Bit is set */ 10049 10050 fis->h.command = SAT_MEDIA_EJECT; /* 0xED */ 10051 fis->h.features = 0; /* FIS features NA */ 10052 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 10053 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 10054 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 10055 fis->d.lbaLowExp = 0; 10056 fis->d.lbaMidExp = 0; 10057 fis->d.lbaHighExp = 0; 10058 fis->d.featuresExp = 0; 10059 /* sector count zero */ 10060 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 10061 fis->d.sectorCountExp = 0; 10062 fis->d.device = 0; /* FIS DEV is discared in SATA */ 10063 fis->d.control = 0; /* FIS HOB bit clear */ 10064 fis->d.reserved4 = 0; 10065 fis->d.reserved5 = 0; 10066 10067 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 10068 10069 /* Initialize CB for SATA completion. 10070 */ 10071 satIOContext->satCompleteCB = &satStartStopUnitCB; 10072 10073 /* 10074 * Prepare SGL and send FIS to LL layer. 10075 */ 10076 satIOContext->reqType = agRequestType; /* Save it */ 10077 10078 status = sataLLIOStart( tiRoot, 10079 tiIORequest, 10080 tiDeviceHandle, 10081 tiScsiRequest, 10082 satIOContext); 10083 10084 return status; 10085 } 10086 else 10087 { 10088 /* no support for removal media */ 10089 satSetSensePayload( pSense, 10090 SCSI_SNSKEY_ILLEGAL_REQUEST, 10091 0, 10092 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10093 satIOContext); 10094 10095 ostiInitiatorIOCompleted( tiRoot, 10096 tiIORequest, 10097 tiIOSuccess, 10098 SCSI_STAT_CHECK_CONDITION, 10099 satIOContext->pTiSenseData, 10100 satIOContext->interruptContext ); 10101 10102 TI_DBG5(("satStartStopUnit: return Table 29 case 3 2\n")); 10103 return tiSuccess; 10104 } 10105 10106 } 10107 /* case 4 */ 10108 else /* ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) */ 10109 { 10110 satSetSensePayload( pSense, 10111 SCSI_SNSKEY_ILLEGAL_REQUEST, 10112 0, 10113 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10114 satIOContext); 10115 10116 ostiInitiatorIOCompleted( tiRoot, 10117 tiIORequest, 10118 tiIOSuccess, 10119 SCSI_STAT_CHECK_CONDITION, 10120 satIOContext->pTiSenseData, 10121 satIOContext->interruptContext ); 10122 10123 TI_DBG5(("satStartStopUnit: return Table 29 case 4\n")); 10124 return tiSuccess; 10125 } 10126 10127 10128 } 10129 10130 10131 /*****************************************************************************/ 10132 /*! \brief SAT implementation for SCSI satStartStopUnit_1. 10133 * 10134 * SAT implementation for SCSI satStartStopUnit_1. 10135 * Sub function of satStartStopUnit 10136 * 10137 * \param tiRoot: Pointer to TISA initiator driver/port instance. 10138 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 10139 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 10140 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 10141 * \param satIOContext_t: Pointer to the SAT IO Context 10142 * 10143 * \return If command is started successfully 10144 * - \e tiSuccess: I/O request successfully initiated. 10145 * - \e tiBusy: No resources available, try again later. 10146 * - \e tiIONoDevice: Invalid device handle. 10147 * - \e tiError: Other errors. 10148 */ 10149 /*****************************************************************************/ 10150 GLOBAL bit32 satStartStopUnit_1( 10151 tiRoot_t *tiRoot, 10152 tiIORequest_t *tiIORequest, 10153 tiDeviceHandle_t *tiDeviceHandle, 10154 tiScsiInitiatorRequest_t *tiScsiRequest, 10155 satIOContext_t *satIOContext) 10156 { 10157 /* 10158 SAT Rev 8, Table 48, 9.11.3 p55 10159 sends STANDBY 10160 */ 10161 bit32 status; 10162 bit32 agRequestType; 10163 agsaFisRegHostToDevice_t *fis; 10164 10165 TI_DBG5(("satStartStopUnit_1 entry: tiDeviceHandle=%p tiIORequest=%p\n", 10166 tiDeviceHandle, tiIORequest)); 10167 10168 fis = satIOContext->pFis; 10169 10170 /* STANDBY */ 10171 fis->h.fisType = 0x27; /* Reg host to device */ 10172 fis->h.c_pmPort = 0x80; /* C Bit is set */ 10173 10174 fis->h.command = SAT_STANDBY; /* 0xE2 */ 10175 fis->h.features = 0; /* FIS features NA */ 10176 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 10177 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 10178 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 10179 fis->d.lbaLowExp = 0; 10180 fis->d.lbaMidExp = 0; 10181 fis->d.lbaHighExp = 0; 10182 fis->d.featuresExp = 0; 10183 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 10184 fis->d.sectorCountExp = 0; 10185 fis->d.reserved4 = 0; 10186 fis->d.device = 0; /* 0 */ 10187 fis->d.control = 0; /* FIS HOB bit clear */ 10188 fis->d.reserved5 = 0; 10189 10190 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 10191 10192 /* Initialize CB for SATA completion. 10193 */ 10194 satIOContext->satCompleteCB = &satStartStopUnitCB; 10195 10196 /* 10197 * Prepare SGL and send FIS to LL layer. 10198 */ 10199 satIOContext->reqType = agRequestType; /* Save it */ 10200 10201 status = sataLLIOStart( tiRoot, 10202 tiIORequest, 10203 tiDeviceHandle, 10204 tiScsiRequest, 10205 satIOContext); 10206 10207 TI_DBG5(("satStartStopUnit_1 return status %d\n", status)); 10208 return status; 10209 } 10210 10211 /*****************************************************************************/ 10212 /*! \brief SAT implementation for SCSI satRead10_2. 10213 * 10214 * SAT implementation for SCSI satRead10_2 10215 * Sub function of satRead10 10216 * 10217 * \param tiRoot: Pointer to TISA initiator driver/port instance. 10218 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 10219 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 10220 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 10221 * \param satIOContext_t: Pointer to the SAT IO Context 10222 * 10223 * \return If command is started successfully 10224 * - \e tiSuccess: I/O request successfully initiated. 10225 * - \e tiBusy: No resources available, try again later. 10226 * - \e tiIONoDevice: Invalid device handle. 10227 * - \e tiError: Other errors. 10228 */ 10229 /*****************************************************************************/ 10230 GLOBAL bit32 satRead10_2( 10231 tiRoot_t *tiRoot, 10232 tiIORequest_t *tiIORequest, 10233 tiDeviceHandle_t *tiDeviceHandle, 10234 tiScsiInitiatorRequest_t *tiScsiRequest, 10235 satIOContext_t *satIOContext) 10236 { 10237 /* 10238 externally generated ATA cmd, there is corresponding scsi cmnd 10239 called by satStartStopUnit() or maybe satRead10() 10240 */ 10241 10242 bit32 status; 10243 bit32 agRequestType; 10244 satDeviceData_t *pSatDevData; 10245 agsaFisRegHostToDevice_t *fis; 10246 10247 pSatDevData = satIOContext->pSatDevData; 10248 fis = satIOContext->pFis; 10249 10250 TI_DBG5(("satReadVerifySectorsNoChain: start\n")); 10251 10252 /* specifying ReadVerifySectors has no chain */ 10253 pSatDevData->satVerifyState = 0xFFFFFFFF; 10254 10255 if (pSatDevData->sat48BitSupport == agTRUE) 10256 { 10257 /* READ VERIFY SECTOR(S) EXT*/ 10258 fis->h.fisType = 0x27; /* Reg host to device */ 10259 fis->h.c_pmPort = 0x80; /* C Bit is set */ 10260 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 10261 fis->h.features = 0; /* FIS reserve */ 10262 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */ 10263 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 10264 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */ 10265 fis->d.lbaLowExp = 0xF1; /* FIS LBA (31:24) */ 10266 fis->d.lbaMidExp = 0x5F; /* FIS LBA (39:32) */ 10267 fis->d.lbaHighExp = 0xFF; /* FIS LBA (47:40) */ 10268 fis->d.featuresExp = 0; /* FIS reserve */ 10269 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 10270 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 10271 fis->d.reserved4 = 0; 10272 fis->d.device = 0x4E; /* 01001110 */ 10273 fis->d.control = 0; /* FIS HOB bit clear */ 10274 fis->d.reserved5 = 0; 10275 10276 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 10277 } 10278 else 10279 { 10280 /* READ VERIFY SECTOR(S)*/ 10281 fis->h.fisType = 0x27; /* Reg host to device */ 10282 fis->h.c_pmPort = 0x80; /* C Bit is set */ 10283 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 10284 fis->h.features = 0; /* FIS features NA */ 10285 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */ 10286 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 10287 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */ 10288 fis->d.lbaLowExp = 0; 10289 fis->d.lbaMidExp = 0; 10290 fis->d.lbaHighExp = 0; 10291 fis->d.featuresExp = 0; 10292 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 10293 fis->d.sectorCountExp = 0; 10294 fis->d.reserved4 = 0; 10295 fis->d.device = 0x4E; /* 01001110 */ 10296 fis->d.control = 0; /* FIS HOB bit clear */ 10297 fis->d.reserved5 = 0; 10298 10299 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 10300 } 10301 10302 /* Initialize CB for SATA completion. 10303 */ 10304 satIOContext->satCompleteCB = &satNonDataIOCB; 10305 10306 /* 10307 * Prepare SGL and send FIS to LL layer. 10308 */ 10309 satIOContext->reqType = agRequestType; /* Save it */ 10310 10311 status = sataLLIOStart( tiRoot, 10312 tiIORequest, 10313 tiDeviceHandle, 10314 tiScsiRequest, 10315 satIOContext); 10316 10317 TI_DBG5(("satReadVerifySectorsNoChain: return last\n")); 10318 10319 return status; 10320 } 10321 10322 10323 /*****************************************************************************/ 10324 /*! \brief SAT implementation for SCSI satWriteSame10. 10325 * 10326 * SAT implementation for SCSI satWriteSame10. 10327 * 10328 * \param tiRoot: Pointer to TISA initiator driver/port instance. 10329 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 10330 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 10331 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 10332 * \param satIOContext_t: Pointer to the SAT IO Context 10333 * 10334 * \return If command is started successfully 10335 * - \e tiSuccess: I/O request successfully initiated. 10336 * - \e tiBusy: No resources available, try again later. 10337 * - \e tiIONoDevice: Invalid device handle. 10338 * - \e tiError: Other errors. 10339 */ 10340 /*****************************************************************************/ 10341 GLOBAL bit32 satWriteSame10( 10342 tiRoot_t *tiRoot, 10343 tiIORequest_t *tiIORequest, 10344 tiDeviceHandle_t *tiDeviceHandle, 10345 tiScsiInitiatorRequest_t *tiScsiRequest, 10346 satIOContext_t *satIOContext) 10347 { 10348 bit32 status; 10349 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 10350 satDeviceData_t *pSatDevData; 10351 scsiRspSense_t *pSense; 10352 tiIniScsiCmnd_t *scsiCmnd; 10353 agsaFisRegHostToDevice_t *fis; 10354 bit32 lba = 0; 10355 bit32 tl = 0; 10356 10357 pSense = satIOContext->pSense; 10358 pSatDevData = satIOContext->pSatDevData; 10359 scsiCmnd = &tiScsiRequest->scsiCmnd; 10360 fis = satIOContext->pFis; 10361 10362 TI_DBG5(("satWriteSame10: start\n")); 10363 10364 /* checking CONTROL */ 10365 /* NACA == 1 or LINK == 1*/ 10366 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 10367 { 10368 satSetSensePayload( pSense, 10369 SCSI_SNSKEY_ILLEGAL_REQUEST, 10370 0, 10371 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10372 satIOContext); 10373 10374 ostiInitiatorIOCompleted( tiRoot, 10375 tiIORequest, 10376 tiIOSuccess, 10377 SCSI_STAT_CHECK_CONDITION, 10378 satIOContext->pTiSenseData, 10379 satIOContext->interruptContext ); 10380 10381 TI_DBG1(("satWriteSame10: return control\n")); 10382 return tiSuccess; 10383 } 10384 10385 10386 /* checking LBDATA and PBDATA */ 10387 /* case 1 */ 10388 if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) && 10389 !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) 10390 { 10391 TI_DBG5(("satWriteSame10: case 1\n")); 10392 /* spec 9.26.2, Table 62, p64, case 1*/ 10393 /* 10394 normal case 10395 just like write in 9.17.1 10396 */ 10397 10398 if ( pSatDevData->sat48BitSupport != agTRUE ) 10399 { 10400 /* 10401 writeSame10 but no support for 48 bit addressing 10402 -> problem in transfer length. Therefore, return check condition 10403 */ 10404 satSetSensePayload( pSense, 10405 SCSI_SNSKEY_ILLEGAL_REQUEST, 10406 0, 10407 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10408 satIOContext); 10409 10410 ostiInitiatorIOCompleted( tiRoot, 10411 tiIORequest, 10412 tiIOSuccess, 10413 SCSI_STAT_CHECK_CONDITION, 10414 satIOContext->pTiSenseData, 10415 satIOContext->interruptContext ); 10416 10417 TI_DBG1(("satWriteSame10: return internal checking\n")); 10418 return tiSuccess; 10419 } 10420 10421 /* cdb10; computing LBA and transfer length */ 10422 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 10423 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 10424 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 10425 10426 10427 /* Table 34, 9.1, p 46 */ 10428 /* 10429 note: As of 2/10/2006, no support for DMA QUEUED 10430 */ 10431 10432 /* 10433 Table 34, 9.1, p 46, b (footnote) 10434 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 10435 return check condition 10436 */ 10437 if (pSatDevData->satNCQ != agTRUE && 10438 pSatDevData->sat48BitSupport != agTRUE 10439 ) 10440 { 10441 if (lba > SAT_TR_LBA_LIMIT - 1) /* SAT_TR_LBA_LIMIT is 2^28, 0x10000000 */ 10442 { 10443 satSetSensePayload( pSense, 10444 SCSI_SNSKEY_ILLEGAL_REQUEST, 10445 0, 10446 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 10447 satIOContext); 10448 10449 ostiInitiatorIOCompleted( tiRoot, 10450 tiIORequest, 10451 tiIOSuccess, 10452 SCSI_STAT_CHECK_CONDITION, 10453 satIOContext->pTiSenseData, 10454 satIOContext->interruptContext ); 10455 10456 TI_DBG1(("satWriteSame10: return LBA out of range\n")); 10457 return tiSuccess; 10458 } 10459 } 10460 10461 if (lba + tl <= SAT_TR_LBA_LIMIT) 10462 { 10463 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 10464 { 10465 /* case 2 */ 10466 /* WRITE DMA */ 10467 /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */ 10468 TI_DBG5(("satWriteSame10: case 1-2 !!! error due to writeSame10\n")); 10469 satSetSensePayload( pSense, 10470 SCSI_SNSKEY_ILLEGAL_REQUEST, 10471 0, 10472 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10473 satIOContext); 10474 10475 ostiInitiatorIOCompleted( tiRoot, 10476 tiIORequest, 10477 tiIOSuccess, 10478 SCSI_STAT_CHECK_CONDITION, 10479 satIOContext->pTiSenseData, 10480 satIOContext->interruptContext ); 10481 return tiSuccess; 10482 } 10483 else 10484 { 10485 /* case 1 */ 10486 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 10487 /* WRITE SECTORS is chosen for easier implemetation */ 10488 /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */ 10489 TI_DBG5(("satWriteSame10: case 1-1 !!! error due to writesame10\n")); 10490 satSetSensePayload( pSense, 10491 SCSI_SNSKEY_ILLEGAL_REQUEST, 10492 0, 10493 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10494 satIOContext); 10495 10496 ostiInitiatorIOCompleted( tiRoot, 10497 tiIORequest, 10498 tiIOSuccess, 10499 SCSI_STAT_CHECK_CONDITION, 10500 satIOContext->pTiSenseData, 10501 satIOContext->interruptContext ); 10502 return tiSuccess; 10503 } 10504 } /* end of case 1 and 2 */ 10505 10506 /* case 3 and 4 */ 10507 if (pSatDevData->sat48BitSupport == agTRUE) 10508 { 10509 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 10510 { 10511 /* case 3 */ 10512 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 10513 /* WRITE DMA EXT is chosen since WRITE SAME does not have FUA bit */ 10514 TI_DBG5(("satWriteSame10: case 1-3\n")); 10515 fis->h.fisType = 0x27; /* Reg host to device */ 10516 fis->h.c_pmPort = 0x80; /* C Bit is set */ 10517 10518 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 10519 10520 fis->h.features = 0; /* FIS reserve */ 10521 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 10522 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 10523 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 10524 fis->d.device = 0x40; /* FIS LBA mode set */ 10525 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 10526 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 10527 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 10528 fis->d.featuresExp = 0; /* FIS reserve */ 10529 if (tl == 0) 10530 { 10531 /* error check 10532 ATA spec, p125, 6.17.29 10533 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF 10534 and allowed value is 0x0FFFFFFF - 1 10535 */ 10536 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF) 10537 { 10538 TI_DBG5(("satWriteSame10: case 3 !!! warning can't fit sectors\n")); 10539 satSetSensePayload( pSense, 10540 SCSI_SNSKEY_ILLEGAL_REQUEST, 10541 0, 10542 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10543 satIOContext); 10544 10545 ostiInitiatorIOCompleted( tiRoot, 10546 tiIORequest, 10547 tiIOSuccess, 10548 SCSI_STAT_CHECK_CONDITION, 10549 satIOContext->pTiSenseData, 10550 satIOContext->interruptContext ); 10551 return tiSuccess; 10552 } 10553 } 10554 /* one sector at a time */ 10555 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 10556 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 10557 fis->d.reserved4 = 0; 10558 fis->d.control = 0; /* FIS HOB bit clear */ 10559 fis->d.reserved5 = 0; 10560 10561 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 10562 } 10563 else 10564 { 10565 /* case 4 */ 10566 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 10567 /* WRITE SECTORS EXT is chosen for easier implemetation */ 10568 TI_DBG5(("satWriteSame10: case 1-4\n")); 10569 fis->h.fisType = 0x27; /* Reg host to device */ 10570 fis->h.c_pmPort = 0x80; /* C Bit is set */ 10571 10572 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 10573 fis->h.features = 0; /* FIS reserve */ 10574 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 10575 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 10576 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 10577 fis->d.device = 0x40; /* FIS LBA mode set */ 10578 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 10579 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 10580 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 10581 fis->d.featuresExp = 0; /* FIS reserve */ 10582 if (tl == 0) 10583 { 10584 /* error check 10585 ATA spec, p125, 6.17.29 10586 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF 10587 and allowed value is 0x0FFFFFFF - 1 10588 */ 10589 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF) 10590 { 10591 TI_DBG5(("satWriteSame10: case 4 !!! warning can't fit sectors\n")); 10592 satSetSensePayload( pSense, 10593 SCSI_SNSKEY_ILLEGAL_REQUEST, 10594 0, 10595 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10596 satIOContext); 10597 10598 ostiInitiatorIOCompleted( tiRoot, 10599 tiIORequest, 10600 tiIOSuccess, 10601 SCSI_STAT_CHECK_CONDITION, 10602 satIOContext->pTiSenseData, 10603 satIOContext->interruptContext ); 10604 return tiSuccess; 10605 } 10606 } 10607 /* one sector at a time */ 10608 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 10609 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 10610 fis->d.reserved4 = 0; 10611 fis->d.control = 0; /* FIS HOB bit clear */ 10612 fis->d.reserved5 = 0; 10613 10614 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 10615 } 10616 } 10617 10618 /* case 5 */ 10619 if (pSatDevData->satNCQ == agTRUE) 10620 { 10621 /* WRITE FPDMA QUEUED */ 10622 if (pSatDevData->sat48BitSupport != agTRUE) 10623 { 10624 TI_DBG5(("satWriteSame10: case 1-5 !!! error NCQ but 28 bit address support \n")); 10625 satSetSensePayload( pSense, 10626 SCSI_SNSKEY_ILLEGAL_REQUEST, 10627 0, 10628 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10629 satIOContext); 10630 10631 ostiInitiatorIOCompleted( tiRoot, 10632 tiIORequest, 10633 tiIOSuccess, 10634 SCSI_STAT_CHECK_CONDITION, 10635 satIOContext->pTiSenseData, 10636 satIOContext->interruptContext ); 10637 return tiSuccess; 10638 } 10639 TI_DBG5(("satWriteSame10: case 1-5\n")); 10640 10641 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 10642 10643 fis->h.fisType = 0x27; /* Reg host to device */ 10644 fis->h.c_pmPort = 0x80; /* C Bit is set */ 10645 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 10646 10647 if (tl == 0) 10648 { 10649 /* error check 10650 ATA spec, p125, 6.17.29 10651 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF 10652 and allowed value is 0x0FFFFFFF - 1 10653 */ 10654 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF) 10655 { 10656 TI_DBG5(("satWriteSame10: case 4 !!! warning can't fit sectors\n")); 10657 satSetSensePayload( pSense, 10658 SCSI_SNSKEY_ILLEGAL_REQUEST, 10659 0, 10660 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10661 satIOContext); 10662 10663 ostiInitiatorIOCompleted( tiRoot, 10664 tiIORequest, 10665 tiIOSuccess, 10666 SCSI_STAT_CHECK_CONDITION, 10667 satIOContext->pTiSenseData, 10668 satIOContext->interruptContext ); 10669 return tiSuccess; 10670 } 10671 } 10672 /* one sector at a time */ 10673 fis->h.features = 1; /* FIS sector count (7:0) */ 10674 fis->d.featuresExp = 0; /* FIS sector count (15:8) */ 10675 10676 10677 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 10678 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 10679 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 10680 10681 /* NO FUA bit in the WRITE SAME 10 */ 10682 fis->d.device = 0x40; /* FIS FUA clear */ 10683 10684 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 10685 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 10686 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 10687 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 10688 fis->d.sectorCountExp = 0; 10689 fis->d.reserved4 = 0; 10690 fis->d.control = 0; /* FIS HOB bit clear */ 10691 fis->d.reserved5 = 0; 10692 10693 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 10694 } 10695 /* Initialize CB for SATA completion. 10696 */ 10697 satIOContext->satCompleteCB = &satWriteSame10CB; 10698 10699 /* 10700 * Prepare SGL and send FIS to LL layer. 10701 */ 10702 satIOContext->reqType = agRequestType; /* Save it */ 10703 10704 status = sataLLIOStart( tiRoot, 10705 tiIORequest, 10706 tiDeviceHandle, 10707 tiScsiRequest, 10708 satIOContext); 10709 return (status); 10710 10711 10712 } /* end of case 1 */ 10713 else if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) && 10714 (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) 10715 { 10716 /* spec 9.26.2, Table 62, p64, case 2*/ 10717 satSetSensePayload( pSense, 10718 SCSI_SNSKEY_ILLEGAL_REQUEST, 10719 0, 10720 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10721 satIOContext); 10722 10723 ostiInitiatorIOCompleted( tiRoot, 10724 tiIORequest, 10725 tiIOSuccess, 10726 SCSI_STAT_CHECK_CONDITION, 10727 satIOContext->pTiSenseData, 10728 satIOContext->interruptContext ); 10729 10730 TI_DBG5(("satWriteSame10: return Table 62 case 2\n")); 10731 return tiSuccess; 10732 } 10733 else if ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) && 10734 !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) 10735 { 10736 TI_DBG5(("satWriteSame10: Table 62 case 3\n")); 10737 10738 } 10739 else /* ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) && 10740 (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) */ 10741 { 10742 10743 /* spec 9.26.2, Table 62, p64, case 4*/ 10744 satSetSensePayload( pSense, 10745 SCSI_SNSKEY_ILLEGAL_REQUEST, 10746 0, 10747 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10748 satIOContext); 10749 10750 ostiInitiatorIOCompleted( tiRoot, 10751 tiIORequest, 10752 tiIOSuccess, 10753 SCSI_STAT_CHECK_CONDITION, 10754 satIOContext->pTiSenseData, 10755 satIOContext->interruptContext ); 10756 10757 TI_DBG5(("satWriteSame10: return Table 62 case 4\n")); 10758 return tiSuccess; 10759 } 10760 10761 10762 return tiSuccess; 10763 } 10764 10765 /*****************************************************************************/ 10766 /*! \brief SAT implementation for SCSI satWriteSame10_1. 10767 * 10768 * SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer. 10769 * This is used when WRITESAME10 is divided into multiple ATA commands 10770 * 10771 * \param tiRoot: Pointer to TISA initiator driver/port instance. 10772 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 10773 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 10774 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 10775 * \param satIOContext_t: Pointer to the SAT IO Context 10776 * \param lba: LBA 10777 * 10778 * \return If command is started successfully 10779 * - \e tiSuccess: I/O request successfully initiated. 10780 * - \e tiBusy: No resources available, try again later. 10781 * - \e tiIONoDevice: Invalid device handle. 10782 * - \e tiError: Other errors. 10783 */ 10784 /*****************************************************************************/ 10785 GLOBAL bit32 satWriteSame10_1( 10786 tiRoot_t *tiRoot, 10787 tiIORequest_t *tiIORequest, 10788 tiDeviceHandle_t *tiDeviceHandle, 10789 tiScsiInitiatorRequest_t *tiScsiRequest, 10790 satIOContext_t *satIOContext, 10791 bit32 lba 10792 ) 10793 { 10794 /* 10795 sends SAT_WRITE_DMA_EXT 10796 */ 10797 10798 bit32 status; 10799 bit32 agRequestType; 10800 agsaFisRegHostToDevice_t *fis; 10801 bit8 lba1, lba2 ,lba3, lba4; 10802 10803 TI_DBG5(("satWriteSame10_1 entry: tiDeviceHandle=%p tiIORequest=%p\n", 10804 tiDeviceHandle, tiIORequest)); 10805 10806 fis = satIOContext->pFis; 10807 10808 /* MSB */ 10809 lba1 = (bit8)((lba & 0xFF000000) >> (8*3)); 10810 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2)); 10811 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1)); 10812 /* LSB */ 10813 lba4 = (bit8)(lba & 0x000000FF); 10814 10815 /* SAT_WRITE_DMA_EXT */ 10816 fis->h.fisType = 0x27; /* Reg host to device */ 10817 fis->h.c_pmPort = 0x80; /* C Bit is set */ 10818 10819 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 10820 10821 fis->h.features = 0; /* FIS reserve */ 10822 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */ 10823 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */ 10824 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */ 10825 fis->d.device = 0x40; /* FIS LBA mode set */ 10826 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */ 10827 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 10828 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 10829 fis->d.featuresExp = 0; /* FIS reserve */ 10830 /* one sector at a time */ 10831 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 10832 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 10833 10834 fis->d.reserved4 = 0; 10835 fis->d.control = 0; /* FIS HOB bit clear */ 10836 fis->d.reserved5 = 0; 10837 10838 10839 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 10840 10841 /* Initialize CB for SATA completion. 10842 */ 10843 satIOContext->satCompleteCB = &satWriteSame10CB; 10844 10845 /* 10846 * Prepare SGL and send FIS to LL layer. 10847 */ 10848 satIOContext->reqType = agRequestType; /* Save it */ 10849 10850 status = sataLLIOStart( tiRoot, 10851 tiIORequest, 10852 tiDeviceHandle, 10853 tiScsiRequest, 10854 satIOContext); 10855 10856 TI_DBG5(("satWriteSame10_1 return status %d\n", status)); 10857 return status; 10858 } 10859 10860 /*****************************************************************************/ 10861 /*! \brief SAT implementation for SCSI satWriteSame10_2. 10862 * 10863 * SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer. 10864 * This is used when WRITESAME10 is divided into multiple ATA commands 10865 * 10866 * \param tiRoot: Pointer to TISA initiator driver/port instance. 10867 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 10868 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 10869 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 10870 * \param satIOContext_t: Pointer to the SAT IO Context 10871 * \param lba: LBA 10872 * 10873 * \return If command is started successfully 10874 * - \e tiSuccess: I/O request successfully initiated. 10875 * - \e tiBusy: No resources available, try again later. 10876 * - \e tiIONoDevice: Invalid device handle. 10877 * - \e tiError: Other errors. 10878 */ 10879 /*****************************************************************************/ 10880 GLOBAL bit32 satWriteSame10_2( 10881 tiRoot_t *tiRoot, 10882 tiIORequest_t *tiIORequest, 10883 tiDeviceHandle_t *tiDeviceHandle, 10884 tiScsiInitiatorRequest_t *tiScsiRequest, 10885 satIOContext_t *satIOContext, 10886 bit32 lba 10887 ) 10888 { 10889 /* 10890 sends SAT_WRITE_SECTORS_EXT 10891 */ 10892 10893 bit32 status; 10894 bit32 agRequestType; 10895 agsaFisRegHostToDevice_t *fis; 10896 bit8 lba1, lba2 ,lba3, lba4; 10897 10898 TI_DBG5(("satWriteSame10_2 entry: tiDeviceHandle=%p tiIORequest=%p\n", 10899 tiDeviceHandle, tiIORequest)); 10900 10901 fis = satIOContext->pFis; 10902 10903 /* MSB */ 10904 lba1 = (bit8)((lba & 0xFF000000) >> (8*3)); 10905 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2)); 10906 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1)); 10907 /* LSB */ 10908 lba4 = (bit8)(lba & 0x000000FF); 10909 10910 10911 /* SAT_WRITE_SECTORS_EXT */ 10912 fis->h.fisType = 0x27; /* Reg host to device */ 10913 fis->h.c_pmPort = 0x80; /* C Bit is set */ 10914 10915 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 10916 fis->h.features = 0; /* FIS reserve */ 10917 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */ 10918 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */ 10919 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */ 10920 fis->d.device = 0x40; /* FIS LBA mode set */ 10921 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */ 10922 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 10923 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 10924 fis->d.featuresExp = 0; /* FIS reserve */ 10925 /* one sector at a time */ 10926 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 10927 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 10928 10929 fis->d.reserved4 = 0; 10930 fis->d.control = 0; /* FIS HOB bit clear */ 10931 fis->d.reserved5 = 0; 10932 10933 10934 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 10935 10936 /* Initialize CB for SATA completion. 10937 */ 10938 satIOContext->satCompleteCB = &satWriteSame10CB; 10939 10940 /* 10941 * Prepare SGL and send FIS to LL layer. 10942 */ 10943 satIOContext->reqType = agRequestType; /* Save it */ 10944 10945 status = sataLLIOStart( tiRoot, 10946 tiIORequest, 10947 tiDeviceHandle, 10948 tiScsiRequest, 10949 satIOContext); 10950 10951 TI_DBG5(("satWriteSame10_2 return status %d\n", status)); 10952 return status; 10953 } 10954 10955 /*****************************************************************************/ 10956 /*! \brief SAT implementation for SCSI satWriteSame10_3. 10957 * 10958 * SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer. 10959 * This is used when WRITESAME10 is divided into multiple ATA commands 10960 * 10961 * \param tiRoot: Pointer to TISA initiator driver/port instance. 10962 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 10963 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 10964 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 10965 * \param satIOContext_t: Pointer to the SAT IO Context 10966 * \param lba: LBA 10967 * 10968 * \return If command is started successfully 10969 * - \e tiSuccess: I/O request successfully initiated. 10970 * - \e tiBusy: No resources available, try again later. 10971 * - \e tiIONoDevice: Invalid device handle. 10972 * - \e tiError: Other errors. 10973 */ 10974 /*****************************************************************************/ 10975 GLOBAL bit32 satWriteSame10_3( 10976 tiRoot_t *tiRoot, 10977 tiIORequest_t *tiIORequest, 10978 tiDeviceHandle_t *tiDeviceHandle, 10979 tiScsiInitiatorRequest_t *tiScsiRequest, 10980 satIOContext_t *satIOContext, 10981 bit32 lba 10982 ) 10983 { 10984 /* 10985 sends SAT_WRITE_FPDMA_QUEUED 10986 */ 10987 10988 bit32 status; 10989 bit32 agRequestType; 10990 agsaFisRegHostToDevice_t *fis; 10991 bit8 lba1, lba2 ,lba3, lba4; 10992 10993 TI_DBG5(("satWriteSame10_3 entry: tiDeviceHandle=%p tiIORequest=%p\n", 10994 tiDeviceHandle, tiIORequest)); 10995 10996 fis = satIOContext->pFis; 10997 10998 /* MSB */ 10999 lba1 = (bit8)((lba & 0xFF000000) >> (8*3)); 11000 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2)); 11001 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1)); 11002 /* LSB */ 11003 lba4 = (bit8)(lba & 0x000000FF); 11004 11005 /* SAT_WRITE_FPDMA_QUEUED */ 11006 fis->h.fisType = 0x27; /* Reg host to device */ 11007 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11008 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 11009 11010 11011 /* one sector at a time */ 11012 fis->h.features = 1; /* FIS sector count (7:0) */ 11013 fis->d.featuresExp = 0; /* FIS sector count (15:8) */ 11014 11015 11016 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */ 11017 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */ 11018 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */ 11019 11020 /* NO FUA bit in the WRITE SAME 10 */ 11021 fis->d.device = 0x40; /* FIS FUA clear */ 11022 11023 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */ 11024 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 11025 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 11026 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 11027 fis->d.sectorCountExp = 0; 11028 fis->d.reserved4 = 0; 11029 fis->d.control = 0; /* FIS HOB bit clear */ 11030 fis->d.reserved5 = 0; 11031 11032 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 11033 11034 /* Initialize CB for SATA completion. 11035 */ 11036 satIOContext->satCompleteCB = &satWriteSame10CB; 11037 11038 /* 11039 * Prepare SGL and send FIS to LL layer. 11040 */ 11041 satIOContext->reqType = agRequestType; /* Save it */ 11042 11043 status = sataLLIOStart( tiRoot, 11044 tiIORequest, 11045 tiDeviceHandle, 11046 tiScsiRequest, 11047 satIOContext); 11048 11049 TI_DBG5(("satWriteSame10_2 return status %d\n", status)); 11050 return status; 11051 } 11052 /*****************************************************************************/ 11053 /*! \brief SAT implementation for SCSI satWriteSame16. 11054 * 11055 * SAT implementation for SCSI satWriteSame16. 11056 * 11057 * \param tiRoot: Pointer to TISA initiator driver/port instance. 11058 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 11059 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 11060 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 11061 * \param satIOContext_t: Pointer to the SAT IO Context 11062 * 11063 * \return If command is started successfully 11064 * - \e tiSuccess: I/O request successfully initiated. 11065 * - \e tiBusy: No resources available, try again later. 11066 * - \e tiIONoDevice: Invalid device handle. 11067 * - \e tiError: Other errors. 11068 */ 11069 /*****************************************************************************/ 11070 GLOBAL bit32 satWriteSame16( 11071 tiRoot_t *tiRoot, 11072 tiIORequest_t *tiIORequest, 11073 tiDeviceHandle_t *tiDeviceHandle, 11074 tiScsiInitiatorRequest_t *tiScsiRequest, 11075 satIOContext_t *satIOContext) 11076 { 11077 scsiRspSense_t *pSense; 11078 11079 pSense = satIOContext->pSense; 11080 11081 TI_DBG5(("satWriteSame16:start\n")); 11082 11083 11084 satSetSensePayload( pSense, 11085 SCSI_SNSKEY_NO_SENSE, 11086 0, 11087 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 11088 satIOContext); 11089 11090 ostiInitiatorIOCompleted( tiRoot, 11091 tiIORequest, /* == &satIntIo->satOrgTiIORequest */ 11092 tiIOSuccess, 11093 SCSI_STAT_CHECK_CONDITION, 11094 satIOContext->pTiSenseData, 11095 satIOContext->interruptContext ); 11096 TI_DBG5(("satWriteSame16: return internal checking\n")); 11097 return tiSuccess; 11098 } 11099 11100 /*****************************************************************************/ 11101 /*! \brief SAT implementation for SCSI satLogSense_1. 11102 * 11103 * Part of SAT implementation for SCSI satLogSense. 11104 * 11105 * \param tiRoot: Pointer to TISA initiator driver/port instance. 11106 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 11107 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 11108 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 11109 * \param satIOContext_t: Pointer to the SAT IO Context 11110 * 11111 * \return If command is started successfully 11112 * - \e tiSuccess: I/O request successfully initiated. 11113 * - \e tiBusy: No resources available, try again later. 11114 * - \e tiIONoDevice: Invalid device handle. 11115 * - \e tiError: Other errors. 11116 */ 11117 /*****************************************************************************/ 11118 GLOBAL bit32 satLogSense_1( 11119 tiRoot_t *tiRoot, 11120 tiIORequest_t *tiIORequest, 11121 tiDeviceHandle_t *tiDeviceHandle, 11122 tiScsiInitiatorRequest_t *tiScsiRequest, 11123 satIOContext_t *satIOContext) 11124 { 11125 bit32 status; 11126 bit32 agRequestType; 11127 satDeviceData_t *pSatDevData; 11128 agsaFisRegHostToDevice_t *fis; 11129 11130 pSatDevData = satIOContext->pSatDevData; 11131 fis = satIOContext->pFis; 11132 11133 TI_DBG5(("satLogSense_1: start\n")); 11134 11135 11136 /* SAT Rev 8, 10.2.4 p74 */ 11137 if ( pSatDevData->sat48BitSupport == agTRUE ) 11138 { 11139 TI_DBG5(("satLogSense_1: case 2-1 sends READ LOG EXT\n")); 11140 /* sends READ LOG EXT */ 11141 fis->h.fisType = 0x27; /* Reg host to device */ 11142 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11143 11144 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */ 11145 fis->h.features = 0; /* FIS reserve */ 11146 fis->d.lbaLow = 0x07; /* 0x07 */ 11147 fis->d.lbaMid = 0; /* */ 11148 fis->d.lbaHigh = 0; /* */ 11149 fis->d.device = 0; /* */ 11150 fis->d.lbaLowExp = 0; /* */ 11151 fis->d.lbaMidExp = 0; /* */ 11152 fis->d.lbaHighExp = 0; /* */ 11153 fis->d.featuresExp = 0; /* FIS reserve */ 11154 fis->d.sectorCount = 0x01; /* 1 sector counts */ 11155 fis->d.sectorCountExp = 0x00; /* 1 sector counts */ 11156 fis->d.reserved4 = 0; 11157 fis->d.control = 0; /* FIS HOB bit clear */ 11158 fis->d.reserved5 = 0; 11159 11160 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 11161 11162 /* Initialize CB for SATA completion. 11163 */ 11164 satIOContext->satCompleteCB = &satLogSenseCB; 11165 11166 /* 11167 * Prepare SGL and send FIS to LL layer. 11168 */ 11169 satIOContext->reqType = agRequestType; /* Save it */ 11170 11171 status = sataLLIOStart( tiRoot, 11172 tiIORequest, 11173 tiDeviceHandle, 11174 tiScsiRequest, 11175 satIOContext); 11176 return status; 11177 11178 } 11179 else 11180 { 11181 TI_DBG5(("satLogSense_1: case 2-2 sends SMART READ LOG\n")); 11182 /* sends SMART READ LOG */ 11183 fis->h.fisType = 0x27; /* Reg host to device */ 11184 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11185 11186 fis->h.command = SAT_SMART_READ_LOG; /* 0x2F */ 11187 fis->h.features = 0x00; /* 0xd5 */ 11188 fis->d.lbaLow = 0x06; /* 0x06 */ 11189 fis->d.lbaMid = 0x00; /* 0x4f */ 11190 fis->d.lbaHigh = 0x00; /* 0xc2 */ 11191 fis->d.device = 0; /* */ 11192 fis->d.lbaLowExp = 0; /* */ 11193 fis->d.lbaMidExp = 0; /* */ 11194 fis->d.lbaHighExp = 0; /* */ 11195 fis->d.featuresExp = 0; /* FIS reserve */ 11196 fis->d.sectorCount = 0x01; /* */ 11197 fis->d.sectorCountExp = 0x00; /* */ 11198 fis->d.reserved4 = 0; 11199 fis->d.control = 0; /* FIS HOB bit clear */ 11200 fis->d.reserved5 = 0; 11201 11202 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 11203 11204 /* Initialize CB for SATA completion. 11205 */ 11206 satIOContext->satCompleteCB = &satLogSenseCB; 11207 11208 /* 11209 * Prepare SGL and send FIS to LL layer. 11210 */ 11211 satIOContext->reqType = agRequestType; /* Save it */ 11212 11213 status = sataLLIOStart( tiRoot, 11214 tiIORequest, 11215 tiDeviceHandle, 11216 tiScsiRequest, 11217 satIOContext); 11218 return status; 11219 11220 } 11221 } 11222 11223 /*****************************************************************************/ 11224 /*! \brief SAT implementation for SCSI satSMARTEnable. 11225 * 11226 * Part of SAT implementation for SCSI satLogSense. 11227 * 11228 * \param tiRoot: Pointer to TISA initiator driver/port instance. 11229 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 11230 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 11231 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 11232 * \param satIOContext_t: Pointer to the SAT IO Context 11233 * 11234 * \return If command is started successfully 11235 * - \e tiSuccess: I/O request successfully initiated. 11236 * - \e tiBusy: No resources available, try again later. 11237 * - \e tiIONoDevice: Invalid device handle. 11238 * - \e tiError: Other errors. 11239 */ 11240 /*****************************************************************************/ 11241 GLOBAL bit32 satSMARTEnable( 11242 tiRoot_t *tiRoot, 11243 tiIORequest_t *tiIORequest, 11244 tiDeviceHandle_t *tiDeviceHandle, 11245 tiScsiInitiatorRequest_t *tiScsiRequest, 11246 satIOContext_t *satIOContext) 11247 { 11248 bit32 status; 11249 bit32 agRequestType; 11250 agsaFisRegHostToDevice_t *fis; 11251 11252 TI_DBG4(("satSMARTEnable entry: tiDeviceHandle=%p tiIORequest=%p\n", 11253 tiDeviceHandle, tiIORequest)); 11254 11255 fis = satIOContext->pFis; 11256 11257 /* 11258 * Send the SAT_SMART_ENABLE_OPERATIONS command. 11259 */ 11260 fis->h.fisType = 0x27; /* Reg host to device */ 11261 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11262 11263 fis->h.command = SAT_SMART_ENABLE_OPERATIONS; /* 0xB0 */ 11264 fis->h.features = 0xD8; 11265 fis->d.lbaLow = 0; 11266 fis->d.lbaMid = 0x4F; 11267 fis->d.lbaHigh = 0xC2; 11268 fis->d.device = 0; 11269 fis->d.lbaLowExp = 0; 11270 fis->d.lbaMidExp = 0; 11271 fis->d.lbaHighExp = 0; 11272 fis->d.featuresExp = 0; 11273 fis->d.sectorCount = 0; 11274 fis->d.sectorCountExp = 0; 11275 fis->d.reserved4 = 0; 11276 fis->d.control = 0; /* FIS HOB bit clear */ 11277 fis->d.reserved5 = 0; 11278 11279 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 11280 11281 /* Initialize CB for SATA completion. 11282 */ 11283 satIOContext->satCompleteCB = &satSMARTEnableCB; 11284 11285 /* 11286 * Prepare SGL and send FIS to LL layer. 11287 */ 11288 satIOContext->reqType = agRequestType; /* Save it */ 11289 11290 status = sataLLIOStart( tiRoot, 11291 tiIORequest, 11292 tiDeviceHandle, 11293 tiScsiRequest, 11294 satIOContext); 11295 11296 11297 return status; 11298 } 11299 11300 /*****************************************************************************/ 11301 /*! \brief SAT implementation for SCSI satLogSense_3. 11302 * 11303 * Part of SAT implementation for SCSI satLogSense. 11304 * 11305 * \param tiRoot: Pointer to TISA initiator driver/port instance. 11306 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 11307 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 11308 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 11309 * \param satIOContext_t: Pointer to the SAT IO Context 11310 * 11311 * \return If command is started successfully 11312 * - \e tiSuccess: I/O request successfully initiated. 11313 * - \e tiBusy: No resources available, try again later. 11314 * - \e tiIONoDevice: Invalid device handle. 11315 * - \e tiError: Other errors. 11316 */ 11317 /*****************************************************************************/ 11318 GLOBAL bit32 satLogSense_3( 11319 tiRoot_t *tiRoot, 11320 tiIORequest_t *tiIORequest, 11321 tiDeviceHandle_t *tiDeviceHandle, 11322 tiScsiInitiatorRequest_t *tiScsiRequest, 11323 satIOContext_t *satIOContext) 11324 { 11325 bit32 status; 11326 bit32 agRequestType; 11327 agsaFisRegHostToDevice_t *fis; 11328 11329 TI_DBG4(("satLogSense_3 entry: tiDeviceHandle=%p tiIORequest=%p\n", 11330 tiDeviceHandle, tiIORequest)); 11331 11332 fis = satIOContext->pFis; 11333 /* sends READ LOG EXT */ 11334 fis->h.fisType = 0x27; /* Reg host to device */ 11335 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11336 11337 fis->h.command = SAT_SMART_READ_LOG; /* 0x2F */ 11338 fis->h.features = 0xD5; /* 0xd5 */ 11339 fis->d.lbaLow = 0x06; /* 0x06 */ 11340 fis->d.lbaMid = 0x4F; /* 0x4f */ 11341 fis->d.lbaHigh = 0xC2; /* 0xc2 */ 11342 fis->d.device = 0; /* */ 11343 fis->d.lbaLowExp = 0; /* */ 11344 fis->d.lbaMidExp = 0; /* */ 11345 fis->d.lbaHighExp = 0; /* */ 11346 fis->d.featuresExp = 0; /* FIS reserve */ 11347 fis->d.sectorCount = 0x01; /* 1 sector counts */ 11348 fis->d.sectorCountExp = 0x00; /* 1 sector counts */ 11349 fis->d.reserved4 = 0; 11350 fis->d.control = 0; /* FIS HOB bit clear */ 11351 fis->d.reserved5 = 0; 11352 11353 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 11354 11355 /* Initialize CB for SATA completion. 11356 */ 11357 satIOContext->satCompleteCB = &satLogSenseCB; 11358 11359 /* 11360 * Prepare SGL and send FIS to LL layer. 11361 */ 11362 satIOContext->reqType = agRequestType; /* Save it */ 11363 11364 status = sataLLIOStart( tiRoot, 11365 tiIORequest, 11366 tiDeviceHandle, 11367 tiScsiRequest, 11368 satIOContext); 11369 return status; 11370 } 11371 11372 /*****************************************************************************/ 11373 /*! \brief SAT implementation for SCSI satLogSense_2. 11374 * 11375 * Part of SAT implementation for SCSI satLogSense. 11376 * 11377 * \param tiRoot: Pointer to TISA initiator driver/port instance. 11378 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 11379 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 11380 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 11381 * \param satIOContext_t: Pointer to the SAT IO Context 11382 * 11383 * \return If command is started successfully 11384 * - \e tiSuccess: I/O request successfully initiated. 11385 * - \e tiBusy: No resources available, try again later. 11386 * - \e tiIONoDevice: Invalid device handle. 11387 * - \e tiError: Other errors. 11388 */ 11389 /*****************************************************************************/ 11390 GLOBAL bit32 satLogSense_2( 11391 tiRoot_t *tiRoot, 11392 tiIORequest_t *tiIORequest, 11393 tiDeviceHandle_t *tiDeviceHandle, 11394 tiScsiInitiatorRequest_t *tiScsiRequest, 11395 satIOContext_t *satIOContext) 11396 { 11397 bit32 status; 11398 bit32 agRequestType; 11399 agsaFisRegHostToDevice_t *fis; 11400 11401 TI_DBG4(("satLogSense_2 entry: tiDeviceHandle=%p tiIORequest=%p\n", 11402 tiDeviceHandle, tiIORequest)); 11403 11404 fis = satIOContext->pFis; 11405 /* sends READ LOG EXT */ 11406 fis->h.fisType = 0x27; /* Reg host to device */ 11407 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11408 11409 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */ 11410 fis->h.features = 0; /* FIS reserve */ 11411 fis->d.lbaLow = 0x07; /* 0x07 */ 11412 fis->d.lbaMid = 0; /* */ 11413 fis->d.lbaHigh = 0; /* */ 11414 fis->d.device = 0; /* */ 11415 fis->d.lbaLowExp = 0; /* */ 11416 fis->d.lbaMidExp = 0; /* */ 11417 fis->d.lbaHighExp = 0; /* */ 11418 fis->d.featuresExp = 0; /* FIS reserve */ 11419 fis->d.sectorCount = 0x01; /* 1 sector counts */ 11420 fis->d.sectorCountExp = 0x00; /* 1 sector counts */ 11421 fis->d.reserved4 = 0; 11422 fis->d.control = 0; /* FIS HOB bit clear */ 11423 fis->d.reserved5 = 0; 11424 11425 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 11426 11427 /* Initialize CB for SATA completion. 11428 */ 11429 satIOContext->satCompleteCB = &satLogSenseCB; 11430 11431 /* 11432 * Prepare SGL and send FIS to LL layer. 11433 */ 11434 satIOContext->reqType = agRequestType; /* Save it */ 11435 11436 status = sataLLIOStart( tiRoot, 11437 tiIORequest, 11438 tiDeviceHandle, 11439 tiScsiRequest, 11440 satIOContext); 11441 return status; 11442 } 11443 11444 /*****************************************************************************/ 11445 /*! \brief SAT implementation for SCSI satLogSenseAllocate. 11446 * 11447 * Part of SAT implementation for SCSI satLogSense. 11448 * 11449 * \param tiRoot: Pointer to TISA initiator driver/port instance. 11450 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 11451 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 11452 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 11453 * \param satIOContext_t: Pointer to the SAT IO Context 11454 * \param payloadSize: size of payload to be allocated. 11455 * \param flag: flag value 11456 * 11457 * \return If command is started successfully 11458 * - \e tiSuccess: I/O request successfully initiated. 11459 * - \e tiBusy: No resources available, try again later. 11460 * - \e tiIONoDevice: Invalid device handle. 11461 * - \e tiError: Other errors. 11462 * \note 11463 * - flag values: LOG_SENSE_0, LOG_SENSE_1, LOG_SENSE_2 11464 */ 11465 /*****************************************************************************/ 11466 GLOBAL bit32 satLogSenseAllocate( 11467 tiRoot_t *tiRoot, 11468 tiIORequest_t *tiIORequest, 11469 tiDeviceHandle_t *tiDeviceHandle, 11470 tiScsiInitiatorRequest_t *tiScsiRequest, 11471 satIOContext_t *satIOContext, 11472 bit32 payloadSize, 11473 bit32 flag 11474 ) 11475 { 11476 satDeviceData_t *pSatDevData; 11477 tdIORequestBody_t *tdIORequestBody; 11478 satInternalIo_t *satIntIo = agNULL; 11479 satIOContext_t *satIOContext2; 11480 bit32 status; 11481 11482 TI_DBG4(("satLogSense_2 entry: tiDeviceHandle=%p tiIORequest=%p\n", 11483 tiDeviceHandle, tiIORequest)); 11484 11485 pSatDevData = satIOContext->pSatDevData; 11486 11487 /* create internal satIOContext */ 11488 satIntIo = satAllocIntIoResource( tiRoot, 11489 tiIORequest, /* original request */ 11490 pSatDevData, 11491 payloadSize, 11492 satIntIo); 11493 11494 if (satIntIo == agNULL) 11495 { 11496 /* memory allocation failure */ 11497 satFreeIntIoResource( tiRoot, 11498 pSatDevData, 11499 satIntIo); 11500 11501 ostiInitiatorIOCompleted( tiRoot, 11502 tiIORequest, 11503 tiIOFailed, 11504 tiDetailOtherError, 11505 agNULL, 11506 satIOContext->interruptContext ); 11507 11508 TI_DBG4(("satLogSense_2: fail in allocation\n")); 11509 return tiSuccess; 11510 } /* end of memory allocation failure */ 11511 11512 satIntIo->satOrgTiIORequest = tiIORequest; 11513 tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody; 11514 satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext); 11515 11516 satIOContext2->pSatDevData = pSatDevData; 11517 satIOContext2->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 11518 satIOContext2->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd); 11519 satIOContext2->pSense = &(tdIORequestBody->transport.SATA.sensePayload); 11520 satIOContext2->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData); 11521 satIOContext2->pTiSenseData->senseData = satIOContext2->pSense; 11522 satIOContext2->tiRequestBody = satIntIo->satIntRequestBody; 11523 satIOContext2->interruptContext = satIOContext->interruptContext; 11524 satIOContext2->satIntIoContext = satIntIo; 11525 satIOContext2->ptiDeviceHandle = tiDeviceHandle; 11526 satIOContext2->satOrgIOContext = satIOContext; 11527 11528 if (flag == LOG_SENSE_0) 11529 { 11530 /* SAT_SMART_ENABLE_OPERATIONS */ 11531 status = satSMARTEnable( tiRoot, 11532 &(satIntIo->satIntTiIORequest), 11533 tiDeviceHandle, 11534 &(satIntIo->satIntTiScsiXchg), 11535 satIOContext2); 11536 } 11537 else if (flag == LOG_SENSE_1) 11538 { 11539 /* SAT_READ_LOG_EXT */ 11540 status = satLogSense_2( tiRoot, 11541 &(satIntIo->satIntTiIORequest), 11542 tiDeviceHandle, 11543 &(satIntIo->satIntTiScsiXchg), 11544 satIOContext2); 11545 } 11546 else 11547 { 11548 /* SAT_SMART_READ_LOG */ 11549 /* SAT_READ_LOG_EXT */ 11550 status = satLogSense_3( tiRoot, 11551 &(satIntIo->satIntTiIORequest), 11552 tiDeviceHandle, 11553 &(satIntIo->satIntTiScsiXchg), 11554 satIOContext2); 11555 11556 } 11557 if (status != tiSuccess) 11558 { 11559 satFreeIntIoResource( tiRoot, 11560 pSatDevData, 11561 satIntIo); 11562 11563 ostiInitiatorIOCompleted( tiRoot, 11564 tiIORequest, 11565 tiIOFailed, 11566 tiDetailOtherError, 11567 agNULL, 11568 satIOContext->interruptContext ); 11569 return tiSuccess; 11570 } 11571 11572 11573 return tiSuccess; 11574 } 11575 11576 11577 /*****************************************************************************/ 11578 /*! \brief SAT implementation for SCSI satLogSense. 11579 * 11580 * SAT implementation for SCSI satLogSense. 11581 * 11582 * \param tiRoot: Pointer to TISA initiator driver/port instance. 11583 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 11584 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 11585 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 11586 * \param satIOContext_t: Pointer to the SAT IO Context 11587 * 11588 * \return If command is started successfully 11589 * - \e tiSuccess: I/O request successfully initiated. 11590 * - \e tiBusy: No resources available, try again later. 11591 * - \e tiIONoDevice: Invalid device handle. 11592 * - \e tiError: Other errors. 11593 */ 11594 /*****************************************************************************/ 11595 GLOBAL bit32 satLogSense( 11596 tiRoot_t *tiRoot, 11597 tiIORequest_t *tiIORequest, 11598 tiDeviceHandle_t *tiDeviceHandle, 11599 tiScsiInitiatorRequest_t *tiScsiRequest, 11600 satIOContext_t *satIOContext) 11601 { 11602 bit32 status; 11603 bit32 agRequestType; 11604 satDeviceData_t *pSatDevData; 11605 scsiRspSense_t *pSense; 11606 tiIniScsiCmnd_t *scsiCmnd; 11607 agsaFisRegHostToDevice_t *fis; 11608 bit8 *pLogPage; /* Log Page data buffer */ 11609 bit32 flag = 0; 11610 bit16 AllocLen = 0; /* allocation length */ 11611 bit8 AllLogPages[8]; 11612 bit16 lenRead = 0; 11613 11614 pSense = satIOContext->pSense; 11615 pSatDevData = satIOContext->pSatDevData; 11616 scsiCmnd = &tiScsiRequest->scsiCmnd; 11617 fis = satIOContext->pFis; 11618 pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr; 11619 11620 TI_DBG5(("satLogSense: start\n")); 11621 11622 osti_memset(&AllLogPages, 0, 8); 11623 /* checking CONTROL */ 11624 /* NACA == 1 or LINK == 1*/ 11625 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 11626 { 11627 satSetSensePayload( pSense, 11628 SCSI_SNSKEY_ILLEGAL_REQUEST, 11629 0, 11630 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11631 satIOContext); 11632 11633 ostiInitiatorIOCompleted( tiRoot, 11634 tiIORequest, 11635 tiIOSuccess, 11636 SCSI_STAT_CHECK_CONDITION, 11637 satIOContext->pTiSenseData, 11638 satIOContext->interruptContext ); 11639 11640 TI_DBG2(("satLogSense: return control\n")); 11641 return tiSuccess; 11642 } 11643 11644 11645 AllocLen = (bit8)((scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]); 11646 11647 /* checking PC (Page Control) */ 11648 /* nothing */ 11649 11650 /* special cases */ 11651 if (AllocLen == 4) 11652 { 11653 TI_DBG1(("satLogSense: AllocLen is 4\n")); 11654 switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK) 11655 { 11656 case LOGSENSE_SUPPORTED_LOG_PAGES: 11657 TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n")); 11658 11659 /* SAT Rev 8, 10.2.5 p76 */ 11660 if (pSatDevData->satSMARTFeatureSet == agTRUE) 11661 { 11662 /* add informational exception log */ 11663 flag = 1; 11664 if (pSatDevData->satSMARTSelfTest == agTRUE) 11665 { 11666 /* add Self-Test results log page */ 11667 flag = 2; 11668 } 11669 } 11670 else 11671 { 11672 /* only supported, no informational exception log, no Self-Test results log page */ 11673 flag = 0; 11674 } 11675 lenRead = 4; 11676 AllLogPages[0] = LOGSENSE_SUPPORTED_LOG_PAGES; /* page code */ 11677 AllLogPages[1] = 0; /* reserved */ 11678 switch (flag) 11679 { 11680 case 0: 11681 /* only supported */ 11682 AllLogPages[2] = 0; /* page length */ 11683 AllLogPages[3] = 1; /* page length */ 11684 break; 11685 case 1: 11686 /* supported and informational exception log */ 11687 AllLogPages[2] = 0; /* page length */ 11688 AllLogPages[3] = 2; /* page length */ 11689 break; 11690 case 2: 11691 /* supported and informational exception log */ 11692 AllLogPages[2] = 0; /* page length */ 11693 AllLogPages[3] = 3; /* page length */ 11694 break; 11695 default: 11696 TI_DBG1(("satLogSense: error unallowed flag value %d\n", flag)); 11697 break; 11698 } 11699 osti_memcpy(pLogPage, &AllLogPages, lenRead); 11700 break; 11701 case LOGSENSE_SELFTEST_RESULTS_PAGE: 11702 TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n")); 11703 lenRead = 4; 11704 AllLogPages[0] = LOGSENSE_SELFTEST_RESULTS_PAGE; /* page code */ 11705 AllLogPages[1] = 0; /* reserved */ 11706 /* page length = SELFTEST_RESULTS_LOG_PAGE_LENGTH - 1 - 3 = 400 = 0x190 */ 11707 AllLogPages[2] = 0x01; 11708 AllLogPages[3] = 0x90; /* page length */ 11709 osti_memcpy(pLogPage, &AllLogPages, lenRead); 11710 11711 break; 11712 case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE: 11713 TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n")); 11714 lenRead = 4; 11715 AllLogPages[0] = LOGSENSE_INFORMATION_EXCEPTIONS_PAGE; /* page code */ 11716 AllLogPages[1] = 0; /* reserved */ 11717 AllLogPages[2] = 0; /* page length */ 11718 AllLogPages[3] = INFORMATION_EXCEPTIONS_LOG_PAGE_LENGTH - 1 - 3; /* page length */ 11719 osti_memcpy(pLogPage, &AllLogPages, lenRead); 11720 break; 11721 default: 11722 TI_DBG1(("satLogSense: default Page Code 0x%x\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)); 11723 satSetSensePayload( pSense, 11724 SCSI_SNSKEY_ILLEGAL_REQUEST, 11725 0, 11726 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11727 satIOContext); 11728 11729 ostiInitiatorIOCompleted( tiRoot, 11730 tiIORequest, 11731 tiIOSuccess, 11732 SCSI_STAT_CHECK_CONDITION, 11733 satIOContext->pTiSenseData, 11734 satIOContext->interruptContext ); 11735 return tiSuccess; 11736 } 11737 ostiInitiatorIOCompleted( tiRoot, 11738 tiIORequest, 11739 tiIOSuccess, 11740 SCSI_STAT_GOOD, 11741 agNULL, 11742 satIOContext->interruptContext); 11743 return tiSuccess; 11744 11745 } /* if */ 11746 11747 /* SAT rev8 Table 11 p30*/ 11748 /* checking Page Code */ 11749 switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK) 11750 { 11751 case LOGSENSE_SUPPORTED_LOG_PAGES: 11752 TI_DBG5(("satLogSense: case 1\n")); 11753 11754 /* SAT Rev 8, 10.2.5 p76 */ 11755 11756 if (pSatDevData->satSMARTFeatureSet == agTRUE) 11757 { 11758 /* add informational exception log */ 11759 flag = 1; 11760 if (pSatDevData->satSMARTSelfTest == agTRUE) 11761 { 11762 /* add Self-Test results log page */ 11763 flag = 2; 11764 } 11765 } 11766 else 11767 { 11768 /* only supported, no informational exception log, no Self-Test results log page */ 11769 flag = 0; 11770 } 11771 AllLogPages[0] = 0; /* page code */ 11772 AllLogPages[1] = 0; /* reserved */ 11773 switch (flag) 11774 { 11775 case 0: 11776 /* only supported */ 11777 AllLogPages[2] = 0; /* page length */ 11778 AllLogPages[3] = 1; /* page length */ 11779 AllLogPages[4] = 0x00; /* supported page list */ 11780 lenRead = (bit8)(MIN(AllocLen, 5)); 11781 break; 11782 case 1: 11783 /* supported and informational exception log */ 11784 AllLogPages[2] = 0; /* page length */ 11785 AllLogPages[3] = 2; /* page length */ 11786 AllLogPages[4] = 0x00; /* supported page list */ 11787 AllLogPages[5] = 0x10; /* supported page list */ 11788 lenRead = (bit8)(MIN(AllocLen, 6)); 11789 break; 11790 case 2: 11791 /* supported and informational exception log */ 11792 AllLogPages[2] = 0; /* page length */ 11793 AllLogPages[3] = 3; /* page length */ 11794 AllLogPages[4] = 0x00; /* supported page list */ 11795 AllLogPages[5] = 0x10; /* supported page list */ 11796 AllLogPages[6] = 0x2F; /* supported page list */ 11797 lenRead = (bit8)(MIN(AllocLen, 7)); 11798 break; 11799 default: 11800 TI_DBG1(("satLogSense: error unallowed flag value %d\n", flag)); 11801 break; 11802 } 11803 11804 osti_memcpy(pLogPage, &AllLogPages, lenRead); 11805 /* comparing allocation length to Log Page byte size */ 11806 /* SPC-4, 4.3.4.6, p28 */ 11807 if (AllocLen > lenRead ) 11808 { 11809 TI_DBG1(("satLogSense reporting underrun lenRead=0x%x AllocLen=0x%x tiIORequest=%p\n", lenRead, AllocLen, tiIORequest)); 11810 ostiInitiatorIOCompleted( tiRoot, 11811 tiIORequest, 11812 tiIOUnderRun, 11813 AllocLen - lenRead, 11814 agNULL, 11815 satIOContext->interruptContext ); 11816 } 11817 else 11818 { 11819 ostiInitiatorIOCompleted( tiRoot, 11820 tiIORequest, 11821 tiIOSuccess, 11822 SCSI_STAT_GOOD, 11823 agNULL, 11824 satIOContext->interruptContext); 11825 } 11826 break; 11827 case LOGSENSE_SELFTEST_RESULTS_PAGE: 11828 TI_DBG5(("satLogSense: case 2\n")); 11829 /* checking SMART self-test */ 11830 if (pSatDevData->satSMARTSelfTest == agFALSE) 11831 { 11832 TI_DBG5(("satLogSense: case 2 no SMART Self Test\n")); 11833 satSetSensePayload( pSense, 11834 SCSI_SNSKEY_ILLEGAL_REQUEST, 11835 0, 11836 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11837 satIOContext); 11838 11839 ostiInitiatorIOCompleted( tiRoot, 11840 tiIORequest, 11841 tiIOSuccess, 11842 SCSI_STAT_CHECK_CONDITION, 11843 satIOContext->pTiSenseData, 11844 satIOContext->interruptContext ); 11845 } 11846 else 11847 { 11848 /* if satSMARTEnabled is false, send SMART_ENABLE_OPERATIONS */ 11849 if (pSatDevData->satSMARTEnabled == agFALSE) 11850 { 11851 TI_DBG5(("satLogSense: case 2 calling satSMARTEnable\n")); 11852 status = satLogSenseAllocate(tiRoot, 11853 tiIORequest, 11854 tiDeviceHandle, 11855 tiScsiRequest, 11856 satIOContext, 11857 0, 11858 LOG_SENSE_0 11859 ); 11860 11861 return status; 11862 11863 } 11864 else 11865 { 11866 /* SAT Rev 8, 10.2.4 p74 */ 11867 if ( pSatDevData->sat48BitSupport == agTRUE ) 11868 { 11869 TI_DBG5(("satLogSense: case 2-1 sends READ LOG EXT\n")); 11870 status = satLogSenseAllocate(tiRoot, 11871 tiIORequest, 11872 tiDeviceHandle, 11873 tiScsiRequest, 11874 satIOContext, 11875 512, 11876 LOG_SENSE_1 11877 ); 11878 11879 return status; 11880 } 11881 else 11882 { 11883 TI_DBG5(("satLogSense: case 2-2 sends SMART READ LOG\n")); 11884 status = satLogSenseAllocate(tiRoot, 11885 tiIORequest, 11886 tiDeviceHandle, 11887 tiScsiRequest, 11888 satIOContext, 11889 512, 11890 LOG_SENSE_2 11891 ); 11892 11893 return status; 11894 } 11895 } 11896 } 11897 break; 11898 case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE: 11899 TI_DBG5(("satLogSense: case 3\n")); 11900 /* checking SMART feature set */ 11901 if (pSatDevData->satSMARTFeatureSet == agFALSE) 11902 { 11903 satSetSensePayload( pSense, 11904 SCSI_SNSKEY_ILLEGAL_REQUEST, 11905 0, 11906 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11907 satIOContext); 11908 11909 ostiInitiatorIOCompleted( tiRoot, 11910 tiIORequest, 11911 tiIOSuccess, 11912 SCSI_STAT_CHECK_CONDITION, 11913 satIOContext->pTiSenseData, 11914 satIOContext->interruptContext ); 11915 } 11916 else 11917 { 11918 /* checking SMART feature enabled */ 11919 if (pSatDevData->satSMARTEnabled == agFALSE) 11920 { 11921 satSetSensePayload( pSense, 11922 SCSI_SNSKEY_ABORTED_COMMAND, 11923 0, 11924 SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED, 11925 satIOContext); 11926 11927 ostiInitiatorIOCompleted( tiRoot, 11928 tiIORequest, 11929 tiIOSuccess, 11930 SCSI_STAT_CHECK_CONDITION, 11931 satIOContext->pTiSenseData, 11932 satIOContext->interruptContext ); 11933 } 11934 else 11935 { 11936 /* SAT Rev 8, 10.2.3 p72 */ 11937 TI_DBG5(("satLogSense: case 3 sends SMART RETURN STATUS\n")); 11938 11939 /* sends SMART RETURN STATUS */ 11940 fis->h.fisType = 0x27; /* Reg host to device */ 11941 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11942 11943 fis->h.command = SAT_SMART_RETURN_STATUS;/* 0xB0 */ 11944 fis->h.features = 0xDA; /* FIS features */ 11945 fis->d.featuresExp = 0; /* FIS reserve */ 11946 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 11947 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 11948 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 11949 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 11950 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 11951 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 11952 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 11953 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 11954 fis->d.device = 0; /* FIS DEV is discared in SATA */ 11955 fis->d.control = 0; /* FIS HOB bit clear */ 11956 fis->d.reserved4 = 0; 11957 fis->d.reserved5 = 0; 11958 11959 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 11960 /* Initialize CB for SATA completion. 11961 */ 11962 satIOContext->satCompleteCB = &satLogSenseCB; 11963 11964 /* 11965 * Prepare SGL and send FIS to LL layer. 11966 */ 11967 satIOContext->reqType = agRequestType; /* Save it */ 11968 11969 status = sataLLIOStart( tiRoot, 11970 tiIORequest, 11971 tiDeviceHandle, 11972 tiScsiRequest, 11973 satIOContext); 11974 11975 11976 return status; 11977 } 11978 } 11979 break; 11980 default: 11981 TI_DBG1(("satLogSense: default Page Code 0x%x\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)); 11982 satSetSensePayload( pSense, 11983 SCSI_SNSKEY_ILLEGAL_REQUEST, 11984 0, 11985 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11986 satIOContext); 11987 11988 ostiInitiatorIOCompleted( tiRoot, 11989 tiIORequest, 11990 tiIOSuccess, 11991 SCSI_STAT_CHECK_CONDITION, 11992 satIOContext->pTiSenseData, 11993 satIOContext->interruptContext ); 11994 11995 break; 11996 } /* end switch */ 11997 11998 return tiSuccess; 11999 12000 12001 } 12002 12003 /*****************************************************************************/ 12004 /*! \brief SAT implementation for SCSI satModeSelect6. 12005 * 12006 * SAT implementation for SCSI satModeSelect6. 12007 * 12008 * \param tiRoot: Pointer to TISA initiator driver/port instance. 12009 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 12010 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 12011 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 12012 * \param satIOContext_t: Pointer to the SAT IO Context 12013 * 12014 * \return If command is started successfully 12015 * - \e tiSuccess: I/O request successfully initiated. 12016 * - \e tiBusy: No resources available, try again later. 12017 * - \e tiIONoDevice: Invalid device handle. 12018 * - \e tiError: Other errors. 12019 */ 12020 /*****************************************************************************/ 12021 GLOBAL bit32 satModeSelect6( 12022 tiRoot_t *tiRoot, 12023 tiIORequest_t *tiIORequest, 12024 tiDeviceHandle_t *tiDeviceHandle, 12025 tiScsiInitiatorRequest_t *tiScsiRequest, 12026 satIOContext_t *satIOContext) 12027 { 12028 bit32 status; 12029 bit32 agRequestType; 12030 satDeviceData_t *pSatDevData; 12031 scsiRspSense_t *pSense; 12032 tiIniScsiCmnd_t *scsiCmnd; 12033 agsaFisRegHostToDevice_t *fis; 12034 bit8 *pLogPage; /* Log Page data buffer */ 12035 bit32 StartingIndex = 0; 12036 bit8 PageCode = 0; 12037 bit32 chkCnd = agFALSE; 12038 12039 pSense = satIOContext->pSense; 12040 pSatDevData = satIOContext->pSatDevData; 12041 scsiCmnd = &tiScsiRequest->scsiCmnd; 12042 fis = satIOContext->pFis; 12043 pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr; 12044 12045 TI_DBG5(("satModeSelect6: start\n")); 12046 12047 /* checking CONTROL */ 12048 /* NACA == 1 or LINK == 1*/ 12049 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 12050 { 12051 satSetSensePayload( pSense, 12052 SCSI_SNSKEY_ILLEGAL_REQUEST, 12053 0, 12054 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12055 satIOContext); 12056 12057 ostiInitiatorIOCompleted( tiRoot, 12058 tiIORequest, 12059 tiIOSuccess, 12060 SCSI_STAT_CHECK_CONDITION, 12061 satIOContext->pTiSenseData, 12062 satIOContext->interruptContext ); 12063 12064 TI_DBG2(("satModeSelect6: return control\n")); 12065 return tiSuccess; 12066 } 12067 12068 /* checking PF bit */ 12069 if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT6_PF_MASK)) 12070 { 12071 satSetSensePayload( pSense, 12072 SCSI_SNSKEY_ILLEGAL_REQUEST, 12073 0, 12074 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12075 satIOContext); 12076 12077 ostiInitiatorIOCompleted( tiRoot, 12078 tiIORequest, 12079 tiIOSuccess, 12080 SCSI_STAT_CHECK_CONDITION, 12081 satIOContext->pTiSenseData, 12082 satIOContext->interruptContext ); 12083 12084 TI_DBG1(("satModeSelect6: PF bit check \n")); 12085 return tiSuccess; 12086 12087 } 12088 12089 /* checking Block Descriptor Length on Mode parameter header(6)*/ 12090 if (pLogPage[3] == 8) 12091 { 12092 /* mode parameter block descriptor exists */ 12093 PageCode = (bit8)(pLogPage[12] & 0x3F); /* page code and index is 4 + 8 */ 12094 StartingIndex = 12; 12095 } 12096 else if (pLogPage[3] == 0) 12097 { 12098 /* mode parameter block descriptor does not exist */ 12099 PageCode = (bit8)(pLogPage[4] & 0x3F); /* page code and index is 4 + 0 */ 12100 StartingIndex = 4; 12101 ostiInitiatorIOCompleted( tiRoot, 12102 tiIORequest, 12103 tiIOSuccess, 12104 SCSI_STAT_GOOD, 12105 agNULL, 12106 satIOContext->interruptContext); 12107 return tiSuccess; 12108 } 12109 else 12110 { 12111 TI_DBG1(("satModeSelect6: return mode parameter block descriptor 0x%x\n", pLogPage[3])); 12112 /* no more than one mode parameter block descriptor shall be supported */ 12113 satSetSensePayload( pSense, 12114 SCSI_SNSKEY_NO_SENSE, 12115 0, 12116 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 12117 satIOContext); 12118 12119 ostiInitiatorIOCompleted( tiRoot, 12120 tiIORequest, 12121 tiIOSuccess, 12122 SCSI_STAT_CHECK_CONDITION, 12123 satIOContext->pTiSenseData, 12124 satIOContext->interruptContext ); 12125 return tiSuccess; 12126 } 12127 12128 12129 12130 switch (PageCode) /* page code */ 12131 { 12132 case MODESELECT_CONTROL_PAGE: 12133 TI_DBG1(("satModeSelect6: Control mode page\n")); 12134 /* 12135 compare pLogPage to expected value (SAT Table 65, p67) 12136 If not match, return check condition 12137 */ 12138 if ( pLogPage[StartingIndex+1] != 0x0A || 12139 pLogPage[StartingIndex+2] != 0x02 || 12140 (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) || 12141 (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) || 12142 (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */ 12143 (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */ 12144 (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */ 12145 12146 (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */ 12147 (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */ 12148 (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */ 12149 (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */ 12150 12151 pLogPage[StartingIndex+8] != 0xFF || 12152 pLogPage[StartingIndex+9] != 0xFF || 12153 pLogPage[StartingIndex+10] != 0x00 || 12154 pLogPage[StartingIndex+11] != 0x00 12155 ) 12156 { 12157 chkCnd = agTRUE; 12158 } 12159 if (chkCnd == agTRUE) 12160 { 12161 satSetSensePayload( pSense, 12162 SCSI_SNSKEY_ILLEGAL_REQUEST, 12163 0, 12164 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12165 satIOContext); 12166 12167 ostiInitiatorIOCompleted( tiRoot, 12168 tiIORequest, 12169 tiIOSuccess, 12170 SCSI_STAT_CHECK_CONDITION, 12171 satIOContext->pTiSenseData, 12172 satIOContext->interruptContext ); 12173 12174 TI_DBG1(("satModeSelect10: unexpected values\n")); 12175 } 12176 else 12177 { 12178 ostiInitiatorIOCompleted( tiRoot, 12179 tiIORequest, 12180 tiIOSuccess, 12181 SCSI_STAT_GOOD, 12182 agNULL, 12183 satIOContext->interruptContext); 12184 } 12185 return tiSuccess; 12186 break; 12187 case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE: 12188 TI_DBG1(("satModeSelect6: Read-Write Error Recovery mode page\n")); 12189 12190 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_AWRE_MASK) || 12191 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_RC_MASK) || 12192 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_EER_MASK) || 12193 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PER_MASK) || 12194 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DTE_MASK) || 12195 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DCR_MASK) || 12196 (pLogPage[StartingIndex + 10]) || 12197 (pLogPage[StartingIndex + 11]) 12198 ) 12199 { 12200 TI_DBG5(("satModeSelect6: return check condition \n")); 12201 12202 satSetSensePayload( pSense, 12203 SCSI_SNSKEY_ILLEGAL_REQUEST, 12204 0, 12205 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 12206 satIOContext); 12207 12208 ostiInitiatorIOCompleted( tiRoot, 12209 tiIORequest, 12210 tiIOSuccess, 12211 SCSI_STAT_CHECK_CONDITION, 12212 satIOContext->pTiSenseData, 12213 satIOContext->interruptContext ); 12214 return tiSuccess; 12215 } 12216 else 12217 { 12218 TI_DBG5(("satModeSelect6: return GOOD \n")); 12219 ostiInitiatorIOCompleted( tiRoot, 12220 tiIORequest, 12221 tiIOSuccess, 12222 SCSI_STAT_GOOD, 12223 agNULL, 12224 satIOContext->interruptContext); 12225 return tiSuccess; 12226 } 12227 12228 break; 12229 case MODESELECT_CACHING: 12230 /* SAT rev8 Table67, p69*/ 12231 TI_DBG5(("satModeSelect6: Caching mode page\n")); 12232 if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */ 12233 (pLogPage[StartingIndex + 3]) || 12234 (pLogPage[StartingIndex + 4]) || 12235 (pLogPage[StartingIndex + 5]) || 12236 (pLogPage[StartingIndex + 6]) || 12237 (pLogPage[StartingIndex + 7]) || 12238 (pLogPage[StartingIndex + 8]) || 12239 (pLogPage[StartingIndex + 9]) || 12240 (pLogPage[StartingIndex + 10]) || 12241 (pLogPage[StartingIndex + 11]) || 12242 12243 (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */ 12244 (pLogPage[StartingIndex + 13]) || 12245 (pLogPage[StartingIndex + 14]) || 12246 (pLogPage[StartingIndex + 15]) 12247 ) 12248 { 12249 TI_DBG1(("satModeSelect6: return check condition \n")); 12250 12251 satSetSensePayload( pSense, 12252 SCSI_SNSKEY_ILLEGAL_REQUEST, 12253 0, 12254 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 12255 satIOContext); 12256 12257 ostiInitiatorIOCompleted( tiRoot, 12258 tiIORequest, 12259 tiIOSuccess, 12260 SCSI_STAT_CHECK_CONDITION, 12261 satIOContext->pTiSenseData, 12262 satIOContext->interruptContext ); 12263 return tiSuccess; 12264 12265 } 12266 else 12267 { 12268 /* sends ATA SET FEATURES based on WCE bit */ 12269 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_WCE_MASK) ) 12270 { 12271 TI_DBG5(("satModeSelect6: disable write cache\n")); 12272 /* sends SET FEATURES */ 12273 fis->h.fisType = 0x27; /* Reg host to device */ 12274 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12275 12276 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 12277 fis->h.features = 0x82; /* disable write cache */ 12278 fis->d.lbaLow = 0; /* */ 12279 fis->d.lbaMid = 0; /* */ 12280 fis->d.lbaHigh = 0; /* */ 12281 fis->d.device = 0; /* */ 12282 fis->d.lbaLowExp = 0; /* */ 12283 fis->d.lbaMidExp = 0; /* */ 12284 fis->d.lbaHighExp = 0; /* */ 12285 fis->d.featuresExp = 0; /* */ 12286 fis->d.sectorCount = 0; /* */ 12287 fis->d.sectorCountExp = 0; /* */ 12288 fis->d.reserved4 = 0; 12289 fis->d.control = 0; /* FIS HOB bit clear */ 12290 fis->d.reserved5 = 0; 12291 12292 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12293 12294 /* Initialize CB for SATA completion. 12295 */ 12296 satIOContext->satCompleteCB = &satModeSelect6n10CB; 12297 12298 /* 12299 * Prepare SGL and send FIS to LL layer. 12300 */ 12301 satIOContext->reqType = agRequestType; /* Save it */ 12302 12303 status = sataLLIOStart( tiRoot, 12304 tiIORequest, 12305 tiDeviceHandle, 12306 tiScsiRequest, 12307 satIOContext); 12308 return status; 12309 } 12310 else 12311 { 12312 TI_DBG5(("satModeSelect6: enable write cache\n")); 12313 /* sends SET FEATURES */ 12314 fis->h.fisType = 0x27; /* Reg host to device */ 12315 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12316 12317 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 12318 fis->h.features = 0x02; /* enable write cache */ 12319 fis->d.lbaLow = 0; /* */ 12320 fis->d.lbaMid = 0; /* */ 12321 fis->d.lbaHigh = 0; /* */ 12322 fis->d.device = 0; /* */ 12323 fis->d.lbaLowExp = 0; /* */ 12324 fis->d.lbaMidExp = 0; /* */ 12325 fis->d.lbaHighExp = 0; /* */ 12326 fis->d.featuresExp = 0; /* */ 12327 fis->d.sectorCount = 0; /* */ 12328 fis->d.sectorCountExp = 0; /* */ 12329 fis->d.reserved4 = 0; 12330 fis->d.control = 0; /* FIS HOB bit clear */ 12331 fis->d.reserved5 = 0; 12332 12333 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12334 12335 /* Initialize CB for SATA completion. 12336 */ 12337 satIOContext->satCompleteCB = &satModeSelect6n10CB; 12338 12339 /* 12340 * Prepare SGL and send FIS to LL layer. 12341 */ 12342 satIOContext->reqType = agRequestType; /* Save it */ 12343 12344 status = sataLLIOStart( tiRoot, 12345 tiIORequest, 12346 tiDeviceHandle, 12347 tiScsiRequest, 12348 satIOContext); 12349 return status; 12350 12351 } 12352 } 12353 break; 12354 case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE: 12355 TI_DBG5(("satModeSelect6: Informational Exception Control mode page\n")); 12356 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PERF_MASK) || 12357 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_TEST_MASK) 12358 ) 12359 { 12360 TI_DBG1(("satModeSelect6: return check condition \n")); 12361 12362 satSetSensePayload( pSense, 12363 SCSI_SNSKEY_ILLEGAL_REQUEST, 12364 0, 12365 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 12366 satIOContext); 12367 12368 ostiInitiatorIOCompleted( tiRoot, 12369 tiIORequest, 12370 tiIOSuccess, 12371 SCSI_STAT_CHECK_CONDITION, 12372 satIOContext->pTiSenseData, 12373 satIOContext->interruptContext ); 12374 return tiSuccess; 12375 } 12376 else 12377 { 12378 /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */ 12379 if ( !(pLogPage[StartingIndex + 2] & 0x08) ) 12380 { 12381 TI_DBG5(("satModeSelect6: enable information exceptions reporting\n")); 12382 /* sends SMART ENABLE OPERATIONS */ 12383 fis->h.fisType = 0x27; /* Reg host to device */ 12384 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12385 12386 fis->h.command = SAT_SMART_ENABLE_OPERATIONS; /* 0xB0 */ 12387 fis->h.features = 0xD8; /* enable */ 12388 fis->d.lbaLow = 0; /* */ 12389 fis->d.lbaMid = 0x4F; /* 0x4F */ 12390 fis->d.lbaHigh = 0xC2; /* 0xC2 */ 12391 fis->d.device = 0; /* */ 12392 fis->d.lbaLowExp = 0; /* */ 12393 fis->d.lbaMidExp = 0; /* */ 12394 fis->d.lbaHighExp = 0; /* */ 12395 fis->d.featuresExp = 0; /* */ 12396 fis->d.sectorCount = 0; /* */ 12397 fis->d.sectorCountExp = 0; /* */ 12398 fis->d.reserved4 = 0; 12399 fis->d.control = 0; /* FIS HOB bit clear */ 12400 fis->d.reserved5 = 0; 12401 12402 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12403 12404 /* Initialize CB for SATA completion. 12405 */ 12406 satIOContext->satCompleteCB = &satModeSelect6n10CB; 12407 12408 /* 12409 * Prepare SGL and send FIS to LL layer. 12410 */ 12411 satIOContext->reqType = agRequestType; /* Save it */ 12412 12413 status = sataLLIOStart( tiRoot, 12414 tiIORequest, 12415 tiDeviceHandle, 12416 tiScsiRequest, 12417 satIOContext); 12418 return status; 12419 } 12420 else 12421 { 12422 TI_DBG5(("satModeSelect6: disable information exceptions reporting\n")); 12423 /* sends SMART DISABLE OPERATIONS */ 12424 fis->h.fisType = 0x27; /* Reg host to device */ 12425 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12426 12427 fis->h.command = SAT_SMART_DISABLE_OPERATIONS; /* 0xB0 */ 12428 fis->h.features = 0xD9; /* disable */ 12429 fis->d.lbaLow = 0; /* */ 12430 fis->d.lbaMid = 0x4F; /* 0x4F */ 12431 fis->d.lbaHigh = 0xC2; /* 0xC2 */ 12432 fis->d.device = 0; /* */ 12433 fis->d.lbaLowExp = 0; /* */ 12434 fis->d.lbaMidExp = 0; /* */ 12435 fis->d.lbaHighExp = 0; /* */ 12436 fis->d.featuresExp = 0; /* */ 12437 fis->d.sectorCount = 0; /* */ 12438 fis->d.sectorCountExp = 0; /* */ 12439 fis->d.reserved4 = 0; 12440 fis->d.control = 0; /* FIS HOB bit clear */ 12441 fis->d.reserved5 = 0; 12442 12443 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12444 12445 /* Initialize CB for SATA completion. 12446 */ 12447 satIOContext->satCompleteCB = &satModeSelect6n10CB; 12448 12449 /* 12450 * Prepare SGL and send FIS to LL layer. 12451 */ 12452 satIOContext->reqType = agRequestType; /* Save it */ 12453 12454 status = sataLLIOStart( tiRoot, 12455 tiIORequest, 12456 tiDeviceHandle, 12457 tiScsiRequest, 12458 satIOContext); 12459 return status; 12460 12461 } 12462 } 12463 break; 12464 default: 12465 TI_DBG1(("satModeSelect6: Error unknown page code 0x%x\n", pLogPage[12])); 12466 satSetSensePayload( pSense, 12467 SCSI_SNSKEY_NO_SENSE, 12468 0, 12469 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 12470 satIOContext); 12471 12472 ostiInitiatorIOCompleted( tiRoot, 12473 tiIORequest, 12474 tiIOSuccess, 12475 SCSI_STAT_CHECK_CONDITION, 12476 satIOContext->pTiSenseData, 12477 satIOContext->interruptContext ); 12478 return tiSuccess; 12479 } 12480 12481 } 12482 12483 /*****************************************************************************/ 12484 /*! \brief SAT implementation for SCSI satModeSelect6n10_1. 12485 * 12486 * This function is part of implementation of ModeSelect6 and ModeSelect10. 12487 * When ModeSelect6 or ModeSelect10 is coverted into multiple ATA commands, 12488 * this function is used. 12489 * 12490 * \param tiRoot: Pointer to TISA initiator driver/port instance. 12491 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 12492 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 12493 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 12494 * \param satIOContext_t: Pointer to the SAT IO Context 12495 * 12496 * \return If command is started successfully 12497 * - \e tiSuccess: I/O request successfully initiated. 12498 * - \e tiBusy: No resources available, try again later. 12499 * - \e tiIONoDevice: Invalid device handle. 12500 * - \e tiError: Other errors. 12501 */ 12502 /*****************************************************************************/ 12503 GLOBAL bit32 satModeSelect6n10_1( 12504 tiRoot_t *tiRoot, 12505 tiIORequest_t *tiIORequest, 12506 tiDeviceHandle_t *tiDeviceHandle, 12507 tiScsiInitiatorRequest_t *tiScsiRequest, 12508 satIOContext_t *satIOContext) 12509 { 12510 /* sends either ATA SET FEATURES based on DRA bit */ 12511 bit32 status; 12512 bit32 agRequestType; 12513 agsaFisRegHostToDevice_t *fis; 12514 bit8 *pLogPage; /* Log Page data buffer */ 12515 bit32 StartingIndex = 0; 12516 12517 fis = satIOContext->pFis; 12518 pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr; 12519 TI_DBG5(("satModeSelect6_1: start\n")); 12520 /* checking Block Descriptor Length on Mode parameter header(6)*/ 12521 if (pLogPage[3] == 8) 12522 { 12523 /* mode parameter block descriptor exists */ 12524 StartingIndex = 12; 12525 } 12526 else 12527 { 12528 /* mode parameter block descriptor does not exist */ 12529 StartingIndex = 4; 12530 } 12531 12532 /* sends ATA SET FEATURES based on DRA bit */ 12533 if ( !(pLogPage[StartingIndex + 12] & SCSI_MODE_SELECT6_DRA_MASK) ) 12534 { 12535 TI_DBG5(("satModeSelect6_1: enable read look-ahead feature\n")); 12536 /* sends SET FEATURES */ 12537 fis->h.fisType = 0x27; /* Reg host to device */ 12538 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12539 12540 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 12541 fis->h.features = 0xAA; /* enable read look-ahead */ 12542 fis->d.lbaLow = 0; /* */ 12543 fis->d.lbaMid = 0; /* */ 12544 fis->d.lbaHigh = 0; /* */ 12545 fis->d.device = 0; /* */ 12546 fis->d.lbaLowExp = 0; /* */ 12547 fis->d.lbaMidExp = 0; /* */ 12548 fis->d.lbaHighExp = 0; /* */ 12549 fis->d.featuresExp = 0; /* */ 12550 fis->d.sectorCount = 0; /* */ 12551 fis->d.sectorCountExp = 0; /* */ 12552 fis->d.reserved4 = 0; 12553 fis->d.control = 0; /* FIS HOB bit clear */ 12554 fis->d.reserved5 = 0; 12555 12556 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12557 12558 /* Initialize CB for SATA completion. 12559 */ 12560 satIOContext->satCompleteCB = &satModeSelect6n10CB; 12561 12562 /* 12563 * Prepare SGL and send FIS to LL layer. 12564 */ 12565 satIOContext->reqType = agRequestType; /* Save it */ 12566 12567 status = sataLLIOStart( tiRoot, 12568 tiIORequest, 12569 tiDeviceHandle, 12570 tiScsiRequest, 12571 satIOContext); 12572 return status; 12573 } 12574 else 12575 { 12576 TI_DBG5(("satModeSelect6_1: disable read look-ahead feature\n")); 12577 /* sends SET FEATURES */ 12578 fis->h.fisType = 0x27; /* Reg host to device */ 12579 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12580 12581 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 12582 fis->h.features = 0x55; /* disable read look-ahead */ 12583 fis->d.lbaLow = 0; /* */ 12584 fis->d.lbaMid = 0; /* */ 12585 fis->d.lbaHigh = 0; /* */ 12586 fis->d.device = 0; /* */ 12587 fis->d.lbaLowExp = 0; /* */ 12588 fis->d.lbaMidExp = 0; /* */ 12589 fis->d.lbaHighExp = 0; /* */ 12590 fis->d.featuresExp = 0; /* */ 12591 fis->d.sectorCount = 0; /* */ 12592 fis->d.sectorCountExp = 0; /* */ 12593 fis->d.reserved4 = 0; 12594 fis->d.control = 0; /* FIS HOB bit clear */ 12595 fis->d.reserved5 = 0; 12596 12597 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12598 12599 /* Initialize CB for SATA completion. 12600 */ 12601 satIOContext->satCompleteCB = &satModeSelect6n10CB; 12602 12603 /* 12604 * Prepare SGL and send FIS to LL layer. 12605 */ 12606 satIOContext->reqType = agRequestType; /* Save it */ 12607 12608 status = sataLLIOStart( tiRoot, 12609 tiIORequest, 12610 tiDeviceHandle, 12611 tiScsiRequest, 12612 satIOContext); 12613 return status; 12614 } 12615 12616 } 12617 12618 12619 /*****************************************************************************/ 12620 /*! \brief SAT implementation for SCSI satModeSelect10. 12621 * 12622 * SAT implementation for SCSI satModeSelect10. 12623 * 12624 * \param tiRoot: Pointer to TISA initiator driver/port instance. 12625 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 12626 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 12627 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 12628 * \param satIOContext_t: Pointer to the SAT IO Context 12629 * 12630 * \return If command is started successfully 12631 * - \e tiSuccess: I/O request successfully initiated. 12632 * - \e tiBusy: No resources available, try again later. 12633 * - \e tiIONoDevice: Invalid device handle. 12634 * - \e tiError: Other errors. 12635 */ 12636 /*****************************************************************************/ 12637 GLOBAL bit32 satModeSelect10( 12638 tiRoot_t *tiRoot, 12639 tiIORequest_t *tiIORequest, 12640 tiDeviceHandle_t *tiDeviceHandle, 12641 tiScsiInitiatorRequest_t *tiScsiRequest, 12642 satIOContext_t *satIOContext) 12643 { 12644 bit32 status; 12645 bit32 agRequestType; 12646 satDeviceData_t *pSatDevData; 12647 scsiRspSense_t *pSense; 12648 tiIniScsiCmnd_t *scsiCmnd; 12649 agsaFisRegHostToDevice_t *fis; 12650 bit8 *pLogPage; /* Log Page data buffer */ 12651 bit16 BlkDescLen = 0; /* Block Descriptor Length */ 12652 bit32 StartingIndex = 0; 12653 bit8 PageCode = 0; 12654 bit32 chkCnd = agFALSE; 12655 12656 pSense = satIOContext->pSense; 12657 pSatDevData = satIOContext->pSatDevData; 12658 scsiCmnd = &tiScsiRequest->scsiCmnd; 12659 fis = satIOContext->pFis; 12660 pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr; 12661 12662 TI_DBG5(("satModeSelect10: start\n")); 12663 12664 /* checking CONTROL */ 12665 /* NACA == 1 or LINK == 1*/ 12666 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 12667 { 12668 satSetSensePayload( pSense, 12669 SCSI_SNSKEY_ILLEGAL_REQUEST, 12670 0, 12671 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12672 satIOContext); 12673 12674 ostiInitiatorIOCompleted( tiRoot, 12675 tiIORequest, 12676 tiIOSuccess, 12677 SCSI_STAT_CHECK_CONDITION, 12678 satIOContext->pTiSenseData, 12679 satIOContext->interruptContext ); 12680 12681 TI_DBG2(("satModeSelect10: return control\n")); 12682 return tiSuccess; 12683 } 12684 12685 /* checking PF bit */ 12686 if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT10_PF_MASK)) 12687 { 12688 satSetSensePayload( pSense, 12689 SCSI_SNSKEY_ILLEGAL_REQUEST, 12690 0, 12691 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12692 satIOContext); 12693 12694 ostiInitiatorIOCompleted( tiRoot, 12695 tiIORequest, 12696 tiIOSuccess, 12697 SCSI_STAT_CHECK_CONDITION, 12698 satIOContext->pTiSenseData, 12699 satIOContext->interruptContext ); 12700 12701 TI_DBG1(("satModeSelect10: PF bit check \n")); 12702 return tiSuccess; 12703 12704 } 12705 12706 BlkDescLen = (bit8)((pLogPage[6] << 8) + pLogPage[7]); 12707 12708 /* checking Block Descriptor Length on Mode parameter header(10) and LONGLBA bit*/ 12709 if ( (BlkDescLen == 8) && !(pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) ) 12710 { 12711 /* mode parameter block descriptor exists and length is 8 byte */ 12712 PageCode = (bit8)(pLogPage[16] & 0x3F); /* page code and index is 8 + 8 */ 12713 StartingIndex = 16; 12714 } 12715 else if ( (BlkDescLen == 16) && (pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) ) 12716 { 12717 /* mode parameter block descriptor exists and length is 16 byte */ 12718 PageCode = (bit8)(pLogPage[24] & 0x3F); /* page code and index is 8 + 16 */ 12719 StartingIndex = 24; 12720 } 12721 else if (BlkDescLen == 0) 12722 { 12723 /* 12724 mode parameter block descriptor does not exist 12725 */ 12726 PageCode = (bit8)(pLogPage[8] & 0x3F); /* page code and index is 8 + 0 */ 12727 StartingIndex = 8; 12728 ostiInitiatorIOCompleted( tiRoot, 12729 tiIORequest, 12730 tiIOSuccess, 12731 SCSI_STAT_GOOD, 12732 agNULL, 12733 satIOContext->interruptContext); 12734 return tiSuccess; 12735 } 12736 else 12737 { 12738 TI_DBG1(("satModeSelect10: return mode parameter block descriptor 0x%x\n", BlkDescLen)); 12739 /* no more than one mode parameter block descriptor shall be supported */ 12740 satSetSensePayload( pSense, 12741 SCSI_SNSKEY_NO_SENSE, 12742 0, 12743 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 12744 satIOContext); 12745 12746 ostiInitiatorIOCompleted( tiRoot, 12747 tiIORequest, 12748 tiIOSuccess, 12749 SCSI_STAT_CHECK_CONDITION, 12750 satIOContext->pTiSenseData, 12751 satIOContext->interruptContext ); 12752 return tiSuccess; 12753 } 12754 /* 12755 for debugging only 12756 */ 12757 if (StartingIndex == 8) 12758 { 12759 tdhexdump("startingindex 8", (bit8 *)pLogPage, 8); 12760 } 12761 else if(StartingIndex == 16) 12762 { 12763 if (PageCode == MODESELECT_CACHING) 12764 { 12765 tdhexdump("startingindex 16", (bit8 *)pLogPage, 16+20); 12766 } 12767 else 12768 { 12769 tdhexdump("startingindex 16", (bit8 *)pLogPage, 16+12); 12770 } 12771 } 12772 else 12773 { 12774 if (PageCode == MODESELECT_CACHING) 12775 { 12776 tdhexdump("startingindex 24", (bit8 *)pLogPage, 24+20); 12777 } 12778 else 12779 { 12780 tdhexdump("startingindex 24", (bit8 *)pLogPage, 24+12); 12781 } 12782 } 12783 switch (PageCode) /* page code */ 12784 { 12785 case MODESELECT_CONTROL_PAGE: 12786 TI_DBG5(("satModeSelect10: Control mode page\n")); 12787 /* 12788 compare pLogPage to expected value (SAT Table 65, p67) 12789 If not match, return check condition 12790 */ 12791 if ( pLogPage[StartingIndex+1] != 0x0A || 12792 pLogPage[StartingIndex+2] != 0x02 || 12793 (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) || 12794 (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) || 12795 (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */ 12796 (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */ 12797 (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */ 12798 12799 (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */ 12800 (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */ 12801 (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */ 12802 (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */ 12803 12804 pLogPage[StartingIndex+8] != 0xFF || 12805 pLogPage[StartingIndex+9] != 0xFF || 12806 pLogPage[StartingIndex+10] != 0x00 || 12807 pLogPage[StartingIndex+11] != 0x00 12808 ) 12809 { 12810 chkCnd = agTRUE; 12811 } 12812 if (chkCnd == agTRUE) 12813 { 12814 satSetSensePayload( pSense, 12815 SCSI_SNSKEY_ILLEGAL_REQUEST, 12816 0, 12817 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12818 satIOContext); 12819 12820 ostiInitiatorIOCompleted( tiRoot, 12821 tiIORequest, 12822 tiIOSuccess, 12823 SCSI_STAT_CHECK_CONDITION, 12824 satIOContext->pTiSenseData, 12825 satIOContext->interruptContext ); 12826 12827 TI_DBG1(("satModeSelect10: unexpected values\n")); 12828 } 12829 else 12830 { 12831 ostiInitiatorIOCompleted( tiRoot, 12832 tiIORequest, 12833 tiIOSuccess, 12834 SCSI_STAT_GOOD, 12835 agNULL, 12836 satIOContext->interruptContext); 12837 } 12838 return tiSuccess; 12839 break; 12840 case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE: 12841 TI_DBG5(("satModeSelect10: Read-Write Error Recovery mode page\n")); 12842 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_AWRE_MASK) || 12843 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_RC_MASK) || 12844 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_EER_MASK) || 12845 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PER_MASK) || 12846 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DTE_MASK) || 12847 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DCR_MASK) || 12848 (pLogPage[StartingIndex + 10]) || 12849 (pLogPage[StartingIndex + 11]) 12850 ) 12851 { 12852 TI_DBG1(("satModeSelect10: return check condition \n")); 12853 12854 satSetSensePayload( pSense, 12855 SCSI_SNSKEY_ILLEGAL_REQUEST, 12856 0, 12857 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 12858 satIOContext); 12859 12860 ostiInitiatorIOCompleted( tiRoot, 12861 tiIORequest, 12862 tiIOSuccess, 12863 SCSI_STAT_CHECK_CONDITION, 12864 satIOContext->pTiSenseData, 12865 satIOContext->interruptContext ); 12866 return tiSuccess; 12867 } 12868 else 12869 { 12870 TI_DBG2(("satModeSelect10: return GOOD \n")); 12871 ostiInitiatorIOCompleted( tiRoot, 12872 tiIORequest, 12873 tiIOSuccess, 12874 SCSI_STAT_GOOD, 12875 agNULL, 12876 satIOContext->interruptContext); 12877 return tiSuccess; 12878 } 12879 12880 break; 12881 case MODESELECT_CACHING: 12882 /* SAT rev8 Table67, p69*/ 12883 TI_DBG5(("satModeSelect10: Caching mode page\n")); 12884 if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */ 12885 (pLogPage[StartingIndex + 3]) || 12886 (pLogPage[StartingIndex + 4]) || 12887 (pLogPage[StartingIndex + 5]) || 12888 (pLogPage[StartingIndex + 6]) || 12889 (pLogPage[StartingIndex + 7]) || 12890 (pLogPage[StartingIndex + 8]) || 12891 (pLogPage[StartingIndex + 9]) || 12892 (pLogPage[StartingIndex + 10]) || 12893 (pLogPage[StartingIndex + 11]) || 12894 12895 (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */ 12896 (pLogPage[StartingIndex + 13]) || 12897 (pLogPage[StartingIndex + 14]) || 12898 (pLogPage[StartingIndex + 15]) 12899 ) 12900 { 12901 TI_DBG1(("satModeSelect10: return check condition \n")); 12902 12903 satSetSensePayload( pSense, 12904 SCSI_SNSKEY_ILLEGAL_REQUEST, 12905 0, 12906 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 12907 satIOContext); 12908 12909 ostiInitiatorIOCompleted( tiRoot, 12910 tiIORequest, 12911 tiIOSuccess, 12912 SCSI_STAT_CHECK_CONDITION, 12913 satIOContext->pTiSenseData, 12914 satIOContext->interruptContext ); 12915 return tiSuccess; 12916 12917 } 12918 else 12919 { 12920 /* sends ATA SET FEATURES based on WCE bit */ 12921 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_WCE_MASK) ) 12922 { 12923 TI_DBG5(("satModeSelect10: disable write cache\n")); 12924 /* sends SET FEATURES */ 12925 fis->h.fisType = 0x27; /* Reg host to device */ 12926 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12927 12928 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 12929 fis->h.features = 0x82; /* disable write cache */ 12930 fis->d.lbaLow = 0; /* */ 12931 fis->d.lbaMid = 0; /* */ 12932 fis->d.lbaHigh = 0; /* */ 12933 fis->d.device = 0; /* */ 12934 fis->d.lbaLowExp = 0; /* */ 12935 fis->d.lbaMidExp = 0; /* */ 12936 fis->d.lbaHighExp = 0; /* */ 12937 fis->d.featuresExp = 0; /* */ 12938 fis->d.sectorCount = 0; /* */ 12939 fis->d.sectorCountExp = 0; /* */ 12940 fis->d.reserved4 = 0; 12941 fis->d.control = 0; /* FIS HOB bit clear */ 12942 fis->d.reserved5 = 0; 12943 12944 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12945 12946 /* Initialize CB for SATA completion. 12947 */ 12948 satIOContext->satCompleteCB = &satModeSelect6n10CB; 12949 12950 /* 12951 * Prepare SGL and send FIS to LL layer. 12952 */ 12953 satIOContext->reqType = agRequestType; /* Save it */ 12954 12955 status = sataLLIOStart( tiRoot, 12956 tiIORequest, 12957 tiDeviceHandle, 12958 tiScsiRequest, 12959 satIOContext); 12960 return status; 12961 } 12962 else 12963 { 12964 TI_DBG5(("satModeSelect10: enable write cache\n")); 12965 /* sends SET FEATURES */ 12966 fis->h.fisType = 0x27; /* Reg host to device */ 12967 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12968 12969 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 12970 fis->h.features = 0x02; /* enable write cache */ 12971 fis->d.lbaLow = 0; /* */ 12972 fis->d.lbaMid = 0; /* */ 12973 fis->d.lbaHigh = 0; /* */ 12974 fis->d.device = 0; /* */ 12975 fis->d.lbaLowExp = 0; /* */ 12976 fis->d.lbaMidExp = 0; /* */ 12977 fis->d.lbaHighExp = 0; /* */ 12978 fis->d.featuresExp = 0; /* */ 12979 fis->d.sectorCount = 0; /* */ 12980 fis->d.sectorCountExp = 0; /* */ 12981 fis->d.reserved4 = 0; 12982 fis->d.control = 0; /* FIS HOB bit clear */ 12983 fis->d.reserved5 = 0; 12984 12985 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12986 12987 /* Initialize CB for SATA completion. 12988 */ 12989 satIOContext->satCompleteCB = &satModeSelect6n10CB; 12990 12991 /* 12992 * Prepare SGL and send FIS to LL layer. 12993 */ 12994 satIOContext->reqType = agRequestType; /* Save it */ 12995 12996 status = sataLLIOStart( tiRoot, 12997 tiIORequest, 12998 tiDeviceHandle, 12999 tiScsiRequest, 13000 satIOContext); 13001 return status; 13002 13003 } 13004 } 13005 break; 13006 case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE: 13007 TI_DBG5(("satModeSelect10: Informational Exception Control mode page\n")); 13008 13009 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PERF_MASK) || 13010 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_TEST_MASK) 13011 ) 13012 { 13013 TI_DBG1(("satModeSelect10: return check condition \n")); 13014 13015 satSetSensePayload( pSense, 13016 SCSI_SNSKEY_ILLEGAL_REQUEST, 13017 0, 13018 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 13019 satIOContext); 13020 13021 ostiInitiatorIOCompleted( tiRoot, 13022 tiIORequest, 13023 tiIOSuccess, 13024 SCSI_STAT_CHECK_CONDITION, 13025 satIOContext->pTiSenseData, 13026 satIOContext->interruptContext ); 13027 return tiSuccess; 13028 } 13029 else 13030 { 13031 /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */ 13032 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DEXCPT_MASK) ) 13033 { 13034 TI_DBG5(("satModeSelect10: enable information exceptions reporting\n")); 13035 /* sends SMART ENABLE OPERATIONS */ 13036 fis->h.fisType = 0x27; /* Reg host to device */ 13037 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13038 13039 fis->h.command = SAT_SMART_ENABLE_OPERATIONS; /* 0xB0 */ 13040 fis->h.features = 0xD8; /* enable */ 13041 fis->d.lbaLow = 0; /* */ 13042 fis->d.lbaMid = 0x4F; /* 0x4F */ 13043 fis->d.lbaHigh = 0xC2; /* 0xC2 */ 13044 fis->d.device = 0; /* */ 13045 fis->d.lbaLowExp = 0; /* */ 13046 fis->d.lbaMidExp = 0; /* */ 13047 fis->d.lbaHighExp = 0; /* */ 13048 fis->d.featuresExp = 0; /* */ 13049 fis->d.sectorCount = 0; /* */ 13050 fis->d.sectorCountExp = 0; /* */ 13051 fis->d.reserved4 = 0; 13052 fis->d.control = 0; /* FIS HOB bit clear */ 13053 fis->d.reserved5 = 0; 13054 13055 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 13056 13057 /* Initialize CB for SATA completion. 13058 */ 13059 satIOContext->satCompleteCB = &satModeSelect6n10CB; 13060 13061 /* 13062 * Prepare SGL and send FIS to LL layer. 13063 */ 13064 satIOContext->reqType = agRequestType; /* Save it */ 13065 13066 status = sataLLIOStart( tiRoot, 13067 tiIORequest, 13068 tiDeviceHandle, 13069 tiScsiRequest, 13070 satIOContext); 13071 return status; 13072 } 13073 else 13074 { 13075 TI_DBG5(("satModeSelect10: disable information exceptions reporting\n")); 13076 /* sends SMART DISABLE OPERATIONS */ 13077 fis->h.fisType = 0x27; /* Reg host to device */ 13078 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13079 13080 fis->h.command = SAT_SMART_DISABLE_OPERATIONS; /* 0xB0 */ 13081 fis->h.features = 0xD9; /* disable */ 13082 fis->d.lbaLow = 0; /* */ 13083 fis->d.lbaMid = 0x4F; /* 0x4F */ 13084 fis->d.lbaHigh = 0xC2; /* 0xC2 */ 13085 fis->d.device = 0; /* */ 13086 fis->d.lbaLowExp = 0; /* */ 13087 fis->d.lbaMidExp = 0; /* */ 13088 fis->d.lbaHighExp = 0; /* */ 13089 fis->d.featuresExp = 0; /* */ 13090 fis->d.sectorCount = 0; /* */ 13091 fis->d.sectorCountExp = 0; /* */ 13092 fis->d.reserved4 = 0; 13093 fis->d.control = 0; /* FIS HOB bit clear */ 13094 fis->d.reserved5 = 0; 13095 13096 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 13097 13098 /* Initialize CB for SATA completion. 13099 */ 13100 satIOContext->satCompleteCB = &satModeSelect6n10CB; 13101 13102 /* 13103 * Prepare SGL and send FIS to LL layer. 13104 */ 13105 satIOContext->reqType = agRequestType; /* Save it */ 13106 13107 status = sataLLIOStart( tiRoot, 13108 tiIORequest, 13109 tiDeviceHandle, 13110 tiScsiRequest, 13111 satIOContext); 13112 return status; 13113 13114 } 13115 } 13116 break; 13117 default: 13118 TI_DBG1(("satModeSelect10: Error unknown page code 0x%x\n", pLogPage[12])); 13119 satSetSensePayload( pSense, 13120 SCSI_SNSKEY_NO_SENSE, 13121 0, 13122 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 13123 satIOContext); 13124 13125 ostiInitiatorIOCompleted( tiRoot, 13126 tiIORequest, 13127 tiIOSuccess, 13128 SCSI_STAT_CHECK_CONDITION, 13129 satIOContext->pTiSenseData, 13130 satIOContext->interruptContext ); 13131 return tiSuccess; 13132 } 13133 13134 } 13135 13136 13137 /*****************************************************************************/ 13138 /*! \brief SAT implementation for SCSI satSynchronizeCache10. 13139 * 13140 * SAT implementation for SCSI satSynchronizeCache10. 13141 * 13142 * \param tiRoot: Pointer to TISA initiator driver/port instance. 13143 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 13144 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 13145 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 13146 * \param satIOContext_t: Pointer to the SAT IO Context 13147 * 13148 * \return If command is started successfully 13149 * - \e tiSuccess: I/O request successfully initiated. 13150 * - \e tiBusy: No resources available, try again later. 13151 * - \e tiIONoDevice: Invalid device handle. 13152 * - \e tiError: Other errors. 13153 */ 13154 /*****************************************************************************/ 13155 GLOBAL bit32 satSynchronizeCache10( 13156 tiRoot_t *tiRoot, 13157 tiIORequest_t *tiIORequest, 13158 tiDeviceHandle_t *tiDeviceHandle, 13159 tiScsiInitiatorRequest_t *tiScsiRequest, 13160 satIOContext_t *satIOContext) 13161 { 13162 bit32 status; 13163 bit32 agRequestType; 13164 satDeviceData_t *pSatDevData; 13165 scsiRspSense_t *pSense; 13166 tiIniScsiCmnd_t *scsiCmnd; 13167 agsaFisRegHostToDevice_t *fis; 13168 13169 pSense = satIOContext->pSense; 13170 pSatDevData = satIOContext->pSatDevData; 13171 scsiCmnd = &tiScsiRequest->scsiCmnd; 13172 fis = satIOContext->pFis; 13173 13174 TI_DBG5(("satSynchronizeCache10: start\n")); 13175 13176 /* checking CONTROL */ 13177 /* NACA == 1 or LINK == 1*/ 13178 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 13179 { 13180 satSetSensePayload( pSense, 13181 SCSI_SNSKEY_ILLEGAL_REQUEST, 13182 0, 13183 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13184 satIOContext); 13185 13186 ostiInitiatorIOCompleted( tiRoot, 13187 tiIORequest, 13188 tiIOSuccess, 13189 SCSI_STAT_CHECK_CONDITION, 13190 satIOContext->pTiSenseData, 13191 satIOContext->interruptContext ); 13192 13193 TI_DBG2(("satSynchronizeCache10: return control\n")); 13194 return tiSuccess; 13195 } 13196 13197 /* checking IMMED bit */ 13198 if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK) 13199 { 13200 TI_DBG1(("satSynchronizeCache10: GOOD status due to IMMED bit\n")); 13201 13202 /* return GOOD status first here */ 13203 ostiInitiatorIOCompleted( tiRoot, 13204 tiIORequest, 13205 tiIOSuccess, 13206 SCSI_STAT_GOOD, 13207 agNULL, 13208 satIOContext->interruptContext); 13209 } 13210 13211 /* sends FLUSH CACHE or FLUSH CACHE EXT */ 13212 if (pSatDevData->sat48BitSupport == agTRUE) 13213 { 13214 TI_DBG5(("satSynchronizeCache10: sends FLUSH CACHE EXT\n")); 13215 /* FLUSH CACHE EXT */ 13216 fis->h.fisType = 0x27; /* Reg host to device */ 13217 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13218 13219 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */ 13220 fis->h.features = 0; /* FIS reserve */ 13221 fis->d.featuresExp = 0; /* FIS reserve */ 13222 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 13223 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 13224 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 13225 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 13226 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 13227 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 13228 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 13229 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 13230 fis->d.device = 0; /* FIS DEV is discared in SATA */ 13231 fis->d.control = 0; /* FIS HOB bit clear */ 13232 fis->d.reserved4 = 0; 13233 fis->d.reserved5 = 0; 13234 13235 } 13236 else 13237 { 13238 TI_DBG5(("satSynchronizeCache10: sends FLUSH CACHE\n")); 13239 /* FLUSH CACHE */ 13240 fis->h.fisType = 0x27; /* Reg host to device */ 13241 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13242 13243 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */ 13244 fis->h.features = 0; /* FIS features NA */ 13245 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 13246 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 13247 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 13248 fis->d.lbaLowExp = 0; 13249 fis->d.lbaMidExp = 0; 13250 fis->d.lbaHighExp = 0; 13251 fis->d.featuresExp = 0; 13252 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 13253 fis->d.sectorCountExp = 0; 13254 fis->d.device = 0; /* FIS DEV is discared in SATA */ 13255 fis->d.control = 0; /* FIS HOB bit clear */ 13256 fis->d.reserved4 = 0; 13257 fis->d.reserved5 = 0; 13258 13259 } 13260 13261 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 13262 13263 /* Initialize CB for SATA completion. 13264 */ 13265 satIOContext->satCompleteCB = &satSynchronizeCache10n16CB; 13266 13267 /* 13268 * Prepare SGL and send FIS to LL layer. 13269 */ 13270 satIOContext->reqType = agRequestType; /* Save it */ 13271 13272 status = sataLLIOStart( tiRoot, 13273 tiIORequest, 13274 tiDeviceHandle, 13275 tiScsiRequest, 13276 satIOContext); 13277 13278 13279 return (status); 13280 } 13281 13282 /*****************************************************************************/ 13283 /*! \brief SAT implementation for SCSI satSynchronizeCache16. 13284 * 13285 * SAT implementation for SCSI satSynchronizeCache16. 13286 * 13287 * \param tiRoot: Pointer to TISA initiator driver/port instance. 13288 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 13289 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 13290 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 13291 * \param satIOContext_t: Pointer to the SAT IO Context 13292 * 13293 * \return If command is started successfully 13294 * - \e tiSuccess: I/O request successfully initiated. 13295 * - \e tiBusy: No resources available, try again later. 13296 * - \e tiIONoDevice: Invalid device handle. 13297 * - \e tiError: Other errors. 13298 */ 13299 /*****************************************************************************/ 13300 GLOBAL bit32 satSynchronizeCache16( 13301 tiRoot_t *tiRoot, 13302 tiIORequest_t *tiIORequest, 13303 tiDeviceHandle_t *tiDeviceHandle, 13304 tiScsiInitiatorRequest_t *tiScsiRequest, 13305 satIOContext_t *satIOContext) 13306 { 13307 bit32 status; 13308 bit32 agRequestType; 13309 satDeviceData_t *pSatDevData; 13310 scsiRspSense_t *pSense; 13311 tiIniScsiCmnd_t *scsiCmnd; 13312 agsaFisRegHostToDevice_t *fis; 13313 13314 pSense = satIOContext->pSense; 13315 pSatDevData = satIOContext->pSatDevData; 13316 scsiCmnd = &tiScsiRequest->scsiCmnd; 13317 fis = satIOContext->pFis; 13318 13319 TI_DBG5(("satSynchronizeCache16: start\n")); 13320 13321 /* checking CONTROL */ 13322 /* NACA == 1 or LINK == 1*/ 13323 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 13324 { 13325 satSetSensePayload( pSense, 13326 SCSI_SNSKEY_ILLEGAL_REQUEST, 13327 0, 13328 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13329 satIOContext); 13330 13331 ostiInitiatorIOCompleted( tiRoot, 13332 tiIORequest, 13333 tiIOSuccess, 13334 SCSI_STAT_CHECK_CONDITION, 13335 satIOContext->pTiSenseData, 13336 satIOContext->interruptContext ); 13337 13338 TI_DBG1(("satSynchronizeCache16: return control\n")); 13339 return tiSuccess; 13340 } 13341 13342 13343 /* checking IMMED bit */ 13344 if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK) 13345 { 13346 TI_DBG1(("satSynchronizeCache16: GOOD status due to IMMED bit\n")); 13347 13348 /* return GOOD status first here */ 13349 ostiInitiatorIOCompleted( tiRoot, 13350 tiIORequest, 13351 tiIOSuccess, 13352 SCSI_STAT_GOOD, 13353 agNULL, 13354 satIOContext->interruptContext); 13355 } 13356 13357 /* sends FLUSH CACHE or FLUSH CACHE EXT */ 13358 if (pSatDevData->sat48BitSupport == agTRUE) 13359 { 13360 TI_DBG5(("satSynchronizeCache16: sends FLUSH CACHE EXT\n")); 13361 /* FLUSH CACHE EXT */ 13362 fis->h.fisType = 0x27; /* Reg host to device */ 13363 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13364 13365 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */ 13366 fis->h.features = 0; /* FIS reserve */ 13367 fis->d.featuresExp = 0; /* FIS reserve */ 13368 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 13369 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 13370 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 13371 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 13372 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 13373 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 13374 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 13375 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 13376 fis->d.device = 0; /* FIS DEV is discared in SATA */ 13377 fis->d.control = 0; /* FIS HOB bit clear */ 13378 fis->d.reserved4 = 0; 13379 fis->d.reserved5 = 0; 13380 13381 } 13382 else 13383 { 13384 TI_DBG5(("satSynchronizeCache16: sends FLUSH CACHE\n")); 13385 /* FLUSH CACHE */ 13386 fis->h.fisType = 0x27; /* Reg host to device */ 13387 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13388 13389 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */ 13390 fis->h.features = 0; /* FIS features NA */ 13391 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 13392 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 13393 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 13394 fis->d.lbaLowExp = 0; 13395 fis->d.lbaMidExp = 0; 13396 fis->d.lbaHighExp = 0; 13397 fis->d.featuresExp = 0; 13398 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 13399 fis->d.sectorCountExp = 0; 13400 fis->d.device = 0; /* FIS DEV is discared in SATA */ 13401 fis->d.control = 0; /* FIS HOB bit clear */ 13402 fis->d.reserved4 = 0; 13403 fis->d.reserved5 = 0; 13404 13405 } 13406 13407 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 13408 13409 /* Initialize CB for SATA completion. 13410 */ 13411 satIOContext->satCompleteCB = &satSynchronizeCache10n16CB; 13412 13413 /* 13414 * Prepare SGL and send FIS to LL layer. 13415 */ 13416 satIOContext->reqType = agRequestType; /* Save it */ 13417 13418 status = sataLLIOStart( tiRoot, 13419 tiIORequest, 13420 tiDeviceHandle, 13421 tiScsiRequest, 13422 satIOContext); 13423 13424 13425 return (status); 13426 } 13427 13428 13429 /*****************************************************************************/ 13430 /*! \brief SAT implementation for SCSI satWriteAndVerify10. 13431 * 13432 * SAT implementation for SCSI satWriteAndVerify10. 13433 * 13434 * \param tiRoot: Pointer to TISA initiator driver/port instance. 13435 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 13436 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 13437 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 13438 * \param satIOContext_t: Pointer to the SAT IO Context 13439 * 13440 * \return If command is started successfully 13441 * - \e tiSuccess: I/O request successfully initiated. 13442 * - \e tiBusy: No resources available, try again later. 13443 * - \e tiIONoDevice: Invalid device handle. 13444 * - \e tiError: Other errors. 13445 */ 13446 /*****************************************************************************/ 13447 GLOBAL bit32 satWriteAndVerify10( 13448 tiRoot_t *tiRoot, 13449 tiIORequest_t *tiIORequest, 13450 tiDeviceHandle_t *tiDeviceHandle, 13451 tiScsiInitiatorRequest_t *tiScsiRequest, 13452 satIOContext_t *satIOContext) 13453 { 13454 /* 13455 combination of write10 and verify10 13456 */ 13457 13458 bit32 status; 13459 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 13460 satDeviceData_t *pSatDevData; 13461 scsiRspSense_t *pSense; 13462 tiIniScsiCmnd_t *scsiCmnd; 13463 agsaFisRegHostToDevice_t *fis; 13464 bit32 lba = 0; 13465 bit32 tl = 0; 13466 bit32 LoopNum = 1; 13467 bit8 LBA[4]; 13468 bit8 TL[4]; 13469 bit32 rangeChk = agFALSE; /* lba and tl range check */ 13470 13471 pSense = satIOContext->pSense; 13472 pSatDevData = satIOContext->pSatDevData; 13473 scsiCmnd = &tiScsiRequest->scsiCmnd; 13474 fis = satIOContext->pFis; 13475 13476 TI_DBG5(("satWriteAndVerify10: start\n")); 13477 13478 13479 /* checking BYTCHK bit */ 13480 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK) 13481 { 13482 satSetSensePayload( pSense, 13483 SCSI_SNSKEY_ILLEGAL_REQUEST, 13484 0, 13485 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13486 satIOContext); 13487 13488 ostiInitiatorIOCompleted( tiRoot, 13489 tiIORequest, 13490 tiIOSuccess, 13491 SCSI_STAT_CHECK_CONDITION, 13492 satIOContext->pTiSenseData, 13493 satIOContext->interruptContext ); 13494 13495 TI_DBG1(("satWriteAndVerify10: BYTCHK bit checking \n")); 13496 return tiSuccess; 13497 } 13498 13499 13500 /* checking CONTROL */ 13501 /* NACA == 1 or LINK == 1*/ 13502 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 13503 { 13504 satSetSensePayload( pSense, 13505 SCSI_SNSKEY_ILLEGAL_REQUEST, 13506 0, 13507 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13508 satIOContext); 13509 13510 ostiInitiatorIOCompleted( tiRoot, 13511 tiIORequest, 13512 tiIOSuccess, 13513 SCSI_STAT_CHECK_CONDITION, 13514 satIOContext->pTiSenseData, 13515 satIOContext->interruptContext ); 13516 13517 TI_DBG1(("satWriteAndVerify10: return control\n")); 13518 return tiSuccess; 13519 } 13520 13521 osti_memset(LBA, 0, sizeof(LBA)); 13522 osti_memset(TL, 0, sizeof(TL)); 13523 13524 /* do not use memcpy due to indexing in LBA and TL */ 13525 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 13526 LBA[1] = scsiCmnd->cdb[3]; 13527 LBA[2] = scsiCmnd->cdb[4]; 13528 LBA[3] = scsiCmnd->cdb[5]; /* LSB */ 13529 13530 TL[0] = 0; 13531 TL[1] = 0; 13532 TL[2] = scsiCmnd->cdb[7]; /* MSB */ 13533 TL[3] = scsiCmnd->cdb[8]; /* LSB */ 13534 13535 rangeChk = satAddNComparebit32(LBA, TL); 13536 13537 /* cbd10; computing LBA and transfer length */ 13538 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 13539 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 13540 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 13541 13542 13543 /* Table 34, 9.1, p 46 */ 13544 /* 13545 note: As of 2/10/2006, no support for DMA QUEUED 13546 */ 13547 13548 /* 13549 Table 34, 9.1, p 46, b 13550 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 13551 return check condition 13552 */ 13553 if (pSatDevData->satNCQ != agTRUE && 13554 pSatDevData->sat48BitSupport != agTRUE 13555 ) 13556 { 13557 if (lba > SAT_TR_LBA_LIMIT - 1) 13558 { 13559 satSetSensePayload( pSense, 13560 SCSI_SNSKEY_ILLEGAL_REQUEST, 13561 0, 13562 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 13563 satIOContext); 13564 13565 ostiInitiatorIOCompleted( tiRoot, 13566 tiIORequest, 13567 tiIOSuccess, 13568 SCSI_STAT_CHECK_CONDITION, 13569 satIOContext->pTiSenseData, 13570 satIOContext->interruptContext ); 13571 13572 TI_DBG1(("satWriteAndVerify10: return LBA out of range\n")); 13573 return tiSuccess; 13574 } 13575 13576 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 13577 { 13578 TI_DBG1(("satWrite10: return LBA+TL out of range, not EXT\n")); 13579 satSetSensePayload( pSense, 13580 SCSI_SNSKEY_ILLEGAL_REQUEST, 13581 0, 13582 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 13583 satIOContext); 13584 13585 ostiInitiatorIOCompleted( tiRoot, 13586 tiIORequest, 13587 tiIOSuccess, 13588 SCSI_STAT_CHECK_CONDITION, 13589 satIOContext->pTiSenseData, 13590 satIOContext->interruptContext ); 13591 13592 return tiSuccess; 13593 } 13594 } 13595 13596 13597 /* case 1 and 2 */ 13598 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT) 13599 { 13600 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 13601 { 13602 /* case 2 */ 13603 /* WRITE DMA*/ 13604 /* can't fit the transfer length */ 13605 TI_DBG5(("satWriteAndVerify10: case 2 !!!\n")); 13606 fis->h.fisType = 0x27; /* Reg host to device */ 13607 fis->h.c_pmPort = 0x80; /* C bit is set */ 13608 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 13609 fis->h.features = 0; /* FIS reserve */ 13610 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 13611 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 13612 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 13613 13614 /* FIS LBA mode set LBA (27:24) */ 13615 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 13616 13617 fis->d.lbaLowExp = 0; 13618 fis->d.lbaMidExp = 0; 13619 fis->d.lbaHighExp = 0; 13620 fis->d.featuresExp = 0; 13621 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 13622 fis->d.sectorCountExp = 0; 13623 fis->d.reserved4 = 0; 13624 fis->d.control = 0; /* FIS HOB bit clear */ 13625 fis->d.reserved5 = 0; 13626 13627 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 13628 satIOContext->ATACmd = SAT_WRITE_DMA; 13629 } 13630 else 13631 { 13632 /* case 1 */ 13633 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 13634 /* WRITE SECTORS for easier implemetation */ 13635 /* can't fit the transfer length */ 13636 TI_DBG5(("satWriteAndVerify10: case 1 !!!\n")); 13637 fis->h.fisType = 0x27; /* Reg host to device */ 13638 fis->h.c_pmPort = 0x80; /* C bit is set */ 13639 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 13640 fis->h.features = 0; /* FIS reserve */ 13641 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 13642 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 13643 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 13644 13645 /* FIS LBA mode set LBA (27:24) */ 13646 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 13647 13648 fis->d.lbaLowExp = 0; 13649 fis->d.lbaMidExp = 0; 13650 fis->d.lbaHighExp = 0; 13651 fis->d.featuresExp = 0; 13652 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 13653 fis->d.sectorCountExp = 0; 13654 fis->d.reserved4 = 0; 13655 fis->d.control = 0; /* FIS HOB bit clear */ 13656 fis->d.reserved5 = 0; 13657 13658 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 13659 satIOContext->ATACmd = SAT_WRITE_SECTORS; 13660 13661 } 13662 } 13663 13664 /* case 3 and 4 */ 13665 if (pSatDevData->sat48BitSupport == agTRUE) 13666 { 13667 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 13668 { 13669 /* case 3 */ 13670 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 13671 TI_DBG5(("satWriteAndVerify10: case 3\n")); 13672 fis->h.fisType = 0x27; /* Reg host to device */ 13673 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13674 13675 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 13676 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 13677 13678 fis->h.features = 0; /* FIS reserve */ 13679 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 13680 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 13681 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 13682 fis->d.device = 0x40; /* FIS LBA mode set */ 13683 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 13684 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 13685 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 13686 fis->d.featuresExp = 0; /* FIS reserve */ 13687 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 13688 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 13689 fis->d.reserved4 = 0; 13690 fis->d.control = 0; /* FIS HOB bit clear */ 13691 fis->d.reserved5 = 0; 13692 13693 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 13694 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 13695 } 13696 else 13697 { 13698 /* case 4 */ 13699 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 13700 /* WRITE SECTORS EXT for easier implemetation */ 13701 TI_DBG5(("satWriteAndVerify10: case 4\n")); 13702 fis->h.fisType = 0x27; /* Reg host to device */ 13703 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13704 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 13705 13706 fis->h.features = 0; /* FIS reserve */ 13707 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 13708 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 13709 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 13710 fis->d.device = 0x40; /* FIS LBA mode set */ 13711 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 13712 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 13713 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 13714 fis->d.featuresExp = 0; /* FIS reserve */ 13715 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 13716 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 13717 fis->d.reserved4 = 0; 13718 fis->d.control = 0; /* FIS HOB bit clear */ 13719 fis->d.reserved5 = 0; 13720 13721 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 13722 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 13723 } 13724 } 13725 /* case 5 */ 13726 if (pSatDevData->satNCQ == agTRUE) 13727 { 13728 /* WRITE FPDMA QUEUED */ 13729 if (pSatDevData->sat48BitSupport != agTRUE) 13730 { 13731 TI_DBG5(("satWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support \n")); 13732 satSetSensePayload( pSense, 13733 SCSI_SNSKEY_ILLEGAL_REQUEST, 13734 0, 13735 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13736 satIOContext); 13737 13738 ostiInitiatorIOCompleted( tiRoot, 13739 tiIORequest, 13740 tiIOSuccess, 13741 SCSI_STAT_CHECK_CONDITION, 13742 satIOContext->pTiSenseData, 13743 satIOContext->interruptContext ); 13744 return tiSuccess; 13745 } 13746 TI_DBG5(("satWriteAndVerify10: case 5\n")); 13747 13748 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 13749 13750 fis->h.fisType = 0x27; /* Reg host to device */ 13751 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13752 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 13753 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 13754 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 13755 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 13756 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 13757 13758 /* Check FUA bit */ 13759 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK) 13760 fis->d.device = 0xC0; /* FIS FUA set */ 13761 else 13762 fis->d.device = 0x40; /* FIS FUA clear */ 13763 13764 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 13765 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 13766 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 13767 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 13768 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 13769 fis->d.sectorCountExp = 0; 13770 fis->d.reserved4 = 0; 13771 fis->d.control = 0; /* FIS HOB bit clear */ 13772 fis->d.reserved5 = 0; 13773 13774 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 13775 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 13776 } 13777 13778 satIOContext->currentLBA = lba; 13779 satIOContext->OrgTL = tl; 13780 13781 /* 13782 computing number of loop and remainder for tl 13783 0xFF in case not ext 13784 0xFFFF in case EXT 13785 */ 13786 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 13787 { 13788 LoopNum = satComputeLoopNum(tl, 0xFF); 13789 } 13790 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 13791 fis->h.command == SAT_WRITE_DMA_EXT || 13792 fis->h.command == SAT_WRITE_DMA_FUA_EXT 13793 ) 13794 { 13795 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 13796 LoopNum = satComputeLoopNum(tl, 0xFFFF); 13797 } 13798 else 13799 { 13800 /* SAT_WRITE_FPDMA_QUEUED */ 13801 LoopNum = satComputeLoopNum(tl, 0xFFFF); 13802 } 13803 13804 satIOContext->LoopNum = LoopNum; 13805 13806 13807 if (LoopNum == 1) 13808 { 13809 TI_DBG5(("satWriteAndVerify10: NON CHAINED data\n")); 13810 /* Initialize CB for SATA completion. 13811 */ 13812 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB; 13813 } 13814 else 13815 { 13816 TI_DBG1(("satWriteAndVerify10: CHAINED data\n")); 13817 /* re-setting tl */ 13818 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 13819 { 13820 fis->d.sectorCount = 0xFF; 13821 } 13822 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 13823 fis->h.command == SAT_WRITE_DMA_EXT || 13824 fis->h.command == SAT_WRITE_DMA_FUA_EXT 13825 ) 13826 { 13827 fis->d.sectorCount = 0xFF; 13828 fis->d.sectorCountExp = 0xFF; 13829 } 13830 else 13831 { 13832 /* SAT_WRITE_FPDMA_QUEUED */ 13833 fis->h.features = 0xFF; 13834 fis->d.featuresExp = 0xFF; 13835 } 13836 13837 /* Initialize CB for SATA completion. 13838 */ 13839 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB; 13840 } 13841 13842 13843 /* 13844 * Prepare SGL and send FIS to LL layer. 13845 */ 13846 satIOContext->reqType = agRequestType; /* Save it */ 13847 13848 status = sataLLIOStart( tiRoot, 13849 tiIORequest, 13850 tiDeviceHandle, 13851 tiScsiRequest, 13852 satIOContext); 13853 return (status); 13854 13855 } 13856 13857 13858 13859 13860 13861 13862 #ifdef REMOVED 13863 GLOBAL bit32 satWriteAndVerify10( 13864 tiRoot_t *tiRoot, 13865 tiIORequest_t *tiIORequest, 13866 tiDeviceHandle_t *tiDeviceHandle, 13867 tiScsiInitiatorRequest_t *tiScsiRequest, 13868 satIOContext_t *satIOContext) 13869 { 13870 /* 13871 combination of write10 and verify10 13872 */ 13873 13874 bit32 status; 13875 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 13876 satDeviceData_t *pSatDevData; 13877 scsiRspSense_t *pSense; 13878 tiIniScsiCmnd_t *scsiCmnd; 13879 agsaFisRegHostToDevice_t *fis; 13880 bit32 lba = 0; 13881 bit32 tl = 0; 13882 13883 pSense = satIOContext->pSense; 13884 pSatDevData = satIOContext->pSatDevData; 13885 scsiCmnd = &tiScsiRequest->scsiCmnd; 13886 fis = satIOContext->pFis; 13887 13888 TI_DBG5(("satWriteAndVerify10: start\n")); 13889 13890 13891 /* checking BYTCHK bit */ 13892 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK) 13893 { 13894 satSetSensePayload( pSense, 13895 SCSI_SNSKEY_ILLEGAL_REQUEST, 13896 0, 13897 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13898 satIOContext); 13899 13900 ostiInitiatorIOCompleted( tiRoot, 13901 tiIORequest, 13902 tiIOSuccess, 13903 SCSI_STAT_CHECK_CONDITION, 13904 satIOContext->pTiSenseData, 13905 satIOContext->interruptContext ); 13906 13907 TI_DBG1(("satWriteAndVerify10: BYTCHK bit checking \n")); 13908 return tiSuccess; 13909 } 13910 13911 13912 /* checking CONTROL */ 13913 /* NACA == 1 or LINK == 1*/ 13914 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 13915 { 13916 satSetSensePayload( pSense, 13917 SCSI_SNSKEY_ILLEGAL_REQUEST, 13918 0, 13919 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13920 satIOContext); 13921 13922 ostiInitiatorIOCompleted( tiRoot, 13923 tiIORequest, 13924 tiIOSuccess, 13925 SCSI_STAT_CHECK_CONDITION, 13926 satIOContext->pTiSenseData, 13927 satIOContext->interruptContext ); 13928 13929 TI_DBG2(("satWriteAndVerify10: return control\n")); 13930 return tiSuccess; 13931 } 13932 13933 /* let's do write10 */ 13934 if ( pSatDevData->sat48BitSupport != agTRUE ) 13935 { 13936 /* 13937 writeandverify10 but no support for 48 bit addressing -> problem in transfer 13938 length(sector count) 13939 */ 13940 satSetSensePayload( pSense, 13941 SCSI_SNSKEY_ILLEGAL_REQUEST, 13942 0, 13943 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13944 satIOContext); 13945 13946 ostiInitiatorIOCompleted( tiRoot, 13947 tiIORequest, 13948 tiIOSuccess, 13949 SCSI_STAT_CHECK_CONDITION, 13950 satIOContext->pTiSenseData, 13951 satIOContext->interruptContext ); 13952 13953 TI_DBG1(("satWriteAndVerify10: return internal checking\n")); 13954 return tiSuccess; 13955 } 13956 13957 /* cbd10; computing LBA and transfer length */ 13958 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 13959 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 13960 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 13961 13962 13963 /* Table 34, 9.1, p 46 */ 13964 /* 13965 note: As of 2/10/2006, no support for DMA QUEUED 13966 */ 13967 13968 /* 13969 Table 34, 9.1, p 46, b 13970 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 13971 return check condition 13972 */ 13973 if (pSatDevData->satNCQ != agTRUE && 13974 pSatDevData->sat48BitSupport != agTRUE 13975 ) 13976 { 13977 if (lba > SAT_TR_LBA_LIMIT - 1) 13978 { 13979 satSetSensePayload( pSense, 13980 SCSI_SNSKEY_ILLEGAL_REQUEST, 13981 0, 13982 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 13983 satIOContext); 13984 13985 ostiInitiatorIOCompleted( tiRoot, 13986 tiIORequest, 13987 tiIOSuccess, 13988 SCSI_STAT_CHECK_CONDITION, 13989 satIOContext->pTiSenseData, 13990 satIOContext->interruptContext ); 13991 13992 TI_DBG1(("satWriteAndVerify10: return LBA out of range\n")); 13993 return tiSuccess; 13994 } 13995 } 13996 13997 13998 /* case 1 and 2 */ 13999 if (lba + tl <= SAT_TR_LBA_LIMIT) 14000 { 14001 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 14002 { 14003 /* case 2 */ 14004 /* WRITE DMA*/ 14005 /* can't fit the transfer length */ 14006 TI_DBG5(("satWriteAndVerify10: case 2 !!!\n")); 14007 fis->h.fisType = 0x27; /* Reg host to device */ 14008 fis->h.c_pmPort = 0x80; /* C bit is set */ 14009 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 14010 fis->h.features = 0; /* FIS reserve */ 14011 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14012 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14013 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14014 14015 /* FIS LBA mode set LBA (27:24) */ 14016 fis->d.device = (0x4 << 4) | (scsiCmnd->cdb[2] & 0xF); 14017 14018 fis->d.lbaLowExp = 0; 14019 fis->d.lbaMidExp = 0; 14020 fis->d.lbaHighExp = 0; 14021 fis->d.featuresExp = 0; 14022 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 14023 fis->d.sectorCountExp = 0; 14024 fis->d.reserved4 = 0; 14025 fis->d.control = 0; /* FIS HOB bit clear */ 14026 fis->d.reserved5 = 0; 14027 14028 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14029 satIOContext->ATACmd = SAT_WRITE_DMA; 14030 } 14031 else 14032 { 14033 /* case 1 */ 14034 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 14035 /* WRITE SECTORS for easier implemetation */ 14036 /* can't fit the transfer length */ 14037 TI_DBG5(("satWriteAndVerify10: case 1 !!!\n")); 14038 fis->h.fisType = 0x27; /* Reg host to device */ 14039 fis->h.c_pmPort = 0x80; /* C bit is set */ 14040 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 14041 fis->h.features = 0; /* FIS reserve */ 14042 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14043 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14044 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14045 14046 /* FIS LBA mode set LBA (27:24) */ 14047 fis->d.device = (0x4 << 4) | (scsiCmnd->cdb[2] & 0xF); 14048 14049 fis->d.lbaLowExp = 0; 14050 fis->d.lbaMidExp = 0; 14051 fis->d.lbaHighExp = 0; 14052 fis->d.featuresExp = 0; 14053 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 14054 fis->d.sectorCountExp = 0; 14055 fis->d.reserved4 = 0; 14056 fis->d.control = 0; /* FIS HOB bit clear */ 14057 fis->d.reserved5 = 0; 14058 14059 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 14060 satIOContext->ATACmd = SAT_WRITE_SECTORS; 14061 14062 } 14063 } 14064 14065 /* case 3 and 4 */ 14066 if (pSatDevData->sat48BitSupport == agTRUE) 14067 { 14068 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 14069 { 14070 /* case 3 */ 14071 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 14072 TI_DBG5(("satWriteAndVerify10: case 3\n")); 14073 fis->h.fisType = 0x27; /* Reg host to device */ 14074 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14075 14076 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 14077 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 14078 14079 fis->h.features = 0; /* FIS reserve */ 14080 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14081 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14082 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14083 fis->d.device = 0x40; /* FIS LBA mode set */ 14084 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 14085 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14086 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14087 fis->d.featuresExp = 0; /* FIS reserve */ 14088 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 14089 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 14090 fis->d.reserved4 = 0; 14091 fis->d.control = 0; /* FIS HOB bit clear */ 14092 fis->d.reserved5 = 0; 14093 14094 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14095 } 14096 else 14097 { 14098 /* case 4 */ 14099 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 14100 /* WRITE SECTORS EXT for easier implemetation */ 14101 TI_DBG5(("satWriteAndVerify10: case 4\n")); 14102 fis->h.fisType = 0x27; /* Reg host to device */ 14103 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14104 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 14105 14106 fis->h.features = 0; /* FIS reserve */ 14107 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14108 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14109 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14110 fis->d.device = 0x40; /* FIS LBA mode set */ 14111 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 14112 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14113 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14114 fis->d.featuresExp = 0; /* FIS reserve */ 14115 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 14116 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 14117 fis->d.reserved4 = 0; 14118 fis->d.control = 0; /* FIS HOB bit clear */ 14119 fis->d.reserved5 = 0; 14120 14121 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 14122 } 14123 } 14124 /* case 5 */ 14125 if (pSatDevData->satNCQ == agTRUE) 14126 { 14127 /* WRITE FPDMA QUEUED */ 14128 if (pSatDevData->sat48BitSupport != agTRUE) 14129 { 14130 TI_DBG5(("satWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support \n")); 14131 satSetSensePayload( pSense, 14132 SCSI_SNSKEY_ILLEGAL_REQUEST, 14133 0, 14134 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 14135 satIOContext); 14136 14137 ostiInitiatorIOCompleted( tiRoot, 14138 tiIORequest, 14139 tiIOSuccess, 14140 SCSI_STAT_CHECK_CONDITION, 14141 satIOContext->pTiSenseData, 14142 satIOContext->interruptContext ); 14143 return tiSuccess; 14144 } 14145 TI_DBG5(("satWriteAndVerify10: case 5\n")); 14146 14147 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 14148 14149 fis->h.fisType = 0x27; /* Reg host to device */ 14150 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14151 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 14152 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 14153 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14154 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14155 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14156 14157 /* Check FUA bit */ 14158 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK) 14159 fis->d.device = 0xC0; /* FIS FUA set */ 14160 else 14161 fis->d.device = 0x40; /* FIS FUA clear */ 14162 14163 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 14164 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14165 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14166 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 14167 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 14168 fis->d.sectorCountExp = 0; 14169 fis->d.reserved4 = 0; 14170 fis->d.control = 0; /* FIS HOB bit clear */ 14171 fis->d.reserved5 = 0; 14172 14173 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 14174 } 14175 14176 /* Initialize CB for SATA completion. 14177 */ 14178 satIOContext->satCompleteCB = &satWriteAndVerify10CB; 14179 14180 /* 14181 * Prepare SGL and send FIS to LL layer. 14182 */ 14183 satIOContext->reqType = agRequestType; /* Save it */ 14184 14185 status = sataLLIOStart( tiRoot, 14186 tiIORequest, 14187 tiDeviceHandle, 14188 tiScsiRequest, 14189 satIOContext); 14190 return (status); 14191 14192 } 14193 #endif /* REMOVED */ 14194 14195 #ifdef REMOVED 14196 /*****************************************************************************/ 14197 /*! \brief SAT implementation for SCSI satWriteAndVerify10_1. 14198 * 14199 * SAT implementation for SCSI satWriteAndVerify10_1. 14200 * Sub function of satWriteAndVerify10 14201 * 14202 * \param tiRoot: Pointer to TISA initiator driver/port instance. 14203 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 14204 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 14205 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 14206 * \param satIOContext_t: Pointer to the SAT IO Context 14207 * 14208 * \return If command is started successfully 14209 * - \e tiSuccess: I/O request successfully initiated. 14210 * - \e tiBusy: No resources available, try again later. 14211 * - \e tiIONoDevice: Invalid device handle. 14212 * - \e tiError: Other errors. 14213 */ 14214 /*****************************************************************************/ 14215 GLOBAL bit32 satWriteAndVerify10_1( 14216 tiRoot_t *tiRoot, 14217 tiIORequest_t *tiIORequest, 14218 tiDeviceHandle_t *tiDeviceHandle, 14219 tiScsiInitiatorRequest_t *tiScsiRequest, 14220 satIOContext_t *satIOContext) 14221 { 14222 bit32 status; 14223 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14224 satDeviceData_t *pSatDevData; 14225 scsiRspSense_t *pSense; 14226 tiIniScsiCmnd_t *scsiCmnd; 14227 agsaFisRegHostToDevice_t *fis; 14228 14229 pSense = satIOContext->pSense; 14230 pSatDevData = satIOContext->pSatDevData; 14231 scsiCmnd = &tiScsiRequest->scsiCmnd; 14232 fis = satIOContext->pFis; 14233 14234 TI_DBG5(("satWriteAndVerify10_1: start\n")); 14235 14236 if (pSatDevData->sat48BitSupport == agTRUE) 14237 { 14238 fis->h.fisType = 0x27; /* Reg host to device */ 14239 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14240 14241 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 14242 fis->h.features = 0; /* FIS reserve */ 14243 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14244 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14245 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14246 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 14247 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 14248 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14249 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14250 fis->d.featuresExp = 0; /* FIS reserve */ 14251 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 14252 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 14253 14254 fis->d.reserved4 = 0; 14255 fis->d.control = 0; /* FIS HOB bit clear */ 14256 fis->d.reserved5 = 0; 14257 14258 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14259 14260 /* Initialize CB for SATA completion. 14261 */ 14262 satIOContext->satCompleteCB = &satWriteAndVerify10CB; 14263 14264 /* 14265 * Prepare SGL and send FIS to LL layer. 14266 */ 14267 satIOContext->reqType = agRequestType; /* Save it */ 14268 14269 status = sataLLIOStart( tiRoot, 14270 tiIORequest, 14271 tiDeviceHandle, 14272 tiScsiRequest, 14273 satIOContext); 14274 14275 14276 TI_DBG1(("satWriteAndVerify10_1: return status %d\n", status)); 14277 return (status); 14278 } 14279 else 14280 { 14281 /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */ 14282 TI_DBG1(("satWriteAndVerify10_1: can't fit in SAT_READ_VERIFY_SECTORS\n")); 14283 return tiError; 14284 } 14285 14286 14287 return tiSuccess; 14288 } 14289 #endif /* REMOVED */ 14290 14291 /*****************************************************************************/ 14292 /*! \brief SAT implementation for SCSI satWriteAndVerify12. 14293 * 14294 * SAT implementation for SCSI satWriteAndVerify12. 14295 * 14296 * \param tiRoot: Pointer to TISA initiator driver/port instance. 14297 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 14298 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 14299 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 14300 * \param satIOContext_t: Pointer to the SAT IO Context 14301 * 14302 * \return If command is started successfully 14303 * - \e tiSuccess: I/O request successfully initiated. 14304 * - \e tiBusy: No resources available, try again later. 14305 * - \e tiIONoDevice: Invalid device handle. 14306 * - \e tiError: Other errors. 14307 */ 14308 /*****************************************************************************/ 14309 GLOBAL bit32 satWriteAndVerify12( 14310 tiRoot_t *tiRoot, 14311 tiIORequest_t *tiIORequest, 14312 tiDeviceHandle_t *tiDeviceHandle, 14313 tiScsiInitiatorRequest_t *tiScsiRequest, 14314 satIOContext_t *satIOContext) 14315 { 14316 /* 14317 combination of write12 and verify12 14318 temp: since write12 is not support (due to internal checking), no support 14319 */ 14320 bit32 status; 14321 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14322 satDeviceData_t *pSatDevData; 14323 scsiRspSense_t *pSense; 14324 tiIniScsiCmnd_t *scsiCmnd; 14325 agsaFisRegHostToDevice_t *fis; 14326 bit32 lba = 0; 14327 bit32 tl = 0; 14328 bit32 LoopNum = 1; 14329 bit8 LBA[4]; 14330 bit8 TL[4]; 14331 bit32 rangeChk = agFALSE; /* lba and tl range check */ 14332 14333 pSense = satIOContext->pSense; 14334 pSatDevData = satIOContext->pSatDevData; 14335 scsiCmnd = &tiScsiRequest->scsiCmnd; 14336 fis = satIOContext->pFis; 14337 14338 TI_DBG5(("satWriteAndVerify12: start\n")); 14339 14340 /* checking BYTCHK bit */ 14341 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK) 14342 { 14343 satSetSensePayload( pSense, 14344 SCSI_SNSKEY_ILLEGAL_REQUEST, 14345 0, 14346 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 14347 satIOContext); 14348 14349 ostiInitiatorIOCompleted( tiRoot, 14350 tiIORequest, 14351 tiIOSuccess, 14352 SCSI_STAT_CHECK_CONDITION, 14353 satIOContext->pTiSenseData, 14354 satIOContext->interruptContext ); 14355 14356 TI_DBG1(("satWriteAndVerify12: BYTCHK bit checking \n")); 14357 return tiSuccess; 14358 } 14359 14360 /* checking CONTROL */ 14361 /* NACA == 1 or LINK == 1*/ 14362 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) ) 14363 { 14364 satSetSensePayload( pSense, 14365 SCSI_SNSKEY_ILLEGAL_REQUEST, 14366 0, 14367 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 14368 satIOContext); 14369 14370 ostiInitiatorIOCompleted( tiRoot, 14371 tiIORequest, 14372 tiIOSuccess, 14373 SCSI_STAT_CHECK_CONDITION, 14374 satIOContext->pTiSenseData, 14375 satIOContext->interruptContext ); 14376 14377 TI_DBG2(("satWriteAndVerify12: return control\n")); 14378 return tiSuccess; 14379 } 14380 14381 osti_memset(LBA, 0, sizeof(LBA)); 14382 osti_memset(TL, 0, sizeof(TL)); 14383 14384 /* do not use memcpy due to indexing in LBA and TL */ 14385 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 14386 LBA[1] = scsiCmnd->cdb[3]; 14387 LBA[2] = scsiCmnd->cdb[4]; 14388 LBA[3] = scsiCmnd->cdb[5]; /* LSB */ 14389 14390 TL[0] = scsiCmnd->cdb[6]; /* MSB */ 14391 TL[1] = scsiCmnd->cdb[7]; 14392 TL[2] = scsiCmnd->cdb[7]; 14393 TL[3] = scsiCmnd->cdb[8]; /* LSB */ 14394 14395 rangeChk = satAddNComparebit32(LBA, TL); 14396 14397 lba = satComputeCDB12LBA(satIOContext); 14398 tl = satComputeCDB12TL(satIOContext); 14399 14400 14401 /* Table 34, 9.1, p 46 */ 14402 /* 14403 note: As of 2/10/2006, no support for DMA QUEUED 14404 */ 14405 14406 /* 14407 Table 34, 9.1, p 46, b 14408 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 14409 return check condition 14410 */ 14411 if (pSatDevData->satNCQ != agTRUE && 14412 pSatDevData->sat48BitSupport != agTRUE 14413 ) 14414 { 14415 if (lba > SAT_TR_LBA_LIMIT - 1) 14416 { 14417 satSetSensePayload( pSense, 14418 SCSI_SNSKEY_ILLEGAL_REQUEST, 14419 0, 14420 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 14421 satIOContext); 14422 14423 ostiInitiatorIOCompleted( tiRoot, 14424 tiIORequest, 14425 tiIOSuccess, 14426 SCSI_STAT_CHECK_CONDITION, 14427 satIOContext->pTiSenseData, 14428 satIOContext->interruptContext ); 14429 14430 TI_DBG1(("satWriteAndVerify12: return LBA out of range, not EXT\n")); 14431 return tiSuccess; 14432 } 14433 14434 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 14435 { 14436 TI_DBG1(("satWriteAndVerify12: return LBA+TL out of range, not EXT\n")); 14437 satSetSensePayload( pSense, 14438 SCSI_SNSKEY_ILLEGAL_REQUEST, 14439 0, 14440 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 14441 satIOContext); 14442 14443 ostiInitiatorIOCompleted( tiRoot, 14444 tiIORequest, 14445 tiIOSuccess, 14446 SCSI_STAT_CHECK_CONDITION, 14447 satIOContext->pTiSenseData, 14448 satIOContext->interruptContext ); 14449 14450 return tiSuccess; 14451 } 14452 } 14453 14454 /* case 1 and 2 */ 14455 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT) 14456 { 14457 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 14458 { 14459 /* case 2 */ 14460 /* WRITE DMA*/ 14461 /* In case that we can't fit the transfer length, we loop */ 14462 TI_DBG5(("satWriteAndVerify12: case 2\n")); 14463 fis->h.fisType = 0x27; /* Reg host to device */ 14464 fis->h.c_pmPort = 0x80; /* C bit is set */ 14465 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 14466 fis->h.features = 0; /* FIS reserve */ 14467 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14468 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14469 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14470 14471 /* FIS LBA mode set LBA (27:24) */ 14472 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 14473 14474 fis->d.lbaLowExp = 0; 14475 fis->d.lbaMidExp = 0; 14476 fis->d.lbaHighExp = 0; 14477 fis->d.featuresExp = 0; 14478 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 14479 fis->d.sectorCountExp = 0; 14480 fis->d.reserved4 = 0; 14481 fis->d.control = 0; /* FIS HOB bit clear */ 14482 fis->d.reserved5 = 0; 14483 14484 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14485 satIOContext->ATACmd = SAT_WRITE_DMA; 14486 } 14487 else 14488 { 14489 /* case 1 */ 14490 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 14491 /* WRITE SECTORS for easier implemetation */ 14492 /* In case that we can't fit the transfer length, we loop */ 14493 TI_DBG5(("satWriteAndVerify12: case 1\n")); 14494 fis->h.fisType = 0x27; /* Reg host to device */ 14495 fis->h.c_pmPort = 0x80; /* C bit is set */ 14496 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 14497 fis->h.features = 0; /* FIS reserve */ 14498 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14499 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14500 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14501 14502 /* FIS LBA mode set LBA (27:24) */ 14503 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 14504 14505 fis->d.lbaLowExp = 0; 14506 fis->d.lbaMidExp = 0; 14507 fis->d.lbaHighExp = 0; 14508 fis->d.featuresExp = 0; 14509 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 14510 fis->d.sectorCountExp = 0; 14511 fis->d.reserved4 = 0; 14512 fis->d.control = 0; /* FIS HOB bit clear */ 14513 fis->d.reserved5 = 0; 14514 14515 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 14516 satIOContext->ATACmd = SAT_WRITE_SECTORS; 14517 } 14518 } 14519 14520 /* case 3 and 4 */ 14521 if (pSatDevData->sat48BitSupport == agTRUE) 14522 { 14523 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 14524 { 14525 /* case 3 */ 14526 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 14527 TI_DBG5(("satWriteAndVerify12: case 3\n")); 14528 fis->h.fisType = 0x27; /* Reg host to device */ 14529 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14530 14531 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 14532 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 14533 14534 fis->h.features = 0; /* FIS reserve */ 14535 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14536 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14537 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14538 fis->d.device = 0x40; /* FIS LBA mode set */ 14539 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 14540 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14541 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14542 fis->d.featuresExp = 0; /* FIS reserve */ 14543 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 14544 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 14545 fis->d.reserved4 = 0; 14546 fis->d.control = 0; /* FIS HOB bit clear */ 14547 fis->d.reserved5 = 0; 14548 14549 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14550 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 14551 } 14552 else 14553 { 14554 /* case 4 */ 14555 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 14556 /* WRITE SECTORS EXT for easier implemetation */ 14557 TI_DBG5(("satWriteAndVerify12: case 4\n")); 14558 fis->h.fisType = 0x27; /* Reg host to device */ 14559 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14560 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 14561 14562 fis->h.features = 0; /* FIS reserve */ 14563 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14564 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14565 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14566 fis->d.device = 0x40; /* FIS LBA mode set */ 14567 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 14568 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14569 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14570 fis->d.featuresExp = 0; /* FIS reserve */ 14571 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 14572 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 14573 fis->d.reserved4 = 0; 14574 fis->d.control = 0; /* FIS HOB bit clear */ 14575 fis->d.reserved5 = 0; 14576 14577 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 14578 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 14579 } 14580 } 14581 14582 /* case 5 */ 14583 if (pSatDevData->satNCQ == agTRUE) 14584 { 14585 /* WRITE FPDMA QUEUED */ 14586 if (pSatDevData->sat48BitSupport != agTRUE) 14587 { 14588 TI_DBG5(("satWriteAndVerify12: case 5 !!! error NCQ but 28 bit address support \n")); 14589 satSetSensePayload( pSense, 14590 SCSI_SNSKEY_ILLEGAL_REQUEST, 14591 0, 14592 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 14593 satIOContext); 14594 14595 ostiInitiatorIOCompleted( tiRoot, 14596 tiIORequest, 14597 tiIOSuccess, 14598 SCSI_STAT_CHECK_CONDITION, 14599 satIOContext->pTiSenseData, 14600 satIOContext->interruptContext ); 14601 return tiSuccess; 14602 } 14603 TI_DBG6(("satWriteAndVerify12: case 5\n")); 14604 14605 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 14606 14607 fis->h.fisType = 0x27; /* Reg host to device */ 14608 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14609 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 14610 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 14611 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14612 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14613 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14614 14615 /* Check FUA bit */ 14616 if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK) 14617 fis->d.device = 0xC0; /* FIS FUA set */ 14618 else 14619 fis->d.device = 0x40; /* FIS FUA clear */ 14620 14621 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 14622 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14623 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14624 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 14625 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 14626 fis->d.sectorCountExp = 0; 14627 fis->d.reserved4 = 0; 14628 fis->d.control = 0; /* FIS HOB bit clear */ 14629 fis->d.reserved5 = 0; 14630 14631 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 14632 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 14633 } 14634 14635 satIOContext->currentLBA = lba; 14636 // satIOContext->OrgLBA = lba; 14637 satIOContext->OrgTL = tl; 14638 14639 /* 14640 computing number of loop and remainder for tl 14641 0xFF in case not ext 14642 0xFFFF in case EXT 14643 */ 14644 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 14645 { 14646 LoopNum = satComputeLoopNum(tl, 0xFF); 14647 } 14648 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 14649 fis->h.command == SAT_WRITE_DMA_EXT || 14650 fis->h.command == SAT_WRITE_DMA_FUA_EXT 14651 ) 14652 { 14653 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 14654 LoopNum = satComputeLoopNum(tl, 0xFFFF); 14655 } 14656 else 14657 { 14658 /* SAT_WRITE_FPDMA_QUEUEDK */ 14659 LoopNum = satComputeLoopNum(tl, 0xFFFF); 14660 } 14661 14662 satIOContext->LoopNum = LoopNum; 14663 satIOContext->LoopNum2 = LoopNum; 14664 14665 14666 if (LoopNum == 1) 14667 { 14668 TI_DBG5(("satWriteAndVerify12: NON CHAINED data\n")); 14669 /* Initialize CB for SATA completion. 14670 */ 14671 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB; 14672 } 14673 else 14674 { 14675 TI_DBG1(("satWriteAndVerify12: CHAINED data\n")); 14676 /* re-setting tl */ 14677 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 14678 { 14679 fis->d.sectorCount = 0xFF; 14680 } 14681 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 14682 fis->h.command == SAT_WRITE_DMA_EXT || 14683 fis->h.command == SAT_WRITE_DMA_FUA_EXT 14684 ) 14685 { 14686 fis->d.sectorCount = 0xFF; 14687 fis->d.sectorCountExp = 0xFF; 14688 } 14689 else 14690 { 14691 /* SAT_WRITE_FPDMA_QUEUED */ 14692 fis->h.features = 0xFF; 14693 fis->d.featuresExp = 0xFF; 14694 } 14695 14696 /* Initialize CB for SATA completion. 14697 */ 14698 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB; 14699 } 14700 14701 14702 /* 14703 * Prepare SGL and send FIS to LL layer. 14704 */ 14705 satIOContext->reqType = agRequestType; /* Save it */ 14706 14707 status = sataLLIOStart( tiRoot, 14708 tiIORequest, 14709 tiDeviceHandle, 14710 tiScsiRequest, 14711 satIOContext); 14712 return (status); 14713 } 14714 14715 GLOBAL bit32 satNonChainedWriteNVerify_Verify( 14716 tiRoot_t *tiRoot, 14717 tiIORequest_t *tiIORequest, 14718 tiDeviceHandle_t *tiDeviceHandle, 14719 tiScsiInitiatorRequest_t *tiScsiRequest, 14720 satIOContext_t *satIOContext) 14721 { 14722 bit32 status; 14723 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14724 satDeviceData_t *pSatDevData; 14725 tiIniScsiCmnd_t *scsiCmnd; 14726 agsaFisRegHostToDevice_t *fis; 14727 14728 pSatDevData = satIOContext->pSatDevData; 14729 scsiCmnd = &tiScsiRequest->scsiCmnd; 14730 fis = satIOContext->pFis; 14731 14732 TI_DBG5(("satNonChainedWriteNVerify_Verify: start\n")); 14733 14734 if (pSatDevData->sat48BitSupport == agTRUE) 14735 { 14736 fis->h.fisType = 0x27; /* Reg host to device */ 14737 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14738 14739 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 14740 fis->h.features = 0; /* FIS reserve */ 14741 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 14742 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 14743 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 14744 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 14745 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 14746 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14747 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14748 fis->d.featuresExp = 0; /* FIS reserve */ 14749 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 14750 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 14751 14752 fis->d.reserved4 = 0; 14753 fis->d.control = 0; /* FIS HOB bit clear */ 14754 fis->d.reserved5 = 0; 14755 14756 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14757 14758 /* Initialize CB for SATA completion. 14759 */ 14760 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB; 14761 14762 /* 14763 * Prepare SGL and send FIS to LL layer. 14764 */ 14765 satIOContext->reqType = agRequestType; /* Save it */ 14766 14767 status = sataLLIOStart( tiRoot, 14768 tiIORequest, 14769 tiDeviceHandle, 14770 tiScsiRequest, 14771 satIOContext); 14772 14773 14774 TI_DBG1(("satNonChainedWriteNVerify_Verify: return status %d\n", status)); 14775 return (status); 14776 } 14777 else 14778 { 14779 /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */ 14780 TI_DBG1(("satNonChainedWriteNVerify_Verify: can't fit in SAT_READ_VERIFY_SECTORS\n")); 14781 return tiError; 14782 } 14783 14784 } 14785 14786 GLOBAL bit32 satChainedWriteNVerify_Write( 14787 tiRoot_t *tiRoot, 14788 tiIORequest_t *tiIORequest, 14789 tiDeviceHandle_t *tiDeviceHandle, 14790 tiScsiInitiatorRequest_t *tiScsiRequest, 14791 satIOContext_t *satIOContext) 14792 { 14793 /* 14794 Assumption: error check on lba and tl has been done in satWrite*() 14795 lba = lba + tl; 14796 */ 14797 bit32 status; 14798 satIOContext_t *satOrgIOContext = agNULL; 14799 tiIniScsiCmnd_t *scsiCmnd; 14800 agsaFisRegHostToDevice_t *fis; 14801 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14802 bit32 lba = 0; 14803 bit32 DenomTL = 0xFF; 14804 bit32 Remainder = 0; 14805 bit8 LBA[4]; /* 0 MSB, 3 LSB */ 14806 14807 TI_DBG1(("satChainedWriteNVerify_Write: start\n")); 14808 14809 fis = satIOContext->pFis; 14810 satOrgIOContext = satIOContext->satOrgIOContext; 14811 scsiCmnd = satOrgIOContext->pScsiCmnd; 14812 14813 osti_memset(LBA,0, sizeof(LBA)); 14814 14815 switch (satOrgIOContext->ATACmd) 14816 { 14817 case SAT_WRITE_DMA: 14818 DenomTL = 0xFF; 14819 break; 14820 case SAT_WRITE_SECTORS: 14821 DenomTL = 0xFF; 14822 break; 14823 case SAT_WRITE_DMA_EXT: 14824 DenomTL = 0xFFFF; 14825 break; 14826 case SAT_WRITE_DMA_FUA_EXT: 14827 DenomTL = 0xFFFF; 14828 break; 14829 case SAT_WRITE_SECTORS_EXT: 14830 DenomTL = 0xFFFF; 14831 break; 14832 case SAT_WRITE_FPDMA_QUEUED: 14833 DenomTL = 0xFFFF; 14834 break; 14835 default: 14836 TI_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x\n", satIOContext->ATACmd)); 14837 return tiError; 14838 break; 14839 } 14840 14841 Remainder = satOrgIOContext->OrgTL % DenomTL; 14842 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL; 14843 lba = satOrgIOContext->currentLBA; 14844 14845 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */ 14846 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2)); 14847 LBA[2] = (bit8)((lba & 0xF0) >> 8); 14848 LBA[3] = (bit8)(lba & 0xF); /* LSB */ 14849 14850 switch (satOrgIOContext->ATACmd) 14851 { 14852 case SAT_WRITE_DMA: 14853 fis->h.fisType = 0x27; /* Reg host to device */ 14854 fis->h.c_pmPort = 0x80; /* C bit is set */ 14855 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 14856 fis->h.features = 0; /* FIS reserve */ 14857 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 14858 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 14859 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 14860 14861 /* FIS LBA mode set LBA (27:24) */ 14862 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 14863 14864 fis->d.lbaLowExp = 0; 14865 fis->d.lbaMidExp = 0; 14866 fis->d.lbaHighExp = 0; 14867 fis->d.featuresExp = 0; 14868 if (satOrgIOContext->LoopNum == 1) 14869 { 14870 /* last loop */ 14871 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 14872 } 14873 else 14874 { 14875 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 14876 } 14877 fis->d.sectorCountExp = 0; 14878 fis->d.reserved4 = 0; 14879 fis->d.control = 0; /* FIS HOB bit clear */ 14880 fis->d.reserved5 = 0; 14881 14882 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14883 14884 break; 14885 case SAT_WRITE_SECTORS: 14886 fis->h.fisType = 0x27; /* Reg host to device */ 14887 fis->h.c_pmPort = 0x80; /* C bit is set */ 14888 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 14889 fis->h.features = 0; /* FIS reserve */ 14890 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 14891 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 14892 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 14893 14894 /* FIS LBA mode set LBA (27:24) */ 14895 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 14896 14897 fis->d.lbaLowExp = 0; 14898 fis->d.lbaMidExp = 0; 14899 fis->d.lbaHighExp = 0; 14900 fis->d.featuresExp = 0; 14901 if (satOrgIOContext->LoopNum == 1) 14902 { 14903 /* last loop */ 14904 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 14905 } 14906 else 14907 { 14908 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 14909 } 14910 fis->d.sectorCountExp = 0; 14911 fis->d.reserved4 = 0; 14912 fis->d.control = 0; /* FIS HOB bit clear */ 14913 fis->d.reserved5 = 0; 14914 14915 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 14916 14917 break; 14918 case SAT_WRITE_DMA_EXT: 14919 fis->h.fisType = 0x27; /* Reg host to device */ 14920 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14921 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x3D */ 14922 fis->h.features = 0; /* FIS reserve */ 14923 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 14924 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 14925 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 14926 fis->d.device = 0x40; /* FIS LBA mode set */ 14927 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 14928 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14929 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14930 fis->d.featuresExp = 0; /* FIS reserve */ 14931 if (satOrgIOContext->LoopNum == 1) 14932 { 14933 /* last loop */ 14934 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 14935 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 14936 } 14937 else 14938 { 14939 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 14940 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 14941 } 14942 fis->d.reserved4 = 0; 14943 fis->d.control = 0; /* FIS HOB bit clear */ 14944 fis->d.reserved5 = 0; 14945 14946 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14947 14948 break; 14949 case SAT_WRITE_SECTORS_EXT: 14950 fis->h.fisType = 0x27; /* Reg host to device */ 14951 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14952 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 14953 14954 fis->h.features = 0; /* FIS reserve */ 14955 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 14956 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 14957 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 14958 fis->d.device = 0x40; /* FIS LBA mode set */ 14959 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 14960 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14961 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14962 fis->d.featuresExp = 0; /* FIS reserve */ 14963 if (satOrgIOContext->LoopNum == 1) 14964 { 14965 /* last loop */ 14966 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 14967 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 14968 } 14969 else 14970 { 14971 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 14972 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 14973 } 14974 fis->d.reserved4 = 0; 14975 fis->d.control = 0; /* FIS HOB bit clear */ 14976 fis->d.reserved5 = 0; 14977 14978 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 14979 14980 break; 14981 case SAT_WRITE_FPDMA_QUEUED: 14982 fis->h.fisType = 0x27; /* Reg host to device */ 14983 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14984 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 14985 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 14986 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 14987 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 14988 14989 /* Check FUA bit */ 14990 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK) 14991 fis->d.device = 0xC0; /* FIS FUA set */ 14992 else 14993 fis->d.device = 0x40; /* FIS FUA clear */ 14994 14995 fis->d.lbaLowExp = LBA[0];; /* FIS LBA (31:24) */ 14996 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14997 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14998 if (satOrgIOContext->LoopNum == 1) 14999 { 15000 /* last loop */ 15001 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 15002 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 15003 } 15004 else 15005 { 15006 fis->h.features = 0xFF; /* FIS sector count (7:0) */ 15007 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */ 15008 } 15009 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 15010 fis->d.sectorCountExp = 0; 15011 fis->d.reserved4 = 0; 15012 fis->d.control = 0; /* FIS HOB bit clear */ 15013 fis->d.reserved5 = 0; 15014 15015 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 15016 break; 15017 15018 default: 15019 TI_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x\n", satIOContext->ATACmd)); 15020 return tiError; 15021 break; 15022 } 15023 15024 /* Initialize CB for SATA completion. 15025 */ 15026 /* chained data */ 15027 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB; 15028 15029 15030 /* 15031 * Prepare SGL and send FIS to LL layer. 15032 */ 15033 satIOContext->reqType = agRequestType; /* Save it */ 15034 15035 status = sataLLIOStart( tiRoot, 15036 tiIORequest, 15037 tiDeviceHandle, 15038 tiScsiRequest, 15039 satIOContext); 15040 15041 TI_DBG5(("satChainedWriteNVerify_Write: return\n")); 15042 return (status); 15043 15044 } 15045 15046 /* 15047 similar to write12 and verify10; 15048 this will be similar to verify12 15049 */ 15050 GLOBAL bit32 satChainedWriteNVerify_Start_Verify( 15051 tiRoot_t *tiRoot, 15052 tiIORequest_t *tiIORequest, 15053 tiDeviceHandle_t *tiDeviceHandle, 15054 tiScsiInitiatorRequest_t *tiScsiRequest, 15055 satIOContext_t *satIOContext) 15056 { 15057 /* 15058 deal with transfer length; others have been handled previously at this point; 15059 no LBA check; no range check; 15060 */ 15061 bit32 status; 15062 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 15063 satDeviceData_t *pSatDevData; 15064 tiIniScsiCmnd_t *scsiCmnd; 15065 agsaFisRegHostToDevice_t *fis; 15066 bit32 lba = 0; 15067 bit32 tl = 0; 15068 bit32 LoopNum = 1; 15069 bit8 LBA[4]; 15070 bit8 TL[4]; 15071 15072 pSatDevData = satIOContext->pSatDevData; 15073 scsiCmnd = &tiScsiRequest->scsiCmnd; 15074 fis = satIOContext->pFis; 15075 15076 TI_DBG5(("satChainedWriteNVerify_Start_Verify: start\n")); 15077 15078 osti_memset(LBA, 0, sizeof(LBA)); 15079 osti_memset(TL, 0, sizeof(TL)); 15080 15081 /* do not use memcpy due to indexing in LBA and TL */ 15082 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 15083 LBA[1] = scsiCmnd->cdb[3]; 15084 LBA[2] = scsiCmnd->cdb[4]; 15085 LBA[3] = scsiCmnd->cdb[5]; /* LSB */ 15086 15087 TL[0] = scsiCmnd->cdb[6]; /* MSB */ 15088 TL[1] = scsiCmnd->cdb[7]; 15089 TL[2] = scsiCmnd->cdb[7]; 15090 TL[3] = scsiCmnd->cdb[8]; /* LSB */ 15091 15092 lba = satComputeCDB12LBA(satIOContext); 15093 tl = satComputeCDB12TL(satIOContext); 15094 15095 if (pSatDevData->sat48BitSupport == agTRUE) 15096 { 15097 TI_DBG5(("satChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS_EXT\n")); 15098 fis->h.fisType = 0x27; /* Reg host to device */ 15099 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15100 15101 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 15102 fis->h.features = 0; /* FIS reserve */ 15103 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15104 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15105 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15106 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 15107 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 15108 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 15109 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 15110 fis->d.featuresExp = 0; /* FIS reserve */ 15111 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 15112 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 15113 15114 fis->d.reserved4 = 0; 15115 fis->d.control = 0; /* FIS HOB bit clear */ 15116 fis->d.reserved5 = 0; 15117 15118 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 15119 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT; 15120 } 15121 else 15122 { 15123 TI_DBG5(("satChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS\n")); 15124 fis->h.fisType = 0x27; /* Reg host to device */ 15125 fis->h.c_pmPort = 0x80; /* C bit is set */ 15126 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 15127 fis->h.features = 0; /* FIS reserve */ 15128 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15129 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15130 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15131 /* FIS LBA mode set LBA (27:24) */ 15132 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 15133 fis->d.lbaLowExp = 0; 15134 fis->d.lbaMidExp = 0; 15135 fis->d.lbaHighExp = 0; 15136 fis->d.featuresExp = 0; 15137 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 15138 fis->d.sectorCountExp = 0; 15139 fis->d.reserved4 = 0; 15140 fis->d.control = 0; /* FIS HOB bit clear */ 15141 fis->d.reserved5 = 0; 15142 15143 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 15144 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS; 15145 15146 } 15147 15148 satIOContext->currentLBA = lba; 15149 satIOContext->OrgTL = tl; 15150 15151 /* 15152 computing number of loop and remainder for tl 15153 0xFF in case not ext 15154 0xFFFF in case EXT 15155 */ 15156 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 15157 { 15158 LoopNum = satComputeLoopNum(tl, 0xFF); 15159 } 15160 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 15161 { 15162 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 15163 LoopNum = satComputeLoopNum(tl, 0xFFFF); 15164 } 15165 else 15166 { 15167 TI_DBG1(("satChainedWriteNVerify_Start_Verify: error case 1!!!\n")); 15168 LoopNum = 1; 15169 } 15170 15171 satIOContext->LoopNum = LoopNum; 15172 15173 if (LoopNum == 1) 15174 { 15175 TI_DBG5(("satChainedWriteNVerify_Start_Verify: NON CHAINED data\n")); 15176 /* Initialize CB for SATA completion. 15177 */ 15178 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB; 15179 } 15180 else 15181 { 15182 TI_DBG1(("satChainedWriteNVerify_Start_Verify: CHAINED data\n")); 15183 /* re-setting tl */ 15184 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 15185 { 15186 fis->d.sectorCount = 0xFF; 15187 } 15188 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 15189 { 15190 fis->d.sectorCount = 0xFF; 15191 fis->d.sectorCountExp = 0xFF; 15192 } 15193 else 15194 { 15195 TI_DBG1(("satChainedWriteNVerify_Start_Verify: error case 2!!!\n")); 15196 } 15197 15198 /* Initialize CB for SATA completion. 15199 */ 15200 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB; 15201 } 15202 15203 15204 /* 15205 * Prepare SGL and send FIS to LL layer. 15206 */ 15207 satIOContext->reqType = agRequestType; /* Save it */ 15208 15209 status = sataLLIOStart( tiRoot, 15210 tiIORequest, 15211 tiDeviceHandle, 15212 tiScsiRequest, 15213 satIOContext); 15214 return (status); 15215 } 15216 15217 GLOBAL bit32 satChainedWriteNVerify_Verify( 15218 tiRoot_t *tiRoot, 15219 tiIORequest_t *tiIORequest, 15220 tiDeviceHandle_t *tiDeviceHandle, 15221 tiScsiInitiatorRequest_t *tiScsiRequest, 15222 satIOContext_t *satIOContext) 15223 { 15224 bit32 status; 15225 satIOContext_t *satOrgIOContext = agNULL; 15226 agsaFisRegHostToDevice_t *fis; 15227 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 15228 bit32 lba = 0; 15229 bit32 DenomTL = 0xFF; 15230 bit32 Remainder = 0; 15231 bit8 LBA[4]; /* 0 MSB, 3 LSB */ 15232 15233 TI_DBG2(("satChainedWriteNVerify_Verify: start\n")); 15234 15235 fis = satIOContext->pFis; 15236 satOrgIOContext = satIOContext->satOrgIOContext; 15237 15238 osti_memset(LBA,0, sizeof(LBA)); 15239 15240 switch (satOrgIOContext->ATACmd) 15241 { 15242 case SAT_READ_VERIFY_SECTORS: 15243 DenomTL = 0xFF; 15244 break; 15245 case SAT_READ_VERIFY_SECTORS_EXT: 15246 DenomTL = 0xFFFF; 15247 break; 15248 default: 15249 TI_DBG1(("satChainedWriteNVerify_Verify: error incorrect ata command 0x%x\n", satIOContext->ATACmd)); 15250 return tiError; 15251 break; 15252 } 15253 15254 Remainder = satOrgIOContext->OrgTL % DenomTL; 15255 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL; 15256 lba = satOrgIOContext->currentLBA; 15257 15258 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */ 15259 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2)); 15260 LBA[2] = (bit8)((lba & 0xF0) >> 8); 15261 LBA[3] = (bit8)(lba & 0xF); /* LSB */ 15262 15263 switch (satOrgIOContext->ATACmd) 15264 { 15265 case SAT_READ_VERIFY_SECTORS: 15266 fis->h.fisType = 0x27; /* Reg host to device */ 15267 fis->h.c_pmPort = 0x80; /* C bit is set */ 15268 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 15269 fis->h.features = 0; /* FIS reserve */ 15270 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 15271 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 15272 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 15273 15274 /* FIS LBA mode set LBA (27:24) */ 15275 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 15276 15277 fis->d.lbaLowExp = 0; 15278 fis->d.lbaMidExp = 0; 15279 fis->d.lbaHighExp = 0; 15280 fis->d.featuresExp = 0; 15281 if (satOrgIOContext->LoopNum == 1) 15282 { 15283 /* last loop */ 15284 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 15285 } 15286 else 15287 { 15288 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 15289 } 15290 fis->d.sectorCountExp = 0; 15291 fis->d.reserved4 = 0; 15292 fis->d.control = 0; /* FIS HOB bit clear */ 15293 fis->d.reserved5 = 0; 15294 15295 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 15296 15297 break; 15298 case SAT_READ_VERIFY_SECTORS_EXT: 15299 fis->h.fisType = 0x27; /* Reg host to device */ 15300 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15301 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT; /* 0x42 */ 15302 fis->h.features = 0; /* FIS reserve */ 15303 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 15304 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 15305 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 15306 fis->d.device = 0x40; /* FIS LBA mode set */ 15307 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 15308 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 15309 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 15310 fis->d.featuresExp = 0; /* FIS reserve */ 15311 if (satOrgIOContext->LoopNum == 1) 15312 { 15313 /* last loop */ 15314 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 15315 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 15316 } 15317 else 15318 { 15319 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 15320 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 15321 } 15322 fis->d.reserved4 = 0; 15323 fis->d.control = 0; /* FIS HOB bit clear */ 15324 fis->d.reserved5 = 0; 15325 15326 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 15327 15328 break; 15329 15330 default: 15331 TI_DBG1(("satChainedWriteNVerify_Verify: error incorrect ata command 0x%x\n", satIOContext->ATACmd)); 15332 return tiError; 15333 break; 15334 } 15335 15336 /* Initialize CB for SATA completion. 15337 */ 15338 /* chained data */ 15339 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB; 15340 15341 15342 /* 15343 * Prepare SGL and send FIS to LL layer. 15344 */ 15345 satIOContext->reqType = agRequestType; /* Save it */ 15346 15347 status = sataLLIOStart( tiRoot, 15348 tiIORequest, 15349 tiDeviceHandle, 15350 tiScsiRequest, 15351 satIOContext); 15352 15353 TI_DBG5(("satChainedWriteNVerify_Verify: return\n")); 15354 return (status); 15355 15356 } 15357 15358 15359 /*****************************************************************************/ 15360 /*! \brief SAT implementation for SCSI satWriteAndVerify16. 15361 * 15362 * SAT implementation for SCSI satWriteAndVerify16. 15363 * 15364 * \param tiRoot: Pointer to TISA initiator driver/port instance. 15365 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 15366 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 15367 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 15368 * \param satIOContext_t: Pointer to the SAT IO Context 15369 * 15370 * \return If command is started successfully 15371 * - \e tiSuccess: I/O request successfully initiated. 15372 * - \e tiBusy: No resources available, try again later. 15373 * - \e tiIONoDevice: Invalid device handle. 15374 * - \e tiError: Other errors. 15375 */ 15376 /*****************************************************************************/ 15377 GLOBAL bit32 satWriteAndVerify16( 15378 tiRoot_t *tiRoot, 15379 tiIORequest_t *tiIORequest, 15380 tiDeviceHandle_t *tiDeviceHandle, 15381 tiScsiInitiatorRequest_t *tiScsiRequest, 15382 satIOContext_t *satIOContext) 15383 { 15384 /* 15385 combination of write16 and verify16 15386 since write16 has 8 bytes LBA -> problem ATA LBA(upto 6 bytes), no support 15387 */ 15388 bit32 status; 15389 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 15390 satDeviceData_t *pSatDevData; 15391 scsiRspSense_t *pSense; 15392 tiIniScsiCmnd_t *scsiCmnd; 15393 agsaFisRegHostToDevice_t *fis; 15394 bit32 lba = 0; 15395 bit32 tl = 0; 15396 bit32 LoopNum = 1; 15397 bit8 LBA[8]; 15398 bit8 TL[8]; 15399 bit32 rangeChk = agFALSE; /* lba and tl range check */ 15400 bit32 limitChk = agFALSE; /* lba and tl range check */ 15401 15402 pSense = satIOContext->pSense; 15403 pSatDevData = satIOContext->pSatDevData; 15404 scsiCmnd = &tiScsiRequest->scsiCmnd; 15405 fis = satIOContext->pFis; 15406 TI_DBG5(("satWriteAndVerify16:start\n")); 15407 15408 /* checking BYTCHK bit */ 15409 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK) 15410 { 15411 satSetSensePayload( pSense, 15412 SCSI_SNSKEY_ILLEGAL_REQUEST, 15413 0, 15414 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15415 satIOContext); 15416 15417 ostiInitiatorIOCompleted( tiRoot, 15418 tiIORequest, 15419 tiIOSuccess, 15420 SCSI_STAT_CHECK_CONDITION, 15421 satIOContext->pTiSenseData, 15422 satIOContext->interruptContext ); 15423 15424 TI_DBG1(("satWriteAndVerify16: BYTCHK bit checking \n")); 15425 return tiSuccess; 15426 } 15427 15428 15429 /* checking CONTROL */ 15430 /* NACA == 1 or LINK == 1*/ 15431 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 15432 { 15433 satSetSensePayload( pSense, 15434 SCSI_SNSKEY_ILLEGAL_REQUEST, 15435 0, 15436 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15437 satIOContext); 15438 15439 ostiInitiatorIOCompleted( tiRoot, 15440 tiIORequest, 15441 tiIOSuccess, 15442 SCSI_STAT_CHECK_CONDITION, 15443 satIOContext->pTiSenseData, 15444 satIOContext->interruptContext ); 15445 15446 TI_DBG2(("satWriteAndVerify16: return control\n")); 15447 return tiSuccess; 15448 } 15449 15450 osti_memset(LBA, 0, sizeof(LBA)); 15451 osti_memset(TL, 0, sizeof(TL)); 15452 15453 15454 /* do not use memcpy due to indexing in LBA and TL */ 15455 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 15456 LBA[1] = scsiCmnd->cdb[3]; 15457 LBA[2] = scsiCmnd->cdb[4]; 15458 LBA[3] = scsiCmnd->cdb[5]; 15459 LBA[4] = scsiCmnd->cdb[6]; 15460 LBA[5] = scsiCmnd->cdb[7]; 15461 LBA[6] = scsiCmnd->cdb[8]; 15462 LBA[7] = scsiCmnd->cdb[9]; /* LSB */ 15463 15464 TL[0] = 0; 15465 TL[1] = 0; 15466 TL[2] = 0; 15467 TL[3] = 0; 15468 TL[4] = scsiCmnd->cdb[10]; /* MSB */ 15469 TL[5] = scsiCmnd->cdb[11]; 15470 TL[6] = scsiCmnd->cdb[12]; 15471 TL[7] = scsiCmnd->cdb[13]; /* LSB */ 15472 15473 rangeChk = satAddNComparebit64(LBA, TL); 15474 15475 limitChk = satCompareLBALimitbit(LBA); 15476 15477 lba = satComputeCDB16LBA(satIOContext); 15478 tl = satComputeCDB16TL(satIOContext); 15479 15480 15481 /* Table 34, 9.1, p 46 */ 15482 /* 15483 note: As of 2/10/2006, no support for DMA QUEUED 15484 */ 15485 15486 /* 15487 Table 34, 9.1, p 46, b 15488 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 15489 return check condition 15490 */ 15491 if (pSatDevData->satNCQ != agTRUE && 15492 pSatDevData->sat48BitSupport != agTRUE 15493 ) 15494 { 15495 if (limitChk) 15496 { 15497 TI_DBG1(("satWriteAndVerify16: return LBA out of range, not EXT\n")); 15498 satSetSensePayload( pSense, 15499 SCSI_SNSKEY_ILLEGAL_REQUEST, 15500 0, 15501 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 15502 satIOContext); 15503 15504 ostiInitiatorIOCompleted( tiRoot, 15505 tiIORequest, 15506 tiIOSuccess, 15507 SCSI_STAT_CHECK_CONDITION, 15508 satIOContext->pTiSenseData, 15509 satIOContext->interruptContext ); 15510 15511 return tiSuccess; 15512 } 15513 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT) 15514 { 15515 TI_DBG1(("satWriteAndVerify16: return LBA+TL out of range, not EXT\n")); 15516 satSetSensePayload( pSense, 15517 SCSI_SNSKEY_ILLEGAL_REQUEST, 15518 0, 15519 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 15520 satIOContext); 15521 15522 ostiInitiatorIOCompleted( tiRoot, 15523 tiIORequest, 15524 tiIOSuccess, 15525 SCSI_STAT_CHECK_CONDITION, 15526 satIOContext->pTiSenseData, 15527 satIOContext->interruptContext ); 15528 15529 return tiSuccess; 15530 } 15531 } 15532 15533 15534 /* case 1 and 2 */ 15535 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT) 15536 { 15537 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 15538 { 15539 /* case 2 */ 15540 /* WRITE DMA*/ 15541 /* In case that we can't fit the transfer length, we loop */ 15542 TI_DBG5(("satWriteAndVerify16: case 2\n")); 15543 fis->h.fisType = 0x27; /* Reg host to device */ 15544 fis->h.c_pmPort = 0x80; /* C bit is set */ 15545 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 15546 fis->h.features = 0; /* FIS reserve */ 15547 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 15548 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 15549 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 15550 15551 /* FIS LBA mode set LBA (27:24) */ 15552 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); 15553 15554 fis->d.lbaLowExp = 0; 15555 fis->d.lbaMidExp = 0; 15556 fis->d.lbaHighExp = 0; 15557 fis->d.featuresExp = 0; 15558 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 15559 fis->d.sectorCountExp = 0; 15560 fis->d.reserved4 = 0; 15561 fis->d.control = 0; /* FIS HOB bit clear */ 15562 fis->d.reserved5 = 0; 15563 15564 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 15565 satIOContext->ATACmd = SAT_WRITE_DMA; 15566 } 15567 else 15568 { 15569 /* case 1 */ 15570 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 15571 /* WRITE SECTORS for easier implemetation */ 15572 /* In case that we can't fit the transfer length, we loop */ 15573 TI_DBG5(("satWriteAndVerify16: case 1\n")); 15574 fis->h.fisType = 0x27; /* Reg host to device */ 15575 fis->h.c_pmPort = 0x80; /* C bit is set */ 15576 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 15577 fis->h.features = 0; /* FIS reserve */ 15578 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 15579 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 15580 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 15581 15582 /* FIS LBA mode set LBA (27:24) */ 15583 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); 15584 15585 fis->d.lbaLowExp = 0; 15586 fis->d.lbaMidExp = 0; 15587 fis->d.lbaHighExp = 0; 15588 fis->d.featuresExp = 0; 15589 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 15590 fis->d.sectorCountExp = 0; 15591 fis->d.reserved4 = 0; 15592 fis->d.control = 0; /* FIS HOB bit clear */ 15593 fis->d.reserved5 = 0; 15594 15595 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 15596 satIOContext->ATACmd = SAT_WRITE_SECTORS; 15597 } 15598 } 15599 15600 /* case 3 and 4 */ 15601 if (pSatDevData->sat48BitSupport == agTRUE) 15602 { 15603 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 15604 { 15605 /* case 3 */ 15606 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 15607 TI_DBG5(("satWriteAndVerify16: case 3\n")); 15608 fis->h.fisType = 0x27; /* Reg host to device */ 15609 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15610 15611 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 15612 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 15613 15614 fis->h.features = 0; /* FIS reserve */ 15615 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 15616 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 15617 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 15618 fis->d.device = 0x40; /* FIS LBA mode set */ 15619 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 15620 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 15621 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 15622 fis->d.featuresExp = 0; /* FIS reserve */ 15623 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 15624 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 15625 fis->d.reserved4 = 0; 15626 fis->d.control = 0; /* FIS HOB bit clear */ 15627 fis->d.reserved5 = 0; 15628 15629 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 15630 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 15631 } 15632 else 15633 { 15634 /* case 4 */ 15635 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 15636 /* WRITE SECTORS EXT for easier implemetation */ 15637 TI_DBG5(("satWriteAndVerify16: case 4\n")); 15638 fis->h.fisType = 0x27; /* Reg host to device */ 15639 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15640 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 15641 15642 fis->h.features = 0; /* FIS reserve */ 15643 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 15644 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 15645 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 15646 fis->d.device = 0x40; /* FIS LBA mode set */ 15647 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 15648 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 15649 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 15650 fis->d.featuresExp = 0; /* FIS reserve */ 15651 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 15652 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 15653 fis->d.reserved4 = 0; 15654 fis->d.control = 0; /* FIS HOB bit clear */ 15655 fis->d.reserved5 = 0; 15656 15657 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 15658 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 15659 } 15660 } 15661 15662 /* case 5 */ 15663 if (pSatDevData->satNCQ == agTRUE) 15664 { 15665 /* WRITE FPDMA QUEUED */ 15666 if (pSatDevData->sat48BitSupport != agTRUE) 15667 { 15668 TI_DBG5(("satWriteAndVerify16: case 5 !!! error NCQ but 28 bit address support \n")); 15669 satSetSensePayload( pSense, 15670 SCSI_SNSKEY_ILLEGAL_REQUEST, 15671 0, 15672 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15673 satIOContext); 15674 15675 ostiInitiatorIOCompleted( tiRoot, 15676 tiIORequest, 15677 tiIOSuccess, 15678 SCSI_STAT_CHECK_CONDITION, 15679 satIOContext->pTiSenseData, 15680 satIOContext->interruptContext ); 15681 return tiSuccess; 15682 } 15683 TI_DBG6(("satWriteAndVerify16: case 5\n")); 15684 15685 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 15686 15687 fis->h.fisType = 0x27; /* Reg host to device */ 15688 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15689 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 15690 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 15691 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 15692 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 15693 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 15694 15695 /* Check FUA bit */ 15696 if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK) 15697 fis->d.device = 0xC0; /* FIS FUA set */ 15698 else 15699 fis->d.device = 0x40; /* FIS FUA clear */ 15700 15701 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 15702 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 15703 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 15704 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 15705 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 15706 fis->d.sectorCountExp = 0; 15707 fis->d.reserved4 = 0; 15708 fis->d.control = 0; /* FIS HOB bit clear */ 15709 fis->d.reserved5 = 0; 15710 15711 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 15712 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 15713 } 15714 15715 satIOContext->currentLBA = lba; 15716 satIOContext->OrgTL = tl; 15717 15718 /* 15719 computing number of loop and remainder for tl 15720 0xFF in case not ext 15721 0xFFFF in case EXT 15722 */ 15723 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 15724 { 15725 LoopNum = satComputeLoopNum(tl, 0xFF); 15726 } 15727 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 15728 fis->h.command == SAT_WRITE_DMA_EXT || 15729 fis->h.command == SAT_WRITE_DMA_FUA_EXT 15730 ) 15731 { 15732 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 15733 LoopNum = satComputeLoopNum(tl, 0xFFFF); 15734 } 15735 else 15736 { 15737 /* SAT_WRITE_FPDMA_QUEUEDK */ 15738 LoopNum = satComputeLoopNum(tl, 0xFFFF); 15739 } 15740 15741 satIOContext->LoopNum = LoopNum; 15742 15743 15744 if (LoopNum == 1) 15745 { 15746 TI_DBG5(("satWriteAndVerify16: NON CHAINED data\n")); 15747 /* Initialize CB for SATA completion. 15748 */ 15749 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB; 15750 } 15751 else 15752 { 15753 TI_DBG1(("satWriteAndVerify16: CHAINED data\n")); 15754 /* re-setting tl */ 15755 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 15756 { 15757 fis->d.sectorCount = 0xFF; 15758 } 15759 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 15760 fis->h.command == SAT_WRITE_DMA_EXT || 15761 fis->h.command == SAT_WRITE_DMA_FUA_EXT 15762 ) 15763 { 15764 fis->d.sectorCount = 0xFF; 15765 fis->d.sectorCountExp = 0xFF; 15766 } 15767 else 15768 { 15769 /* SAT_WRITE_FPDMA_QUEUED */ 15770 fis->h.features = 0xFF; 15771 fis->d.featuresExp = 0xFF; 15772 } 15773 15774 /* Initialize CB for SATA completion. 15775 */ 15776 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB; 15777 } 15778 15779 15780 /* 15781 * Prepare SGL and send FIS to LL layer. 15782 */ 15783 satIOContext->reqType = agRequestType; /* Save it */ 15784 15785 status = sataLLIOStart( tiRoot, 15786 tiIORequest, 15787 tiDeviceHandle, 15788 tiScsiRequest, 15789 satIOContext); 15790 return (status); 15791 } 15792 15793 /*****************************************************************************/ 15794 /*! \brief SAT implementation for SCSI satReadMediaSerialNumber. 15795 * 15796 * SAT implementation for SCSI Read Media Serial Number. 15797 * 15798 * \param tiRoot: Pointer to TISA initiator driver/port instance. 15799 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 15800 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 15801 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 15802 * \param satIOContext_t: Pointer to the SAT IO Context 15803 * 15804 * \return If command is started successfully 15805 * - \e tiSuccess: I/O request successfully initiated. 15806 * - \e tiBusy: No resources available, try again later. 15807 * - \e tiIONoDevice: Invalid device handle. 15808 * - \e tiError: Other errors. 15809 */ 15810 /*****************************************************************************/ 15811 GLOBAL bit32 satReadMediaSerialNumber( 15812 tiRoot_t *tiRoot, 15813 tiIORequest_t *tiIORequest, 15814 tiDeviceHandle_t *tiDeviceHandle, 15815 tiScsiInitiatorRequest_t *tiScsiRequest, 15816 satIOContext_t *satIOContext) 15817 { 15818 bit32 status; 15819 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 15820 satDeviceData_t *pSatDevData; 15821 scsiRspSense_t *pSense; 15822 tiIniScsiCmnd_t *scsiCmnd; 15823 agsaFisRegHostToDevice_t *fis; 15824 agsaSATAIdentifyData_t *pSATAIdData; 15825 bit8 *pSerialNumber; 15826 15827 pSense = satIOContext->pSense; 15828 pSatDevData = satIOContext->pSatDevData; 15829 scsiCmnd = &tiScsiRequest->scsiCmnd; 15830 fis = satIOContext->pFis; 15831 pSATAIdData = &(pSatDevData->satIdentifyData); 15832 pSerialNumber = (bit8 *) tiScsiRequest->sglVirtualAddr; 15833 15834 15835 TI_DBG1(("satReadMediaSerialNumber: start\n")); 15836 15837 /* checking CONTROL */ 15838 /* NACA == 1 or LINK == 1*/ 15839 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) ) 15840 { 15841 satSetSensePayload( pSense, 15842 SCSI_SNSKEY_ILLEGAL_REQUEST, 15843 0, 15844 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15845 satIOContext); 15846 15847 ostiInitiatorIOCompleted( tiRoot, 15848 tiIORequest, 15849 tiIOSuccess, 15850 SCSI_STAT_CHECK_CONDITION, 15851 satIOContext->pTiSenseData, 15852 satIOContext->interruptContext ); 15853 15854 TI_DBG1(("satReadMediaSerialNumber: return control\n")); 15855 return tiSuccess; 15856 } 15857 15858 if (tiScsiRequest->scsiCmnd.expDataLength == 4) 15859 { 15860 if (pSATAIdData->commandSetFeatureDefault & 0x4) 15861 { 15862 TI_DBG1(("satReadMediaSerialNumber: Media serial number returning only length\n")); 15863 /* SPC-3 6.16 p192; filling in length */ 15864 pSerialNumber[0] = 0; 15865 pSerialNumber[1] = 0; 15866 pSerialNumber[2] = 0; 15867 pSerialNumber[3] = 0x3C; 15868 } 15869 else 15870 { 15871 /* 1 sector - 4 = 512 - 4 to avoid underflow; 0x1fc*/ 15872 pSerialNumber[0] = 0; 15873 pSerialNumber[1] = 0; 15874 pSerialNumber[2] = 0x1; 15875 pSerialNumber[3] = 0xfc; 15876 } 15877 15878 ostiInitiatorIOCompleted( tiRoot, 15879 tiIORequest, 15880 tiIOSuccess, 15881 SCSI_STAT_GOOD, 15882 agNULL, 15883 satIOContext->interruptContext); 15884 15885 return tiSuccess; 15886 } 15887 15888 if ( pSatDevData->IDDeviceValid == agTRUE) 15889 { 15890 if (pSATAIdData->commandSetFeatureDefault & 0x4) 15891 { 15892 /* word87 bit2 Media serial number is valid */ 15893 /* read word 176 to 205; length is 2*30 = 60 = 0x3C*/ 15894 tdhexdump("ID satReadMediaSerialNumber", (bit8*)pSATAIdData->currentMediaSerialNumber, 2*30); 15895 /* SPC-3 6.16 p192; filling in length */ 15896 pSerialNumber[0] = 0; 15897 pSerialNumber[1] = 0; 15898 pSerialNumber[2] = 0; 15899 pSerialNumber[3] = 0x3C; 15900 osti_memcpy(&pSerialNumber[4], (void *)pSATAIdData->currentMediaSerialNumber, 60); 15901 tdhexdump("satReadMediaSerialNumber", (bit8*)pSerialNumber, 2*30 + 4); 15902 15903 ostiInitiatorIOCompleted( tiRoot, 15904 tiIORequest, 15905 tiIOSuccess, 15906 SCSI_STAT_GOOD, 15907 agNULL, 15908 satIOContext->interruptContext); 15909 return tiSuccess; 15910 15911 15912 } 15913 else 15914 { 15915 /* word87 bit2 Media serial number is NOT valid */ 15916 TI_DBG1(("satReadMediaSerialNumber: Media serial number is NOT valid \n")); 15917 15918 if (pSatDevData->sat48BitSupport == agTRUE) 15919 { 15920 /* READ VERIFY SECTORS EXT */ 15921 fis->h.fisType = 0x27; /* Reg host to device */ 15922 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15923 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 15924 15925 fis->h.features = 0; /* FIS reserve */ 15926 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 15927 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 15928 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 15929 fis->d.device = 0x40; /* FIS LBA mode set */ 15930 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 15931 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 15932 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 15933 fis->d.featuresExp = 0; /* FIS reserve */ 15934 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 15935 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 15936 fis->d.reserved4 = 0; 15937 fis->d.control = 0; /* FIS HOB bit clear */ 15938 fis->d.reserved5 = 0; 15939 15940 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 15941 } 15942 else 15943 { 15944 /* READ VERIFY SECTORS */ 15945 fis->h.fisType = 0x27; /* Reg host to device */ 15946 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15947 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 15948 fis->h.features = 0; /* FIS reserve */ 15949 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 15950 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 15951 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 15952 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */ 15953 fis->d.lbaLowExp = 0; 15954 fis->d.lbaMidExp = 0; 15955 fis->d.lbaHighExp = 0; 15956 fis->d.featuresExp = 0; 15957 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 15958 fis->d.sectorCountExp = 0; 15959 fis->d.reserved4 = 0; 15960 fis->d.control = 0; /* FIS HOB bit clear */ 15961 fis->d.reserved5 = 0; 15962 15963 15964 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 15965 } 15966 satIOContext->satCompleteCB = &satReadMediaSerialNumberCB; 15967 satIOContext->reqType = agRequestType; /* Save it */ 15968 status = sataLLIOStart( tiRoot, 15969 tiIORequest, 15970 tiDeviceHandle, 15971 tiScsiRequest, 15972 satIOContext); 15973 15974 return status; 15975 } 15976 } 15977 else 15978 { 15979 /* temporary failure */ 15980 ostiInitiatorIOCompleted( tiRoot, 15981 tiIORequest, 15982 tiIOFailed, 15983 tiDetailOtherError, 15984 agNULL, 15985 satIOContext->interruptContext); 15986 15987 return tiSuccess; 15988 15989 } 15990 15991 } 15992 15993 /*****************************************************************************/ 15994 /*! \brief SAT implementation for SCSI satReadBuffer. 15995 * 15996 * SAT implementation for SCSI Read Buffer. 15997 * 15998 * \param tiRoot: Pointer to TISA initiator driver/port instance. 15999 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 16000 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 16001 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 16002 * \param satIOContext_t: Pointer to the SAT IO Context 16003 * 16004 * \return If command is started successfully 16005 * - \e tiSuccess: I/O request successfully initiated. 16006 * - \e tiBusy: No resources available, try again later. 16007 * - \e tiIONoDevice: Invalid device handle. 16008 * - \e tiError: Other errors. 16009 */ 16010 /*****************************************************************************/ 16011 /* SAT-2, Revision 00*/ 16012 GLOBAL bit32 satReadBuffer( 16013 tiRoot_t *tiRoot, 16014 tiIORequest_t *tiIORequest, 16015 tiDeviceHandle_t *tiDeviceHandle, 16016 tiScsiInitiatorRequest_t *tiScsiRequest, 16017 satIOContext_t *satIOContext) 16018 { 16019 bit32 status = tiSuccess; 16020 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 16021 scsiRspSense_t *pSense; 16022 tiIniScsiCmnd_t *scsiCmnd; 16023 agsaFisRegHostToDevice_t *fis; 16024 bit32 bufferOffset; 16025 bit32 tl; 16026 bit8 mode; 16027 bit8 bufferID; 16028 bit8 *pBuff; 16029 16030 pSense = satIOContext->pSense; 16031 scsiCmnd = &tiScsiRequest->scsiCmnd; 16032 fis = satIOContext->pFis; 16033 pBuff = (bit8 *) tiScsiRequest->sglVirtualAddr; 16034 16035 TI_DBG2(("satReadBuffer: start\n")); 16036 /* checking CONTROL */ 16037 /* NACA == 1 or LINK == 1*/ 16038 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 16039 { 16040 satSetSensePayload( pSense, 16041 SCSI_SNSKEY_ILLEGAL_REQUEST, 16042 0, 16043 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16044 satIOContext); 16045 ostiInitiatorIOCompleted( tiRoot, 16046 tiIORequest, 16047 tiIOSuccess, 16048 SCSI_STAT_CHECK_CONDITION, 16049 satIOContext->pTiSenseData, 16050 satIOContext->interruptContext ); 16051 TI_DBG1(("satReadBuffer: return control\n")); 16052 return tiSuccess; 16053 } 16054 16055 bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 16056 tl = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 16057 16058 mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK); 16059 bufferID = scsiCmnd->cdb[2]; 16060 16061 if (mode == READ_BUFFER_DATA_MODE) /* 2 */ 16062 { 16063 if (bufferID == 0 && bufferOffset == 0 && tl == 512) 16064 { 16065 /* send ATA READ BUFFER */ 16066 fis->h.fisType = 0x27; /* Reg host to device */ 16067 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16068 fis->h.command = SAT_READ_BUFFER; /* 0xE4 */ 16069 fis->h.features = 0; /* FIS reserve */ 16070 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 16071 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 16072 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 16073 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */ 16074 fis->d.lbaLowExp = 0; 16075 fis->d.lbaMidExp = 0; 16076 fis->d.lbaHighExp = 0; 16077 fis->d.featuresExp = 0; 16078 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 16079 fis->d.sectorCountExp = 0; 16080 fis->d.reserved4 = 0; 16081 fis->d.control = 0; /* FIS HOB bit clear */ 16082 fis->d.reserved5 = 0; 16083 16084 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 16085 satIOContext->satCompleteCB = &satReadBufferCB; 16086 satIOContext->reqType = agRequestType; /* Save it */ 16087 16088 status = sataLLIOStart( tiRoot, 16089 tiIORequest, 16090 tiDeviceHandle, 16091 tiScsiRequest, 16092 satIOContext); 16093 return status; 16094 } 16095 if (bufferID == 0 && bufferOffset == 0 && tl != 512) 16096 { 16097 satSetSensePayload( pSense, 16098 SCSI_SNSKEY_ILLEGAL_REQUEST, 16099 0, 16100 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16101 satIOContext); 16102 ostiInitiatorIOCompleted( tiRoot, 16103 tiIORequest, 16104 tiIOSuccess, 16105 SCSI_STAT_CHECK_CONDITION, 16106 satIOContext->pTiSenseData, 16107 satIOContext->interruptContext ); 16108 TI_DBG1(("satReadBuffer: allocation length is not 512; it is %d\n", tl)); 16109 return tiSuccess; 16110 } 16111 if (bufferID == 0 && bufferOffset != 0) 16112 { 16113 satSetSensePayload( pSense, 16114 SCSI_SNSKEY_ILLEGAL_REQUEST, 16115 0, 16116 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16117 satIOContext); 16118 ostiInitiatorIOCompleted( tiRoot, 16119 tiIORequest, 16120 tiIOSuccess, 16121 SCSI_STAT_CHECK_CONDITION, 16122 satIOContext->pTiSenseData, 16123 satIOContext->interruptContext ); 16124 TI_DBG1(("satReadBuffer: buffer offset is not 0; it is %d\n", bufferOffset)); 16125 return tiSuccess; 16126 } 16127 /* all other cases unsupported */ 16128 TI_DBG1(("satReadBuffer: unsupported case 1\n")); 16129 satSetSensePayload( pSense, 16130 SCSI_SNSKEY_ILLEGAL_REQUEST, 16131 0, 16132 SCSI_SNSCODE_INVALID_COMMAND, 16133 satIOContext); 16134 16135 ostiInitiatorIOCompleted( tiRoot, 16136 tiIORequest, 16137 tiIOSuccess, 16138 SCSI_STAT_CHECK_CONDITION, 16139 satIOContext->pTiSenseData, 16140 satIOContext->interruptContext ); 16141 return tiSuccess; 16142 } 16143 else if (mode == READ_BUFFER_DESCRIPTOR_MODE) /* 3 */ 16144 { 16145 if (tl < READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN) /* 4 */ 16146 { 16147 satSetSensePayload( pSense, 16148 SCSI_SNSKEY_ILLEGAL_REQUEST, 16149 0, 16150 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16151 satIOContext); 16152 ostiInitiatorIOCompleted( tiRoot, 16153 tiIORequest, 16154 tiIOSuccess, 16155 SCSI_STAT_CHECK_CONDITION, 16156 satIOContext->pTiSenseData, 16157 satIOContext->interruptContext ); 16158 TI_DBG1(("satReadBuffer: tl < 4; tl is %d\n", tl)); 16159 return tiSuccess; 16160 } 16161 if (bufferID == 0) 16162 { 16163 /* SPC-4, 6.15.5, p189; SAT-2 Rev00, 8.7.2.3, p41*/ 16164 pBuff[0] = 0xFF; 16165 pBuff[1] = 0x00; 16166 pBuff[2] = 0x02; 16167 pBuff[3] = 0x00; 16168 if (READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN < tl) 16169 { 16170 /* underrrun */ 16171 TI_DBG1(("satReadBuffer: underrun tl %d data %d\n", tl, READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN)); 16172 ostiInitiatorIOCompleted( tiRoot, 16173 tiIORequest, 16174 tiIOUnderRun, 16175 tl - READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN, 16176 agNULL, 16177 satIOContext->interruptContext ); 16178 return tiSuccess; 16179 } 16180 else 16181 { 16182 ostiInitiatorIOCompleted( tiRoot, 16183 tiIORequest, 16184 tiIOSuccess, 16185 SCSI_STAT_GOOD, 16186 agNULL, 16187 satIOContext->interruptContext); 16188 return tiSuccess; 16189 } 16190 } 16191 else 16192 { 16193 /* We don't support other than bufferID 0 */ 16194 satSetSensePayload( pSense, 16195 SCSI_SNSKEY_ILLEGAL_REQUEST, 16196 0, 16197 SCSI_SNSCODE_INVALID_COMMAND, 16198 satIOContext); 16199 16200 ostiInitiatorIOCompleted( tiRoot, 16201 tiIORequest, 16202 tiIOSuccess, 16203 SCSI_STAT_CHECK_CONDITION, 16204 satIOContext->pTiSenseData, 16205 satIOContext->interruptContext ); 16206 return tiSuccess; 16207 } 16208 } 16209 else 16210 { 16211 /* We don't support any other mode */ 16212 TI_DBG1(("satReadBuffer: unsupported mode %d\n", mode)); 16213 satSetSensePayload( pSense, 16214 SCSI_SNSKEY_ILLEGAL_REQUEST, 16215 0, 16216 SCSI_SNSCODE_INVALID_COMMAND, 16217 satIOContext); 16218 16219 ostiInitiatorIOCompleted( tiRoot, 16220 tiIORequest, 16221 tiIOSuccess, 16222 SCSI_STAT_CHECK_CONDITION, 16223 satIOContext->pTiSenseData, 16224 satIOContext->interruptContext ); 16225 return tiSuccess; 16226 } 16227 } 16228 16229 /*****************************************************************************/ 16230 /*! \brief SAT implementation for SCSI satWriteBuffer. 16231 * 16232 * SAT implementation for SCSI Write Buffer. 16233 * 16234 * \param tiRoot: Pointer to TISA initiator driver/port instance. 16235 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 16236 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 16237 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 16238 * \param satIOContext_t: Pointer to the SAT IO Context 16239 * 16240 * \return If command is started successfully 16241 * - \e tiSuccess: I/O request successfully initiated. 16242 * - \e tiBusy: No resources available, try again later. 16243 * - \e tiIONoDevice: Invalid device handle. 16244 * - \e tiError: Other errors. 16245 */ 16246 /*****************************************************************************/ 16247 /* SAT-2, Revision 00*/ 16248 GLOBAL bit32 satWriteBuffer( 16249 tiRoot_t *tiRoot, 16250 tiIORequest_t *tiIORequest, 16251 tiDeviceHandle_t *tiDeviceHandle, 16252 tiScsiInitiatorRequest_t *tiScsiRequest, 16253 satIOContext_t *satIOContext) 16254 { 16255 #ifdef NOT_YET 16256 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 16257 #endif 16258 scsiRspSense_t *pSense; 16259 tiIniScsiCmnd_t *scsiCmnd; 16260 bit32 bufferOffset; 16261 bit32 parmLen; 16262 bit8 mode; 16263 bit8 bufferID; 16264 bit8 *pBuff; 16265 16266 pSense = satIOContext->pSense; 16267 scsiCmnd = &tiScsiRequest->scsiCmnd; 16268 pBuff = (bit8 *) tiScsiRequest->sglVirtualAddr; 16269 16270 TI_DBG2(("satWriteBuffer: start\n")); 16271 16272 /* checking CONTROL */ 16273 /* NACA == 1 or LINK == 1*/ 16274 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 16275 { 16276 satSetSensePayload( pSense, 16277 SCSI_SNSKEY_ILLEGAL_REQUEST, 16278 0, 16279 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16280 satIOContext); 16281 16282 ostiInitiatorIOCompleted( tiRoot, 16283 tiIORequest, 16284 tiIOSuccess, 16285 SCSI_STAT_CHECK_CONDITION, 16286 satIOContext->pTiSenseData, 16287 satIOContext->interruptContext ); 16288 16289 TI_DBG1(("satWriteBuffer: return control\n")); 16290 return tiSuccess; 16291 } 16292 16293 bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 16294 parmLen = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 16295 16296 mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK); 16297 bufferID = scsiCmnd->cdb[2]; 16298 16299 /* for debugging only */ 16300 tdhexdump("satWriteBuffer pBuff", (bit8 *)pBuff, 24); 16301 16302 if (mode == WRITE_BUFFER_DATA_MODE) /* 2 */ 16303 { 16304 if (bufferID == 0 && bufferOffset == 0 && parmLen == 512) 16305 { 16306 TI_DBG1(("satWriteBuffer: sending ATA WRITE BUFFER\n")); 16307 /* send ATA WRITE BUFFER */ 16308 #ifdef NOT_YET 16309 fis->h.fisType = 0x27; /* Reg host to device */ 16310 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16311 fis->h.command = SAT_WRITE_BUFFER; /* 0xE8 */ 16312 fis->h.features = 0; /* FIS reserve */ 16313 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 16314 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 16315 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 16316 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */ 16317 fis->d.lbaLowExp = 0; 16318 fis->d.lbaMidExp = 0; 16319 fis->d.lbaHighExp = 0; 16320 fis->d.featuresExp = 0; 16321 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 16322 fis->d.sectorCountExp = 0; 16323 fis->d.reserved4 = 0; 16324 fis->d.control = 0; /* FIS HOB bit clear */ 16325 fis->d.reserved5 = 0; 16326 16327 16328 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 16329 16330 satIOContext->satCompleteCB = &satWriteBufferCB; 16331 16332 satIOContext->reqType = agRequestType; /* Save it */ 16333 16334 status = sataLLIOStart( tiRoot, 16335 tiIORequest, 16336 tiDeviceHandle, 16337 tiScsiRequest, 16338 satIOContext); 16339 return status; 16340 #endif 16341 /* temp */ 16342 ostiInitiatorIOCompleted( tiRoot, 16343 tiIORequest, 16344 tiIOSuccess, 16345 SCSI_STAT_GOOD, 16346 agNULL, 16347 satIOContext->interruptContext); 16348 return tiSuccess; 16349 } 16350 if ( (bufferID == 0 && bufferOffset != 0) || 16351 (bufferID == 0 && parmLen != 512) 16352 ) 16353 { 16354 satSetSensePayload( pSense, 16355 SCSI_SNSKEY_ILLEGAL_REQUEST, 16356 0, 16357 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16358 satIOContext); 16359 16360 ostiInitiatorIOCompleted( tiRoot, 16361 tiIORequest, 16362 tiIOSuccess, 16363 SCSI_STAT_CHECK_CONDITION, 16364 satIOContext->pTiSenseData, 16365 satIOContext->interruptContext ); 16366 16367 TI_DBG1(("satWriteBuffer: wrong buffer offset %d or parameter length parmLen %d\n", bufferOffset, parmLen)); 16368 return tiSuccess; 16369 } 16370 16371 /* all other cases unsupported */ 16372 TI_DBG1(("satWriteBuffer: unsupported case 1\n")); 16373 satSetSensePayload( pSense, 16374 SCSI_SNSKEY_ILLEGAL_REQUEST, 16375 0, 16376 SCSI_SNSCODE_INVALID_COMMAND, 16377 satIOContext); 16378 16379 ostiInitiatorIOCompleted( tiRoot, 16380 tiIORequest, 16381 tiIOSuccess, 16382 SCSI_STAT_CHECK_CONDITION, 16383 satIOContext->pTiSenseData, 16384 satIOContext->interruptContext ); 16385 16386 return tiSuccess; 16387 16388 } 16389 else if (mode == WRITE_BUFFER_DL_MICROCODE_SAVE_MODE) /* 5 */ 16390 { 16391 TI_DBG1(("satWriteBuffer: not yet supported mode %d\n", mode)); 16392 satSetSensePayload( pSense, 16393 SCSI_SNSKEY_ILLEGAL_REQUEST, 16394 0, 16395 SCSI_SNSCODE_INVALID_COMMAND, 16396 satIOContext); 16397 16398 ostiInitiatorIOCompleted( tiRoot, 16399 tiIORequest, 16400 tiIOSuccess, 16401 SCSI_STAT_CHECK_CONDITION, 16402 satIOContext->pTiSenseData, 16403 satIOContext->interruptContext ); 16404 16405 return tiSuccess; 16406 } 16407 else 16408 { 16409 /* We don't support any other mode */ 16410 TI_DBG1(("satWriteBuffer: unsupported mode %d\n", mode)); 16411 satSetSensePayload( pSense, 16412 SCSI_SNSKEY_ILLEGAL_REQUEST, 16413 0, 16414 SCSI_SNSCODE_INVALID_COMMAND, 16415 satIOContext); 16416 16417 ostiInitiatorIOCompleted( tiRoot, 16418 tiIORequest, 16419 tiIOSuccess, 16420 SCSI_STAT_CHECK_CONDITION, 16421 satIOContext->pTiSenseData, 16422 satIOContext->interruptContext ); 16423 16424 return tiSuccess; 16425 } 16426 16427 } 16428 16429 /*****************************************************************************/ 16430 /*! \brief SAT implementation for SCSI satReassignBlocks. 16431 * 16432 * SAT implementation for SCSI Reassign Blocks. 16433 * 16434 * \param tiRoot: Pointer to TISA initiator driver/port instance. 16435 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 16436 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 16437 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 16438 * \param satIOContext_t: Pointer to the SAT IO Context 16439 * 16440 * \return If command is started successfully 16441 * - \e tiSuccess: I/O request successfully initiated. 16442 * - \e tiBusy: No resources available, try again later. 16443 * - \e tiIONoDevice: Invalid device handle. 16444 * - \e tiError: Other errors. 16445 */ 16446 /*****************************************************************************/ 16447 GLOBAL bit32 satReassignBlocks( 16448 tiRoot_t *tiRoot, 16449 tiIORequest_t *tiIORequest, 16450 tiDeviceHandle_t *tiDeviceHandle, 16451 tiScsiInitiatorRequest_t *tiScsiRequest, 16452 satIOContext_t *satIOContext) 16453 { 16454 /* 16455 assumes all LBA fits in ATA command; no boundary condition is checked here yet 16456 */ 16457 bit32 status; 16458 bit32 agRequestType; 16459 satDeviceData_t *pSatDevData; 16460 scsiRspSense_t *pSense; 16461 tiIniScsiCmnd_t *scsiCmnd; 16462 agsaFisRegHostToDevice_t *fis; 16463 bit8 *pParmList; /* Log Page data buffer */ 16464 bit8 LongLBA; 16465 bit8 LongList; 16466 bit32 defectListLen; 16467 bit8 LBA[8]; 16468 bit32 startingIndex; 16469 16470 pSense = satIOContext->pSense; 16471 pSatDevData = satIOContext->pSatDevData; 16472 scsiCmnd = &tiScsiRequest->scsiCmnd; 16473 fis = satIOContext->pFis; 16474 pParmList = (bit8 *) tiScsiRequest->sglVirtualAddr; 16475 16476 TI_DBG5(("satReassignBlocks: start\n")); 16477 16478 /* checking CONTROL */ 16479 /* NACA == 1 or LINK == 1*/ 16480 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 16481 { 16482 satSetSensePayload( pSense, 16483 SCSI_SNSKEY_ILLEGAL_REQUEST, 16484 0, 16485 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16486 satIOContext); 16487 16488 ostiInitiatorIOCompleted( tiRoot, 16489 tiIORequest, 16490 tiIOSuccess, 16491 SCSI_STAT_CHECK_CONDITION, 16492 satIOContext->pTiSenseData, 16493 satIOContext->interruptContext ); 16494 16495 TI_DBG1(("satReassignBlocks: return control\n")); 16496 return tiSuccess; 16497 } 16498 16499 osti_memset(satIOContext->LBA, 0, 8); 16500 satIOContext->ParmIndex = 0; 16501 satIOContext->ParmLen = 0; 16502 16503 LongList = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLIST_MASK); 16504 LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK); 16505 osti_memset(LBA, 0, sizeof(LBA)); 16506 16507 if (LongList == 0) 16508 { 16509 defectListLen = (pParmList[2] << 8) + pParmList[3]; 16510 } 16511 else 16512 { 16513 defectListLen = (pParmList[0] << (8*3)) + (pParmList[1] << (8*2)) 16514 + (pParmList[2] << 8) + pParmList[3]; 16515 } 16516 /* SBC 5.16.2, p61*/ 16517 satIOContext->ParmLen = defectListLen + 4 /* header size */; 16518 16519 startingIndex = 4; 16520 16521 if (LongLBA == 0) 16522 { 16523 LBA[4] = pParmList[startingIndex]; /* MSB */ 16524 LBA[5] = pParmList[startingIndex+1]; 16525 LBA[6] = pParmList[startingIndex+2]; 16526 LBA[7] = pParmList[startingIndex+3]; /* LSB */ 16527 startingIndex = startingIndex + 4; 16528 } 16529 else 16530 { 16531 LBA[0] = pParmList[startingIndex]; /* MSB */ 16532 LBA[1] = pParmList[startingIndex+1]; 16533 LBA[2] = pParmList[startingIndex+2]; 16534 LBA[3] = pParmList[startingIndex+3]; 16535 LBA[4] = pParmList[startingIndex+4]; 16536 LBA[5] = pParmList[startingIndex+5]; 16537 LBA[6] = pParmList[startingIndex+6]; 16538 LBA[7] = pParmList[startingIndex+7]; /* LSB */ 16539 startingIndex = startingIndex + 8; 16540 } 16541 16542 tdhexdump("satReassignBlocks Parameter list", (bit8 *)pParmList, 4 + defectListLen); 16543 16544 if (pSatDevData->sat48BitSupport == agTRUE) 16545 { 16546 /* sends READ VERIFY SECTOR(S) EXT*/ 16547 fis->h.fisType = 0x27; /* Reg host to device */ 16548 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16549 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 16550 fis->h.features = 0; /* FIS reserve */ 16551 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 16552 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 16553 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 16554 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */ 16555 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */ 16556 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */ 16557 fis->d.featuresExp = 0; /* FIS reserve */ 16558 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 16559 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 16560 fis->d.reserved4 = 0; 16561 fis->d.device = 0x40; /* 01000000 */ 16562 fis->d.control = 0; /* FIS HOB bit clear */ 16563 fis->d.reserved5 = 0; 16564 } 16565 else 16566 { 16567 /* READ VERIFY SECTOR(S)*/ 16568 fis->h.fisType = 0x27; /* Reg host to device */ 16569 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16570 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 16571 fis->h.features = 0; /* FIS features NA */ 16572 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 16573 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 16574 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 16575 fis->d.lbaLowExp = 0; 16576 fis->d.lbaMidExp = 0; 16577 fis->d.lbaHighExp = 0; 16578 fis->d.featuresExp = 0; 16579 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 16580 fis->d.sectorCountExp = 0; 16581 fis->d.reserved4 = 0; 16582 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF)); 16583 /* DEV and LBA 27:24 */ 16584 fis->d.control = 0; /* FIS HOB bit clear */ 16585 fis->d.reserved5 = 0; 16586 } 16587 16588 osti_memcpy(satIOContext->LBA, LBA, 8); 16589 satIOContext->ParmIndex = startingIndex; 16590 16591 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 16592 16593 /* Initialize CB for SATA completion. 16594 */ 16595 satIOContext->satCompleteCB = &satReassignBlocksCB; 16596 16597 /* 16598 * Prepare SGL and send FIS to LL layer. 16599 */ 16600 satIOContext->reqType = agRequestType; /* Save it */ 16601 16602 status = sataLLIOStart( tiRoot, 16603 tiIORequest, 16604 tiDeviceHandle, 16605 tiScsiRequest, 16606 satIOContext); 16607 16608 return status; 16609 } 16610 16611 /*****************************************************************************/ 16612 /*! \brief SAT implementation for SCSI satReassignBlocks_1. 16613 * 16614 * SAT implementation for SCSI Reassign Blocks. This is helper function for 16615 * satReassignBlocks and satReassignBlocksCB. This sends ATA verify command. 16616 * 16617 * \param tiRoot: Pointer to TISA initiator driver/port instance. 16618 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 16619 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 16620 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 16621 * \param satIOContext_t: Pointer to the SAT IO Context 16622 * 16623 * \return If command is started successfully 16624 * - \e tiSuccess: I/O request successfully initiated. 16625 * - \e tiBusy: No resources available, try again later. 16626 * - \e tiIONoDevice: Invalid device handle. 16627 * - \e tiError: Other errors. 16628 */ 16629 /*****************************************************************************/ 16630 /* next LBA; sends READ VERIFY SECTOR; update LBA and ParmIdx */ 16631 GLOBAL bit32 satReassignBlocks_1( 16632 tiRoot_t *tiRoot, 16633 tiIORequest_t *tiIORequest, 16634 tiDeviceHandle_t *tiDeviceHandle, 16635 tiScsiInitiatorRequest_t *tiScsiRequest, 16636 satIOContext_t *satIOContext, 16637 satIOContext_t *satOrgIOContext 16638 ) 16639 { 16640 /* 16641 assumes all LBA fits in ATA command; no boundary condition is checked here yet 16642 tiScsiRequest is OS generated; needs for accessing parameter list 16643 */ 16644 bit32 agRequestType; 16645 satDeviceData_t *pSatDevData; 16646 tiIniScsiCmnd_t *scsiCmnd; 16647 agsaFisRegHostToDevice_t *fis; 16648 bit8 *pParmList; /* Log Page data buffer */ 16649 bit8 LongLBA; 16650 bit8 LBA[8]; 16651 bit32 startingIndex; 16652 16653 pSatDevData = satIOContext->pSatDevData; 16654 scsiCmnd = &tiScsiRequest->scsiCmnd; 16655 fis = satIOContext->pFis; 16656 pParmList = (bit8 *) tiScsiRequest->sglVirtualAddr; 16657 16658 TI_DBG5(("satReassignBlocks_1: start\n")); 16659 16660 LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK); 16661 osti_memset(LBA, 0, sizeof(LBA)); 16662 16663 startingIndex = satOrgIOContext->ParmIndex; 16664 16665 if (LongLBA == 0) 16666 { 16667 LBA[4] = pParmList[startingIndex]; 16668 LBA[5] = pParmList[startingIndex+1]; 16669 LBA[6] = pParmList[startingIndex+2]; 16670 LBA[7] = pParmList[startingIndex+3]; 16671 startingIndex = startingIndex + 4; 16672 } 16673 else 16674 { 16675 LBA[0] = pParmList[startingIndex]; 16676 LBA[1] = pParmList[startingIndex+1]; 16677 LBA[2] = pParmList[startingIndex+2]; 16678 LBA[3] = pParmList[startingIndex+3]; 16679 LBA[4] = pParmList[startingIndex+4]; 16680 LBA[5] = pParmList[startingIndex+5]; 16681 LBA[6] = pParmList[startingIndex+6]; 16682 LBA[7] = pParmList[startingIndex+7]; 16683 startingIndex = startingIndex + 8; 16684 } 16685 16686 if (pSatDevData->sat48BitSupport == agTRUE) 16687 { 16688 /* sends READ VERIFY SECTOR(S) EXT*/ 16689 fis->h.fisType = 0x27; /* Reg host to device */ 16690 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16691 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 16692 fis->h.features = 0; /* FIS reserve */ 16693 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 16694 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 16695 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 16696 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */ 16697 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */ 16698 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */ 16699 fis->d.featuresExp = 0; /* FIS reserve */ 16700 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 16701 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 16702 fis->d.reserved4 = 0; 16703 fis->d.device = 0x40; /* 01000000 */ 16704 fis->d.control = 0; /* FIS HOB bit clear */ 16705 fis->d.reserved5 = 0; 16706 } 16707 else 16708 { 16709 /* READ VERIFY SECTOR(S)*/ 16710 fis->h.fisType = 0x27; /* Reg host to device */ 16711 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16712 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 16713 fis->h.features = 0; /* FIS features NA */ 16714 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 16715 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 16716 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 16717 fis->d.lbaLowExp = 0; 16718 fis->d.lbaMidExp = 0; 16719 fis->d.lbaHighExp = 0; 16720 fis->d.featuresExp = 0; 16721 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 16722 fis->d.sectorCountExp = 0; 16723 fis->d.reserved4 = 0; 16724 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF)); 16725 /* DEV and LBA 27:24 */ 16726 fis->d.control = 0; /* FIS HOB bit clear */ 16727 fis->d.reserved5 = 0; 16728 } 16729 osti_memcpy(satOrgIOContext->LBA, LBA, 8); 16730 satOrgIOContext->ParmIndex = startingIndex; 16731 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 16732 /* Initialize CB for SATA completion. 16733 */ 16734 satIOContext->satCompleteCB = &satReassignBlocksCB; 16735 /* 16736 * Prepare SGL and send FIS to LL layer. 16737 */ 16738 satIOContext->reqType = agRequestType; /* Save it */ 16739 16740 sataLLIOStart( tiRoot, 16741 tiIORequest, 16742 tiDeviceHandle, 16743 tiScsiRequest, 16744 satIOContext ); 16745 return tiSuccess; 16746 } 16747 16748 /*****************************************************************************/ 16749 /*! \brief SAT implementation for SCSI satReassignBlocks_2. 16750 * 16751 * SAT implementation for SCSI Reassign Blocks. This is helper function for 16752 * satReassignBlocks and satReassignBlocksCB. This sends ATA write command. 16753 * 16754 * \param tiRoot: Pointer to TISA initiator driver/port instance. 16755 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 16756 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 16757 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 16758 * \param satIOContext_t: Pointer to the SAT IO Context 16759 * \param LBA: Pointer to the LBA to be processed 16760 * 16761 * \return If command is started successfully 16762 * - \e tiSuccess: I/O request successfully initiated. 16763 * - \e tiBusy: No resources available, try again later. 16764 * - \e tiIONoDevice: Invalid device handle. 16765 * - \e tiError: Other errors. 16766 */ 16767 /*****************************************************************************/ 16768 /* current LBA; sends WRITE */ 16769 GLOBAL bit32 satReassignBlocks_2( 16770 tiRoot_t *tiRoot, 16771 tiIORequest_t *tiIORequest, 16772 tiDeviceHandle_t *tiDeviceHandle, 16773 tiScsiInitiatorRequest_t *tiScsiRequest, 16774 satIOContext_t *satIOContext, 16775 bit8 *LBA 16776 ) 16777 { 16778 /* 16779 assumes all LBA fits in ATA command; no boundary condition is checked here yet 16780 tiScsiRequest is TD generated for writing 16781 */ 16782 bit32 status; 16783 bit32 agRequestType; 16784 satDeviceData_t *pSatDevData; 16785 scsiRspSense_t *pSense; 16786 agsaFisRegHostToDevice_t *fis; 16787 16788 pSense = satIOContext->pSense; 16789 pSatDevData = satIOContext->pSatDevData; 16790 fis = satIOContext->pFis; 16791 16792 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 16793 { 16794 /* case 2 */ 16795 /* WRITE DMA*/ 16796 /* can't fit the transfer length */ 16797 TI_DBG5(("satReassignBlocks_2: case 2\n")); 16798 fis->h.fisType = 0x27; /* Reg host to device */ 16799 fis->h.c_pmPort = 0x80; /* C bit is set */ 16800 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 16801 fis->h.features = 0; /* FIS reserve */ 16802 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 16803 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 16804 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 16805 16806 /* FIS LBA mode set LBA (27:24) */ 16807 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF)); 16808 16809 fis->d.lbaLowExp = 0; 16810 fis->d.lbaMidExp = 0; 16811 fis->d.lbaHighExp = 0; 16812 fis->d.featuresExp = 0; 16813 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 16814 fis->d.sectorCountExp = 0; 16815 fis->d.reserved4 = 0; 16816 fis->d.control = 0; /* FIS HOB bit clear */ 16817 fis->d.reserved5 = 0; 16818 16819 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 16820 satIOContext->ATACmd = SAT_WRITE_DMA; 16821 } 16822 else 16823 { 16824 /* case 1 */ 16825 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 16826 /* WRITE SECTORS for easier implemetation */ 16827 /* can't fit the transfer length */ 16828 TI_DBG5(("satReassignBlocks_2: case 1\n")); 16829 fis->h.fisType = 0x27; /* Reg host to device */ 16830 fis->h.c_pmPort = 0x80; /* C bit is set */ 16831 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 16832 fis->h.features = 0; /* FIS reserve */ 16833 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 16834 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 16835 fis->d.lbaHigh = LBA[7]; /* FIS LBA (23:16) */ 16836 16837 /* FIS LBA mode set LBA (27:24) */ 16838 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF)); 16839 16840 fis->d.lbaLowExp = 0; 16841 fis->d.lbaMidExp = 0; 16842 fis->d.lbaHighExp = 0; 16843 fis->d.featuresExp = 0; 16844 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 16845 fis->d.sectorCountExp = 0; 16846 fis->d.reserved4 = 0; 16847 fis->d.control = 0; /* FIS HOB bit clear */ 16848 fis->d.reserved5 = 0; 16849 16850 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 16851 satIOContext->ATACmd = SAT_WRITE_SECTORS; 16852 } 16853 16854 /* case 3 and 4 */ 16855 if (pSatDevData->sat48BitSupport == agTRUE) 16856 { 16857 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 16858 { 16859 /* case 3 */ 16860 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 16861 TI_DBG5(("satReassignBlocks_2: case 3\n")); 16862 fis->h.fisType = 0x27; /* Reg host to device */ 16863 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16864 16865 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 16866 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 16867 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 16868 16869 fis->h.features = 0; /* FIS reserve */ 16870 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 16871 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 16872 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 16873 fis->d.device = 0x40; /* FIS LBA mode set */ 16874 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */ 16875 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */ 16876 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */ 16877 fis->d.featuresExp = 0; /* FIS reserve */ 16878 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 16879 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 16880 fis->d.reserved4 = 0; 16881 fis->d.control = 0; /* FIS HOB bit clear */ 16882 fis->d.reserved5 = 0; 16883 16884 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 16885 } 16886 else 16887 { 16888 /* case 4 */ 16889 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 16890 /* WRITE SECTORS EXT for easier implemetation */ 16891 TI_DBG5(("satReassignBlocks_2: case 4\n")); 16892 fis->h.fisType = 0x27; /* Reg host to device */ 16893 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16894 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 16895 16896 fis->h.features = 0; /* FIS reserve */ 16897 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 16898 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 16899 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 16900 fis->d.device = 0x40; /* FIS LBA mode set */ 16901 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */ 16902 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */ 16903 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */ 16904 fis->d.featuresExp = 0; /* FIS reserve */ 16905 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 16906 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 16907 fis->d.reserved4 = 0; 16908 fis->d.control = 0; /* FIS HOB bit clear */ 16909 fis->d.reserved5 = 0; 16910 16911 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 16912 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 16913 } 16914 } 16915 /* case 5 */ 16916 if (pSatDevData->satNCQ == agTRUE) 16917 { 16918 /* WRITE FPDMA QUEUED */ 16919 if (pSatDevData->sat48BitSupport != agTRUE) 16920 { 16921 TI_DBG5(("satReassignBlocks_2: case 5 !!! error NCQ but 28 bit address support \n")); 16922 satSetSensePayload( pSense, 16923 SCSI_SNSKEY_HARDWARE_ERROR, 16924 0, 16925 SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED, 16926 satIOContext); 16927 16928 ostiInitiatorIOCompleted( tiRoot, 16929 tiIORequest, 16930 tiIOSuccess, 16931 SCSI_STAT_CHECK_CONDITION, 16932 satIOContext->pTiSenseData, 16933 satIOContext->interruptContext ); 16934 return tiSuccess; 16935 } 16936 TI_DBG6(("satWrite10: case 5\n")); 16937 16938 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 16939 16940 fis->h.fisType = 0x27; /* Reg host to device */ 16941 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16942 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 16943 fis->h.features = 1; /* FIS sector count (7:0) */ 16944 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 16945 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 16946 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 16947 16948 /* Check FUA bit */ 16949 fis->d.device = 0x40; /* FIS FUA clear */ 16950 16951 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */ 16952 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */ 16953 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */ 16954 fis->d.featuresExp = 0; /* FIS sector count (15:8) */ 16955 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 16956 fis->d.sectorCountExp = 0; 16957 fis->d.reserved4 = 0; 16958 fis->d.control = 0; /* FIS HOB bit clear */ 16959 fis->d.reserved5 = 0; 16960 16961 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 16962 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 16963 } 16964 16965 satIOContext->satCompleteCB = &satReassignBlocksCB; 16966 16967 /* 16968 * Prepare SGL and send FIS to LL layer. 16969 */ 16970 satIOContext->reqType = agRequestType; /* Save it */ 16971 16972 status = sataLLIOStart( tiRoot, 16973 tiIORequest, 16974 tiDeviceHandle, 16975 /* not the original, should be the TD generated one */ 16976 tiScsiRequest, 16977 satIOContext); 16978 return (status); 16979 } 16980 16981 16982 /*****************************************************************************/ 16983 /*! \brief SAT implementation for SCSI satPrepareNewIO. 16984 * 16985 * This function fills in the fields of internal IO generated by TD layer. 16986 * This is mostly used in the callback functions. 16987 * 16988 * \param satNewIntIo: Pointer to the internal IO structure. 16989 * \param tiOrgIORequest: Pointer to the original tiIOrequest sent by OS layer 16990 * \param satDevData: Pointer to the device data. 16991 * \param scsiCmnd: Pointer to SCSI command. 16992 * \param satOrgIOContext: Pointer to the original SAT IO Context 16993 * 16994 * \return 16995 * - \e Pointer to the new SAT IO Context 16996 */ 16997 /*****************************************************************************/ 16998 GLOBAL satIOContext_t *satPrepareNewIO( 16999 satInternalIo_t *satNewIntIo, 17000 tiIORequest_t *tiOrgIORequest, 17001 satDeviceData_t *satDevData, 17002 tiIniScsiCmnd_t *scsiCmnd, 17003 satIOContext_t *satOrgIOContext 17004 ) 17005 { 17006 satIOContext_t *satNewIOContext; 17007 tdIORequestBody_t *tdNewIORequestBody; 17008 17009 TI_DBG2(("satPrepareNewIO: start\n")); 17010 17011 /* the one to be used; good 8/2/07 */ 17012 satNewIntIo->satOrgTiIORequest = tiOrgIORequest; /* this is already done in 17013 satAllocIntIoResource() */ 17014 17015 tdNewIORequestBody = (tdIORequestBody_t *)satNewIntIo->satIntRequestBody; 17016 satNewIOContext = &(tdNewIORequestBody->transport.SATA.satIOContext); 17017 17018 satNewIOContext->pSatDevData = satDevData; 17019 satNewIOContext->pFis = &(tdNewIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 17020 satNewIOContext->pScsiCmnd = &(satNewIntIo->satIntTiScsiXchg.scsiCmnd); 17021 if (scsiCmnd != agNULL) 17022 { 17023 /* saves only CBD; not scsi command for LBA and number of blocks */ 17024 osti_memcpy(satNewIOContext->pScsiCmnd->cdb, scsiCmnd->cdb, 16); 17025 } 17026 satNewIOContext->pSense = &(tdNewIORequestBody->transport.SATA.sensePayload); 17027 satNewIOContext->pTiSenseData = &(tdNewIORequestBody->transport.SATA.tiSenseData); 17028 satNewIOContext->pTiSenseData->senseData = satNewIOContext->pSense; 17029 satNewIOContext->tiRequestBody = satNewIntIo->satIntRequestBody; 17030 satNewIOContext->interruptContext = satNewIOContext->interruptContext; 17031 satNewIOContext->satIntIoContext = satNewIntIo; 17032 satNewIOContext->ptiDeviceHandle = satOrgIOContext->ptiDeviceHandle; 17033 satNewIOContext->satOrgIOContext = satOrgIOContext; 17034 /* saves tiScsiXchg; only for writesame10() */ 17035 satNewIOContext->tiScsiXchg = satOrgIOContext->tiScsiXchg; 17036 17037 return satNewIOContext; 17038 } 17039 /***************************************************************************** 17040 *! \brief satIOAbort 17041 * 17042 * This routine is called to initiate a I/O abort to SATL. 17043 * This routine is independent of HW/LL API. 17044 * 17045 * \param tiRoot: Pointer to TISA initiator driver/port instance. 17046 * \param taskTag: Pointer to TISA I/O request context/tag to be aborted. 17047 * 17048 * \return: 17049 * 17050 * \e tiSuccess: I/O request successfully initiated. 17051 * \e tiBusy: No resources available, try again later. 17052 * \e tiError: Other errors that prevent the I/O request to be started. 17053 * 17054 * 17055 *****************************************************************************/ 17056 GLOBAL bit32 satIOAbort( 17057 tiRoot_t *tiRoot, 17058 tiIORequest_t *taskTag ) 17059 { 17060 17061 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 17062 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 17063 agsaRoot_t *agRoot; 17064 tdIORequestBody_t *tdIORequestBody; 17065 tdIORequestBody_t *tdIONewRequestBody; 17066 agsaIORequest_t *agIORequest; 17067 bit32 status; 17068 agsaIORequest_t *agAbortIORequest; 17069 tdIORequestBody_t *tdAbortIORequestBody; 17070 bit32 PhysUpper32; 17071 bit32 PhysLower32; 17072 bit32 memAllocStatus; 17073 void *osMemHandle; 17074 satIOContext_t *satIOContext; 17075 satInternalIo_t *satIntIo; 17076 17077 TI_DBG2(("satIOAbort: start\n")); 17078 17079 agRoot = &(tdsaAllShared->agRootNonInt); 17080 tdIORequestBody = (tdIORequestBody_t *)taskTag->tdData; 17081 17082 /* needs to distinguish internally generated or externally generated */ 17083 satIOContext = &(tdIORequestBody->transport.SATA.satIOContext); 17084 satIntIo = satIOContext->satIntIoContext; 17085 if (satIntIo == agNULL) 17086 { 17087 TI_DBG1(("satIOAbort: External, OS generated\n")); 17088 agIORequest = &(tdIORequestBody->agIORequest); 17089 } 17090 else 17091 { 17092 TI_DBG1(("satIOAbort: Internal, TD generated\n")); 17093 tdIONewRequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody; 17094 agIORequest = &(tdIONewRequestBody->agIORequest); 17095 } 17096 17097 /* allocating agIORequest for abort itself */ 17098 memAllocStatus = ostiAllocMemory( 17099 tiRoot, 17100 &osMemHandle, 17101 (void **)&tdAbortIORequestBody, 17102 &PhysUpper32, 17103 &PhysLower32, 17104 8, 17105 sizeof(tdIORequestBody_t), 17106 agTRUE 17107 ); 17108 if (memAllocStatus != tiSuccess) 17109 { 17110 /* let os process IO */ 17111 TI_DBG1(("satIOAbort: ostiAllocMemory failed...\n")); 17112 return tiError; 17113 } 17114 17115 if (tdAbortIORequestBody == agNULL) 17116 { 17117 /* let os process IO */ 17118 TI_DBG1(("satIOAbort: ostiAllocMemory returned NULL tdAbortIORequestBody\n")); 17119 return tiError; 17120 } 17121 17122 /* setup task management structure */ 17123 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 17124 tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle; 17125 17126 /* initialize agIORequest */ 17127 agAbortIORequest = &(tdAbortIORequestBody->agIORequest); 17128 agAbortIORequest->osData = (void *) tdAbortIORequestBody; 17129 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */ 17130 17131 /* remember IO to be aborted */ 17132 tdAbortIORequestBody->tiIOToBeAbortedRequest = taskTag; 17133 17134 status = saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agIORequest, agNULL ); 17135 17136 TI_DBG5(("satIOAbort: return status=0x%x\n", status)); 17137 17138 if (status == AGSA_RC_SUCCESS) 17139 return tiSuccess; 17140 else 17141 return tiError; 17142 17143 } 17144 17145 17146 /***************************************************************************** 17147 *! \brief satTM 17148 * 17149 * This routine is called to initiate a TM request to SATL. 17150 * This routine is independent of HW/LL API. 17151 * 17152 * \param tiRoot: Pointer to TISA initiator driver/port instance. 17153 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 17154 * \param task: SAM-3 task management request. 17155 * \param lun: Pointer to LUN. 17156 * \param taskTag: Pointer to the associated task where the TM 17157 * command is to be applied. 17158 * \param currentTaskTag: Pointer to tag/context for this TM request. 17159 * 17160 * \return: 17161 * 17162 * \e tiSuccess: I/O request successfully initiated. 17163 * \e tiBusy: No resources available, try again later. 17164 * \e tiIONoDevice: Invalid device handle. 17165 * \e tiError: Other errors that prevent the I/O request to be started. 17166 * 17167 * 17168 *****************************************************************************/ 17169 /* save task in satIOContext */ 17170 osGLOBAL bit32 satTM( 17171 tiRoot_t *tiRoot, 17172 tiDeviceHandle_t *tiDeviceHandle, 17173 bit32 task, 17174 tiLUN_t *lun, 17175 tiIORequest_t *taskTag, 17176 tiIORequest_t *currentTaskTag, 17177 tdIORequestBody_t *tiRequestBody, 17178 bit32 NotifyOS 17179 ) 17180 { 17181 tdIORequestBody_t *tdIORequestBody = agNULL; 17182 satIOContext_t *satIOContext = agNULL; 17183 tdsaDeviceData_t *oneDeviceData = agNULL; 17184 bit32 status; 17185 17186 TI_DBG3(("satTM: tiDeviceHandle=%p task=0x%x\n", tiDeviceHandle, task )); 17187 17188 /* set satIOContext fields and etc */ 17189 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 17190 17191 17192 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody; 17193 satIOContext = &(tdIORequestBody->transport.SATA.satIOContext); 17194 17195 satIOContext->pSatDevData = &oneDeviceData->satDevData; 17196 satIOContext->pFis = 17197 &tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev; 17198 17199 17200 satIOContext->tiRequestBody = tiRequestBody; 17201 satIOContext->ptiDeviceHandle = tiDeviceHandle; 17202 satIOContext->satIntIoContext = agNULL; 17203 satIOContext->satOrgIOContext = agNULL; 17204 17205 /* followings are used only for internal IO */ 17206 satIOContext->currentLBA = 0; 17207 satIOContext->OrgTL = 0; 17208 17209 /* saving task in satIOContext */ 17210 satIOContext->TMF = task; 17211 17212 satIOContext->satToBeAbortedIOContext = agNULL; 17213 17214 if (NotifyOS == agTRUE) 17215 { 17216 satIOContext->NotifyOS = agTRUE; 17217 } 17218 else 17219 { 17220 satIOContext->NotifyOS = agFALSE; 17221 } 17222 /* 17223 * Our SAT supports RESET LUN and partially support ABORT TASK (only if there 17224 * is no more than one I/O pending on the drive. 17225 */ 17226 17227 if (task == AG_LOGICAL_UNIT_RESET) 17228 { 17229 status = satTmResetLUN( tiRoot, 17230 currentTaskTag, 17231 tiDeviceHandle, 17232 agNULL, 17233 satIOContext, 17234 lun); 17235 return status; 17236 } 17237 #ifdef TO_BE_REMOVED 17238 else if (task == AG_TARGET_WARM_RESET) 17239 { 17240 status = satTmWarmReset( tiRoot, 17241 currentTaskTag, 17242 tiDeviceHandle, 17243 agNULL, 17244 satIOContext); 17245 17246 return status; 17247 } 17248 #endif 17249 else if (task == AG_ABORT_TASK) 17250 { 17251 status = satTmAbortTask( tiRoot, 17252 currentTaskTag, 17253 tiDeviceHandle, 17254 agNULL, 17255 satIOContext, 17256 taskTag); 17257 17258 return status; 17259 } 17260 else if (task == TD_INTERNAL_TM_RESET) 17261 { 17262 status = satTDInternalTmReset( tiRoot, 17263 currentTaskTag, 17264 tiDeviceHandle, 17265 agNULL, 17266 satIOContext); 17267 return status; 17268 } 17269 else 17270 { 17271 TI_DBG1(("satTM: tiDeviceHandle=%p UNSUPPORTED TM task=0x%x\n", 17272 tiDeviceHandle, task )); 17273 17274 /* clean up TD layer's IORequestBody */ 17275 ostiFreeMemory( 17276 tiRoot, 17277 tiRequestBody->IOType.InitiatorTMIO.osMemHandle, 17278 sizeof(tdIORequestBody_t) 17279 ); 17280 return tiError; 17281 } 17282 17283 } 17284 17285 17286 /***************************************************************************** 17287 *! \brief satTmResetLUN 17288 * 17289 * This routine is called to initiate a TM RESET LUN request to SATL. 17290 * This routine is independent of HW/LL API. 17291 * 17292 * \param tiRoot: Pointer to TISA initiator driver/port instance. 17293 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 17294 * \param lun: Pointer to LUN. 17295 * \param currentTaskTag: Pointer to tag/context for this TM request. 17296 * 17297 * \return: 17298 * 17299 * \e tiSuccess: I/O request successfully initiated. 17300 * \e tiBusy: No resources available, try again later. 17301 * \e tiIONoDevice: Invalid device handle. 17302 * \e tiError: Other errors that prevent the I/O request to be started. 17303 * 17304 * 17305 *****************************************************************************/ 17306 osGLOBAL bit32 satTmResetLUN( 17307 tiRoot_t *tiRoot, 17308 tiIORequest_t *tiIORequest, /* current task tag */ 17309 tiDeviceHandle_t *tiDeviceHandle, 17310 tiScsiInitiatorRequest_t *tiScsiRequest, 17311 satIOContext_t *satIOContext, 17312 tiLUN_t *lun) 17313 { 17314 17315 tdsaDeviceData_t *tdsaDeviceData; 17316 satDeviceData_t *satDevData; 17317 17318 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 17319 satDevData = &tdsaDeviceData->satDevData; 17320 17321 TI_DBG1(("satTmResetLUN: tiDeviceHandle=%p.\n", tiDeviceHandle )); 17322 17323 /* 17324 * Only support LUN 0 17325 */ 17326 if ( (lun->lun[0] | lun->lun[1] | lun->lun[2] | lun->lun[3] | 17327 lun->lun[4] | lun->lun[5] | lun->lun[6] | lun->lun[7] ) != 0 ) 17328 { 17329 TI_DBG1(("satTmResetLUN: *** REJECT *** LUN not zero, tiDeviceHandle=%p\n", 17330 tiDeviceHandle)); 17331 return tiError; 17332 } 17333 17334 /* 17335 * Check if there is other TM request pending 17336 */ 17337 if (satDevData->satTmTaskTag != agNULL) 17338 { 17339 TI_DBG1(("satTmResetLUN: *** REJECT *** other TM pending, tiDeviceHandle=%p\n", 17340 tiDeviceHandle)); 17341 return tiError; 17342 } 17343 17344 /* 17345 * Save tiIORequest, will be returned at device reset completion to return 17346 * the TM completion. 17347 */ 17348 satDevData->satTmTaskTag = tiIORequest; 17349 17350 /* 17351 * Set flag to indicate device in recovery mode. 17352 */ 17353 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY; 17354 17355 /* 17356 * Issue SATA device reset. Set flag to indicate NOT to automatically abort 17357 * at the completion of SATA device reset. 17358 */ 17359 satDevData->satAbortAfterReset = agFALSE; 17360 17361 /* SAT rev8 6.3.6 p22 */ 17362 satStartResetDevice( 17363 tiRoot, 17364 tiIORequest, /* currentTaskTag */ 17365 tiDeviceHandle, 17366 tiScsiRequest, 17367 satIOContext 17368 ); 17369 17370 17371 return tiSuccess; 17372 17373 } 17374 17375 /***************************************************************************** 17376 *! \brief satTmWarmReset 17377 * 17378 * This routine is called to initiate a TM warm RESET request to SATL. 17379 * This routine is independent of HW/LL API. 17380 * 17381 * \param tiRoot: Pointer to TISA initiator driver/port instance. 17382 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 17383 * \param currentTaskTag: Pointer to tag/context for this TM request. 17384 * 17385 * \return: 17386 * 17387 * \e tiSuccess: I/O request successfully initiated. 17388 * \e tiBusy: No resources available, try again later. 17389 * \e tiIONoDevice: Invalid device handle. 17390 * \e tiError: Other errors that prevent the I/O request to be started. 17391 * 17392 * 17393 *****************************************************************************/ 17394 osGLOBAL bit32 satTmWarmReset( 17395 tiRoot_t *tiRoot, 17396 tiIORequest_t *tiIORequest, /* current task tag */ 17397 tiDeviceHandle_t *tiDeviceHandle, 17398 tiScsiInitiatorRequest_t *tiScsiRequest, 17399 satIOContext_t *satIOContext) 17400 { 17401 17402 tdsaDeviceData_t *tdsaDeviceData; 17403 satDeviceData_t *satDevData; 17404 17405 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 17406 satDevData = &tdsaDeviceData->satDevData; 17407 17408 TI_DBG1(("satTmWarmReset: tiDeviceHandle=%p.\n", tiDeviceHandle )); 17409 17410 /* 17411 * Check if there is other TM request pending 17412 */ 17413 if (satDevData->satTmTaskTag != agNULL) 17414 { 17415 TI_DBG1(("satTmWarmReset: *** REJECT *** other TM pending, tiDeviceHandle=%p\n", 17416 tiDeviceHandle)); 17417 return tiError; 17418 } 17419 17420 /* 17421 * Save tiIORequest, will be returned at device reset completion to return 17422 * the TM completion. 17423 */ 17424 satDevData->satTmTaskTag = tiIORequest; 17425 17426 /* 17427 * Set flag to indicate device in recovery mode. 17428 */ 17429 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY; 17430 17431 /* 17432 * Issue SATA device reset. Set flag to indicate NOT to automatically abort 17433 * at the completion of SATA device reset. 17434 */ 17435 satDevData->satAbortAfterReset = agFALSE; 17436 17437 /* SAT rev8 6.3.6 p22 */ 17438 satStartResetDevice( 17439 tiRoot, 17440 tiIORequest, /* currentTaskTag */ 17441 tiDeviceHandle, 17442 tiScsiRequest, 17443 satIOContext 17444 ); 17445 17446 return tiSuccess; 17447 17448 } 17449 17450 osGLOBAL bit32 satTDInternalTmReset( 17451 tiRoot_t *tiRoot, 17452 tiIORequest_t *tiIORequest, /* current task tag */ 17453 tiDeviceHandle_t *tiDeviceHandle, 17454 tiScsiInitiatorRequest_t *tiScsiRequest, 17455 satIOContext_t *satIOContext) 17456 { 17457 17458 tdsaDeviceData_t *tdsaDeviceData; 17459 satDeviceData_t *satDevData; 17460 17461 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 17462 satDevData = &tdsaDeviceData->satDevData; 17463 17464 TI_DBG1(("satTmWarmReset: tiDeviceHandle=%p.\n", tiDeviceHandle )); 17465 17466 /* 17467 * Check if there is other TM request pending 17468 */ 17469 if (satDevData->satTmTaskTag != agNULL) 17470 { 17471 TI_DBG1(("satTmWarmReset: *** REJECT *** other TM pending, tiDeviceHandle=%p\n", 17472 tiDeviceHandle)); 17473 return tiError; 17474 } 17475 17476 /* 17477 * Save tiIORequest, will be returned at device reset completion to return 17478 * the TM completion. 17479 */ 17480 satDevData->satTmTaskTag = tiIORequest; 17481 17482 /* 17483 * Set flag to indicate device in recovery mode. 17484 */ 17485 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY; 17486 17487 /* 17488 * Issue SATA device reset. Set flag to indicate NOT to automatically abort 17489 * at the completion of SATA device reset. 17490 */ 17491 satDevData->satAbortAfterReset = agFALSE; 17492 17493 /* SAT rev8 6.3.6 p22 */ 17494 satStartResetDevice( 17495 tiRoot, 17496 tiIORequest, /* currentTaskTag */ 17497 tiDeviceHandle, 17498 tiScsiRequest, 17499 satIOContext 17500 ); 17501 17502 return tiSuccess; 17503 17504 } 17505 17506 /***************************************************************************** 17507 *! \brief satTmAbortTask 17508 * 17509 * This routine is called to initiate a TM ABORT TASK request to SATL. 17510 * This routine is independent of HW/LL API. 17511 * 17512 * \param tiRoot: Pointer to TISA initiator driver/port instance. 17513 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 17514 * \param taskTag: Pointer to the associated task where the TM 17515 * command is to be applied. 17516 * \param currentTaskTag: Pointer to tag/context for this TM request. 17517 * 17518 * \return: 17519 * 17520 * \e tiSuccess: I/O request successfully initiated. 17521 * \e tiBusy: No resources available, try again later. 17522 * \e tiIONoDevice: Invalid device handle. 17523 * \e tiError: Other errors that prevent the I/O request to be started. 17524 * 17525 * 17526 *****************************************************************************/ 17527 osGLOBAL bit32 satTmAbortTask( 17528 tiRoot_t *tiRoot, 17529 tiIORequest_t *tiIORequest, /* current task tag */ 17530 tiDeviceHandle_t *tiDeviceHandle, 17531 tiScsiInitiatorRequest_t *tiScsiRequest, /* NULL */ 17532 satIOContext_t *satIOContext, 17533 tiIORequest_t *taskTag) 17534 { 17535 17536 tdsaDeviceData_t *tdsaDeviceData; 17537 satDeviceData_t *satDevData; 17538 satIOContext_t *satTempIOContext = agNULL; 17539 tdIORequestBody_t *tdIORequestBody; 17540 tdIORequestBody_t *TMtdIORequestBody; 17541 tdList_t *elementHdr; 17542 bit32 found = agFALSE; 17543 tiIORequest_t *tiIOReq; 17544 17545 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 17546 satDevData = &tdsaDeviceData->satDevData; 17547 TMtdIORequestBody = (tdIORequestBody_t *)tiIORequest->tdData; 17548 17549 TI_DBG1(("satTmAbortTask: tiDeviceHandle=%p taskTag=%p.\n", tiDeviceHandle, taskTag )); 17550 /* 17551 * Check if there is other TM request pending 17552 */ 17553 if (satDevData->satTmTaskTag != agNULL) 17554 { 17555 TI_DBG1(("satTmAbortTask: REJECT other TM pending, tiDeviceHandle=%p\n", 17556 tiDeviceHandle)); 17557 /* clean up TD layer's IORequestBody */ 17558 ostiFreeMemory( 17559 tiRoot, 17560 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle, 17561 sizeof(tdIORequestBody_t) 17562 ); 17563 return tiError; 17564 } 17565 17566 #ifdef REMOVED 17567 /* 17568 * Check if there is only one I/O pending. 17569 */ 17570 if (satDevData->satPendingIO > 0) 17571 { 17572 TI_DBG1(("satTmAbortTask: REJECT num pending I/O, tiDeviceHandle=%p, satPendingIO=0x%x\n", 17573 tiDeviceHandle, satDevData->satPendingIO)); 17574 /* clean up TD layer's IORequestBody */ 17575 ostiFreeMemory( 17576 tiRoot, 17577 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle, 17578 sizeof(tdIORequestBody_t) 17579 ); 17580 17581 return tiError; 17582 } 17583 #endif 17584 17585 /* 17586 * Check that the only pending I/O matches taskTag. If not return tiError. 17587 */ 17588 elementHdr = satDevData->satIoLinkList.flink; 17589 17590 while (elementHdr != &satDevData->satIoLinkList) 17591 { 17592 satTempIOContext = TDLIST_OBJECT_BASE( satIOContext_t, 17593 satIoContextLink, 17594 elementHdr ); 17595 17596 tdIORequestBody = (tdIORequestBody_t *) satTempIOContext->tiRequestBody; 17597 tiIOReq = tdIORequestBody->tiIORequest; 17598 17599 elementHdr = elementHdr->flink; /* for the next while loop */ 17600 17601 /* 17602 * Check if the tag matches 17603 */ 17604 if ( tiIOReq == taskTag) 17605 { 17606 found = agTRUE; 17607 satIOContext->satToBeAbortedIOContext = satTempIOContext; 17608 TI_DBG1(("satTmAbortTask: found matching tag.\n")); 17609 17610 break; 17611 17612 } /* if matching tag */ 17613 17614 } /* while loop */ 17615 17616 17617 if (found == agFALSE ) 17618 { 17619 TI_DBG1(("satTmAbortTask: *** REJECT *** no match, tiDeviceHandle=%p\n", 17620 tiDeviceHandle )); 17621 17622 /* clean up TD layer's IORequestBody */ 17623 ostiFreeMemory( 17624 tiRoot, 17625 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle, 17626 sizeof(tdIORequestBody_t) 17627 ); 17628 17629 return tiError; 17630 } 17631 17632 /* 17633 * Save tiIORequest, will be returned at device reset completion to return 17634 * the TM completion. 17635 */ 17636 satDevData->satTmTaskTag = tiIORequest; 17637 17638 /* 17639 * Set flag to indicate device in recovery mode. 17640 */ 17641 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY; 17642 17643 17644 /* 17645 * Issue SATA device reset or check power mode. Set flag to to automatically abort 17646 * at the completion of SATA device reset. 17647 * SAT r09 p25 17648 */ 17649 satDevData->satAbortAfterReset = agTRUE; 17650 17651 if ( (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) || 17652 (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) 17653 ) 17654 { 17655 TI_DBG1(("satTmAbortTask: calling satStartCheckPowerMode\n")); 17656 /* send check power mode */ 17657 satStartCheckPowerMode( 17658 tiRoot, 17659 tiIORequest, /* currentTaskTag */ 17660 tiDeviceHandle, 17661 tiScsiRequest, 17662 satIOContext 17663 ); 17664 } 17665 else 17666 { 17667 TI_DBG1(("satTmAbortTask: calling satStartResetDevice\n")); 17668 /* send AGSA_SATA_PROTOCOL_SRST_ASSERT */ 17669 satStartResetDevice( 17670 tiRoot, 17671 tiIORequest, /* currentTaskTag */ 17672 tiDeviceHandle, 17673 tiScsiRequest, 17674 satIOContext 17675 ); 17676 } 17677 17678 17679 return tiSuccess; 17680 } 17681 17682 /***************************************************************************** 17683 *! \brief osSatResetCB 17684 * 17685 * This routine is called to notify the completion of SATA device reset 17686 * which was initiated previously through the call to sataLLReset(). 17687 * This routine is independent of HW/LL API. 17688 * 17689 * \param tiRoot: Pointer to TISA initiator driver/port instance. 17690 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 17691 * \param resetStatus: Reset status either tiSuccess or tiError. 17692 * \param respFis: Pointer to the Register Device-To-Host FIS 17693 * received from the device. 17694 * 17695 * \return: None 17696 * 17697 *****************************************************************************/ 17698 osGLOBAL void osSatResetCB( 17699 tiRoot_t *tiRoot, 17700 tiDeviceHandle_t *tiDeviceHandle, 17701 bit32 resetStatus, 17702 void *respFis) 17703 { 17704 17705 agsaRoot_t *agRoot; 17706 tdsaDeviceData_t *tdsaDeviceData; 17707 satDeviceData_t *satDevData; 17708 satIOContext_t *satIOContext; 17709 tdIORequestBody_t *tdIORequestBodyTmp; 17710 tdList_t *elementHdr; 17711 agsaIORequest_t *agAbortIORequest; 17712 tdIORequestBody_t *tdAbortIORequestBody; 17713 bit32 PhysUpper32; 17714 bit32 PhysLower32; 17715 bit32 memAllocStatus; 17716 void *osMemHandle; 17717 17718 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 17719 agRoot = tdsaDeviceData->agRoot; 17720 satDevData = &tdsaDeviceData->satDevData; 17721 17722 TI_DBG5(("osSatResetCB: tiDeviceHandle=%p resetStatus=0x%x\n", 17723 tiDeviceHandle, resetStatus )); 17724 17725 /* We may need to check FIS to check device operating condition */ 17726 17727 17728 /* 17729 * Check if need to abort all pending I/Os 17730 */ 17731 if ( satDevData->satAbortAfterReset == agTRUE ) 17732 { 17733 /* 17734 * Issue abort to LL layer to all other pending I/Os for the same SATA drive 17735 */ 17736 elementHdr = satDevData->satIoLinkList.flink; 17737 while (elementHdr != &satDevData->satIoLinkList) 17738 { 17739 satIOContext = TDLIST_OBJECT_BASE( satIOContext_t, 17740 satIoContextLink, 17741 elementHdr ); 17742 17743 tdIORequestBodyTmp = (tdIORequestBody_t *)satIOContext->tiRequestBody; 17744 17745 /* 17746 * Issue abort 17747 */ 17748 TI_DBG5(("osSatResetCB: issuing ABORT tiDeviceHandle=%p agIORequest=%p\n", 17749 tiDeviceHandle, &tdIORequestBodyTmp->agIORequest )); 17750 17751 /* allocating agIORequest for abort itself */ 17752 memAllocStatus = ostiAllocMemory( 17753 tiRoot, 17754 &osMemHandle, 17755 (void **)&tdAbortIORequestBody, 17756 &PhysUpper32, 17757 &PhysLower32, 17758 8, 17759 sizeof(tdIORequestBody_t), 17760 agTRUE 17761 ); 17762 17763 if (memAllocStatus != tiSuccess) 17764 { 17765 /* let os process IO */ 17766 TI_DBG1(("osSatResetCB: ostiAllocMemory failed...\n")); 17767 return; 17768 } 17769 17770 if (tdAbortIORequestBody == agNULL) 17771 { 17772 /* let os process IO */ 17773 TI_DBG1(("osSatResetCB: ostiAllocMemory returned NULL tdAbortIORequestBody\n")); 17774 return; 17775 } 17776 /* setup task management structure */ 17777 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 17778 tdAbortIORequestBody->tiDevHandle = tiDeviceHandle; 17779 17780 /* initialize agIORequest */ 17781 agAbortIORequest = &(tdAbortIORequestBody->agIORequest); 17782 agAbortIORequest->osData = (void *) tdAbortIORequestBody; 17783 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */ 17784 17785 saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, &(tdIORequestBodyTmp->agIORequest), agNULL ); 17786 elementHdr = elementHdr->flink; /* for the next while loop */ 17787 17788 } /* while */ 17789 17790 /* Reset flag */ 17791 satDevData->satAbortAfterReset = agFALSE; 17792 17793 } 17794 17795 17796 /* 17797 * Check if the device reset if the result of TM request. 17798 */ 17799 if ( satDevData->satTmTaskTag != agNULL ) 17800 { 17801 TI_DBG5(("osSatResetCB: calling TM completion tiDeviceHandle=%p satTmTaskTag=%p\n", 17802 tiDeviceHandle, satDevData->satTmTaskTag )); 17803 17804 ostiInitiatorEvent( tiRoot, 17805 agNULL, /* portalContext not used */ 17806 tiDeviceHandle, 17807 tiIntrEventTypeTaskManagement, 17808 tiTMOK, 17809 satDevData->satTmTaskTag); 17810 /* 17811 * Reset flag 17812 */ 17813 satDevData->satTmTaskTag = agNULL; 17814 } 17815 17816 } 17817 17818 17819 /***************************************************************************** 17820 *! \brief osSatIOCompleted 17821 * 17822 * This routine is a callback for SATA completion that required FIS status 17823 * translation to SCSI status. 17824 * 17825 * \param tiRoot: Pointer to TISA initiator driver/port instance. 17826 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 17827 * \param respFis: Pointer to status FIS to read. 17828 * \param respFisLen: Length of response FIS to read. 17829 * \param satIOContext: Pointer to SAT context. 17830 * \param interruptContext: Interrupt context 17831 * 17832 * \return: None 17833 * 17834 *****************************************************************************/ 17835 osGLOBAL void osSatIOCompleted( 17836 tiRoot_t *tiRoot, 17837 tiIORequest_t *tiIORequest, 17838 agsaFisHeader_t *agFirstDword, 17839 bit32 respFisLen, 17840 agsaFrameHandle_t agFrameHandle, 17841 satIOContext_t *satIOContext, 17842 bit32 interruptContext) 17843 17844 { 17845 satDeviceData_t *pSatDevData; 17846 scsiRspSense_t *pSense; 17847 #ifdef TD_DEBUG_ENABLE 17848 tiIniScsiCmnd_t *pScsiCmnd; 17849 #endif 17850 agsaFisRegHostToDevice_t *hostToDevFis = agNULL; 17851 bit32 ataStatus = 0; 17852 bit32 ataError; 17853 satInternalIo_t *satIntIo = agNULL; 17854 bit32 status; 17855 tiDeviceHandle_t *tiDeviceHandle; 17856 satIOContext_t *satIOContext2; 17857 tdIORequestBody_t *tdIORequestBody; 17858 agsaFisRegD2HHeader_t *statDevToHostFisHeader = agNULL; 17859 agsaFisSetDevBitsHeader_t *statSetDevBitFisHeader = agNULL; 17860 tiIORequest_t tiIORequestTMP; 17861 17862 pSense = satIOContext->pSense; 17863 pSatDevData = satIOContext->pSatDevData; 17864 #ifdef TD_DEBUG_ENABLE 17865 pScsiCmnd = satIOContext->pScsiCmnd; 17866 #endif 17867 hostToDevFis = satIOContext->pFis; 17868 17869 tiDeviceHandle = &((tdsaDeviceData_t *)(pSatDevData->satSaDeviceData))->tiDeviceHandle; 17870 /* 17871 * Find out the type of response FIS: 17872 * Set Device Bit FIS or Reg Device To Host FIS. 17873 */ 17874 17875 /* First assume it is Reg Device to Host FIS */ 17876 statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H); 17877 ataStatus = statDevToHostFisHeader->status; /* ATA Status register */ 17878 ataError = statDevToHostFisHeader->error; /* ATA Eror register */ 17879 17880 /* for debugging */ 17881 TI_DBG1(("osSatIOCompleted: H to D command 0x%x\n", hostToDevFis->h.command)); 17882 TI_DBG1(("osSatIOCompleted: D to H fistype 0x%x\n", statDevToHostFisHeader->fisType)); 17883 17884 17885 if (statDevToHostFisHeader->fisType == SET_DEV_BITS_FIS) 17886 { 17887 /* It is Set Device Bits FIS */ 17888 statSetDevBitFisHeader = (agsaFisSetDevBitsHeader_t *)&(agFirstDword->D2H); 17889 /* Get ATA Status register */ 17890 ataStatus = (statSetDevBitFisHeader->statusHi_Lo & 0x70); /* bits 4,5,6 */ 17891 ataStatus = ataStatus | (statSetDevBitFisHeader->statusHi_Lo & 0x07); /* bits 0,1,2 */ 17892 17893 /* ATA Eror register */ 17894 ataError = statSetDevBitFisHeader->error; 17895 17896 statDevToHostFisHeader = agNULL; 17897 } 17898 17899 else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS) 17900 { 17901 TI_DBG1(("osSatIOCompleted: *** UNEXPECTED RESP FIS TYPE 0x%x *** tiIORequest=%p\n", 17902 statDevToHostFisHeader->fisType, tiIORequest)); 17903 17904 satSetSensePayload( pSense, 17905 SCSI_SNSKEY_HARDWARE_ERROR, 17906 0, 17907 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE, 17908 satIOContext); 17909 17910 ostiInitiatorIOCompleted( tiRoot, 17911 tiIORequest, 17912 tiIOSuccess, 17913 SCSI_STAT_CHECK_CONDITION, 17914 satIOContext->pTiSenseData, 17915 interruptContext ); 17916 return; 17917 17918 } 17919 17920 if ( ataStatus & DF_ATA_STATUS_MASK ) 17921 { 17922 pSatDevData->satDeviceFaultState = agTRUE; 17923 } 17924 else 17925 { 17926 pSatDevData->satDeviceFaultState = agFALSE; 17927 } 17928 17929 TI_DBG5(("osSatIOCompleted: tiIORequest=%p CDB=0x%x ATA CMD =0x%x\n", 17930 tiIORequest, pScsiCmnd->cdb[0], hostToDevFis->h.command)); 17931 17932 /* 17933 * Decide which ATA command is the translation needed 17934 */ 17935 switch(hostToDevFis->h.command) 17936 { 17937 case SAT_READ_FPDMA_QUEUED: 17938 case SAT_WRITE_FPDMA_QUEUED: 17939 17940 /************************************************************************ 17941 * 17942 * !!!! See Section 13.5.2.4 of SATA 2.5 specs. !!!! 17943 * !!!! If the NCQ error ends up here, it means that the device sent !!!! 17944 * !!!! Set Device Bit FIS (which has SActive register) instead of !!!! 17945 * !!!! Register Device To Host FIS (which does not have SActive !!!! 17946 * !!!! register). The callback ossaSATAEvent() deals with the case !!!! 17947 * !!!! where Register Device To Host FIS was sent by the device. !!!! 17948 * 17949 * For NCQ we need to issue READ LOG EXT command with log page 10h 17950 * to get the error and to allow other I/Os to continue. 17951 * 17952 * Here is the basic flow or sequence of error recovery, note that due 17953 * to the SATA HW assist that we have, this sequence is slighly different 17954 * from the one described in SATA 2.5: 17955 * 17956 * 1. Set SATA device flag to indicate error condition and returning busy 17957 * for all new request. 17958 * return tiSuccess; 17959 17960 * 2. Because the HW/LL layer received Set Device Bit FIS, it can get the 17961 * tag or I/O context for NCQ request, SATL would translate the ATA error 17962 * to SCSI status and return the original NCQ I/O with the appopriate 17963 * SCSI status. 17964 * 17965 * 3. Prepare READ LOG EXT page 10h command. Set flag to indicate that 17966 * the failed I/O has been returned to the OS Layer. Send command. 17967 * 17968 * 4. When the device receives READ LOG EXT page 10h request all other 17969 * pending I/O are implicitly aborted. No completion (aborted) status 17970 * will be sent to the host for these aborted commands. 17971 * 17972 * 5. SATL receives the completion for READ LOG EXT command in 17973 * satReadLogExtCB(). Steps 6,7,8,9 below are the step 1,2,3,4 in 17974 * satReadLogExtCB(). 17975 * 17976 * 6. Check flag that indicates whether the failed I/O has been returned 17977 * to the OS Layer. If not, search the I/O context in device data 17978 * looking for a matched tag. Then return the completion of the failed 17979 * NCQ command with the appopriate/trasnlated SCSI status. 17980 * 17981 * 7. Issue abort to LL layer to all other pending I/Os for the same SATA 17982 * drive. 17983 * 17984 * 8. Free resource allocated for the internally generated READ LOG EXT. 17985 * 17986 * 9. At the completion of abort, in the context of ossaSATACompleted(), 17987 * return the I/O with error status to the OS-App Specific layer. 17988 * When all I/O aborts are completed, clear SATA device flag to 17989 * indicate ready to process new request. 17990 * 17991 ***********************************************************************/ 17992 17993 TI_DBG1(("osSatIOCompleted: NCQ ERROR tiIORequest=%p ataStatus=0x%x ataError=0x%x\n", 17994 tiIORequest, ataStatus, ataError )); 17995 17996 /* Set flag to indicate we are in recovery */ 17997 pSatDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY; 17998 17999 /* Return the failed NCQ I/O to OS-Apps Specifiic layer */ 18000 osSatDefaultTranslation( tiRoot, 18001 tiIORequest, 18002 satIOContext, 18003 pSense, 18004 (bit8)ataStatus, 18005 (bit8)ataError, 18006 interruptContext ); 18007 18008 /* 18009 * Allocate resource for READ LOG EXT page 10h 18010 */ 18011 satIntIo = satAllocIntIoResource( tiRoot, 18012 &(tiIORequestTMP), /* anything but NULL */ 18013 pSatDevData, 18014 sizeof (satReadLogExtPage10h_t), 18015 satIntIo); 18016 18017 if (satIntIo == agNULL) 18018 { 18019 TI_DBG1(("osSatIOCompleted: can't send RLE due to resource lack\n")); 18020 18021 /* Abort I/O after completion of device reset */ 18022 pSatDevData->satAbortAfterReset = agTRUE; 18023 #ifdef NOT_YET 18024 /* needs further investigation */ 18025 /* no report to OS layer */ 18026 satSubTM(tiRoot, 18027 tiDeviceHandle, 18028 TD_INTERNAL_TM_RESET, 18029 agNULL, 18030 agNULL, 18031 agNULL, 18032 agFALSE); 18033 #endif 18034 18035 18036 TI_DBG1(("osSatIOCompleted: calling saSATADeviceReset 1\n")); 18037 return; 18038 } 18039 18040 18041 /* 18042 * Set flag to indicate that the failed I/O has been returned to the 18043 * OS-App specific Layer. 18044 */ 18045 satIntIo->satIntFlag = AG_SAT_INT_IO_FLAG_ORG_IO_COMPLETED; 18046 18047 /* compare to satPrepareNewIO() */ 18048 /* Send READ LOG EXIT page 10h command */ 18049 18050 /* 18051 * Need to initialize all the fields within satIOContext except 18052 * reqType and satCompleteCB which will be set depending on cmd. 18053 */ 18054 18055 tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody; 18056 satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext); 18057 18058 satIOContext2->pSatDevData = pSatDevData; 18059 satIOContext2->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 18060 satIOContext2->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd); 18061 satIOContext2->pSense = &(tdIORequestBody->transport.SATA.sensePayload); 18062 satIOContext2->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData); 18063 satIOContext2->pTiSenseData->senseData = satIOContext2->pSense; 18064 18065 satIOContext2->tiRequestBody = satIntIo->satIntRequestBody; 18066 satIOContext2->interruptContext = interruptContext; 18067 satIOContext2->satIntIoContext = satIntIo; 18068 18069 satIOContext2->ptiDeviceHandle = tiDeviceHandle; 18070 satIOContext2->satOrgIOContext = agNULL; 18071 satIOContext2->tiScsiXchg = agNULL; 18072 18073 status = satSendReadLogExt( tiRoot, 18074 &satIntIo->satIntTiIORequest, 18075 tiDeviceHandle, 18076 &satIntIo->satIntTiScsiXchg, 18077 satIOContext2); 18078 18079 if (status != tiSuccess) 18080 { 18081 TI_DBG1(("osSatIOCompleted: can't send RLE due to LL api failure\n")); 18082 satFreeIntIoResource( tiRoot, 18083 pSatDevData, 18084 satIntIo); 18085 18086 /* Abort I/O after completion of device reset */ 18087 pSatDevData->satAbortAfterReset = agTRUE; 18088 #ifdef NOT_YET 18089 /* needs further investigation */ 18090 /* no report to OS layer */ 18091 satSubTM(tiRoot, 18092 tiDeviceHandle, 18093 TD_INTERNAL_TM_RESET, 18094 agNULL, 18095 agNULL, 18096 agNULL, 18097 agFALSE); 18098 #endif 18099 18100 TI_DBG1(("osSatIOCompleted: calling saSATADeviceReset 2\n")); 18101 return; 18102 } 18103 18104 break; 18105 18106 case SAT_READ_DMA_EXT: 18107 /* fall through */ 18108 /* Use default status/error translation */ 18109 18110 case SAT_READ_DMA: 18111 /* fall through */ 18112 /* Use default status/error translation */ 18113 18114 default: 18115 osSatDefaultTranslation( tiRoot, 18116 tiIORequest, 18117 satIOContext, 18118 pSense, 18119 (bit8)ataStatus, 18120 (bit8)ataError, 18121 interruptContext ); 18122 break; 18123 18124 } /* end switch */ 18125 } 18126 18127 18128 /*****************************************************************************/ 18129 /*! \brief SAT implementation for SCSI STANDARD INQUIRY. 18130 * 18131 * SAT implementation for SCSI STANDARD INQUIRY. 18132 * 18133 * \param pInquiry: Pointer to Inquiry Data buffer. 18134 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data. 18135 * 18136 * \return None. 18137 */ 18138 /*****************************************************************************/ 18139 GLOBAL void satInquiryStandard( 18140 bit8 *pInquiry, 18141 agsaSATAIdentifyData_t *pSATAIdData, 18142 tiIniScsiCmnd_t *scsiCmnd 18143 ) 18144 { 18145 tiLUN_t *pLun; 18146 pLun = &scsiCmnd->lun; 18147 18148 /* 18149 Assumption: Basic Task Mangement is supported 18150 -> BQUE 1 and CMDQUE 0, SPC-4, Table96, p147 18151 */ 18152 /* 18153 See SPC-4, 6.4.2, p 143 18154 and SAT revision 8, 8.1.2, p 28 18155 */ 18156 18157 TI_DBG5(("satInquiryStandard: start\n")); 18158 18159 if (pInquiry == agNULL) 18160 { 18161 TI_DBG1(("satInquiryStandard: pInquiry is NULL, wrong\n")); 18162 return; 18163 } 18164 else 18165 { 18166 TI_DBG5(("satInquiryStandard: pInquiry is NOT NULL\n")); 18167 } 18168 /* 18169 * Reject all other LUN other than LUN 0. 18170 */ 18171 if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] | 18172 pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) ) 18173 { 18174 /* SAT Spec Table 8, p27, footnote 'a' */ 18175 pInquiry[0] = 0x7F; 18176 18177 } 18178 else 18179 { 18180 pInquiry[0] = 0x00; 18181 } 18182 18183 if (pSATAIdData->rm_ataDevice & ATA_REMOVABLE_MEDIA_DEVICE_MASK ) 18184 { 18185 pInquiry[1] = 0x80; 18186 } 18187 else 18188 { 18189 pInquiry[1] = 0x00; 18190 } 18191 pInquiry[2] = 0x05; /* SPC-3 */ 18192 pInquiry[3] = 0x12; /* set HiSup 1; resp data format set to 2 */ 18193 pInquiry[4] = 0x1F; /* 35 - 4 = 31; Additional length */ 18194 pInquiry[5] = 0x00; 18195 /* The following two are for task management. SAT Rev8, p20 */ 18196 if (pSATAIdData->sataCapabilities & 0x100) 18197 { 18198 /* NCQ supported; multiple outstanding SCSI IO are supported */ 18199 pInquiry[6] = 0x00; /* BQUE bit is not set */ 18200 pInquiry[7] = 0x02; /* CMDQUE bit is set */ 18201 } 18202 else 18203 { 18204 pInquiry[6] = 0x80; /* BQUE bit is set */ 18205 pInquiry[7] = 0x00; /* CMDQUE bit is not set */ 18206 } 18207 /* 18208 * Vendor ID. 18209 */ 18210 osti_strncpy((char*)&pInquiry[8], AG_SAT_VENDOR_ID_STRING,8); /* 8 bytes */ 18211 18212 /* 18213 * Product ID 18214 */ 18215 /* when flipped by LL */ 18216 pInquiry[16] = pSATAIdData->modelNumber[1]; 18217 pInquiry[17] = pSATAIdData->modelNumber[0]; 18218 pInquiry[18] = pSATAIdData->modelNumber[3]; 18219 pInquiry[19] = pSATAIdData->modelNumber[2]; 18220 pInquiry[20] = pSATAIdData->modelNumber[5]; 18221 pInquiry[21] = pSATAIdData->modelNumber[4]; 18222 pInquiry[22] = pSATAIdData->modelNumber[7]; 18223 pInquiry[23] = pSATAIdData->modelNumber[6]; 18224 pInquiry[24] = pSATAIdData->modelNumber[9]; 18225 pInquiry[25] = pSATAIdData->modelNumber[8]; 18226 pInquiry[26] = pSATAIdData->modelNumber[11]; 18227 pInquiry[27] = pSATAIdData->modelNumber[10]; 18228 pInquiry[28] = pSATAIdData->modelNumber[13]; 18229 pInquiry[29] = pSATAIdData->modelNumber[12]; 18230 pInquiry[30] = pSATAIdData->modelNumber[15]; 18231 pInquiry[31] = pSATAIdData->modelNumber[14]; 18232 18233 /* when flipped */ 18234 /* 18235 * Product Revision level. 18236 */ 18237 18238 /* 18239 * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA 18240 * device are ASCII spaces (20h), do this translation. 18241 */ 18242 if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) && 18243 (pSATAIdData->firmwareVersion[5] == 0x00 ) && 18244 (pSATAIdData->firmwareVersion[6] == 0x20 ) && 18245 (pSATAIdData->firmwareVersion[7] == 0x00 ) 18246 ) 18247 { 18248 pInquiry[32] = pSATAIdData->firmwareVersion[1]; 18249 pInquiry[33] = pSATAIdData->firmwareVersion[0]; 18250 pInquiry[34] = pSATAIdData->firmwareVersion[3]; 18251 pInquiry[35] = pSATAIdData->firmwareVersion[2]; 18252 } 18253 else 18254 { 18255 pInquiry[32] = pSATAIdData->firmwareVersion[5]; 18256 pInquiry[33] = pSATAIdData->firmwareVersion[4]; 18257 pInquiry[34] = pSATAIdData->firmwareVersion[7]; 18258 pInquiry[35] = pSATAIdData->firmwareVersion[6]; 18259 } 18260 18261 18262 #ifdef REMOVED 18263 /* 18264 * Product ID 18265 */ 18266 /* when flipped by LL */ 18267 pInquiry[16] = pSATAIdData->modelNumber[0]; 18268 pInquiry[17] = pSATAIdData->modelNumber[1]; 18269 pInquiry[18] = pSATAIdData->modelNumber[2]; 18270 pInquiry[19] = pSATAIdData->modelNumber[3]; 18271 pInquiry[20] = pSATAIdData->modelNumber[4]; 18272 pInquiry[21] = pSATAIdData->modelNumber[5]; 18273 pInquiry[22] = pSATAIdData->modelNumber[6]; 18274 pInquiry[23] = pSATAIdData->modelNumber[7]; 18275 pInquiry[24] = pSATAIdData->modelNumber[8]; 18276 pInquiry[25] = pSATAIdData->modelNumber[9]; 18277 pInquiry[26] = pSATAIdData->modelNumber[10]; 18278 pInquiry[27] = pSATAIdData->modelNumber[11]; 18279 pInquiry[28] = pSATAIdData->modelNumber[12]; 18280 pInquiry[29] = pSATAIdData->modelNumber[13]; 18281 pInquiry[30] = pSATAIdData->modelNumber[14]; 18282 pInquiry[31] = pSATAIdData->modelNumber[15]; 18283 18284 /* when flipped */ 18285 /* 18286 * Product Revision level. 18287 */ 18288 18289 /* 18290 * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA 18291 * device are ASCII spaces (20h), do this translation. 18292 */ 18293 if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) && 18294 (pSATAIdData->firmwareVersion[5] == 0x00 ) && 18295 (pSATAIdData->firmwareVersion[6] == 0x20 ) && 18296 (pSATAIdData->firmwareVersion[7] == 0x00 ) 18297 ) 18298 { 18299 pInquiry[32] = pSATAIdData->firmwareVersion[0]; 18300 pInquiry[33] = pSATAIdData->firmwareVersion[1]; 18301 pInquiry[34] = pSATAIdData->firmwareVersion[2]; 18302 pInquiry[35] = pSATAIdData->firmwareVersion[3]; 18303 } 18304 else 18305 { 18306 pInquiry[32] = pSATAIdData->firmwareVersion[4]; 18307 pInquiry[33] = pSATAIdData->firmwareVersion[5]; 18308 pInquiry[34] = pSATAIdData->firmwareVersion[6]; 18309 pInquiry[35] = pSATAIdData->firmwareVersion[7]; 18310 } 18311 #endif 18312 18313 TI_DBG5(("satInquiryStandard: end\n")); 18314 18315 } 18316 18317 18318 /*****************************************************************************/ 18319 /*! \brief SAT implementation for SCSI INQUIRY page 0. 18320 * 18321 * SAT implementation for SCSI INQUIRY page 0. 18322 * 18323 * \param pInquiry: Pointer to Inquiry Data buffer. 18324 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data. 18325 * 18326 * \return None. 18327 */ 18328 /*****************************************************************************/ 18329 GLOBAL void satInquiryPage0( 18330 bit8 *pInquiry, 18331 agsaSATAIdentifyData_t *pSATAIdData) 18332 { 18333 18334 TI_DBG5(("satInquiryPage0: entry\n")); 18335 18336 /* 18337 See SPC-4, 7.6.9, p 345 18338 and SAT revision 8, 10.3.2, p 77 18339 */ 18340 pInquiry[0] = 0x00; 18341 pInquiry[1] = 0x00; /* page code */ 18342 pInquiry[2] = 0x00; /* reserved */ 18343 pInquiry[3] = 7 - 3; /* last index(in this case, 6) - 3; page length */ 18344 18345 /* supported vpd page list */ 18346 pInquiry[4] = 0x00; /* page 0x00 supported */ 18347 pInquiry[5] = 0x80; /* page 0x80 supported */ 18348 pInquiry[6] = 0x83; /* page 0x83 supported */ 18349 pInquiry[7] = 0x89; /* page 0x89 supported */ 18350 18351 } 18352 18353 18354 /*****************************************************************************/ 18355 /*! \brief SAT implementation for SCSI INQUIRY page 83. 18356 * 18357 * SAT implementation for SCSI INQUIRY page 83. 18358 * 18359 * \param pInquiry: Pointer to Inquiry Data buffer. 18360 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data. 18361 * 18362 * \return None. 18363 */ 18364 /*****************************************************************************/ 18365 GLOBAL void satInquiryPage83( 18366 bit8 *pInquiry, 18367 agsaSATAIdentifyData_t *pSATAIdData, 18368 satDeviceData_t *pSatDevData) 18369 { 18370 18371 satSimpleSATAIdentifyData_t *pSimpleData; 18372 18373 /* 18374 * When translating the fields, in some cases using the simple form of SATA 18375 * Identify Device Data is easier. So we define it here. 18376 * Both pSimpleData and pSATAIdData points to the same data. 18377 */ 18378 pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData; 18379 18380 TI_DBG5(("satInquiryPage83: entry\n")); 18381 18382 pInquiry[0] = 0x00; 18383 pInquiry[1] = 0x83; /* page code */ 18384 pInquiry[2] = 0; /* Reserved */ 18385 18386 /* 18387 * If the ATA device returns word 87 bit 8 set to one in its IDENTIFY DEVICE 18388 * data indicating that it supports the WORLD WIDE NAME field 18389 * (i.e., words 108-111), the SATL shall include an identification descriptor 18390 * containing a logical unit name. 18391 */ 18392 if ( pSatDevData->satWWNSupport) 18393 { 18394 /* Fill in SAT Rev8 Table85 */ 18395 /* 18396 * Logical unit name derived from the world wide name. 18397 */ 18398 pInquiry[3] = 12; /* 15-3; page length, no addition ID descriptor assumed*/ 18399 18400 /* 18401 * Identifier descriptor 18402 */ 18403 pInquiry[4] = 0x01; /* Code set: binary codes */ 18404 pInquiry[5] = 0x03; /* Identifier type : NAA */ 18405 pInquiry[6] = 0x00; /* Reserved */ 18406 pInquiry[7] = 0x08; /* Identifier length */ 18407 18408 /* Bit 4-7 NAA field, bit 0-3 MSB of IEEE Company ID */ 18409 pInquiry[8] = (bit8)((pSATAIdData->namingAuthority) >> 8); 18410 pInquiry[9] = (bit8)((pSATAIdData->namingAuthority) & 0xFF); /* IEEE Company ID */ 18411 pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8); /* IEEE Company ID */ 18412 /* Bit 4-7 LSB of IEEE Company ID, bit 0-3 MSB of Vendor Specific ID */ 18413 pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF); 18414 pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8); /* Vendor Specific ID */ 18415 pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF); /* Vendor Specific ID */ 18416 pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8); /* Vendor Specific ID */ 18417 pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF); /* Vendor Specific ID */ 18418 18419 } 18420 else 18421 { 18422 /* Fill in SAT Rev8 Table86 */ 18423 /* 18424 * Logical unit name derived from the model number and serial number. 18425 */ 18426 pInquiry[3] = 72; /* 75 - 3; page length */ 18427 18428 /* 18429 * Identifier descriptor 18430 */ 18431 pInquiry[4] = 0x02; /* Code set: ASCII codes */ 18432 pInquiry[5] = 0x01; /* Identifier type : T10 vendor ID based */ 18433 pInquiry[6] = 0x00; /* Reserved */ 18434 pInquiry[7] = 0x44; /* 0x44, 68 Identifier length */ 18435 18436 /* Byte 8 to 15 is the vendor id string 'ATA '. */ 18437 osti_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8); 18438 18439 18440 /* 18441 * Byte 16 to 75 is vendor specific id 18442 */ 18443 pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8); 18444 pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff); 18445 pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8); 18446 pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff); 18447 pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8); 18448 pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff); 18449 pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8); 18450 pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff); 18451 pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8); 18452 pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff); 18453 pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8); 18454 pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff); 18455 pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8); 18456 pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff); 18457 pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8); 18458 pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff); 18459 pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8); 18460 pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff); 18461 pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8); 18462 pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff); 18463 pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8); 18464 pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff); 18465 pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8); 18466 pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff); 18467 pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8); 18468 pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff); 18469 pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8); 18470 pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff); 18471 pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8); 18472 pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff); 18473 pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8); 18474 pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff); 18475 pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8); 18476 pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff); 18477 pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8); 18478 pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff); 18479 pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8); 18480 pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff); 18481 pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8); 18482 pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff); 18483 18484 pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8); 18485 pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff); 18486 pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8); 18487 pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff); 18488 pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8); 18489 pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff); 18490 pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8); 18491 pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff); 18492 pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8); 18493 pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff); 18494 pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8); 18495 pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff); 18496 pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8); 18497 pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff); 18498 pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8); 18499 pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff); 18500 pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8); 18501 pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff); 18502 pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8); 18503 pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff); 18504 } 18505 18506 } 18507 18508 /*****************************************************************************/ 18509 /*! \brief SAT implementation for SCSI INQUIRY page 89. 18510 * 18511 * SAT implementation for SCSI INQUIRY page 89. 18512 * 18513 * \param pInquiry: Pointer to Inquiry Data buffer. 18514 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data. 18515 * \param pSatDevData Pointer to internal device data structure 18516 * 18517 * \return None. 18518 */ 18519 /*****************************************************************************/ 18520 GLOBAL void satInquiryPage89( 18521 bit8 *pInquiry, 18522 agsaSATAIdentifyData_t *pSATAIdData, 18523 satDeviceData_t *pSatDevData) 18524 { 18525 /* 18526 SAT revision 8, 10.3.5, p 83 18527 */ 18528 satSimpleSATAIdentifyData_t *pSimpleData; 18529 18530 /* 18531 * When translating the fields, in some cases using the simple form of SATA 18532 * Identify Device Data is easier. So we define it here. 18533 * Both pSimpleData and pSATAIdData points to the same data. 18534 */ 18535 pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData; 18536 18537 TI_DBG5(("satInquiryPage89: start\n")); 18538 18539 pInquiry[0] = 0x00; /* Peripheral Qualifier and Peripheral Device Type */ 18540 pInquiry[1] = 0x89; /* page code */ 18541 18542 /* Page length 0x238 */ 18543 pInquiry[2] = 0x02; 18544 pInquiry[3] = 0x38; 18545 18546 pInquiry[4] = 0x0; /* reserved */ 18547 pInquiry[5] = 0x0; /* reserved */ 18548 pInquiry[6] = 0x0; /* reserved */ 18549 pInquiry[7] = 0x0; /* reserved */ 18550 18551 /* SAT Vendor Identification */ 18552 osti_strncpy((char*)&pInquiry[8], "PMC-SIERRA", 8); /* 8 bytes */ 18553 18554 /* SAT Product Idetification */ 18555 osti_strncpy((char*)&pInquiry[16], "Tachyon-SPC ", 16); /* 16 bytes */ 18556 18557 /* SAT Product Revision Level */ 18558 osti_strncpy((char*)&pInquiry[32], "01", 4); /* 4 bytes */ 18559 18560 /* Signature, SAT revision8, Table88, p85 */ 18561 18562 18563 pInquiry[36] = 0x34; /* FIS type */ 18564 if (pSatDevData->satDeviceType == SATA_ATA_DEVICE) 18565 { 18566 /* interrupt assume to be 0 */ 18567 pInquiry[37] = (bit8)((pSatDevData->satPMField) >> (4 * 7)); /* first four bits of PM field */ 18568 } 18569 else 18570 { 18571 /* interrupt assume to be 1 */ 18572 pInquiry[37] = (bit8)(0x40 + (bit8)(((pSatDevData->satPMField) >> (4 * 7)))); /* first four bits of PM field */ 18573 } 18574 pInquiry[38] = 0; 18575 pInquiry[39] = 0; 18576 18577 if (pSatDevData->satDeviceType == SATA_ATA_DEVICE) 18578 { 18579 pInquiry[40] = 0x01; /* LBA Low */ 18580 pInquiry[41] = 0x00; /* LBA Mid */ 18581 pInquiry[42] = 0x00; /* LBA High */ 18582 pInquiry[43] = 0x00; /* Device */ 18583 pInquiry[44] = 0x00; /* LBA Low Exp */ 18584 pInquiry[45] = 0x00; /* LBA Mid Exp */ 18585 pInquiry[46] = 0x00; /* LBA High Exp */ 18586 pInquiry[47] = 0x00; /* Reserved */ 18587 pInquiry[48] = 0x01; /* Sector Count */ 18588 pInquiry[49] = 0x00; /* Sector Count Exp */ 18589 } 18590 else 18591 { 18592 pInquiry[40] = 0x01; /* LBA Low */ 18593 pInquiry[41] = 0x00; /* LBA Mid */ 18594 pInquiry[42] = 0x00; /* LBA High */ 18595 pInquiry[43] = 0x00; /* Device */ 18596 pInquiry[44] = 0x00; /* LBA Low Exp */ 18597 pInquiry[45] = 0x00; /* LBA Mid Exp */ 18598 pInquiry[46] = 0x00; /* LBA High Exp */ 18599 pInquiry[47] = 0x00; /* Reserved */ 18600 pInquiry[48] = 0x01; /* Sector Count */ 18601 pInquiry[49] = 0x00; /* Sector Count Exp */ 18602 } 18603 18604 /* Reserved */ 18605 pInquiry[50] = 0x00; 18606 pInquiry[51] = 0x00; 18607 pInquiry[52] = 0x00; 18608 pInquiry[53] = 0x00; 18609 pInquiry[54] = 0x00; 18610 pInquiry[55] = 0x00; 18611 18612 /* Command Code */ 18613 if (pSatDevData->satDeviceType == SATA_ATA_DEVICE) 18614 { 18615 pInquiry[56] = 0xEC; /* IDENTIFY DEVICE */ 18616 } 18617 else 18618 { 18619 pInquiry[56] = 0xA1; /* IDENTIFY PACKET DEVICE */ 18620 } 18621 /* Reserved */ 18622 pInquiry[57] = 0x0; 18623 pInquiry[58] = 0x0; 18624 pInquiry[59] = 0x0; 18625 18626 /* Identify Device */ 18627 osti_memcpy(&pInquiry[60], pSimpleData, sizeof(satSimpleSATAIdentifyData_t)); 18628 return; 18629 } 18630 18631 /*****************************************************************************/ 18632 /*! \brief SAT implementation for SCSI INQUIRY page 0. 18633 * 18634 * SAT implementation for SCSI INQUIRY page 0. 18635 * 18636 * \param pInquiry: Pointer to Inquiry Data buffer. 18637 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data. 18638 * 18639 * \return None. 18640 */ 18641 /*****************************************************************************/ 18642 GLOBAL void satInquiryPage80( 18643 bit8 *pInquiry, 18644 agsaSATAIdentifyData_t *pSATAIdData) 18645 { 18646 18647 TI_DBG5(("satInquiryPage80: entry\n")); 18648 18649 /* 18650 See SPC-4, 7.6.9, p 345 18651 and SAT revision 8, 10.3.3, p 77 18652 */ 18653 pInquiry[0] = 0x00; 18654 pInquiry[1] = 0x80; /* page code */ 18655 pInquiry[2] = 0x00; /* reserved */ 18656 pInquiry[3] = 0x14; /* page length */ 18657 18658 /* supported vpd page list */ 18659 pInquiry[4] = pSATAIdData->serialNumber[1]; 18660 pInquiry[5] = pSATAIdData->serialNumber[0]; 18661 pInquiry[6] = pSATAIdData->serialNumber[3]; 18662 pInquiry[7] = pSATAIdData->serialNumber[2]; 18663 pInquiry[8] = pSATAIdData->serialNumber[5]; 18664 pInquiry[9] = pSATAIdData->serialNumber[4]; 18665 pInquiry[10] = pSATAIdData->serialNumber[7]; 18666 pInquiry[11] = pSATAIdData->serialNumber[6]; 18667 pInquiry[12] = pSATAIdData->serialNumber[9]; 18668 pInquiry[13] = pSATAIdData->serialNumber[8]; 18669 pInquiry[14] = pSATAIdData->serialNumber[11]; 18670 pInquiry[15] = pSATAIdData->serialNumber[10]; 18671 pInquiry[16] = pSATAIdData->serialNumber[13]; 18672 pInquiry[17] = pSATAIdData->serialNumber[12]; 18673 pInquiry[18] = pSATAIdData->serialNumber[15]; 18674 pInquiry[19] = pSATAIdData->serialNumber[14]; 18675 pInquiry[20] = pSATAIdData->serialNumber[17]; 18676 pInquiry[21] = pSATAIdData->serialNumber[16]; 18677 pInquiry[22] = pSATAIdData->serialNumber[19]; 18678 pInquiry[23] = pSATAIdData->serialNumber[18]; 18679 18680 18681 } 18682 18683 18684 18685 /*****************************************************************************/ 18686 /*! \brief Send READ LOG EXT ATA PAGE 10h command to sata drive. 18687 * 18688 * Send READ LOG EXT ATA command PAGE 10h request to LL layer. 18689 * 18690 * \param tiRoot: Pointer to TISA initiator driver/port instance. 18691 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 18692 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 18693 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 18694 * \param satIOContext_t: Pointer to the SAT IO Context 18695 * 18696 * \return If command is started successfully 18697 * - \e tiSuccess: I/O request successfully initiated. 18698 * - \e tiBusy: No resources available, try again later. 18699 * - \e tiIONoDevice: Invalid device handle. 18700 * - \e tiError: Other errors. 18701 */ 18702 /*****************************************************************************/ 18703 GLOBAL bit32 satSendReadLogExt( 18704 tiRoot_t *tiRoot, 18705 tiIORequest_t *tiIORequest, 18706 tiDeviceHandle_t *tiDeviceHandle, 18707 tiScsiInitiatorRequest_t *tiScsiRequest, 18708 satIOContext_t *satIOContext) 18709 18710 { 18711 18712 bit32 status; 18713 bit32 agRequestType; 18714 agsaFisRegHostToDevice_t *fis; 18715 18716 fis = satIOContext->pFis; 18717 18718 TI_DBG1(("satSendReadLogExt: tiDeviceHandle=%p tiIORequest=%p\n", 18719 tiDeviceHandle, tiIORequest)); 18720 18721 fis->h.fisType = 0x27; /* Reg host to device */ 18722 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18723 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */ 18724 fis->h.features = 0; /* FIS reserve */ 18725 fis->d.lbaLow = 0x10; /* Page number */ 18726 fis->d.lbaMid = 0; /* */ 18727 fis->d.lbaHigh = 0; /* */ 18728 fis->d.device = 0; /* DEV is ignored in SATA */ 18729 fis->d.lbaLowExp = 0; /* */ 18730 fis->d.lbaMidExp = 0; /* */ 18731 fis->d.lbaHighExp = 0; /* */ 18732 fis->d.featuresExp = 0; /* FIS reserve */ 18733 fis->d.sectorCount = 0x01; /* 1 sector counts*/ 18734 fis->d.sectorCountExp = 0x00; /* 1 sector counts */ 18735 fis->d.reserved4 = 0; 18736 fis->d.control = 0; /* FIS HOB bit clear */ 18737 fis->d.reserved5 = 0; 18738 18739 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 18740 18741 /* Initialize CB for SATA completion. 18742 */ 18743 satIOContext->satCompleteCB = &satReadLogExtCB; 18744 18745 /* 18746 * Prepare SGL and send FIS to LL layer. 18747 */ 18748 satIOContext->reqType = agRequestType; /* Save it */ 18749 18750 status = sataLLIOStart( tiRoot, 18751 tiIORequest, 18752 tiDeviceHandle, 18753 tiScsiRequest, 18754 satIOContext); 18755 18756 TI_DBG1(("satSendReadLogExt: end status %d\n", status)); 18757 18758 return (status); 18759 18760 } 18761 18762 18763 /*****************************************************************************/ 18764 /*! \brief SAT default ATA status and ATA error translation to SCSI. 18765 * 18766 * SSAT default ATA status and ATA error translation to SCSI. 18767 * 18768 * \param tiRoot: Pointer to TISA initiator driver/port instance. 18769 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 18770 * \param satIOContext: Pointer to the SAT IO Context 18771 * \param pSense: Pointer to scsiRspSense_t 18772 * \param ataStatus: ATA status register 18773 * \param ataError: ATA error register 18774 * \param interruptContext: Interrupt context 18775 * 18776 * \return None 18777 */ 18778 /*****************************************************************************/ 18779 GLOBAL void osSatDefaultTranslation( 18780 tiRoot_t *tiRoot, 18781 tiIORequest_t *tiIORequest, 18782 satIOContext_t *satIOContext, 18783 scsiRspSense_t *pSense, 18784 bit8 ataStatus, 18785 bit8 ataError, 18786 bit32 interruptContext ) 18787 { 18788 18789 /* 18790 * Check for device fault case 18791 */ 18792 if ( ataStatus & DF_ATA_STATUS_MASK ) 18793 { 18794 satSetSensePayload( pSense, 18795 SCSI_SNSKEY_HARDWARE_ERROR, 18796 0, 18797 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE, 18798 satIOContext); 18799 18800 ostiInitiatorIOCompleted( tiRoot, 18801 tiIORequest, 18802 tiIOSuccess, 18803 SCSI_STAT_CHECK_CONDITION, 18804 satIOContext->pTiSenseData, 18805 interruptContext ); 18806 return; 18807 } 18808 18809 /* 18810 * If status error bit it set, need to check the error register 18811 */ 18812 if ( ataStatus & ERR_ATA_STATUS_MASK ) 18813 { 18814 if ( ataError & NM_ATA_ERROR_MASK ) 18815 { 18816 TI_DBG1(("osSatDefaultTranslation: NM_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n", 18817 ataError, tiIORequest)); 18818 satSetSensePayload( pSense, 18819 SCSI_SNSKEY_NOT_READY, 18820 0, 18821 SCSI_SNSCODE_MEDIUM_NOT_PRESENT, 18822 satIOContext); 18823 } 18824 18825 else if (ataError & UNC_ATA_ERROR_MASK) 18826 { 18827 TI_DBG1(("osSatDefaultTranslation: UNC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n", 18828 ataError, tiIORequest)); 18829 satSetSensePayload( pSense, 18830 SCSI_SNSKEY_MEDIUM_ERROR, 18831 0, 18832 SCSI_SNSCODE_UNRECOVERED_READ_ERROR, 18833 satIOContext); 18834 } 18835 18836 else if (ataError & IDNF_ATA_ERROR_MASK) 18837 { 18838 TI_DBG1(("osSatDefaultTranslation: IDNF_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n", 18839 ataError, tiIORequest)); 18840 satSetSensePayload( pSense, 18841 SCSI_SNSKEY_MEDIUM_ERROR, 18842 0, 18843 SCSI_SNSCODE_RECORD_NOT_FOUND, 18844 satIOContext); 18845 } 18846 18847 else if (ataError & MC_ATA_ERROR_MASK) 18848 { 18849 TI_DBG1(("osSatDefaultTranslation: MC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n", 18850 ataError, tiIORequest)); 18851 satSetSensePayload( pSense, 18852 SCSI_SNSKEY_UNIT_ATTENTION, 18853 0, 18854 SCSI_SNSCODE_NOT_READY_TO_READY_CHANGE, 18855 satIOContext); 18856 } 18857 18858 else if (ataError & MCR_ATA_ERROR_MASK) 18859 { 18860 TI_DBG1(("osSatDefaultTranslation: MCR_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n", 18861 ataError, tiIORequest)); 18862 satSetSensePayload( pSense, 18863 SCSI_SNSKEY_UNIT_ATTENTION, 18864 0, 18865 SCSI_SNSCODE_OPERATOR_MEDIUM_REMOVAL_REQUEST, 18866 satIOContext); 18867 } 18868 18869 else if (ataError & ICRC_ATA_ERROR_MASK) 18870 { 18871 TI_DBG1(("osSatDefaultTranslation: ICRC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n", 18872 ataError, tiIORequest)); 18873 satSetSensePayload( pSense, 18874 SCSI_SNSKEY_ABORTED_COMMAND, 18875 0, 18876 SCSI_SNSCODE_INFORMATION_UNIT_CRC_ERROR, 18877 satIOContext); 18878 } 18879 18880 else if (ataError & ABRT_ATA_ERROR_MASK) 18881 { 18882 TI_DBG1(("osSatDefaultTranslation: ABRT_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n", 18883 ataError, tiIORequest)); 18884 satSetSensePayload( pSense, 18885 SCSI_SNSKEY_ABORTED_COMMAND, 18886 0, 18887 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 18888 satIOContext); 18889 } 18890 18891 else 18892 { 18893 TI_DBG1(("osSatDefaultTranslation: **** UNEXPECTED ATA_ERROR **** ataError= 0x%x, tiIORequest=%p\n", 18894 ataError, tiIORequest)); 18895 satSetSensePayload( pSense, 18896 SCSI_SNSKEY_HARDWARE_ERROR, 18897 0, 18898 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE, 18899 satIOContext); 18900 } 18901 18902 /* Send the completion response now */ 18903 ostiInitiatorIOCompleted( tiRoot, 18904 tiIORequest, 18905 tiIOSuccess, 18906 SCSI_STAT_CHECK_CONDITION, 18907 satIOContext->pTiSenseData, 18908 interruptContext ); 18909 return; 18910 18911 18912 } 18913 18914 else /* (ataStatus & ERR_ATA_STATUS_MASK ) is false */ 18915 { 18916 /* This case should never happen */ 18917 TI_DBG1(("osSatDefaultTranslation: *** UNEXPECTED ATA status 0x%x *** tiIORequest=%p\n", 18918 ataStatus, tiIORequest)); 18919 satSetSensePayload( pSense, 18920 SCSI_SNSKEY_HARDWARE_ERROR, 18921 0, 18922 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE, 18923 satIOContext); 18924 18925 ostiInitiatorIOCompleted( tiRoot, 18926 tiIORequest, 18927 tiIOSuccess, 18928 SCSI_STAT_CHECK_CONDITION, 18929 satIOContext->pTiSenseData, 18930 interruptContext ); 18931 return; 18932 18933 } 18934 18935 18936 } 18937 18938 /*****************************************************************************/ 18939 /*! \brief Allocate resource for SAT intervally generated I/O. 18940 * 18941 * Allocate resource for SAT intervally generated I/O. 18942 * 18943 * \param tiRoot: Pointer to TISA driver/port instance. 18944 * \param satDevData: Pointer to SAT specific device data. 18945 * \param allocLength: Length in byte of the DMA mem to allocate, upto 18946 * one page size. 18947 * \param satIntIo: Pointer (output) to context for SAT internally 18948 * generated I/O that is allocated by this routine. 18949 * 18950 * \return If command is started successfully 18951 * - \e tiSuccess: Success. 18952 * - \e tiError: Failed allocating resource. 18953 */ 18954 /*****************************************************************************/ 18955 GLOBAL satInternalIo_t * satAllocIntIoResource( 18956 tiRoot_t *tiRoot, 18957 tiIORequest_t *tiIORequest, 18958 satDeviceData_t *satDevData, 18959 bit32 dmaAllocLength, 18960 satInternalIo_t *satIntIo) 18961 { 18962 tdList_t *tdList = agNULL; 18963 bit32 memAllocStatus; 18964 18965 TI_DBG1(("satAllocIntIoResource: start\n")); 18966 TI_DBG6(("satAllocIntIoResource: satIntIo %p\n", satIntIo)); 18967 if (satDevData == agNULL) 18968 { 18969 TI_DBG1(("satAllocIntIoResource: ***** ASSERT satDevData is null\n")); 18970 return agNULL; 18971 } 18972 18973 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK); 18974 if (!TDLIST_EMPTY(&(satDevData->satFreeIntIoLinkList))) 18975 { 18976 TDLIST_DEQUEUE_FROM_HEAD(&tdList, &(satDevData->satFreeIntIoLinkList)); 18977 } 18978 else 18979 { 18980 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK); 18981 TI_DBG1(("satAllocIntIoResource() no more internal free link.\n")); 18982 return agNULL; 18983 } 18984 18985 if (tdList == agNULL) 18986 { 18987 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK); 18988 TI_DBG1(("satAllocIntIoResource() FAIL to alloc satIntIo.\n")); 18989 return agNULL; 18990 } 18991 18992 satIntIo = TDLIST_OBJECT_BASE( satInternalIo_t, satIntIoLink, tdList); 18993 TI_DBG6(("satAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id)); 18994 18995 /* Put in active list */ 18996 TDLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink)); 18997 TDLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satActiveIntIoLinkList)); 18998 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK); 18999 19000 #ifdef REMOVED 19001 /* Put in active list */ 19002 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK); 19003 TDLIST_DEQUEUE_THIS (tdList); 19004 TDLIST_ENQUEUE_AT_TAIL (tdList, &(satDevData->satActiveIntIoLinkList)); 19005 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK); 19006 19007 satIntIo = TDLIST_OBJECT_BASE( satInternalIo_t, satIntIoLink, tdList); 19008 TI_DBG6(("satAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id)); 19009 #endif 19010 19011 /* 19012 typedef struct 19013 { 19014 tdList_t satIntIoLink; 19015 tiIORequest_t satIntTiIORequest; 19016 void *satIntRequestBody; 19017 tiScsiInitiatorRequest_t satIntTiScsiXchg; 19018 tiMem_t satIntDmaMem; 19019 tiMem_t satIntReqBodyMem; 19020 bit32 satIntFlag; 19021 } satInternalIo_t; 19022 */ 19023 19024 /* 19025 * Allocate mem for Request Body 19026 */ 19027 satIntIo->satIntReqBodyMem.totalLength = sizeof(tdIORequestBody_t); 19028 19029 memAllocStatus = ostiAllocMemory( tiRoot, 19030 &satIntIo->satIntReqBodyMem.osHandle, 19031 (void **)&satIntIo->satIntRequestBody, 19032 &satIntIo->satIntReqBodyMem.physAddrUpper, 19033 &satIntIo->satIntReqBodyMem.physAddrLower, 19034 8, 19035 satIntIo->satIntReqBodyMem.totalLength, 19036 agTRUE ); 19037 19038 if (memAllocStatus != tiSuccess) 19039 { 19040 TI_DBG1(("satAllocIntIoResource() FAIL to alloc mem for Req Body.\n")); 19041 /* 19042 * Return satIntIo to the free list 19043 */ 19044 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK); 19045 TDLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink); 19046 TDLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList); 19047 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK); 19048 19049 return agNULL; 19050 } 19051 19052 /* 19053 * Allocate DMA memory if required 19054 */ 19055 if (dmaAllocLength != 0) 19056 { 19057 satIntIo->satIntDmaMem.totalLength = dmaAllocLength; 19058 19059 memAllocStatus = ostiAllocMemory( tiRoot, 19060 &satIntIo->satIntDmaMem.osHandle, 19061 (void **)&satIntIo->satIntDmaMem.virtPtr, 19062 &satIntIo->satIntDmaMem.physAddrUpper, 19063 &satIntIo->satIntDmaMem.physAddrLower, 19064 8, 19065 satIntIo->satIntDmaMem.totalLength, 19066 agFALSE); 19067 TI_DBG6(("satAllocIntIoResource: len %d \n", satIntIo->satIntDmaMem.totalLength)); 19068 TI_DBG6(("satAllocIntIoResource: pointer %p \n", satIntIo->satIntDmaMem.osHandle)); 19069 19070 if (memAllocStatus != tiSuccess) 19071 { 19072 TI_DBG1(("satAllocIntIoResource() FAIL to alloc mem for DMA mem.\n")); 19073 /* 19074 * Return satIntIo to the free list 19075 */ 19076 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK); 19077 TDLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink); 19078 TDLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList); 19079 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK); 19080 19081 /* 19082 * Free mem allocated for Req body 19083 */ 19084 ostiFreeMemory( tiRoot, 19085 satIntIo->satIntReqBodyMem.osHandle, 19086 satIntIo->satIntReqBodyMem.totalLength); 19087 19088 return agNULL; 19089 } 19090 } 19091 19092 /* 19093 typedef struct 19094 { 19095 tdList_t satIntIoLink; 19096 tiIORequest_t satIntTiIORequest; 19097 void *satIntRequestBody; 19098 tiScsiInitiatorRequest_t satIntTiScsiXchg; 19099 tiMem_t satIntDmaMem; 19100 tiMem_t satIntReqBodyMem; 19101 bit32 satIntFlag; 19102 } satInternalIo_t; 19103 */ 19104 19105 /* 19106 * Initialize satIntTiIORequest field 19107 */ 19108 satIntIo->satIntTiIORequest.osData = agNULL; /* Not used for internal SAT I/O */ 19109 satIntIo->satIntTiIORequest.tdData = satIntIo->satIntRequestBody; 19110 19111 /* 19112 * saves the original tiIOrequest 19113 */ 19114 satIntIo->satOrgTiIORequest = tiIORequest; 19115 /* 19116 typedef struct tiIniScsiCmnd 19117 { 19118 tiLUN_t lun; 19119 bit32 expDataLength; 19120 bit32 taskAttribute; 19121 bit32 crn; 19122 bit8 cdb[16]; 19123 } tiIniScsiCmnd_t; 19124 19125 typedef struct tiScsiInitiatorExchange 19126 { 19127 void *sglVirtualAddr; 19128 tiIniScsiCmnd_t scsiCmnd; 19129 tiSgl_t agSgl1; 19130 tiSgl_t agSgl2; 19131 tiDataDirection_t dataDirection; 19132 } tiScsiInitiatorRequest_t; 19133 19134 */ 19135 19136 /* 19137 * Initialize satIntTiScsiXchg. Since the internal SAT request is NOT 19138 * originated from SCSI request, only the following fields are initialized: 19139 * - sglVirtualAddr if DMA transfer is involved 19140 * - agSgl1 if DMA transfer is involved 19141 * - expDataLength in scsiCmnd since this field is read by sataLLIOStart() 19142 */ 19143 if (dmaAllocLength != 0) 19144 { 19145 satIntIo->satIntTiScsiXchg.sglVirtualAddr = satIntIo->satIntDmaMem.virtPtr; 19146 19147 OSSA_WRITE_LE_32(agNULL, &satIntIo->satIntTiScsiXchg.agSgl1.len, 0, 19148 satIntIo->satIntDmaMem.totalLength); 19149 satIntIo->satIntTiScsiXchg.agSgl1.lower = satIntIo->satIntDmaMem.physAddrLower; 19150 satIntIo->satIntTiScsiXchg.agSgl1.upper = satIntIo->satIntDmaMem.physAddrUpper; 19151 satIntIo->satIntTiScsiXchg.agSgl1.type = tiSgl; 19152 19153 satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = satIntIo->satIntDmaMem.totalLength; 19154 } 19155 else 19156 { 19157 satIntIo->satIntTiScsiXchg.sglVirtualAddr = agNULL; 19158 19159 satIntIo->satIntTiScsiXchg.agSgl1.len = 0; 19160 satIntIo->satIntTiScsiXchg.agSgl1.lower = 0; 19161 satIntIo->satIntTiScsiXchg.agSgl1.upper = 0; 19162 satIntIo->satIntTiScsiXchg.agSgl1.type = tiSgl; 19163 19164 satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = 0; 19165 } 19166 19167 TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.len %d\n", satIntIo->satIntTiScsiXchg.agSgl1.len)); 19168 19169 TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.upper %d\n", satIntIo->satIntTiScsiXchg.agSgl1.upper)); 19170 19171 TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.lower %d\n", satIntIo->satIntTiScsiXchg.agSgl1.lower)); 19172 19173 TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.type %d\n", satIntIo->satIntTiScsiXchg.agSgl1.type)); 19174 TI_DBG5(("satAllocIntIoResource: return satIntIo %p\n", satIntIo)); 19175 return satIntIo; 19176 19177 } 19178 19179 /*****************************************************************************/ 19180 /*! \brief Free resource for SAT intervally generated I/O. 19181 * 19182 * Free resource for SAT intervally generated I/O that was previously 19183 * allocated in satAllocIntIoResource(). 19184 * 19185 * \param tiRoot: Pointer to TISA driver/port instance. 19186 * \param satDevData: Pointer to SAT specific device data. 19187 * \param satIntIo: Pointer to context for SAT internal I/O that was 19188 * previously allocated in satAllocIntIoResource(). 19189 * 19190 * \return None 19191 */ 19192 /*****************************************************************************/ 19193 GLOBAL void satFreeIntIoResource( 19194 tiRoot_t *tiRoot, 19195 satDeviceData_t *satDevData, 19196 satInternalIo_t *satIntIo) 19197 { 19198 TI_DBG6(("satFreeIntIoResource: start\n")); 19199 19200 if (satIntIo == agNULL) 19201 { 19202 TI_DBG6(("satFreeIntIoResource: allowed call\n")); 19203 return; 19204 } 19205 19206 /* sets the original tiIOrequest to agNULL for internally generated ATA cmnd */ 19207 satIntIo->satOrgTiIORequest = agNULL; 19208 19209 /* 19210 * Free DMA memory if previosly alocated 19211 */ 19212 if (satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength != 0) 19213 { 19214 TI_DBG1(("satFreeIntIoResource: DMA len %d\n", satIntIo->satIntDmaMem.totalLength)); 19215 TI_DBG6(("satFreeIntIoResource: pointer %p\n", satIntIo->satIntDmaMem.osHandle)); 19216 19217 ostiFreeMemory( tiRoot, 19218 satIntIo->satIntDmaMem.osHandle, 19219 satIntIo->satIntDmaMem.totalLength); 19220 satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = 0; 19221 } 19222 19223 if (satIntIo->satIntReqBodyMem.totalLength != 0) 19224 { 19225 TI_DBG1(("satFreeIntIoResource: req body len %d\n", satIntIo->satIntReqBodyMem.totalLength)); 19226 /* 19227 * Free mem allocated for Req body 19228 */ 19229 ostiFreeMemory( tiRoot, 19230 satIntIo->satIntReqBodyMem.osHandle, 19231 satIntIo->satIntReqBodyMem.totalLength); 19232 19233 satIntIo->satIntReqBodyMem.totalLength = 0; 19234 } 19235 19236 TI_DBG6(("satFreeIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id)); 19237 /* 19238 * Return satIntIo to the free list 19239 */ 19240 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK); 19241 TDLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink)); 19242 TDLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satFreeIntIoLinkList)); 19243 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK); 19244 19245 } 19246 19247 19248 /*****************************************************************************/ 19249 /*! \brief SAT implementation for SCSI INQUIRY. 19250 * 19251 * SAT implementation for SCSI INQUIRY. 19252 * This function sends ATA Identify Device data command for SCSI INQUIRY 19253 * 19254 * \param tiRoot: Pointer to TISA initiator driver/port instance. 19255 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 19256 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 19257 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 19258 * \param satIOContext_t: Pointer to the SAT IO Context 19259 * 19260 * \return If command is started successfully 19261 * - \e tiSuccess: I/O request successfully initiated. 19262 * - \e tiBusy: No resources available, try again later. 19263 * - \e tiIONoDevice: Invalid device handle. 19264 * - \e tiError: Other errors. 19265 */ 19266 /*****************************************************************************/ 19267 GLOBAL bit32 satSendIDDev( 19268 tiRoot_t *tiRoot, 19269 tiIORequest_t *tiIORequest, 19270 tiDeviceHandle_t *tiDeviceHandle, 19271 tiScsiInitiatorRequest_t *tiScsiRequest, 19272 satIOContext_t *satIOContext) 19273 19274 { 19275 bit32 status; 19276 bit32 agRequestType; 19277 satDeviceData_t *pSatDevData; 19278 agsaFisRegHostToDevice_t *fis; 19279 #ifdef TD_DEBUG_ENABLE 19280 satInternalIo_t *satIntIoContext; 19281 tdsaDeviceData_t *oneDeviceData; 19282 tdIORequestBody_t *tdIORequestBody; 19283 #endif 19284 19285 pSatDevData = satIOContext->pSatDevData; 19286 fis = satIOContext->pFis; 19287 19288 TI_DBG5(("satSendIDDev: start\n")); 19289 #ifdef TD_DEBUG_ENABLE 19290 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; 19291 #endif 19292 TI_DBG5(("satSendIDDev: did %d\n", oneDeviceData->id)); 19293 19294 19295 #ifdef TD_DEBUG_ENABLE 19296 satIntIoContext = satIOContext->satIntIoContext; 19297 tdIORequestBody = satIntIoContext->satIntRequestBody; 19298 #endif 19299 19300 TI_DBG5(("satSendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody)); 19301 19302 fis->h.fisType = 0x27; /* Reg host to device */ 19303 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19304 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE) 19305 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0x40 */ 19306 else 19307 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */ 19308 fis->h.features = 0; /* FIS reserve */ 19309 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 19310 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 19311 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 19312 fis->d.device = 0; /* FIS LBA mode */ 19313 fis->d.lbaLowExp = 0; 19314 fis->d.lbaMidExp = 0; 19315 fis->d.lbaHighExp = 0; 19316 fis->d.featuresExp = 0; 19317 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 19318 fis->d.sectorCountExp = 0; 19319 fis->d.reserved4 = 0; 19320 fis->d.control = 0; /* FIS HOB bit clear */ 19321 fis->d.reserved5 = 0; 19322 19323 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 19324 19325 /* Initialize CB for SATA completion. 19326 */ 19327 satIOContext->satCompleteCB = &satInquiryCB; 19328 19329 /* 19330 * Prepare SGL and send FIS to LL layer. 19331 */ 19332 satIOContext->reqType = agRequestType; /* Save it */ 19333 19334 #ifdef TD_INTERNAL_DEBUG 19335 tdhexdump("satSendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 19336 #ifdef TD_DEBUG_ENABLE 19337 tdhexdump("satSendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t)); 19338 #endif 19339 #endif 19340 19341 status = sataLLIOStart( tiRoot, 19342 tiIORequest, 19343 tiDeviceHandle, 19344 tiScsiRequest, 19345 satIOContext); 19346 19347 TI_DBG6(("satSendIDDev: end status %d\n", status)); 19348 return status; 19349 } 19350 19351 19352 /*****************************************************************************/ 19353 /*! \brief SAT implementation for SCSI INQUIRY. 19354 * 19355 * SAT implementation for SCSI INQUIRY. 19356 * This function prepares TD layer internal resource to send ATA 19357 * Identify Device data command for SCSI INQUIRY 19358 * 19359 * \param tiRoot: Pointer to TISA initiator driver/port instance. 19360 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 19361 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 19362 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 19363 * \param satIOContext_t: Pointer to the SAT IO Context 19364 * 19365 * \return If command is started successfully 19366 * - \e tiSuccess: I/O request successfully initiated. 19367 * - \e tiBusy: No resources available, try again later. 19368 * - \e tiIONoDevice: Invalid device handle. 19369 * - \e tiError: Other errors. 19370 */ 19371 /*****************************************************************************/ 19372 /* prerequsite: tdsaDeviceData and agdevhandle must exist; in other words, LL discovered the device 19373 already */ 19374 /* 19375 convert OS generated IO to TD generated IO due to difference in sgl 19376 */ 19377 GLOBAL bit32 satStartIDDev( 19378 tiRoot_t *tiRoot, 19379 tiIORequest_t *tiIORequest, 19380 tiDeviceHandle_t *tiDeviceHandle, 19381 tiScsiInitiatorRequest_t *tiScsiRequest, 19382 satIOContext_t *satIOContext 19383 ) 19384 { 19385 satInternalIo_t *satIntIo = agNULL; 19386 satDeviceData_t *satDevData = agNULL; 19387 tdIORequestBody_t *tdIORequestBody; 19388 satIOContext_t *satNewIOContext; 19389 bit32 status; 19390 19391 TI_DBG6(("satStartIDDev: start\n")); 19392 19393 satDevData = satIOContext->pSatDevData; 19394 19395 TI_DBG6(("satStartIDDev: before alloc\n")); 19396 19397 /* allocate identify device command */ 19398 satIntIo = satAllocIntIoResource( tiRoot, 19399 tiIORequest, 19400 satDevData, 19401 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */ 19402 satIntIo); 19403 19404 TI_DBG6(("satStartIDDev: before after\n")); 19405 19406 if (satIntIo == agNULL) 19407 { 19408 TI_DBG1(("satStartIDDev: can't alloacate\n")); 19409 19410 #if 0 19411 ostiInitiatorIOCompleted ( 19412 tiRoot, 19413 tiIORequest, 19414 tiIOFailed, 19415 tiDetailOtherError, 19416 agNULL, 19417 satIOContext->interruptContext 19418 ); 19419 #endif 19420 19421 return tiError; 19422 } 19423 19424 /* fill in fields */ 19425 /* real ttttttthe one worked and the same; 5/21/07/ */ 19426 satIntIo->satOrgTiIORequest = tiIORequest; /* changed */ 19427 tdIORequestBody = satIntIo->satIntRequestBody; 19428 satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext); 19429 19430 satNewIOContext->pSatDevData = satDevData; 19431 satNewIOContext->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 19432 satNewIOContext->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd); 19433 satNewIOContext->pSense = &(tdIORequestBody->transport.SATA.sensePayload); 19434 satNewIOContext->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData); 19435 satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */ 19436 satNewIOContext->interruptContext = tiInterruptContext; 19437 satNewIOContext->satIntIoContext = satIntIo; 19438 19439 satNewIOContext->ptiDeviceHandle = agNULL; 19440 satNewIOContext->satOrgIOContext = satIOContext; /* changed */ 19441 19442 /* this is valid only for TD layer generated (not triggered by OS at all) IO */ 19443 satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg); 19444 19445 19446 TI_DBG6(("satStartIDDev: OS satIOContext %p \n", satIOContext)); 19447 TI_DBG6(("satStartIDDev: TD satNewIOContext %p \n", satNewIOContext)); 19448 TI_DBG6(("satStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg)); 19449 TI_DBG6(("satStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg)); 19450 19451 19452 19453 TI_DBG1(("satStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody)); 19454 19455 status = satSendIDDev( tiRoot, 19456 &satIntIo->satIntTiIORequest, /* New tiIORequest */ 19457 tiDeviceHandle, 19458 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */ 19459 satNewIOContext); 19460 19461 if (status != tiSuccess) 19462 { 19463 TI_DBG1(("satStartIDDev: failed in sending\n")); 19464 19465 satFreeIntIoResource( tiRoot, 19466 satDevData, 19467 satIntIo); 19468 19469 #if 0 19470 ostiInitiatorIOCompleted ( 19471 tiRoot, 19472 tiIORequest, 19473 tiIOFailed, 19474 tiDetailOtherError, 19475 agNULL, 19476 satIOContext->interruptContext 19477 ); 19478 #endif 19479 19480 return tiError; 19481 } 19482 19483 19484 TI_DBG6(("satStartIDDev: end\n")); 19485 19486 return status; 19487 19488 19489 } 19490 19491 /*****************************************************************************/ 19492 /*! \brief satComputeCDB10LBA. 19493 * 19494 * This fuctions computes LBA of CDB10. 19495 * 19496 * \param satIOContext_t: Pointer to the SAT IO Context 19497 * 19498 * \return 19499 * - \e LBA 19500 */ 19501 /*****************************************************************************/ 19502 bit32 satComputeCDB10LBA(satIOContext_t *satIOContext) 19503 { 19504 tiIniScsiCmnd_t *scsiCmnd; 19505 tiScsiInitiatorRequest_t *tiScsiRequest; 19506 bit32 lba = 0; 19507 19508 TI_DBG5(("satComputeCDB10LBA: start\n")); 19509 tiScsiRequest = satIOContext->tiScsiXchg; 19510 scsiCmnd = &(tiScsiRequest->scsiCmnd); 19511 19512 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 19513 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 19514 19515 return lba; 19516 } 19517 19518 /*****************************************************************************/ 19519 /*! \brief satComputeCDB10TL. 19520 * 19521 * This fuctions computes transfer length of CDB10. 19522 * 19523 * \param satIOContext_t: Pointer to the SAT IO Context 19524 * 19525 * \return 19526 * - \e TL 19527 */ 19528 /*****************************************************************************/ 19529 bit32 satComputeCDB10TL(satIOContext_t *satIOContext) 19530 { 19531 19532 tiIniScsiCmnd_t *scsiCmnd; 19533 tiScsiInitiatorRequest_t *tiScsiRequest; 19534 bit32 tl = 0; 19535 19536 TI_DBG5(("satComputeCDB10TL: start\n")); 19537 tiScsiRequest = satIOContext->tiScsiXchg; 19538 scsiCmnd = &(tiScsiRequest->scsiCmnd); 19539 19540 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 19541 return tl; 19542 } 19543 19544 /*****************************************************************************/ 19545 /*! \brief satComputeCDB12LBA. 19546 * 19547 * This fuctions computes LBA of CDB12. 19548 * 19549 * \param satIOContext_t: Pointer to the SAT IO Context 19550 * 19551 * \return 19552 * - \e LBA 19553 */ 19554 /*****************************************************************************/ 19555 bit32 satComputeCDB12LBA(satIOContext_t *satIOContext) 19556 { 19557 tiIniScsiCmnd_t *scsiCmnd; 19558 tiScsiInitiatorRequest_t *tiScsiRequest; 19559 bit32 lba = 0; 19560 19561 TI_DBG5(("satComputeCDB10LBA: start\n")); 19562 tiScsiRequest = satIOContext->tiScsiXchg; 19563 scsiCmnd = &(tiScsiRequest->scsiCmnd); 19564 19565 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 19566 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 19567 19568 return lba; 19569 } 19570 19571 /*****************************************************************************/ 19572 /*! \brief satComputeCDB12TL. 19573 * 19574 * This fuctions computes transfer length of CDB12. 19575 * 19576 * \param satIOContext_t: Pointer to the SAT IO Context 19577 * 19578 * \return 19579 * - \e TL 19580 */ 19581 /*****************************************************************************/ 19582 bit32 satComputeCDB12TL(satIOContext_t *satIOContext) 19583 { 19584 19585 tiIniScsiCmnd_t *scsiCmnd; 19586 tiScsiInitiatorRequest_t *tiScsiRequest; 19587 bit32 tl = 0; 19588 19589 TI_DBG5(("satComputeCDB10TL: start\n")); 19590 tiScsiRequest = satIOContext->tiScsiXchg; 19591 scsiCmnd = &(tiScsiRequest->scsiCmnd); 19592 19593 tl = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2)) 19594 + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9]; 19595 return tl; 19596 } 19597 19598 19599 /*****************************************************************************/ 19600 /*! \brief satComputeCDB16LBA. 19601 * 19602 * This fuctions computes LBA of CDB16. 19603 * 19604 * \param satIOContext_t: Pointer to the SAT IO Context 19605 * 19606 * \return 19607 * - \e LBA 19608 */ 19609 /*****************************************************************************/ 19610 /* 19611 CBD16 has bit64 LBA 19612 But it has to be less than (2^28 - 1) 19613 Therefore, use last four bytes to compute LBA is OK 19614 */ 19615 bit32 satComputeCDB16LBA(satIOContext_t *satIOContext) 19616 { 19617 tiIniScsiCmnd_t *scsiCmnd; 19618 tiScsiInitiatorRequest_t *tiScsiRequest; 19619 bit32 lba = 0; 19620 19621 TI_DBG5(("satComputeCDB10LBA: start\n")); 19622 tiScsiRequest = satIOContext->tiScsiXchg; 19623 scsiCmnd = &(tiScsiRequest->scsiCmnd); 19624 19625 lba = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2)) 19626 + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9]; 19627 19628 return lba; 19629 } 19630 19631 /*****************************************************************************/ 19632 /*! \brief satComputeCDB16TL. 19633 * 19634 * This fuctions computes transfer length of CDB16. 19635 * 19636 * \param satIOContext_t: Pointer to the SAT IO Context 19637 * 19638 * \return 19639 * - \e TL 19640 */ 19641 /*****************************************************************************/ 19642 bit32 satComputeCDB16TL(satIOContext_t *satIOContext) 19643 { 19644 19645 tiIniScsiCmnd_t *scsiCmnd; 19646 tiScsiInitiatorRequest_t *tiScsiRequest; 19647 bit32 tl = 0; 19648 19649 TI_DBG5(("satComputeCDB10TL: start\n")); 19650 tiScsiRequest = satIOContext->tiScsiXchg; 19651 scsiCmnd = &(tiScsiRequest->scsiCmnd); 19652 19653 tl = (scsiCmnd->cdb[10] << (8*3)) + (scsiCmnd->cdb[11] << (8*2)) 19654 + (scsiCmnd->cdb[12] << 8) + scsiCmnd->cdb[13]; 19655 return tl; 19656 } 19657 19658 /*****************************************************************************/ 19659 /*! \brief satComputeLoopNum. 19660 * 19661 * This fuctions computes the number of interation needed for a transfer 19662 * length with a specific number. 19663 * 19664 * \param a: a numerator 19665 * \param b: a denominator 19666 * 19667 * \return 19668 * - \e number of interation 19669 */ 19670 /*****************************************************************************/ 19671 /* 19672 (tl, denom) 19673 tl can be upto bit32 because CDB16 has bit32 tl 19674 Therefore, fine 19675 either (tl, 0xFF) or (tl, 0xFFFF) 19676 */ 19677 bit32 satComputeLoopNum(bit32 a, bit32 b) 19678 { 19679 19680 bit32 quo = 0, rem = 0; 19681 bit32 LoopNum = 0; 19682 19683 TI_DBG5(("satComputeLoopNum: start\n")); 19684 19685 quo = a/b; 19686 19687 if (quo == 0) 19688 { 19689 LoopNum = 1; 19690 } 19691 else 19692 { 19693 rem = a % b; 19694 if (rem == 0) 19695 { 19696 LoopNum = quo; 19697 } 19698 else 19699 { 19700 LoopNum = quo + 1; 19701 } 19702 } 19703 19704 return LoopNum; 19705 } 19706 19707 /*****************************************************************************/ 19708 /*! \brief satAddNComparebit64. 19709 * 19710 * 19711 * 19712 * 19713 * \param a: lba 19714 * \param b: tl 19715 * 19716 * \return 19717 * - \e TRUE if (lba + tl > SAT_TR_LBA_LIMIT) 19718 * - \e FALSE otherwise 19719 * \note: a and b must be in the same length 19720 */ 19721 /*****************************************************************************/ 19722 /* 19723 input: bit8 a[8], bit8 b[8] (lba, tl) must be in same length 19724 if (lba + tl > SAT_TR_LBA_LIMIT) 19725 then returns true 19726 else returns false 19727 (LBA,TL) 19728 */ 19729 bit32 satAddNComparebit64(bit8 *a, bit8 *b) 19730 { 19731 bit16 ans[8]; // 0 MSB, 8 LSB 19732 bit8 final_ans[9]; // 0 MSB, 9 LSB 19733 bit8 max[9]; 19734 int i; 19735 19736 TI_DBG5(("satAddNComparebit64: start\n")); 19737 19738 osti_memset(ans, 0, sizeof(ans)); 19739 osti_memset(final_ans, 0, sizeof(final_ans)); 19740 osti_memset(max, 0, sizeof(max)); 19741 19742 max[0] = 0x1; //max = 0x1 0000 0000 0000 0000 19743 19744 // adding from LSB to MSB 19745 for(i=7;i>=0;i--) 19746 { 19747 ans[i] = (bit16)(a[i] + b[i]); 19748 if (i != 7) 19749 { 19750 ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8)); 19751 } 19752 } 19753 19754 /* 19755 filling in the final answer 19756 */ 19757 final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8)); 19758 final_ans[1] = (bit8)(ans[0] & 0xFF); 19759 19760 for(i=2;i<=8;i++) 19761 { 19762 final_ans[i] = (bit8)(ans[i-1] & 0xFF); 19763 } 19764 19765 //compare final_ans to max 19766 for(i=0;i<=8;i++) 19767 { 19768 if (final_ans[i] > max[i]) 19769 { 19770 TI_DBG5(("satAddNComparebit64: yes at %d\n", i)); 19771 return agTRUE; 19772 } 19773 else if (final_ans[i] < max[i]) 19774 { 19775 TI_DBG5(("satAddNComparebit64: no at %d\n", i)); 19776 return agFALSE; 19777 } 19778 else 19779 { 19780 continue; 19781 } 19782 } 19783 19784 19785 return agFALSE; 19786 } 19787 19788 /*****************************************************************************/ 19789 /*! \brief satAddNComparebit32. 19790 * 19791 * 19792 * 19793 * 19794 * \param a: lba 19795 * \param b: tl 19796 * 19797 * \return 19798 * - \e TRUE if (lba + tl > SAT_TR_LBA_LIMIT) 19799 * - \e FALSE otherwise 19800 * \note: a and b must be in the same length 19801 */ 19802 /*****************************************************************************/ 19803 /* 19804 input: bit8 a[4], bit8 b[4] (lba, tl) must be in same length 19805 if (lba + tl > SAT_TR_LBA_LIMIT) 19806 then returns true 19807 else returns false 19808 (LBA,TL) 19809 */ 19810 bit32 satAddNComparebit32(bit8 *a, bit8 *b) 19811 { 19812 bit16 ans[4]; // 0 MSB, 4 LSB 19813 bit8 final_ans[5]; // 0 MSB, 5 LSB 19814 bit8 max[4]; 19815 int i; 19816 19817 TI_DBG5(("satAddNComparebit32: start\n")); 19818 19819 osti_memset(ans, 0, sizeof(ans)); 19820 osti_memset(final_ans, 0, sizeof(final_ans)); 19821 osti_memset(max, 0, sizeof(max)); 19822 19823 max[0] = 0x10; // max =0x1000 0000 19824 19825 // adding from LSB to MSB 19826 for(i=3;i>=0;i--) 19827 { 19828 ans[i] = (bit16)(a[i] + b[i]); 19829 if (i != 3) 19830 { 19831 ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8)); 19832 } 19833 } 19834 19835 19836 /* 19837 filling in the final answer 19838 */ 19839 final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8)); 19840 final_ans[1] = (bit8)(ans[0] & 0xFF); 19841 19842 for(i=2;i<=4;i++) 19843 { 19844 final_ans[i] = (bit8)(ans[i-1] & 0xFF); 19845 } 19846 19847 //compare final_ans to max 19848 if (final_ans[0] != 0) 19849 { 19850 TI_DBG5(("satAddNComparebit32: yes bigger and out of range\n")); 19851 return agTRUE; 19852 } 19853 for(i=1;i<=4;i++) 19854 { 19855 if (final_ans[i] > max[i-1]) 19856 { 19857 TI_DBG5(("satAddNComparebit32: yes at %d\n", i)); 19858 return agTRUE; 19859 } 19860 else if (final_ans[i] < max[i-1]) 19861 { 19862 TI_DBG5(("satAddNComparebit32: no at %d\n", i)); 19863 return agFALSE; 19864 } 19865 else 19866 { 19867 continue; 19868 } 19869 } 19870 19871 19872 return agFALSE; 19873 } 19874 19875 /*****************************************************************************/ 19876 /*! \brief satCompareLBALimitbit. 19877 * 19878 * 19879 * 19880 * 19881 * \param lba: lba 19882 * 19883 * \return 19884 * - \e TRUE if (lba > SAT_TR_LBA_LIMIT - 1) 19885 * - \e FALSE otherwise 19886 * \note: a and b must be in the same length 19887 */ 19888 /*****************************************************************************/ 19889 19890 /* 19891 lba 19892 */ 19893 /* 19894 input: bit8 lba[8] 19895 if (lba > SAT_TR_LBA_LIMIT - 1) 19896 then returns true 19897 else returns false 19898 (LBA,TL) 19899 */ 19900 bit32 satCompareLBALimitbit(bit8 *lba) 19901 { 19902 bit32 i; 19903 bit8 limit[8]; 19904 19905 /* limit is 0xF FF FF = 2^28 - 1 */ 19906 limit[0] = 0x0; /* MSB */ 19907 limit[1] = 0x0; 19908 limit[2] = 0x0; 19909 limit[3] = 0x0; 19910 limit[4] = 0xF; 19911 limit[5] = 0xFF; 19912 limit[6] = 0xFF; 19913 limit[7] = 0xFF; /* LSB */ 19914 19915 //compare lba to limit 19916 for(i=0;i<8;i++) 19917 { 19918 if (lba[i] > limit[i]) 19919 { 19920 TI_DBG5(("satCompareLBALimitbit64: yes at %d\n", i)); 19921 return agTRUE; 19922 } 19923 else if (lba[i] < limit[i]) 19924 { 19925 TI_DBG5(("satCompareLBALimitbit64: no at %d\n", i)); 19926 return agFALSE; 19927 } 19928 else 19929 { 19930 continue; 19931 } 19932 } 19933 19934 19935 return agFALSE; 19936 19937 } 19938 /***************************************************************************** 19939 *! \brief 19940 * Purpose: bitwise set 19941 * 19942 * Parameters: 19943 * data - input output buffer 19944 * index - bit to set 19945 * 19946 * Return: 19947 * none 19948 * 19949 *****************************************************************************/ 19950 GLOBAL void 19951 satBitSet(bit8 *data, bit32 index) 19952 { 19953 data[index/8] |= (1 << (index%8)); 19954 } 19955 19956 /***************************************************************************** 19957 *! \brief 19958 * Purpose: bitwise clear 19959 * 19960 * Parameters: 19961 * data - input output buffer 19962 * index - bit to clear 19963 * 19964 * Return: 19965 * none 19966 * 19967 *****************************************************************************/ 19968 GLOBAL void 19969 satBitClear(bit8 *data, bit32 index) 19970 { 19971 data[index/8] &= ~(1 << (index%8)); 19972 } 19973 19974 /***************************************************************************** 19975 *! \brief 19976 * Purpose: bitwise test 19977 * 19978 * Parameters: 19979 * data - input output buffer 19980 * index - bit to test 19981 * 19982 * Return: 19983 * 0 - not set 19984 * 1 - set 19985 * 19986 *****************************************************************************/ 19987 GLOBAL agBOOLEAN 19988 satBitTest(bit8 *data, bit32 index) 19989 { 19990 return ( (BOOLEAN)((data[index/8] & (1 << (index%8)) ) ? 1: 0)); 19991 } 19992 19993 19994 /******************************************************************************/ 19995 /*! \brief allocate an available SATA tag 19996 * 19997 * allocate an available SATA tag 19998 * 19999 * \param tiRoot Pointer to TISA initiator driver/port instance. 20000 * \param pSatDevData 20001 * \param pTag 20002 * 20003 * \return -Success or fail- 20004 */ 20005 /*******************************************************************************/ 20006 GLOBAL bit32 satTagAlloc( 20007 tiRoot_t *tiRoot, 20008 satDeviceData_t *pSatDevData, 20009 bit8 *pTag 20010 ) 20011 { 20012 bit32 retCode = agFALSE; 20013 bit32 i; 20014 20015 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK); 20016 for ( i = 0; i < pSatDevData->satNCQMaxIO; i ++ ) 20017 { 20018 if ( 0 == satBitTest((bit8 *)&pSatDevData->freeSATAFDMATagBitmap, i) ) 20019 { 20020 satBitSet((bit8*)&pSatDevData->freeSATAFDMATagBitmap, i); 20021 *pTag = (bit8) i; 20022 retCode = agTRUE; 20023 break; 20024 } 20025 } 20026 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK); 20027 return retCode; 20028 } 20029 20030 /******************************************************************************/ 20031 /*! \brief release an SATA tag 20032 * 20033 * release an available SATA tag 20034 * 20035 * \param tiRoot Pointer to TISA initiator driver/port instance. 20036 * \param pSatDevData 20037 * \param Tag 20038 * 20039 * \return -the tag- 20040 */ 20041 /*******************************************************************************/ 20042 GLOBAL bit32 satTagRelease( 20043 tiRoot_t *tiRoot, 20044 satDeviceData_t *pSatDevData, 20045 bit8 tag 20046 ) 20047 { 20048 bit32 retCode = agFALSE; 20049 20050 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK); 20051 if ( tag < pSatDevData->satNCQMaxIO ) 20052 { 20053 satBitClear( (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, (bit32)tag); 20054 retCode = agTRUE; 20055 } 20056 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK); 20057 return retCode; 20058 } 20059 20060 /***************************************************************************** 20061 *! \brief satSubTM 20062 * 20063 * This routine is called to initiate a TM request to SATL. 20064 * This routine is independent of HW/LL API. 20065 * 20066 * \param tiRoot: Pointer to TISA initiator driver/port instance. 20067 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 20068 * \param task: SAM-3 task management request. 20069 * \param lun: Pointer to LUN. 20070 * \param taskTag: Pointer to the associated task where the TM 20071 * command is to be applied. 20072 * \param currentTaskTag: Pointer to tag/context for this TM request. 20073 * \param NotifyOS flag determines whether notify OS layer or not 20074 * 20075 * \return: 20076 * 20077 * \e tiSuccess: I/O request successfully initiated. 20078 * \e tiBusy: No resources available, try again later. 20079 * \e tiIONoDevice: Invalid device handle. 20080 * \e tiError: Other errors that prevent the I/O request to be started. 20081 * 20082 * \note: 20083 * This funcion is triggered bottom up. Not yet in use. 20084 *****************************************************************************/ 20085 /* called for bottom up */ 20086 osGLOBAL bit32 satSubTM( 20087 tiRoot_t *tiRoot, 20088 tiDeviceHandle_t *tiDeviceHandle, 20089 bit32 task, 20090 tiLUN_t *lun, 20091 tiIORequest_t *taskTag, 20092 tiIORequest_t *currentTaskTag, 20093 bit32 NotifyOS 20094 ) 20095 { 20096 void *osMemHandle; 20097 tdIORequestBody_t *TMtdIORequestBody; 20098 bit32 PhysUpper32; 20099 bit32 PhysLower32; 20100 bit32 memAllocStatus; 20101 agsaIORequest_t *agIORequest = agNULL; 20102 20103 TI_DBG6(("satSubTM: start\n")); 20104 20105 /* allocation tdIORequestBody and pass it to satTM() */ 20106 memAllocStatus = ostiAllocMemory( 20107 tiRoot, 20108 &osMemHandle, 20109 (void **)&TMtdIORequestBody, 20110 &PhysUpper32, 20111 &PhysLower32, 20112 8, 20113 sizeof(tdIORequestBody_t), 20114 agTRUE 20115 ); 20116 20117 if (memAllocStatus != tiSuccess) 20118 { 20119 TI_DBG1(("satSubTM: ostiAllocMemory failed... \n")); 20120 return tiError; 20121 } 20122 20123 if (TMtdIORequestBody == agNULL) 20124 { 20125 TI_DBG1(("satSubTM: ostiAllocMemory returned NULL TMIORequestBody\n")); 20126 return tiError; 20127 } 20128 20129 /* setup task management structure */ 20130 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 20131 TMtdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = agNULL; 20132 TMtdIORequestBody->IOType.InitiatorTMIO.TaskTag = agNULL; 20133 20134 /* initialize tiDevhandle */ 20135 TMtdIORequestBody->tiDevHandle = tiDeviceHandle; 20136 20137 /* initialize tiIORequest */ 20138 TMtdIORequestBody->tiIORequest = agNULL; 20139 20140 /* initialize agIORequest */ 20141 agIORequest = &(TMtdIORequestBody->agIORequest); 20142 agIORequest->osData = (void *) TMtdIORequestBody; 20143 agIORequest->sdkData = agNULL; /* SA takes care of this */ 20144 satTM(tiRoot, 20145 tiDeviceHandle, 20146 task, /* TD_INTERNAL_TM_RESET */ 20147 agNULL, 20148 agNULL, 20149 agNULL, 20150 TMtdIORequestBody, 20151 agFALSE); 20152 20153 return tiSuccess; 20154 } 20155 20156 20157 /*****************************************************************************/ 20158 /*! \brief SAT implementation for satStartResetDevice. 20159 * 20160 * SAT implementation for sending SRT and send FIS request to LL layer. 20161 * 20162 * \param tiRoot: Pointer to TISA initiator driver/port instance. 20163 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 20164 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 20165 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 20166 * \param satIOContext_t: Pointer to the SAT IO Context 20167 * 20168 * \return If command is started successfully 20169 * - \e tiSuccess: I/O request successfully initiated. 20170 * - \e tiBusy: No resources available, try again later. 20171 * - \e tiIONoDevice: Invalid device handle. 20172 * - \e tiError: Other errors. 20173 * \note : triggerred by OS layer or bottom up 20174 */ 20175 /*****************************************************************************/ 20176 /* OS triggerred or bottom up */ 20177 GLOBAL bit32 20178 satStartResetDevice( 20179 tiRoot_t *tiRoot, 20180 tiIORequest_t *tiIORequest, /* currentTaskTag */ 20181 tiDeviceHandle_t *tiDeviceHandle, 20182 tiScsiInitiatorRequest_t *tiScsiRequest, /* should be NULL */ 20183 satIOContext_t *satIOContext 20184 ) 20185 { 20186 satInternalIo_t *satIntIo = agNULL; 20187 satDeviceData_t *satDevData = agNULL; 20188 satIOContext_t *satNewIOContext; 20189 bit32 status; 20190 tiIORequest_t *currentTaskTag = agNULL; 20191 20192 TI_DBG1(("satStartResetDevice: start\n")); 20193 20194 currentTaskTag = tiIORequest; 20195 20196 satDevData = satIOContext->pSatDevData; 20197 20198 TI_DBG6(("satStartResetDevice: before alloc\n")); 20199 20200 /* allocate any fis for seting SRT bit in device control */ 20201 satIntIo = satAllocIntIoResource( tiRoot, 20202 tiIORequest, 20203 satDevData, 20204 0, 20205 satIntIo); 20206 20207 TI_DBG6(("satStartResetDevice: before after\n")); 20208 20209 if (satIntIo == agNULL) 20210 { 20211 TI_DBG1(("satStartResetDevice: can't alloacate\n")); 20212 if (satIOContext->NotifyOS) 20213 { 20214 ostiInitiatorEvent( tiRoot, 20215 NULL, 20216 NULL, 20217 tiIntrEventTypeTaskManagement, 20218 tiTMFailed, 20219 currentTaskTag ); 20220 } 20221 return tiError; 20222 } 20223 20224 satNewIOContext = satPrepareNewIO(satIntIo, 20225 tiIORequest, 20226 satDevData, 20227 agNULL, 20228 satIOContext); 20229 20230 TI_DBG6(("satStartResetDevice: OS satIOContext %p \n", satIOContext)); 20231 TI_DBG6(("satStartResetDevice: TD satNewIOContext %p \n", satNewIOContext)); 20232 TI_DBG6(("satStartResetDevice: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg)); 20233 TI_DBG6(("satStartResetDevice: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg)); 20234 20235 20236 20237 TI_DBG6(("satStartResetDevice: satNewIOContext %p \n", satNewIOContext)); 20238 20239 if (satDevData->satDeviceType == SATA_ATAPI_DEVICE) 20240 { 20241 status = satDeviceReset(tiRoot, 20242 &satIntIo->satIntTiIORequest, /* New tiIORequest */ 20243 tiDeviceHandle, 20244 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */ 20245 satNewIOContext); 20246 } 20247 else 20248 { 20249 status = satResetDevice(tiRoot, 20250 &satIntIo->satIntTiIORequest, /* New tiIORequest */ 20251 tiDeviceHandle, 20252 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */ 20253 satNewIOContext); 20254 } 20255 20256 if (status != tiSuccess) 20257 { 20258 TI_DBG1(("satStartResetDevice: failed in sending\n")); 20259 20260 satFreeIntIoResource( tiRoot, 20261 satDevData, 20262 satIntIo); 20263 if (satIOContext->NotifyOS) 20264 { 20265 ostiInitiatorEvent( tiRoot, 20266 NULL, 20267 NULL, 20268 tiIntrEventTypeTaskManagement, 20269 tiTMFailed, 20270 currentTaskTag ); 20271 } 20272 20273 return tiError; 20274 } 20275 20276 20277 TI_DBG6(("satStartResetDevice: end\n")); 20278 20279 return status; 20280 } 20281 20282 /*****************************************************************************/ 20283 /*! \brief SAT implementation for satResetDevice. 20284 * 20285 * SAT implementation for building SRT FIS and sends the request to LL layer. 20286 * 20287 * \param tiRoot: Pointer to TISA initiator driver/port instance. 20288 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 20289 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 20290 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 20291 * \param satIOContext_t: Pointer to the SAT IO Context 20292 * 20293 * \return If command is started successfully 20294 * - \e tiSuccess: I/O request successfully initiated. 20295 * - \e tiBusy: No resources available, try again later. 20296 * - \e tiIONoDevice: Invalid device handle. 20297 * - \e tiError: Other errors. 20298 */ 20299 /*****************************************************************************/ 20300 20301 /* 20302 create any fis and set SRST bit in device control 20303 */ 20304 GLOBAL bit32 20305 satResetDevice( 20306 tiRoot_t *tiRoot, 20307 tiIORequest_t *tiIORequest, 20308 tiDeviceHandle_t *tiDeviceHandle, 20309 tiScsiInitiatorRequest_t *tiScsiRequest, 20310 satIOContext_t *satIOContext 20311 ) 20312 { 20313 bit32 status; 20314 bit32 agRequestType; 20315 agsaFisRegHostToDevice_t *fis; 20316 #ifdef TD_DEBUG_ENABLE 20317 tdIORequestBody_t *tdIORequestBody; 20318 satInternalIo_t *satIntIoContext; 20319 #endif 20320 20321 fis = satIOContext->pFis; 20322 20323 TI_DBG2(("satResetDevice: start\n")); 20324 20325 #ifdef TD_DEBUG_ENABLE 20326 satIntIoContext = satIOContext->satIntIoContext; 20327 tdIORequestBody = satIntIoContext->satIntRequestBody; 20328 #endif 20329 TI_DBG5(("satResetDevice: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody)); 20330 /* any fis should work */ 20331 fis->h.fisType = 0x27; /* Reg host to device */ 20332 fis->h.c_pmPort = 0; /* C Bit is not set */ 20333 fis->h.command = 0; /* any command */ 20334 fis->h.features = 0; /* FIS reserve */ 20335 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 20336 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 20337 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 20338 fis->d.device = 0; /* FIS LBA mode */ 20339 fis->d.lbaLowExp = 0; 20340 fis->d.lbaMidExp = 0; 20341 fis->d.lbaHighExp = 0; 20342 fis->d.featuresExp = 0; 20343 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 20344 fis->d.sectorCountExp = 0; 20345 fis->d.reserved4 = 0; 20346 fis->d.control = 0x4; /* SRST bit is set */ 20347 fis->d.reserved5 = 0; 20348 20349 agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT; 20350 20351 satIOContext->satCompleteCB = &satResetDeviceCB; 20352 20353 /* 20354 * Prepare SGL and send FIS to LL layer. 20355 */ 20356 satIOContext->reqType = agRequestType; /* Save it */ 20357 20358 #ifdef TD_INTERNAL_DEBUG 20359 tdhexdump("satResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 20360 #ifdef TD_DEBUG_ENABLE 20361 tdhexdump("satResetDevice LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t)); 20362 #endif 20363 #endif 20364 20365 status = sataLLIOStart( tiRoot, 20366 tiIORequest, 20367 tiDeviceHandle, 20368 tiScsiRequest, 20369 satIOContext); 20370 20371 TI_DBG6(("satResetDevice: end status %d\n", status)); 20372 return status; 20373 } 20374 20375 /***************************************************************************** 20376 *! \brief satResetDeviceCB 20377 * 20378 * This routine is a callback function called from ossaSATACompleted(). 20379 * This CB routine deals with SRT completion. This function send DSRT 20380 * 20381 * \param agRoot: Handles for this instance of SAS/SATA hardware 20382 * \param agIORequest: Pointer to the LL I/O request context for this I/O. 20383 * \param agIOStatus: Status of completed I/O. 20384 * \param agFirstDword:Pointer to the four bytes of FIS. 20385 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS 20386 * length. 20387 * \param agParam: Additional info based on status. 20388 * \param ioContext: Pointer to satIOContext_t. 20389 * 20390 * \return: none 20391 * 20392 *****************************************************************************/ 20393 GLOBAL void satResetDeviceCB( 20394 agsaRoot_t *agRoot, 20395 agsaIORequest_t *agIORequest, 20396 bit32 agIOStatus, 20397 agsaFisHeader_t *agFirstDword, 20398 bit32 agIOInfoLen, 20399 agsaFrameHandle_t agFrameHandle, 20400 void *ioContext 20401 ) 20402 { 20403 /* callback for satResetDevice */ 20404 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 20405 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 20406 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 20407 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 20408 tdIORequestBody_t *tdIORequestBody; 20409 tdIORequestBody_t *tdOrgIORequestBody; 20410 satIOContext_t *satIOContext; 20411 satIOContext_t *satOrgIOContext; 20412 satIOContext_t *satNewIOContext; 20413 satInternalIo_t *satIntIo; 20414 satInternalIo_t *satNewIntIo = agNULL; 20415 satDeviceData_t *satDevData; 20416 tiIORequest_t *tiOrgIORequest; 20417 #ifdef TD_DEBUG_ENABLE 20418 bit32 ataStatus = 0; 20419 bit32 ataError; 20420 agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL; 20421 #endif 20422 bit32 status; 20423 20424 TI_DBG1(("satResetDeviceCB: start\n")); 20425 TI_DBG6(("satResetDeviceCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen)); 20426 20427 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; 20428 satIOContext = (satIOContext_t *) ioContext; 20429 satIntIo = satIOContext->satIntIoContext; 20430 satDevData = satIOContext->pSatDevData; 20431 if (satIntIo == agNULL) 20432 { 20433 TI_DBG6(("satResetDeviceCB: External, OS generated\n")); 20434 satOrgIOContext = satIOContext; 20435 tiOrgIORequest = tdIORequestBody->tiIORequest; 20436 } 20437 else 20438 { 20439 TI_DBG6(("satResetDeviceCB: Internal, TD generated\n")); 20440 satOrgIOContext = satIOContext->satOrgIOContext; 20441 if (satOrgIOContext == agNULL) 20442 { 20443 TI_DBG6(("satResetDeviceCB: satOrgIOContext is NULL, wrong\n")); 20444 return; 20445 } 20446 else 20447 { 20448 TI_DBG6(("satResetDeviceCB: satOrgIOContext is NOT NULL\n")); 20449 } 20450 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody; 20451 tiOrgIORequest = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest; 20452 } 20453 20454 tdIORequestBody->ioCompleted = agTRUE; 20455 tdIORequestBody->ioStarted = agFALSE; 20456 20457 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS) 20458 { 20459 TI_DBG1(("satResetDeviceCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus)); 20460 if (satOrgIOContext->NotifyOS == agTRUE) 20461 { 20462 ostiInitiatorEvent( tiRoot, 20463 NULL, 20464 NULL, 20465 tiIntrEventTypeTaskManagement, 20466 tiTMFailed, 20467 tiOrgIORequest ); 20468 } 20469 20470 satDevData->satTmTaskTag = agNULL; 20471 20472 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 20473 20474 satFreeIntIoResource( tiRoot, 20475 satDevData, 20476 satIntIo); 20477 return; 20478 } 20479 20480 if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED || 20481 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION || 20482 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK || 20483 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS || 20484 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION || 20485 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED || 20486 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION || 20487 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR || 20488 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY 20489 ) 20490 { 20491 TI_DBG1(("satResetDeviceCB: OSSA_IO_OPEN_CNX_ERROR\n")); 20492 20493 if (satOrgIOContext->NotifyOS == agTRUE) 20494 { 20495 ostiInitiatorEvent( tiRoot, 20496 NULL, 20497 NULL, 20498 tiIntrEventTypeTaskManagement, 20499 tiTMFailed, 20500 tiOrgIORequest ); 20501 } 20502 20503 satDevData->satTmTaskTag = agNULL; 20504 20505 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 20506 20507 satFreeIntIoResource( tiRoot, 20508 satDevData, 20509 satIntIo); 20510 return; 20511 } 20512 20513 if (agIOStatus != OSSA_IO_SUCCESS) 20514 { 20515 #ifdef TD_DEBUG_ENABLE 20516 /* only agsaFisPioSetup_t is expected */ 20517 satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup); 20518 ataStatus = satPIOSetupHeader->status; /* ATA Status register */ 20519 ataError = satPIOSetupHeader->error; /* ATA Eror register */ 20520 #endif 20521 TI_DBG1(("satResetDeviceCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError)); 20522 20523 if (satOrgIOContext->NotifyOS == agTRUE) 20524 { 20525 ostiInitiatorEvent( tiRoot, 20526 NULL, 20527 NULL, 20528 tiIntrEventTypeTaskManagement, 20529 tiTMFailed, 20530 tiOrgIORequest ); 20531 } 20532 20533 satDevData->satTmTaskTag = agNULL; 20534 20535 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 20536 20537 satFreeIntIoResource( tiRoot, 20538 satDevData, 20539 satIntIo); 20540 return; 20541 } 20542 20543 /* success */ 20544 20545 satNewIntIo = satAllocIntIoResource( tiRoot, 20546 tiOrgIORequest, 20547 satDevData, 20548 0, 20549 satNewIntIo); 20550 if (satNewIntIo == agNULL) 20551 { 20552 satDevData->satTmTaskTag = agNULL; 20553 20554 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 20555 20556 /* memory allocation failure */ 20557 satFreeIntIoResource( tiRoot, 20558 satDevData, 20559 satNewIntIo); 20560 20561 if (satOrgIOContext->NotifyOS == agTRUE) 20562 { 20563 ostiInitiatorEvent( tiRoot, 20564 NULL, 20565 NULL, 20566 tiIntrEventTypeTaskManagement, 20567 tiTMFailed, 20568 tiOrgIORequest ); 20569 } 20570 20571 20572 TI_DBG1(("satResetDeviceCB: momory allocation fails\n")); 20573 return; 20574 } /* end of memory allocation failure */ 20575 20576 /* 20577 * Need to initialize all the fields within satIOContext 20578 */ 20579 20580 satNewIOContext = satPrepareNewIO( 20581 satNewIntIo, 20582 tiOrgIORequest, 20583 satDevData, 20584 agNULL, 20585 satOrgIOContext 20586 ); 20587 20588 20589 20590 20591 /* send AGSA_SATA_PROTOCOL_SRST_DEASSERT */ 20592 status = satDeResetDevice(tiRoot, 20593 tiOrgIORequest, 20594 satOrgIOContext->ptiDeviceHandle, 20595 agNULL, 20596 satNewIOContext 20597 ); 20598 20599 if (status != tiSuccess) 20600 { 20601 if (satOrgIOContext->NotifyOS == agTRUE) 20602 { 20603 ostiInitiatorEvent( tiRoot, 20604 NULL, 20605 NULL, 20606 tiIntrEventTypeTaskManagement, 20607 tiTMFailed, 20608 tiOrgIORequest ); 20609 } 20610 20611 /* sending AGSA_SATA_PROTOCOL_SRST_DEASSERT fails */ 20612 20613 satDevData->satTmTaskTag = agNULL; 20614 20615 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 20616 20617 satFreeIntIoResource( tiRoot, 20618 satDevData, 20619 satNewIntIo); 20620 return; 20621 20622 } 20623 20624 satDevData->satTmTaskTag = agNULL; 20625 20626 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 20627 20628 satFreeIntIoResource( tiRoot, 20629 satDevData, 20630 satIntIo); 20631 TI_DBG5(("satResetDeviceCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO)); 20632 TI_DBG6(("satResetDeviceCB: end\n")); 20633 return; 20634 20635 } 20636 20637 20638 /*****************************************************************************/ 20639 /*! \brief SAT implementation for satDeResetDevice. 20640 * 20641 * SAT implementation for building DSRT FIS and sends the request to LL layer. 20642 * 20643 * \param tiRoot: Pointer to TISA initiator driver/port instance. 20644 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 20645 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 20646 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 20647 * \param satIOContext_t: Pointer to the SAT IO Context 20648 * 20649 * \return If command is started successfully 20650 * - \e tiSuccess: I/O request successfully initiated. 20651 * - \e tiBusy: No resources available, try again later. 20652 * - \e tiIONoDevice: Invalid device handle. 20653 * - \e tiError: Other errors. 20654 */ 20655 /*****************************************************************************/ 20656 GLOBAL bit32 satDeResetDevice( 20657 tiRoot_t *tiRoot, 20658 tiIORequest_t *tiIORequest, 20659 tiDeviceHandle_t *tiDeviceHandle, 20660 tiScsiInitiatorRequest_t *tiScsiRequest, 20661 satIOContext_t *satIOContext 20662 ) 20663 { 20664 bit32 status; 20665 bit32 agRequestType; 20666 agsaFisRegHostToDevice_t *fis; 20667 #ifdef TD_DEBUG_ENABLE 20668 tdIORequestBody_t *tdIORequestBody; 20669 satInternalIo_t *satIntIoContext; 20670 #endif 20671 fis = satIOContext->pFis; 20672 20673 TI_DBG6(("satDeResetDevice: start\n")); 20674 20675 #ifdef TD_DEBUG_ENABLE 20676 satIntIoContext = satIOContext->satIntIoContext; 20677 tdIORequestBody = satIntIoContext->satIntRequestBody; 20678 TI_DBG5(("satDeResetDevice: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody)); 20679 #endif 20680 /* any fis should work */ 20681 fis->h.fisType = 0x27; /* Reg host to device */ 20682 fis->h.c_pmPort = 0; /* C Bit is not set */ 20683 fis->h.command = 0; /* any command */ 20684 fis->h.features = 0; /* FIS reserve */ 20685 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 20686 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 20687 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 20688 fis->d.device = 0; /* FIS LBA mode */ 20689 fis->d.lbaLowExp = 0; 20690 fis->d.lbaMidExp = 0; 20691 fis->d.lbaHighExp = 0; 20692 fis->d.featuresExp = 0; 20693 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 20694 fis->d.sectorCountExp = 0; 20695 fis->d.reserved4 = 0; 20696 fis->d.control = 0; /* SRST bit is not set */ 20697 fis->d.reserved5 = 0; 20698 20699 agRequestType = AGSA_SATA_PROTOCOL_SRST_DEASSERT; 20700 20701 satIOContext->satCompleteCB = &satDeResetDeviceCB; 20702 20703 /* 20704 * Prepare SGL and send FIS to LL layer. 20705 */ 20706 satIOContext->reqType = agRequestType; /* Save it */ 20707 20708 #ifdef TD_INTERNAL_DEBUG 20709 tdhexdump("satDeResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 20710 #ifdef TD_DEBUG_ENABLE 20711 tdhexdump("satDeResetDevice LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t)); 20712 #endif 20713 #endif 20714 20715 status = sataLLIOStart( tiRoot, 20716 tiIORequest, 20717 tiDeviceHandle, 20718 tiScsiRequest, 20719 satIOContext); 20720 20721 TI_DBG6(("satDeResetDevice: end status %d\n", status)); 20722 return status; 20723 20724 } 20725 20726 /***************************************************************************** 20727 *! \brief satDeResetDeviceCB 20728 * 20729 * This routine is a callback function called from ossaSATACompleted(). 20730 * This CB routine deals with DSRT completion. 20731 * 20732 * \param agRoot: Handles for this instance of SAS/SATA hardware 20733 * \param agIORequest: Pointer to the LL I/O request context for this I/O. 20734 * \param agIOStatus: Status of completed I/O. 20735 * \param agFirstDword:Pointer to the four bytes of FIS. 20736 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS 20737 * length. 20738 * \param agParam: Additional info based on status. 20739 * \param ioContext: Pointer to satIOContext_t. 20740 * 20741 * \return: none 20742 * 20743 *****************************************************************************/ 20744 GLOBAL void satDeResetDeviceCB( 20745 agsaRoot_t *agRoot, 20746 agsaIORequest_t *agIORequest, 20747 bit32 agIOStatus, 20748 agsaFisHeader_t *agFirstDword, 20749 bit32 agIOInfoLen, 20750 agsaFrameHandle_t agFrameHandle, 20751 void *ioContext 20752 ) 20753 { 20754 /* callback for satDeResetDevice */ 20755 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 20756 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 20757 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 20758 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 20759 tdIORequestBody_t *tdIORequestBody; 20760 tdIORequestBody_t *tdOrgIORequestBody = agNULL; 20761 satIOContext_t *satIOContext; 20762 satIOContext_t *satOrgIOContext; 20763 satInternalIo_t *satIntIo; 20764 satDeviceData_t *satDevData; 20765 tiIORequest_t *tiOrgIORequest; 20766 #ifdef TD_DEBUG_ENABLE 20767 bit32 ataStatus = 0; 20768 bit32 ataError; 20769 agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL; 20770 #endif 20771 bit32 report = agFALSE; 20772 bit32 AbortTM = agFALSE; 20773 20774 TI_DBG1(("satDeResetDeviceCB: start\n")); 20775 TI_DBG6(("satDeResetDeviceCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen)); 20776 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; 20777 satIOContext = (satIOContext_t *) ioContext; 20778 satIntIo = satIOContext->satIntIoContext; 20779 satDevData = satIOContext->pSatDevData; 20780 if (satIntIo == agNULL) 20781 { 20782 TI_DBG6(("satDeResetDeviceCB: External, OS generated\n")); 20783 satOrgIOContext = satIOContext; 20784 tiOrgIORequest = tdIORequestBody->tiIORequest; 20785 } 20786 else 20787 { 20788 TI_DBG6(("satDeResetDeviceCB: Internal, TD generated\n")); 20789 satOrgIOContext = satIOContext->satOrgIOContext; 20790 if (satOrgIOContext == agNULL) 20791 { 20792 TI_DBG6(("satDeResetDeviceCB: satOrgIOContext is NULL, wrong\n")); 20793 return; 20794 } 20795 else 20796 { 20797 TI_DBG6(("satDeResetDeviceCB: satOrgIOContext is NOT NULL\n")); 20798 } 20799 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody; 20800 tiOrgIORequest = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest; 20801 } 20802 20803 tdIORequestBody->ioCompleted = agTRUE; 20804 tdIORequestBody->ioStarted = agFALSE; 20805 20806 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS) 20807 { 20808 TI_DBG1(("satDeResetDeviceCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus)); 20809 if (satOrgIOContext->NotifyOS == agTRUE) 20810 { 20811 ostiInitiatorEvent( tiRoot, 20812 NULL, 20813 NULL, 20814 tiIntrEventTypeTaskManagement, 20815 tiTMFailed, 20816 tiOrgIORequest ); 20817 } 20818 20819 satDevData->satTmTaskTag = agNULL; 20820 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 20821 20822 satFreeIntIoResource( tiRoot, 20823 satDevData, 20824 satIntIo); 20825 return; 20826 } 20827 20828 if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED || 20829 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION || 20830 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK || 20831 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS || 20832 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION || 20833 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED || 20834 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION || 20835 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR || 20836 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY 20837 ) 20838 { 20839 TI_DBG1(("satDeResetDeviceCB: OSSA_IO_OPEN_CNX_ERROR\n")); 20840 20841 if (satOrgIOContext->NotifyOS == agTRUE) 20842 { 20843 ostiInitiatorEvent( tiRoot, 20844 NULL, 20845 NULL, 20846 tiIntrEventTypeTaskManagement, 20847 tiTMFailed, 20848 tiOrgIORequest ); 20849 } 20850 20851 satDevData->satTmTaskTag = agNULL; 20852 20853 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 20854 20855 satFreeIntIoResource( tiRoot, 20856 satDevData, 20857 satIntIo); 20858 return; 20859 } 20860 20861 if (agIOStatus != OSSA_IO_SUCCESS) 20862 { 20863 #ifdef TD_DEBUG_ENABLE 20864 /* only agsaFisPioSetup_t is expected */ 20865 satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup); 20866 ataStatus = satPIOSetupHeader->status; /* ATA Status register */ 20867 ataError = satPIOSetupHeader->error; /* ATA Eror register */ 20868 #endif 20869 TI_DBG1(("satDeResetDeviceCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError)); 20870 20871 if (satOrgIOContext->NotifyOS == agTRUE) 20872 { 20873 ostiInitiatorEvent( tiRoot, 20874 NULL, 20875 NULL, 20876 tiIntrEventTypeTaskManagement, 20877 tiTMFailed, 20878 tiOrgIORequest ); 20879 } 20880 20881 satDevData->satTmTaskTag = agNULL; 20882 20883 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 20884 20885 satFreeIntIoResource( tiRoot, 20886 satDevData, 20887 satIntIo); 20888 return; 20889 } 20890 20891 /* success */ 20892 TI_DBG1(("satDeResetDeviceCB: success \n")); 20893 TI_DBG1(("satDeResetDeviceCB: TMF %d\n", satOrgIOContext->TMF)); 20894 20895 if (satOrgIOContext->TMF == AG_ABORT_TASK) 20896 { 20897 AbortTM = agTRUE; 20898 } 20899 20900 if (satOrgIOContext->NotifyOS == agTRUE) 20901 { 20902 report = agTRUE; 20903 } 20904 20905 if (AbortTM == agTRUE) 20906 { 20907 TI_DBG1(("satDeResetDeviceCB: calling satAbort\n")); 20908 satAbort(agRoot, satOrgIOContext->satToBeAbortedIOContext); 20909 } 20910 satDevData->satTmTaskTag = agNULL; 20911 20912 satDevData->satDriveState = SAT_DEV_STATE_NORMAL; 20913 20914 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 20915 20916 TI_DBG1(("satDeResetDeviceCB: satPendingIO %d satNCQMaxIO %d\n", satDevData->satPendingIO, satDevData->satNCQMaxIO )); 20917 TI_DBG1(("satDeResetDeviceCB: satPendingNCQIO %d satPendingNONNCQIO %d\n", satDevData->satPendingNCQIO, satDevData->satPendingNONNCQIO)); 20918 20919 satFreeIntIoResource( tiRoot, 20920 satDevData, 20921 satIntIo); 20922 20923 /* clean up TD layer's IORequestBody */ 20924 if (tdOrgIORequestBody != agNULL) 20925 { 20926 ostiFreeMemory( 20927 tiRoot, 20928 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 20929 sizeof(tdIORequestBody_t) 20930 ); 20931 } 20932 else 20933 { 20934 TI_DBG1(("satDeResetDeviceCB: tdOrgIORequestBody is NULL, wrong\n")); 20935 } 20936 20937 20938 if (report) 20939 { 20940 ostiInitiatorEvent( tiRoot, 20941 NULL, 20942 NULL, 20943 tiIntrEventTypeTaskManagement, 20944 tiTMOK, 20945 tiOrgIORequest ); 20946 } 20947 20948 20949 TI_DBG5(("satDeResetDeviceCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO)); 20950 TI_DBG6(("satDeResetDeviceCB: end\n")); 20951 return; 20952 20953 } 20954 20955 /*****************************************************************************/ 20956 /*! \brief SAT implementation for satStartCheckPowerMode. 20957 * 20958 * SAT implementation for abort task management for non-ncq sata disk. 20959 * This function sends CHECK POWER MODE 20960 * 20961 * \param tiRoot: Pointer to TISA initiator driver/port instance. 20962 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 20963 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 20964 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 20965 * \param satIOContext_t: Pointer to the SAT IO Context 20966 * 20967 * \return If command is started successfully 20968 * - \e tiSuccess: I/O request successfully initiated. 20969 * - \e tiBusy: No resources available, try again later. 20970 * - \e tiIONoDevice: Invalid device handle. 20971 * - \e tiError: Other errors. 20972 */ 20973 /*****************************************************************************/ 20974 GLOBAL bit32 satStartCheckPowerMode( 20975 tiRoot_t *tiRoot, 20976 tiIORequest_t *tiIORequest, 20977 tiDeviceHandle_t *tiDeviceHandle, 20978 tiScsiInitiatorRequest_t *tiScsiRequest, /* NULL */ 20979 satIOContext_t *satIOContext 20980 ) 20981 { 20982 satInternalIo_t *satIntIo = agNULL; 20983 satDeviceData_t *satDevData = agNULL; 20984 satIOContext_t *satNewIOContext; 20985 bit32 status; 20986 tiIORequest_t *currentTaskTag = agNULL; 20987 20988 TI_DBG6(("satStartCheckPowerMode: start\n")); 20989 20990 currentTaskTag = tiIORequest; 20991 20992 satDevData = satIOContext->pSatDevData; 20993 20994 TI_DBG6(("satStartCheckPowerMode: before alloc\n")); 20995 20996 /* allocate any fis for seting SRT bit in device control */ 20997 satIntIo = satAllocIntIoResource( tiRoot, 20998 tiIORequest, 20999 satDevData, 21000 0, 21001 satIntIo); 21002 21003 TI_DBG6(("satStartCheckPowerMode: before after\n")); 21004 21005 if (satIntIo == agNULL) 21006 { 21007 TI_DBG1(("satStartCheckPowerMode: can't alloacate\n")); 21008 if (satIOContext->NotifyOS) 21009 { 21010 ostiInitiatorEvent( tiRoot, 21011 NULL, 21012 NULL, 21013 tiIntrEventTypeTaskManagement, 21014 tiTMFailed, 21015 currentTaskTag ); 21016 } 21017 return tiError; 21018 } 21019 21020 satNewIOContext = satPrepareNewIO(satIntIo, 21021 tiIORequest, 21022 satDevData, 21023 agNULL, 21024 satIOContext); 21025 21026 TI_DBG6(("satStartCheckPowerMode: OS satIOContext %p \n", satIOContext)); 21027 TI_DBG6(("satStartCheckPowerMode: TD satNewIOContext %p \n", satNewIOContext)); 21028 TI_DBG6(("satStartCheckPowerMode: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg)); 21029 TI_DBG6(("satStartCheckPowerMode: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg)); 21030 21031 21032 21033 TI_DBG1(("satStartCheckPowerMode: satNewIOContext %p \n", satNewIOContext)); 21034 21035 status = satCheckPowerMode(tiRoot, 21036 &satIntIo->satIntTiIORequest, /* New tiIORequest */ 21037 tiDeviceHandle, 21038 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */ 21039 satNewIOContext); 21040 21041 if (status != tiSuccess) 21042 { 21043 TI_DBG1(("satStartCheckPowerMode: failed in sending\n")); 21044 21045 satFreeIntIoResource( tiRoot, 21046 satDevData, 21047 satIntIo); 21048 if (satIOContext->NotifyOS) 21049 { 21050 ostiInitiatorEvent( tiRoot, 21051 NULL, 21052 NULL, 21053 tiIntrEventTypeTaskManagement, 21054 tiTMFailed, 21055 currentTaskTag ); 21056 } 21057 21058 return tiError; 21059 } 21060 21061 21062 TI_DBG6(("satStartCheckPowerMode: end\n")); 21063 21064 return status; 21065 } 21066 21067 /*****************************************************************************/ 21068 /*! \brief SAT implementation for satCheckPowerMode. 21069 * 21070 * This function creates CHECK POWER MODE fis and sends the request to LL layer 21071 * 21072 * \param tiRoot: Pointer to TISA initiator driver/port instance. 21073 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 21074 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 21075 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 21076 * \param satIOContext_t: Pointer to the SAT IO Context 21077 * 21078 * \return If command is started successfully 21079 * - \e tiSuccess: I/O request successfully initiated. 21080 * - \e tiBusy: No resources available, try again later. 21081 * - \e tiIONoDevice: Invalid device handle. 21082 * - \e tiError: Other errors. 21083 */ 21084 /*****************************************************************************/ 21085 GLOBAL bit32 satCheckPowerMode( 21086 tiRoot_t *tiRoot, 21087 tiIORequest_t *tiIORequest, 21088 tiDeviceHandle_t *tiDeviceHandle, 21089 tiScsiInitiatorRequest_t *tiScsiRequest, 21090 satIOContext_t *satIOContext 21091 ) 21092 { 21093 /* 21094 sends SAT_CHECK_POWER_MODE as a part of ABORT TASKMANGEMENT for NCQ commands 21095 internally generated - no directly corresponding scsi 21096 */ 21097 bit32 status; 21098 bit32 agRequestType; 21099 agsaFisRegHostToDevice_t *fis; 21100 21101 fis = satIOContext->pFis; 21102 TI_DBG5(("satCheckPowerMode: start\n")); 21103 /* 21104 * Send the ATA CHECK POWER MODE command. 21105 */ 21106 fis->h.fisType = 0x27; /* Reg host to device */ 21107 fis->h.c_pmPort = 0x80; /* C Bit is set */ 21108 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */ 21109 fis->h.features = 0; 21110 fis->d.lbaLow = 0; 21111 fis->d.lbaMid = 0; 21112 fis->d.lbaHigh = 0; 21113 fis->d.device = 0; 21114 fis->d.lbaLowExp = 0; 21115 fis->d.lbaMidExp = 0; 21116 fis->d.lbaHighExp = 0; 21117 fis->d.featuresExp = 0; 21118 fis->d.sectorCount = 0; 21119 fis->d.sectorCountExp = 0; 21120 fis->d.reserved4 = 0; 21121 fis->d.control = 0; /* FIS HOB bit clear */ 21122 fis->d.reserved5 = 0; 21123 21124 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 21125 21126 /* Initialize CB for SATA completion. 21127 */ 21128 satIOContext->satCompleteCB = &satCheckPowerModeCB; 21129 21130 /* 21131 * Prepare SGL and send FIS to LL layer. 21132 */ 21133 satIOContext->reqType = agRequestType; /* Save it */ 21134 21135 status = sataLLIOStart( tiRoot, 21136 tiIORequest, 21137 tiDeviceHandle, 21138 tiScsiRequest, 21139 satIOContext); 21140 21141 TI_DBG5(("satCheckPowerMode: return\n")); 21142 21143 return status; 21144 } 21145 21146 /***************************************************************************** 21147 *! \brief satCheckPowerModeCB 21148 * 21149 * This routine is a callback function called from ossaSATACompleted(). 21150 * This CB routine deals with CHECK POWER MODE completion as abort task 21151 * management. 21152 * 21153 * \param agRoot: Handles for this instance of SAS/SATA hardware 21154 * \param agIORequest: Pointer to the LL I/O request context for this I/O. 21155 * \param agIOStatus: Status of completed I/O. 21156 * \param agFirstDword:Pointer to the four bytes of FIS. 21157 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS 21158 * length. 21159 * \param agParam: Additional info based on status. 21160 * \param ioContext: Pointer to satIOContext_t. 21161 * 21162 * \return: none 21163 * 21164 *****************************************************************************/ 21165 GLOBAL void satCheckPowerModeCB( 21166 agsaRoot_t *agRoot, 21167 agsaIORequest_t *agIORequest, 21168 bit32 agIOStatus, 21169 agsaFisHeader_t *agFirstDword, 21170 bit32 agIOInfoLen, 21171 agsaFrameHandle_t agFrameHandle, 21172 void *ioContext 21173 ) 21174 { 21175 /* callback for satDeResetDevice */ 21176 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 21177 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 21178 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 21179 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 21180 tdIORequestBody_t *tdIORequestBody; 21181 tdIORequestBody_t *tdOrgIORequestBody = agNULL; 21182 satIOContext_t *satIOContext; 21183 satIOContext_t *satOrgIOContext; 21184 satInternalIo_t *satIntIo; 21185 satDeviceData_t *satDevData; 21186 21187 tiIORequest_t *tiOrgIORequest; 21188 #ifdef TD_DEBUG_ENABLE 21189 bit32 ataStatus = 0; 21190 bit32 ataError; 21191 agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL; 21192 #endif 21193 bit32 report = agFALSE; 21194 bit32 AbortTM = agFALSE; 21195 21196 21197 TI_DBG1(("satCheckPowerModeCB: start\n")); 21198 21199 TI_DBG1(("satCheckPowerModeCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen)); 21200 21201 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; 21202 satIOContext = (satIOContext_t *) ioContext; 21203 satIntIo = satIOContext->satIntIoContext; 21204 satDevData = satIOContext->pSatDevData; 21205 if (satIntIo == agNULL) 21206 { 21207 TI_DBG6(("satCheckPowerModeCB: External, OS generated\n")); 21208 satOrgIOContext = satIOContext; 21209 tiOrgIORequest = tdIORequestBody->tiIORequest; 21210 } 21211 else 21212 { 21213 TI_DBG6(("satCheckPowerModeCB: Internal, TD generated\n")); 21214 satOrgIOContext = satIOContext->satOrgIOContext; 21215 if (satOrgIOContext == agNULL) 21216 { 21217 TI_DBG6(("satCheckPowerModeCB: satOrgIOContext is NULL, wrong\n")); 21218 return; 21219 } 21220 else 21221 { 21222 TI_DBG6(("satCheckPowerModeCB: satOrgIOContext is NOT NULL\n")); 21223 } 21224 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody; 21225 tiOrgIORequest = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest; 21226 } 21227 21228 21229 tdIORequestBody->ioCompleted = agTRUE; 21230 tdIORequestBody->ioStarted = agFALSE; 21231 21232 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS) 21233 { 21234 TI_DBG1(("satCheckPowerModeCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus)); 21235 21236 if (satOrgIOContext->NotifyOS == agTRUE) 21237 { 21238 ostiInitiatorEvent( tiRoot, 21239 NULL, 21240 NULL, 21241 tiIntrEventTypeTaskManagement, 21242 tiTMFailed, 21243 tiOrgIORequest ); 21244 } 21245 21246 satDevData->satTmTaskTag = agNULL; 21247 21248 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 21249 21250 satFreeIntIoResource( tiRoot, 21251 satDevData, 21252 satIntIo); 21253 return; 21254 } 21255 21256 if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED || 21257 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION || 21258 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK || 21259 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS || 21260 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION || 21261 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED || 21262 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION || 21263 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR || 21264 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY 21265 ) 21266 { 21267 TI_DBG1(("satCheckPowerModeCB: OSSA_IO_OPEN_CNX_ERROR\n")); 21268 21269 if (satOrgIOContext->NotifyOS == agTRUE) 21270 { 21271 ostiInitiatorEvent( tiRoot, 21272 NULL, 21273 NULL, 21274 tiIntrEventTypeTaskManagement, 21275 tiTMFailed, 21276 tiOrgIORequest ); 21277 } 21278 21279 satDevData->satTmTaskTag = agNULL; 21280 21281 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 21282 21283 satFreeIntIoResource( tiRoot, 21284 satDevData, 21285 satIntIo); 21286 return; 21287 } 21288 21289 if (agIOStatus != OSSA_IO_SUCCESS) 21290 { 21291 #ifdef TD_DEBUG_ENABLE 21292 /* only agsaFisPioSetup_t is expected */ 21293 satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup); 21294 ataStatus = satPIOSetupHeader->status; /* ATA Status register */ 21295 ataError = satPIOSetupHeader->error; /* ATA Eror register */ 21296 #endif 21297 TI_DBG1(("satCheckPowerModeCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError)); 21298 21299 if (satOrgIOContext->NotifyOS == agTRUE) 21300 { 21301 ostiInitiatorEvent( tiRoot, 21302 NULL, 21303 NULL, 21304 tiIntrEventTypeTaskManagement, 21305 tiTMFailed, 21306 tiOrgIORequest ); 21307 } 21308 21309 satDevData->satTmTaskTag = agNULL; 21310 21311 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 21312 21313 satFreeIntIoResource( tiRoot, 21314 satDevData, 21315 satIntIo); 21316 return; 21317 } 21318 21319 /* success */ 21320 TI_DBG1(("satCheckPowerModeCB: success\n")); 21321 TI_DBG1(("satCheckPowerModeCB: TMF %d\n", satOrgIOContext->TMF)); 21322 21323 if (satOrgIOContext->TMF == AG_ABORT_TASK) 21324 { 21325 AbortTM = agTRUE; 21326 } 21327 21328 if (satOrgIOContext->NotifyOS == agTRUE) 21329 { 21330 report = agTRUE; 21331 } 21332 if (AbortTM == agTRUE) 21333 { 21334 TI_DBG1(("satCheckPowerModeCB: calling satAbort\n")); 21335 satAbort(agRoot, satOrgIOContext->satToBeAbortedIOContext); 21336 } 21337 satDevData->satTmTaskTag = agNULL; 21338 21339 satDevData->satDriveState = SAT_DEV_STATE_NORMAL; 21340 21341 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 21342 21343 TI_DBG1(("satCheckPowerModeCB: satPendingIO %d satNCQMaxIO %d\n", satDevData->satPendingIO, satDevData->satNCQMaxIO )); 21344 TI_DBG1(("satCheckPowerModeCB: satPendingNCQIO %d satPendingNONNCQIO %d\n", satDevData->satPendingNCQIO, satDevData->satPendingNONNCQIO)); 21345 21346 satFreeIntIoResource( tiRoot, 21347 satDevData, 21348 satIntIo); 21349 21350 /* clean up TD layer's IORequestBody */ 21351 if (tdOrgIORequestBody != agNULL) 21352 { 21353 ostiFreeMemory( 21354 tiRoot, 21355 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 21356 sizeof(tdIORequestBody_t) 21357 ); 21358 } 21359 else 21360 { 21361 TI_DBG1(("satCheckPowerModeCB: tdOrgIORequestBody is NULL, wrong\n")); 21362 } 21363 if (report) 21364 { 21365 ostiInitiatorEvent( tiRoot, 21366 NULL, 21367 NULL, 21368 tiIntrEventTypeTaskManagement, 21369 tiTMOK, 21370 tiOrgIORequest ); 21371 } 21372 21373 TI_DBG5(("satCheckPowerModeCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO)); 21374 TI_DBG2(("satCheckPowerModeCB: end\n")); 21375 return; 21376 21377 } 21378 21379 /*****************************************************************************/ 21380 /*! \brief SAT implementation for satAddSATAStartIDDev. 21381 * 21382 * This function sends identify device data to find out the uniqueness 21383 * of device. 21384 * 21385 * \param tiRoot: Pointer to TISA initiator driver/port instance. 21386 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 21387 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 21388 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 21389 * \param satIOContext_t: Pointer to the SAT IO Context 21390 * 21391 * \return If command is started successfully 21392 * - \e tiSuccess: I/O request successfully initiated. 21393 * - \e tiBusy: No resources available, try again later. 21394 * - \e tiIONoDevice: Invalid device handle. 21395 * - \e tiError: Other errors. 21396 */ 21397 /*****************************************************************************/ 21398 GLOBAL bit32 satAddSATAStartIDDev( 21399 tiRoot_t *tiRoot, 21400 tiIORequest_t *tiIORequest, 21401 tiDeviceHandle_t *tiDeviceHandle, 21402 tiScsiInitiatorRequest_t *tiScsiRequest, // NULL 21403 satIOContext_t *satIOContext 21404 ) 21405 { 21406 satInternalIo_t *satIntIo = agNULL; 21407 satDeviceData_t *satDevData = agNULL; 21408 tdIORequestBody_t *tdIORequestBody; 21409 satIOContext_t *satNewIOContext; 21410 bit32 status; 21411 21412 TI_DBG2(("satAddSATAStartIDDev: start\n")); 21413 21414 satDevData = satIOContext->pSatDevData; 21415 21416 TI_DBG2(("satAddSATAStartIDDev: before alloc\n")); 21417 21418 /* allocate identify device command */ 21419 satIntIo = satAllocIntIoResource( tiRoot, 21420 tiIORequest, 21421 satDevData, 21422 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */ 21423 satIntIo); 21424 21425 TI_DBG2(("satAddSATAStartIDDev: after alloc\n")); 21426 21427 if (satIntIo == agNULL) 21428 { 21429 TI_DBG1(("satAddSATAStartIDDev: can't alloacate\n")); 21430 21431 return tiError; 21432 } 21433 21434 /* fill in fields */ 21435 /* real ttttttthe one worked and the same; 5/21/07/ */ 21436 satIntIo->satOrgTiIORequest = tiIORequest; /* changed */ 21437 tdIORequestBody = satIntIo->satIntRequestBody; 21438 satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext); 21439 21440 satNewIOContext->pSatDevData = satDevData; 21441 satNewIOContext->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 21442 satNewIOContext->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd); 21443 satNewIOContext->pSense = &(tdIORequestBody->transport.SATA.sensePayload); 21444 satNewIOContext->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData); 21445 satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */ 21446 satNewIOContext->interruptContext = tiInterruptContext; 21447 satNewIOContext->satIntIoContext = satIntIo; 21448 21449 satNewIOContext->ptiDeviceHandle = agNULL; 21450 satNewIOContext->satOrgIOContext = satIOContext; /* changed */ 21451 21452 /* this is valid only for TD layer generated (not triggered by OS at all) IO */ 21453 satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg); 21454 21455 21456 TI_DBG6(("satAddSATAStartIDDev: OS satIOContext %p \n", satIOContext)); 21457 TI_DBG6(("satAddSATAStartIDDev: TD satNewIOContext %p \n", satNewIOContext)); 21458 TI_DBG6(("satAddSATAStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg)); 21459 TI_DBG6(("satAddSATAStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg)); 21460 21461 21462 21463 TI_DBG2(("satAddSATAStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody)); 21464 21465 status = satAddSATASendIDDev( tiRoot, 21466 &satIntIo->satIntTiIORequest, /* New tiIORequest */ 21467 tiDeviceHandle, 21468 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */ 21469 satNewIOContext); 21470 21471 if (status != tiSuccess) 21472 { 21473 TI_DBG1(("satAddSATAStartIDDev: failed in sending\n")); 21474 21475 satFreeIntIoResource( tiRoot, 21476 satDevData, 21477 satIntIo); 21478 21479 return tiError; 21480 } 21481 21482 21483 TI_DBG6(("satAddSATAStartIDDev: end\n")); 21484 21485 return status; 21486 21487 21488 } 21489 21490 /*****************************************************************************/ 21491 /*! \brief SAT implementation for satAddSATASendIDDev. 21492 * 21493 * This function creates identify device data fis and send it to LL 21494 * 21495 * \param tiRoot: Pointer to TISA initiator driver/port instance. 21496 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 21497 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 21498 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 21499 * \param satIOContext_t: Pointer to the SAT IO Context 21500 * 21501 * \return If command is started successfully 21502 * - \e tiSuccess: I/O request successfully initiated. 21503 * - \e tiBusy: No resources available, try again later. 21504 * - \e tiIONoDevice: Invalid device handle. 21505 * - \e tiError: Other errors. 21506 */ 21507 /*****************************************************************************/ 21508 GLOBAL bit32 satAddSATASendIDDev( 21509 tiRoot_t *tiRoot, 21510 tiIORequest_t *tiIORequest, 21511 tiDeviceHandle_t *tiDeviceHandle, 21512 tiScsiInitiatorRequest_t *tiScsiRequest, 21513 satIOContext_t *satIOContext) 21514 { 21515 bit32 status; 21516 bit32 agRequestType; 21517 satDeviceData_t *pSatDevData; 21518 agsaFisRegHostToDevice_t *fis; 21519 #ifdef TD_DEBUG_ENABLE 21520 tdIORequestBody_t *tdIORequestBody; 21521 satInternalIo_t *satIntIoContext; 21522 #endif 21523 21524 pSatDevData = satIOContext->pSatDevData; 21525 fis = satIOContext->pFis; 21526 TI_DBG2(("satAddSATASendIDDev: start\n")); 21527 #ifdef TD_DEBUG_ENABLE 21528 satIntIoContext = satIOContext->satIntIoContext; 21529 tdIORequestBody = satIntIoContext->satIntRequestBody; 21530 #endif 21531 TI_DBG5(("satAddSATASendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody)); 21532 21533 fis->h.fisType = 0x27; /* Reg host to device */ 21534 fis->h.c_pmPort = 0x80; /* C Bit is set */ 21535 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE) 21536 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0x40 */ 21537 else 21538 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */ 21539 fis->h.features = 0; /* FIS reserve */ 21540 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 21541 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 21542 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 21543 fis->d.device = 0; /* FIS LBA mode */ 21544 fis->d.lbaLowExp = 0; 21545 fis->d.lbaMidExp = 0; 21546 fis->d.lbaHighExp = 0; 21547 fis->d.featuresExp = 0; 21548 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 21549 fis->d.sectorCountExp = 0; 21550 fis->d.reserved4 = 0; 21551 fis->d.control = 0; /* FIS HOB bit clear */ 21552 fis->d.reserved5 = 0; 21553 21554 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 21555 21556 /* Initialize CB for SATA completion. 21557 */ 21558 satIOContext->satCompleteCB = &satAddSATAIDDevCB; 21559 21560 /* 21561 * Prepare SGL and send FIS to LL layer. 21562 */ 21563 satIOContext->reqType = agRequestType; /* Save it */ 21564 21565 #ifdef TD_INTERNAL_DEBUG 21566 tdhexdump("satAddSATASendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 21567 #ifdef TD_DEBUG_ENABLE 21568 tdhexdump("satAddSATASendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t)); 21569 #endif 21570 #endif 21571 21572 status = sataLLIOStart( tiRoot, 21573 tiIORequest, 21574 tiDeviceHandle, 21575 tiScsiRequest, 21576 satIOContext); 21577 21578 TI_DBG2(("satAddSATASendIDDev: end status %d\n", status)); 21579 return status; 21580 } 21581 21582 /***************************************************************************** 21583 *! \brief satAddSATAIDDevCB 21584 * 21585 * This routine is a callback function for satAddSATASendIDDev() 21586 * Using Identify Device Data, this function finds whether devicedata is 21587 * new or old. If new, add it to the devicelist. 21588 * 21589 * \param agRoot: Handles for this instance of SAS/SATA hardware 21590 * \param agIORequest: Pointer to the LL I/O request context for this I/O. 21591 * \param agIOStatus: Status of completed I/O. 21592 * \param agFirstDword:Pointer to the four bytes of FIS. 21593 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS 21594 * length. 21595 * \param agParam: Additional info based on status. 21596 * \param ioContext: Pointer to satIOContext_t. 21597 * 21598 * \return: none 21599 * 21600 *****************************************************************************/ 21601 void satAddSATAIDDevCB( 21602 agsaRoot_t *agRoot, 21603 agsaIORequest_t *agIORequest, 21604 bit32 agIOStatus, 21605 agsaFisHeader_t *agFirstDword, 21606 bit32 agIOInfoLen, 21607 void *agParam, 21608 void *ioContext 21609 ) 21610 { 21611 21612 /* 21613 In the process of Inquiry 21614 Process SAT_IDENTIFY_DEVICE 21615 */ 21616 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 21617 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 21618 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 21619 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 21620 tdIORequestBody_t *tdIORequestBody; 21621 tdIORequestBody_t *tdOrgIORequestBody; 21622 satIOContext_t *satIOContext; 21623 satIOContext_t *satOrgIOContext; 21624 satIOContext_t *satNewIOContext; 21625 satInternalIo_t *satIntIo; 21626 satInternalIo_t *satNewIntIo = agNULL; 21627 satDeviceData_t *satDevData; 21628 tiIORequest_t *tiOrgIORequest = agNULL; 21629 agsaSATAIdentifyData_t *pSATAIdData; 21630 bit16 *tmpptr, tmpptr_tmp; 21631 bit32 x; 21632 tdsaDeviceData_t *NewOneDeviceData = agNULL; 21633 tdsaDeviceData_t *oneDeviceData = agNULL; 21634 tdList_t *DeviceListList; 21635 int new_device = agTRUE; 21636 bit8 PhyID; 21637 void *sglVirtualAddr; 21638 bit32 retry_status; 21639 agsaContext_t *agContext; 21640 tdsaPortContext_t *onePortContext; 21641 bit32 status = 0; 21642 21643 TI_DBG2(("satAddSATAIDDevCB: start\n")); 21644 TI_DBG6(("satAddSATAIDDevCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen)); 21645 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; 21646 satIOContext = (satIOContext_t *) ioContext; 21647 satIntIo = satIOContext->satIntIoContext; 21648 satDevData = satIOContext->pSatDevData; 21649 21650 NewOneDeviceData = (tdsaDeviceData_t *)tdIORequestBody->tiDevHandle->tdData; 21651 TI_DBG2(("satAddSATAIDDevCB: NewOneDeviceData %p did %d\n", NewOneDeviceData, NewOneDeviceData->id)); 21652 PhyID = NewOneDeviceData->phyID; 21653 TI_DBG2(("satAddSATAIDDevCB: phyID %d\n", PhyID)); 21654 agContext = &(NewOneDeviceData->agDeviceResetContext); 21655 agContext->osData = agNULL; 21656 if (satIntIo == agNULL) 21657 { 21658 TI_DBG1(("satAddSATAIDDevCB: External, OS generated\n")); 21659 TI_DBG1(("satAddSATAIDDevCB: Not possible case\n")); 21660 satOrgIOContext = satIOContext; 21661 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody; 21662 tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData); 21663 21664 /* put onedevicedata back to free list */ 21665 osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t)); 21666 TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink)); 21667 TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList)); 21668 21669 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 21670 21671 satFreeIntIoResource( tiRoot, 21672 satDevData, 21673 satIntIo); 21674 /* clean up TD layer's IORequestBody */ 21675 ostiFreeMemory( 21676 tiRoot, 21677 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 21678 sizeof(tdIORequestBody_t) 21679 ); 21680 21681 /* notifying link up */ 21682 ostiPortEvent ( 21683 tiRoot, 21684 tiPortLinkUp, 21685 tiSuccess, 21686 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext 21687 ); 21688 #ifdef INITIATOR_DRIVER 21689 /* triggers discovery */ 21690 ostiPortEvent( 21691 tiRoot, 21692 tiPortDiscoveryReady, 21693 tiSuccess, 21694 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext 21695 ); 21696 #endif 21697 return; 21698 } 21699 else 21700 { 21701 TI_DBG1(("satAddSATAIDDevCB: Internal, TD generated\n")); 21702 satOrgIOContext = satIOContext->satOrgIOContext; 21703 if (satOrgIOContext == agNULL) 21704 { 21705 TI_DBG6(("satAddSATAIDDevCB: satOrgIOContext is NULL\n")); 21706 return; 21707 } 21708 else 21709 { 21710 TI_DBG6(("satAddSATAIDDevCB: satOrgIOContext is NOT NULL\n")); 21711 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody; 21712 sglVirtualAddr = satIntIo->satIntTiScsiXchg.sglVirtualAddr; 21713 } 21714 } 21715 tiOrgIORequest = tdIORequestBody->tiIORequest; 21716 21717 tdIORequestBody->ioCompleted = agTRUE; 21718 tdIORequestBody->ioStarted = agFALSE; 21719 TI_DBG2(("satAddSATAIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid)); 21720 /* protect against double completion for old port */ 21721 if (satOrgIOContext->pid != tdsaAllShared->Ports[PhyID].portContext->id) 21722 { 21723 TI_DBG2(("satAddSATAIDDevCB: incorrect pid\n")); 21724 TI_DBG2(("satAddSATAIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid)); 21725 TI_DBG2(("satAddSATAIDDevCB: tiPortalContext pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id)); 21726 tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData); 21727 /* put onedevicedata back to free list */ 21728 osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t)); 21729 TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink)); 21730 TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList)); 21731 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 21732 21733 satFreeIntIoResource( tiRoot, 21734 satDevData, 21735 satIntIo); 21736 /* clean up TD layer's IORequestBody */ 21737 ostiFreeMemory( 21738 tiRoot, 21739 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 21740 sizeof(tdIORequestBody_t) 21741 ); 21742 /* no notification to OS layer */ 21743 return; 21744 } 21745 /* completion after portcontext is invalidated */ 21746 onePortContext = NewOneDeviceData->tdPortContext; 21747 if (onePortContext != agNULL) 21748 { 21749 if (onePortContext->valid == agFALSE) 21750 { 21751 TI_DBG1(("satAddSATAIDDevCB: portcontext is invalid\n")); 21752 TI_DBG1(("satAddSATAIDDevCB: onePortContext->id pid %d\n", onePortContext->id)); 21753 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 21754 21755 satFreeIntIoResource( tiRoot, 21756 satDevData, 21757 satIntIo); 21758 /* clean up TD layer's IORequestBody */ 21759 ostiFreeMemory( 21760 tiRoot, 21761 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 21762 sizeof(tdIORequestBody_t) 21763 ); 21764 /* no notification to OS layer */ 21765 return; 21766 } 21767 } 21768 else 21769 { 21770 TI_DBG1(("satAddSATAIDDevCB: onePortContext is NULL!!!\n")); 21771 return; 21772 } 21773 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS) 21774 { 21775 TI_DBG1(("satAddSATAIDDevCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus)); 21776 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES) 21777 { 21778 satDevData->satPendingNONNCQIO--; 21779 satDevData->satPendingIO--; 21780 retry_status = sataLLIOStart(tiRoot, 21781 &satIntIo->satIntTiIORequest, 21782 &(NewOneDeviceData->tiDeviceHandle), 21783 satIOContext->tiScsiXchg, 21784 satIOContext); 21785 if (retry_status != tiSuccess) 21786 { 21787 /* simply give up */ 21788 satDevData->ID_Retries = 0; 21789 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21790 return; 21791 } 21792 satDevData->ID_Retries++; 21793 tdIORequestBody->ioCompleted = agFALSE; 21794 tdIORequestBody->ioStarted = agTRUE; 21795 return; 21796 } 21797 else 21798 { 21799 if (tdsaAllShared->ResetInDiscovery == 0) 21800 { 21801 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21802 } 21803 else /* ResetInDiscovery in on */ 21804 { 21805 /* RESET only one after ID retries */ 21806 if (satDevData->NumOfIDRetries <= 0) 21807 { 21808 satDevData->NumOfIDRetries++; 21809 satDevData->ID_Retries = 0; 21810 satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21811 /* send link reset */ 21812 saLocalPhyControl(agRoot, 21813 agContext, 21814 tdsaRotateQnumber(tiRoot, NewOneDeviceData), 21815 PhyID, 21816 AGSA_PHY_HARD_RESET, 21817 agNULL); 21818 } 21819 else 21820 { 21821 satDevData->ID_Retries = 0; 21822 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21823 } 21824 } 21825 return; 21826 } 21827 } 21828 if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED || 21829 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION || 21830 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK || 21831 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS || 21832 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION || 21833 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED || 21834 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION || 21835 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR || 21836 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY 21837 ) 21838 { 21839 TI_DBG1(("satAddSATAIDDevCB: OSSA_IO_OPEN_CNX_ERROR\n")); 21840 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES) 21841 { 21842 satDevData->satPendingNONNCQIO--; 21843 satDevData->satPendingIO--; 21844 retry_status = sataLLIOStart(tiRoot, 21845 &satIntIo->satIntTiIORequest, 21846 &(NewOneDeviceData->tiDeviceHandle), 21847 satIOContext->tiScsiXchg, 21848 satIOContext); 21849 if (retry_status != tiSuccess) 21850 { 21851 /* simply give up */ 21852 satDevData->ID_Retries = 0; 21853 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21854 return; 21855 } 21856 satDevData->ID_Retries++; 21857 tdIORequestBody->ioCompleted = agFALSE; 21858 tdIORequestBody->ioStarted = agTRUE; 21859 return; 21860 } 21861 else 21862 { 21863 if (tdsaAllShared->ResetInDiscovery == 0) 21864 { 21865 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21866 } 21867 else /* ResetInDiscovery in on */ 21868 { 21869 /* RESET only one after ID retries */ 21870 if (satDevData->NumOfIDRetries <= 0) 21871 { 21872 satDevData->NumOfIDRetries++; 21873 satDevData->ID_Retries = 0; 21874 satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21875 /* send link reset */ 21876 saLocalPhyControl(agRoot, 21877 agContext, 21878 tdsaRotateQnumber(tiRoot, NewOneDeviceData), 21879 PhyID, 21880 AGSA_PHY_HARD_RESET, 21881 agNULL); 21882 } 21883 else 21884 { 21885 satDevData->ID_Retries = 0; 21886 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21887 } 21888 } 21889 return; 21890 } 21891 } 21892 21893 if ( agIOStatus != OSSA_IO_SUCCESS || 21894 (agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0) 21895 ) 21896 { 21897 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES) 21898 { 21899 satIOContext->pSatDevData->satPendingNONNCQIO--; 21900 satIOContext->pSatDevData->satPendingIO--; 21901 retry_status = sataLLIOStart(tiRoot, 21902 &satIntIo->satIntTiIORequest, 21903 &(NewOneDeviceData->tiDeviceHandle), 21904 satIOContext->tiScsiXchg, 21905 satIOContext); 21906 if (retry_status != tiSuccess) 21907 { 21908 /* simply give up */ 21909 satDevData->ID_Retries = 0; 21910 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21911 return; 21912 } 21913 satDevData->ID_Retries++; 21914 tdIORequestBody->ioCompleted = agFALSE; 21915 tdIORequestBody->ioStarted = agTRUE; 21916 return; 21917 } 21918 else 21919 { 21920 if (tdsaAllShared->ResetInDiscovery == 0) 21921 { 21922 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21923 } 21924 else /* ResetInDiscovery in on */ 21925 { 21926 /* RESET only one after ID retries */ 21927 if (satDevData->NumOfIDRetries <= 0) 21928 { 21929 satDevData->NumOfIDRetries++; 21930 satDevData->ID_Retries = 0; 21931 satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21932 /* send link reset */ 21933 saLocalPhyControl(agRoot, 21934 agContext, 21935 tdsaRotateQnumber(tiRoot, NewOneDeviceData), 21936 PhyID, 21937 AGSA_PHY_HARD_RESET, 21938 agNULL); 21939 } 21940 else 21941 { 21942 satDevData->ID_Retries = 0; 21943 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody); 21944 } 21945 } 21946 return; 21947 } 21948 } 21949 21950 /* success */ 21951 TI_DBG2(("satAddSATAIDDevCB: Success\n")); 21952 /* Convert to host endian */ 21953 tmpptr = (bit16*)sglVirtualAddr; 21954 //tdhexdump("satAddSATAIDDevCB before", (bit8 *)sglVirtualAddr, sizeof(agsaSATAIdentifyData_t)); 21955 for (x=0; x < sizeof(agsaSATAIdentifyData_t)/sizeof(bit16); x++) 21956 { 21957 OSSA_READ_LE_16(AGROOT, &tmpptr_tmp, tmpptr, 0); 21958 *tmpptr = tmpptr_tmp; 21959 tmpptr++; 21960 /*Print tmpptr_tmp here for debugging purpose*/ 21961 } 21962 21963 pSATAIdData = (agsaSATAIdentifyData_t *)sglVirtualAddr; 21964 //tdhexdump("satAddSATAIDDevCB after", (bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t)); 21965 21966 TI_DBG5(("satAddSATAIDDevCB: OS satOrgIOContext %p \n", satOrgIOContext)); 21967 TI_DBG5(("satAddSATAIDDevCB: TD satIOContext %p \n", satIOContext)); 21968 TI_DBG5(("satAddSATAIDDevCB: OS tiScsiXchg %p \n", satOrgIOContext->tiScsiXchg)); 21969 TI_DBG5(("satAddSATAIDDevCB: TD tiScsiXchg %p \n", satIOContext->tiScsiXchg)); 21970 21971 21972 /* compare idenitfy device data to the exiting list */ 21973 DeviceListList = tdsaAllShared->MainDeviceList.flink; 21974 while (DeviceListList != &(tdsaAllShared->MainDeviceList)) 21975 { 21976 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList); 21977 TI_DBG1(("satAddSATAIDDevCB: LOOP oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id)); 21978 //tdhexdump("satAddSATAIDDevCB LOOP", (bit8 *)&oneDeviceData->satDevData.satIdentifyData, sizeof(agsaSATAIdentifyData_t)); 21979 21980 /* what is unique ID for sata device -> response of identify devicedata; not really 21981 Let's compare serial number, firmware version, model number 21982 */ 21983 if ( oneDeviceData->DeviceType == TD_SATA_DEVICE && 21984 (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.serialNumber, 21985 pSATAIdData->serialNumber, 21986 20) == 0) && 21987 (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.firmwareVersion, 21988 pSATAIdData->firmwareVersion, 21989 8) == 0) && 21990 (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.modelNumber, 21991 pSATAIdData->modelNumber, 21992 40) == 0) 21993 ) 21994 { 21995 TI_DBG2(("satAddSATAIDDevCB: did %d\n", oneDeviceData->id)); 21996 new_device = agFALSE; 21997 break; 21998 } 21999 DeviceListList = DeviceListList->flink; 22000 } 22001 22002 if (new_device == agFALSE) 22003 { 22004 TI_DBG2(("satAddSATAIDDevCB: old device data\n")); 22005 oneDeviceData->valid = agTRUE; 22006 oneDeviceData->valid2 = agTRUE; 22007 /* save data field from new device data */ 22008 oneDeviceData->agRoot = agRoot; 22009 oneDeviceData->agDevHandle = NewOneDeviceData->agDevHandle; 22010 oneDeviceData->agDevHandle->osData = oneDeviceData; /* TD layer */ 22011 oneDeviceData->tdPortContext = NewOneDeviceData->tdPortContext; 22012 oneDeviceData->phyID = NewOneDeviceData->phyID; 22013 22014 /* 22015 one SATA directly attached device per phy; 22016 Therefore, deregister then register 22017 */ 22018 saDeregisterDeviceHandle(agRoot, agNULL, NewOneDeviceData->agDevHandle, 0); 22019 22020 if (oneDeviceData->registered == agFALSE) 22021 { 22022 TI_DBG2(("satAddSATAIDDevCB: re-registering old device data\n")); 22023 /* already has old information; just register it again */ 22024 saRegisterNewDevice( /* satAddSATAIDDevCB */ 22025 agRoot, 22026 &oneDeviceData->agContext, 22027 tdsaRotateQnumber(tiRoot, oneDeviceData), 22028 &oneDeviceData->agDeviceInfo, 22029 oneDeviceData->tdPortContext->agPortContext, 22030 0 22031 ); 22032 } 22033 22034 // tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData); 22035 /* put onedevicedata back to free list */ 22036 osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t)); 22037 TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink)); 22038 TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList)); 22039 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22040 22041 satFreeIntIoResource( tiRoot, 22042 satDevData, 22043 satIntIo); 22044 22045 if (satDevData->satDeviceType == SATA_ATAPI_DEVICE) 22046 { 22047 /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/ 22048 satNewIntIo = satAllocIntIoResource( tiRoot, 22049 tiOrgIORequest, 22050 satDevData, 22051 0, 22052 satNewIntIo); 22053 22054 if (satNewIntIo == agNULL) 22055 { 22056 TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n")); 22057 /* clean up TD layer's IORequestBody */ 22058 ostiFreeMemory( 22059 tiRoot, 22060 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22061 sizeof(tdIORequestBody_t) 22062 ); 22063 return; 22064 } /* end memory allocation */ 22065 22066 satNewIOContext = satPrepareNewIO(satNewIntIo, 22067 tiOrgIORequest, 22068 satDevData, 22069 agNULL, 22070 satOrgIOContext 22071 ); 22072 /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/ 22073 status = satSetFeatures(tiRoot, 22074 &satNewIntIo->satIntTiIORequest, 22075 satNewIOContext->ptiDeviceHandle, 22076 &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */ 22077 satNewIOContext, 22078 agFALSE); 22079 if (status != tiSuccess) 22080 { 22081 satFreeIntIoResource( tiRoot, 22082 satDevData, 22083 satIntIo); 22084 /* clean up TD layer's IORequestBody */ 22085 ostiFreeMemory( 22086 tiRoot, 22087 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22088 sizeof(tdIORequestBody_t) 22089 ); 22090 } 22091 } 22092 else 22093 { 22094 /* clean up TD layer's IORequestBody */ 22095 ostiFreeMemory( 22096 tiRoot, 22097 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22098 sizeof(tdIORequestBody_t) 22099 ); 22100 TI_DBG2(("satAddSATAIDDevCB: pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id)); 22101 /* notifying link up */ 22102 ostiPortEvent( 22103 tiRoot, 22104 tiPortLinkUp, 22105 tiSuccess, 22106 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext 22107 ); 22108 22109 22110 #ifdef INITIATOR_DRIVER 22111 /* triggers discovery */ 22112 ostiPortEvent( 22113 tiRoot, 22114 tiPortDiscoveryReady, 22115 tiSuccess, 22116 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext 22117 ); 22118 #endif 22119 } 22120 return; 22121 } 22122 22123 TI_DBG2(("satAddSATAIDDevCB: new device data\n")); 22124 /* copy ID Dev data to satDevData */ 22125 satDevData->satIdentifyData = *pSATAIdData; 22126 22127 22128 satDevData->IDDeviceValid = agTRUE; 22129 #ifdef TD_INTERNAL_DEBUG 22130 tdhexdump("satAddSATAIDDevCB ID Dev data",(bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t)); 22131 tdhexdump("satAddSATAIDDevCB Device ID Dev data",(bit8 *)&satDevData->satIdentifyData, sizeof(agsaSATAIdentifyData_t)); 22132 #endif 22133 22134 /* set satDevData fields from IndentifyData */ 22135 satSetDevInfo(satDevData,pSATAIdData); 22136 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22137 22138 satFreeIntIoResource( tiRoot, 22139 satDevData, 22140 satIntIo); 22141 22142 if (satDevData->satDeviceType == SATA_ATAPI_DEVICE) 22143 { 22144 /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/ 22145 satNewIntIo = satAllocIntIoResource( tiRoot, 22146 tiOrgIORequest, 22147 satDevData, 22148 0, 22149 satNewIntIo); 22150 22151 if (satNewIntIo == agNULL) 22152 { 22153 TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n")); 22154 /* clean up TD layer's IORequestBody */ 22155 ostiFreeMemory( 22156 tiRoot, 22157 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22158 sizeof(tdIORequestBody_t) 22159 ); 22160 return; 22161 } /* end memory allocation */ 22162 22163 satNewIOContext = satPrepareNewIO(satNewIntIo, 22164 tiOrgIORequest, 22165 satDevData, 22166 agNULL, 22167 satOrgIOContext 22168 ); 22169 /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/ 22170 status = satSetFeatures(tiRoot, 22171 &satNewIntIo->satIntTiIORequest, 22172 satNewIOContext->ptiDeviceHandle, 22173 &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */ 22174 satNewIOContext, 22175 agFALSE); 22176 if (status != tiSuccess) 22177 { 22178 satFreeIntIoResource( tiRoot, 22179 satDevData, 22180 satIntIo); 22181 /* clean up TD layer's IORequestBody */ 22182 ostiFreeMemory( 22183 tiRoot, 22184 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22185 sizeof(tdIORequestBody_t) 22186 ); 22187 } 22188 22189 } 22190 else 22191 { 22192 /* clean up TD layer's IORequestBody */ 22193 ostiFreeMemory( 22194 tiRoot, 22195 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22196 sizeof(tdIORequestBody_t) 22197 ); 22198 22199 TI_DBG2(("satAddSATAIDDevCB: pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id)); 22200 /* notifying link up */ 22201 ostiPortEvent ( 22202 tiRoot, 22203 tiPortLinkUp, 22204 tiSuccess, 22205 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext 22206 ); 22207 #ifdef INITIATOR_DRIVER 22208 /* triggers discovery */ 22209 ostiPortEvent( 22210 tiRoot, 22211 tiPortDiscoveryReady, 22212 tiSuccess, 22213 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext 22214 ); 22215 #endif 22216 } 22217 22218 TI_DBG2(("satAddSATAIDDevCB: end\n")); 22219 return; 22220 22221 } 22222 22223 /***************************************************************************** 22224 *! \brief satAddSATAIDDevCBReset 22225 * 22226 * This routine cleans up IOs for failed Identify device data 22227 * 22228 * \param agRoot: Handles for this instance of SAS/SATA hardware 22229 * \param oneDeviceData: Pointer to the device data. 22230 * \param ioContext: Pointer to satIOContext_t. 22231 * \param tdIORequestBody: Pointer to the request body 22232 * \param flag: Decrement pending io or not 22233 * 22234 * \return: none 22235 * 22236 *****************************************************************************/ 22237 void satAddSATAIDDevCBReset( 22238 agsaRoot_t *agRoot, 22239 tdsaDeviceData_t *oneDeviceData, 22240 satIOContext_t *satIOContext, 22241 tdIORequestBody_t *tdIORequestBody 22242 ) 22243 { 22244 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 22245 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 22246 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 22247 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 22248 satInternalIo_t *satIntIo; 22249 satDeviceData_t *satDevData; 22250 22251 TI_DBG2(("satAddSATAIDDevCBReset: start\n")); 22252 satIntIo = satIOContext->satIntIoContext; 22253 satDevData = satIOContext->pSatDevData; 22254 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22255 22256 satFreeIntIoResource( tiRoot, 22257 satDevData, 22258 satIntIo); 22259 /* clean up TD layer's IORequestBody */ 22260 ostiFreeMemory( 22261 tiRoot, 22262 tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22263 sizeof(tdIORequestBody_t) 22264 ); 22265 return; 22266 } 22267 22268 22269 /***************************************************************************** 22270 *! \brief satAddSATAIDDevCBCleanup 22271 * 22272 * This routine cleans up IOs for failed Identify device data 22273 * 22274 * \param agRoot: Handles for this instance of SAS/SATA hardware 22275 * \param oneDeviceData: Pointer to the device data. 22276 * \param ioContext: Pointer to satIOContext_t. 22277 * \param tdIORequestBody: Pointer to the request body 22278 * 22279 * \return: none 22280 * 22281 *****************************************************************************/ 22282 void satAddSATAIDDevCBCleanup( 22283 agsaRoot_t *agRoot, 22284 tdsaDeviceData_t *oneDeviceData, 22285 satIOContext_t *satIOContext, 22286 tdIORequestBody_t *tdIORequestBody 22287 ) 22288 { 22289 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 22290 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 22291 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 22292 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 22293 satInternalIo_t *satIntIo; 22294 satDeviceData_t *satDevData; 22295 bit8 PhyID; 22296 22297 TI_DBG2(("satAddSATAIDDevCBCleanup: start\n")); 22298 satIntIo = satIOContext->satIntIoContext; 22299 satDevData = satIOContext->pSatDevData; 22300 PhyID = oneDeviceData->phyID; 22301 tdsaAbortAll(tiRoot, agRoot, oneDeviceData); 22302 /* put onedevicedata back to free list */ 22303 osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t)); 22304 TDLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink)); 22305 TDLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList)); 22306 22307 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22308 22309 22310 satFreeIntIoResource( tiRoot, 22311 satDevData, 22312 satIntIo); 22313 22314 /* clean up TD layer's IORequestBody */ 22315 ostiFreeMemory( 22316 tiRoot, 22317 tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22318 sizeof(tdIORequestBody_t) 22319 ); 22320 22321 /* notifying link up */ 22322 ostiPortEvent ( 22323 tiRoot, 22324 tiPortLinkUp, 22325 tiSuccess, 22326 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext 22327 ); 22328 #ifdef INITIATOR_DRIVER 22329 /* triggers discovery */ 22330 ostiPortEvent( 22331 tiRoot, 22332 tiPortDiscoveryReady, 22333 tiSuccess, 22334 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext 22335 ); 22336 #endif 22337 22338 return; 22339 } 22340 22341 /*****************************************************************************/ 22342 /*! \brief SAT implementation for tdsaDiscoveryStartIDDev. 22343 * 22344 * This function sends identify device data to SATA device in discovery 22345 * 22346 * 22347 * \param tiRoot: Pointer to TISA initiator driver/port instance. 22348 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 22349 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 22350 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 22351 * \param oneDeviceData : Pointer to the device data. 22352 * 22353 * \return If command is started successfully 22354 * - \e tiSuccess: I/O request successfully initiated. 22355 * - \e tiBusy: No resources available, try again later. 22356 * - \e tiIONoDevice: Invalid device handle. 22357 * - \e tiError: Other errors. 22358 */ 22359 /*****************************************************************************/ 22360 GLOBAL bit32 22361 tdsaDiscoveryStartIDDev(tiRoot_t *tiRoot, 22362 tiIORequest_t *tiIORequest, /* agNULL */ 22363 tiDeviceHandle_t *tiDeviceHandle, 22364 tiScsiInitiatorRequest_t *tiScsiRequest, /* agNULL */ 22365 tdsaDeviceData_t *oneDeviceData 22366 ) 22367 { 22368 void *osMemHandle; 22369 tdIORequestBody_t *tdIORequestBody; 22370 bit32 PhysUpper32; 22371 bit32 PhysLower32; 22372 bit32 memAllocStatus; 22373 agsaIORequest_t *agIORequest = agNULL; /* identify device data itself */ 22374 satIOContext_t *satIOContext = agNULL; 22375 bit32 status; 22376 22377 /* allocate tdiorequestbody and call tdsaDiscoveryIntStartIDDev 22378 tdsaDiscoveryIntStartIDDev(tiRoot, agNULL, tiDeviceHandle, satIOContext); 22379 22380 */ 22381 22382 TI_DBG3(("tdsaDiscoveryStartIDDev: start\n")); 22383 TI_DBG3(("tdsaDiscoveryStartIDDev: did %d\n", oneDeviceData->id)); 22384 22385 /* allocation tdIORequestBody and pass it to satTM() */ 22386 memAllocStatus = ostiAllocMemory( 22387 tiRoot, 22388 &osMemHandle, 22389 (void **)&tdIORequestBody, 22390 &PhysUpper32, 22391 &PhysLower32, 22392 8, 22393 sizeof(tdIORequestBody_t), 22394 agTRUE 22395 ); 22396 22397 if (memAllocStatus != tiSuccess) 22398 { 22399 TI_DBG1(("tdsaDiscoveryStartIDDev: ostiAllocMemory failed... loc 1\n")); 22400 return tiError; 22401 } 22402 if (tdIORequestBody == agNULL) 22403 { 22404 TI_DBG1(("tdsaDiscoveryStartIDDev: ostiAllocMemory returned NULL tdIORequestBody loc 2\n")); 22405 return tiError; 22406 } 22407 22408 /* setup identify device data IO structure */ 22409 tdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 22410 tdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = agNULL; 22411 tdIORequestBody->IOType.InitiatorTMIO.TaskTag = agNULL; 22412 22413 /* initialize tiDevhandle */ 22414 tdIORequestBody->tiDevHandle = &(oneDeviceData->tiDeviceHandle); 22415 tdIORequestBody->tiDevHandle->tdData = oneDeviceData; 22416 22417 /* initialize tiIORequest */ 22418 tdIORequestBody->tiIORequest = agNULL; 22419 22420 /* initialize agIORequest */ 22421 agIORequest = &(tdIORequestBody->agIORequest); 22422 agIORequest->osData = (void *) tdIORequestBody; 22423 agIORequest->sdkData = agNULL; /* SA takes care of this */ 22424 22425 /* set up satIOContext */ 22426 satIOContext = &(tdIORequestBody->transport.SATA.satIOContext); 22427 satIOContext->pSatDevData = &(oneDeviceData->satDevData); 22428 satIOContext->pFis = 22429 &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 22430 22431 satIOContext->tiRequestBody = tdIORequestBody; 22432 satIOContext->ptiDeviceHandle = &(oneDeviceData->tiDeviceHandle); 22433 satIOContext->tiScsiXchg = agNULL; 22434 satIOContext->satIntIoContext = agNULL; 22435 satIOContext->satOrgIOContext = agNULL; 22436 /* followings are used only for internal IO */ 22437 satIOContext->currentLBA = 0; 22438 satIOContext->OrgTL = 0; 22439 satIOContext->satToBeAbortedIOContext = agNULL; 22440 satIOContext->NotifyOS = agFALSE; 22441 22442 /* saving port ID just in case of full discovery to full discovery transition */ 22443 satIOContext->pid = oneDeviceData->tdPortContext->id; 22444 osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0x0, sizeof(agsaSATAIdentifyData_t)); 22445 status = tdsaDiscoveryIntStartIDDev(tiRoot, 22446 tiIORequest, /* agNULL */ 22447 tiDeviceHandle, /* &(oneDeviceData->tiDeviceHandle)*/ 22448 agNULL, 22449 satIOContext 22450 ); 22451 if (status != tiSuccess) 22452 { 22453 TI_DBG1(("tdsaDiscoveryStartIDDev: failed in sending %d\n", status)); 22454 ostiFreeMemory(tiRoot, osMemHandle, sizeof(tdIORequestBody_t)); 22455 } 22456 return status; 22457 } 22458 22459 /*****************************************************************************/ 22460 /*! \brief SAT implementation for tdsaDiscoveryIntStartIDDev. 22461 * 22462 * This function sends identify device data to SATA device. 22463 * 22464 * \param tiRoot: Pointer to TISA initiator driver/port instance. 22465 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 22466 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 22467 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 22468 * \param satIOContext_t: Pointer to the SAT IO Context 22469 * 22470 * \return If command is started successfully 22471 * - \e tiSuccess: I/O request successfully initiated. 22472 * - \e tiBusy: No resources available, try again later. 22473 * - \e tiIONoDevice: Invalid device handle. 22474 * - \e tiError: Other errors. 22475 */ 22476 /*****************************************************************************/ 22477 GLOBAL bit32 22478 tdsaDiscoveryIntStartIDDev(tiRoot_t *tiRoot, 22479 tiIORequest_t *tiIORequest, /* agNULL */ 22480 tiDeviceHandle_t *tiDeviceHandle, 22481 tiScsiInitiatorRequest_t *tiScsiRequest, /* agNULL */ 22482 satIOContext_t *satIOContext 22483 ) 22484 { 22485 satInternalIo_t *satIntIo = agNULL; 22486 satDeviceData_t *satDevData = agNULL; 22487 tdIORequestBody_t *tdIORequestBody; 22488 satIOContext_t *satNewIOContext; 22489 bit32 status; 22490 22491 TI_DBG3(("tdsaDiscoveryIntStartIDDev: start\n")); 22492 22493 satDevData = satIOContext->pSatDevData; 22494 22495 /* allocate identify device command */ 22496 satIntIo = satAllocIntIoResource( tiRoot, 22497 tiIORequest, 22498 satDevData, 22499 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */ 22500 satIntIo); 22501 22502 if (satIntIo == agNULL) 22503 { 22504 TI_DBG2(("tdsaDiscoveryIntStartIDDev: can't alloacate\n")); 22505 22506 return tiError; 22507 } 22508 22509 /* fill in fields */ 22510 /* real ttttttthe one worked and the same; 5/21/07/ */ 22511 satIntIo->satOrgTiIORequest = tiIORequest; /* changed */ 22512 tdIORequestBody = satIntIo->satIntRequestBody; 22513 satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext); 22514 22515 satNewIOContext->pSatDevData = satDevData; 22516 satNewIOContext->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 22517 satNewIOContext->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd); 22518 satNewIOContext->pSense = &(tdIORequestBody->transport.SATA.sensePayload); 22519 satNewIOContext->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData); 22520 satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */ 22521 satNewIOContext->interruptContext = tiInterruptContext; 22522 satNewIOContext->satIntIoContext = satIntIo; 22523 22524 satNewIOContext->ptiDeviceHandle = agNULL; 22525 satNewIOContext->satOrgIOContext = satIOContext; /* changed */ 22526 22527 /* this is valid only for TD layer generated (not triggered by OS at all) IO */ 22528 satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg); 22529 22530 22531 TI_DBG6(("tdsaDiscoveryIntStartIDDev: OS satIOContext %p \n", satIOContext)); 22532 TI_DBG6(("tdsaDiscoveryIntStartIDDev: TD satNewIOContext %p \n", satNewIOContext)); 22533 TI_DBG6(("tdsaDiscoveryIntStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg)); 22534 TI_DBG6(("tdsaDiscoveryIntStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg)); 22535 22536 22537 22538 TI_DBG3(("tdsaDiscoveryIntStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody)); 22539 22540 status = tdsaDiscoverySendIDDev(tiRoot, 22541 &satIntIo->satIntTiIORequest, /* New tiIORequest */ 22542 tiDeviceHandle, 22543 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */ 22544 satNewIOContext); 22545 22546 if (status != tiSuccess) 22547 { 22548 TI_DBG1(("tdsaDiscoveryIntStartIDDev: failed in sending %d\n", status)); 22549 22550 satFreeIntIoResource( tiRoot, 22551 satDevData, 22552 satIntIo); 22553 22554 return tiError; 22555 } 22556 22557 22558 TI_DBG6(("tdsaDiscoveryIntStartIDDev: end\n")); 22559 22560 return status; 22561 } 22562 22563 22564 /*****************************************************************************/ 22565 /*! \brief SAT implementation for tdsaDiscoverySendIDDev. 22566 * 22567 * This function prepares identify device data FIS and sends it to SATA device. 22568 * 22569 * \param tiRoot: Pointer to TISA initiator driver/port instance. 22570 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 22571 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 22572 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 22573 * \param satIOContext_t: Pointer to the SAT IO Context 22574 * 22575 * \return If command is started successfully 22576 * - \e tiSuccess: I/O request successfully initiated. 22577 * - \e tiBusy: No resources available, try again later. 22578 * - \e tiIONoDevice: Invalid device handle. 22579 * - \e tiError: Other errors. 22580 */ 22581 /*****************************************************************************/ 22582 GLOBAL bit32 22583 tdsaDiscoverySendIDDev(tiRoot_t *tiRoot, 22584 tiIORequest_t *tiIORequest, 22585 tiDeviceHandle_t *tiDeviceHandle, 22586 tiScsiInitiatorRequest_t *tiScsiRequest, 22587 satIOContext_t *satIOContext 22588 ) 22589 { 22590 bit32 status; 22591 bit32 agRequestType; 22592 satDeviceData_t *pSatDevData; 22593 agsaFisRegHostToDevice_t *fis; 22594 #ifdef TD_DEBUG_ENABLE 22595 tdIORequestBody_t *tdIORequestBody; 22596 satInternalIo_t *satIntIoContext; 22597 #endif 22598 22599 pSatDevData = satIOContext->pSatDevData; 22600 fis = satIOContext->pFis; 22601 TI_DBG3(("tdsaDiscoverySendIDDev: start\n")); 22602 #ifdef TD_DEBUG_ENABLE 22603 satIntIoContext = satIOContext->satIntIoContext; 22604 tdIORequestBody = satIntIoContext->satIntRequestBody; 22605 #endif 22606 TI_DBG5(("tdsaDiscoverySendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody)); 22607 22608 fis->h.fisType = 0x27; /* Reg host to device */ 22609 fis->h.c_pmPort = 0x80; /* C Bit is set */ 22610 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE) 22611 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0xA1 */ 22612 else 22613 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */ 22614 fis->h.features = 0; /* FIS reserve */ 22615 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 22616 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 22617 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 22618 fis->d.device = 0; /* FIS LBA mode */ 22619 fis->d.lbaLowExp = 0; 22620 fis->d.lbaMidExp = 0; 22621 fis->d.lbaHighExp = 0; 22622 fis->d.featuresExp = 0; 22623 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 22624 fis->d.sectorCountExp = 0; 22625 fis->d.reserved4 = 0; 22626 fis->d.control = 0; /* FIS HOB bit clear */ 22627 fis->d.reserved5 = 0; 22628 22629 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 22630 22631 /* Initialize CB for SATA completion. 22632 */ 22633 satIOContext->satCompleteCB = &tdsaDiscoveryStartIDDevCB; 22634 22635 /* 22636 * Prepare SGL and send FIS to LL layer. 22637 */ 22638 satIOContext->reqType = agRequestType; /* Save it */ 22639 22640 #ifdef TD_INTERNAL_DEBUG 22641 tdhexdump("tdsaDiscoverySendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 22642 #ifdef TD_DEBUG_ENABLE 22643 tdhexdump("tdsaDiscoverySendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t)); 22644 #endif 22645 #endif 22646 status = sataLLIOStart( tiRoot, 22647 tiIORequest, 22648 tiDeviceHandle, 22649 tiScsiRequest, 22650 satIOContext); 22651 TI_DBG3(("tdsaDiscoverySendIDDev: end status %d\n", status)); 22652 return status; 22653 } 22654 22655 22656 /***************************************************************************** 22657 *! \brief tdsaDiscoveryStartIDDevCB 22658 * 22659 * This routine is a callback function for tdsaDiscoverySendIDDev() 22660 * Using Identify Device Data, this function finds whether devicedata is 22661 * new or old. If new, add it to the devicelist. This is done as a part 22662 * of discovery. 22663 * 22664 * \param agRoot: Handles for this instance of SAS/SATA hardware 22665 * \param agIORequest: Pointer to the LL I/O request context for this I/O. 22666 * \param agIOStatus: Status of completed I/O. 22667 * \param agFirstDword:Pointer to the four bytes of FIS. 22668 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS 22669 * length. 22670 * \param agParam: Additional info based on status. 22671 * \param ioContext: Pointer to satIOContext_t. 22672 * 22673 * \return: none 22674 * 22675 *****************************************************************************/ 22676 void tdsaDiscoveryStartIDDevCB( 22677 agsaRoot_t *agRoot, 22678 agsaIORequest_t *agIORequest, 22679 bit32 agIOStatus, 22680 agsaFisHeader_t *agFirstDword, 22681 bit32 agIOInfoLen, 22682 void *agParam, 22683 void *ioContext 22684 ) 22685 { 22686 /* 22687 In the process of SAT_IDENTIFY_DEVICE during discovery 22688 */ 22689 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 22690 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 22691 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; 22692 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared; 22693 tdIORequestBody_t *tdIORequestBody; 22694 tdIORequestBody_t *tdOrgIORequestBody; 22695 satIOContext_t *satIOContext; 22696 satIOContext_t *satOrgIOContext; 22697 satIOContext_t *satNewIOContext; 22698 satInternalIo_t *satIntIo; 22699 satInternalIo_t *satNewIntIo = agNULL; 22700 satDeviceData_t *satDevData; 22701 tiIORequest_t *tiOrgIORequest = agNULL; 22702 22703 #ifdef TD_DEBUG_ENABLE 22704 bit32 ataStatus = 0; 22705 bit32 ataError; 22706 agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL; 22707 #endif 22708 agsaSATAIdentifyData_t *pSATAIdData; 22709 bit16 *tmpptr, tmpptr_tmp; 22710 bit32 x; 22711 tdsaDeviceData_t *oneDeviceData = agNULL; 22712 void *sglVirtualAddr; 22713 tdsaPortContext_t *onePortContext = agNULL; 22714 tiPortalContext_t *tiPortalContext = agNULL; 22715 bit32 retry_status; 22716 22717 TI_DBG3(("tdsaDiscoveryStartIDDevCB: start\n")); 22718 22719 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; 22720 satIOContext = (satIOContext_t *) ioContext; 22721 satIntIo = satIOContext->satIntIoContext; 22722 satDevData = satIOContext->pSatDevData; 22723 oneDeviceData = (tdsaDeviceData_t *)tdIORequestBody->tiDevHandle->tdData; 22724 TI_DBG3(("tdsaDiscoveryStartIDDevCB: did %d\n", oneDeviceData->id)); 22725 onePortContext = oneDeviceData->tdPortContext; 22726 if (onePortContext == agNULL) 22727 { 22728 TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext is NULL\n")); 22729 return; 22730 } 22731 tiPortalContext= onePortContext->tiPortalContext; 22732 22733 satDevData->IDDeviceValid = agFALSE; 22734 22735 if (satIntIo == agNULL) 22736 { 22737 TI_DBG1(("tdsaDiscoveryStartIDDevCB: External, OS generated\n")); 22738 TI_DBG1(("tdsaDiscoveryStartIDDevCB: Not possible case\n")); 22739 satOrgIOContext = satIOContext; 22740 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody; 22741 22742 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22743 22744 satFreeIntIoResource( tiRoot, 22745 satDevData, 22746 satIntIo); 22747 22748 /* clean up TD layer's IORequestBody */ 22749 ostiFreeMemory( 22750 tiRoot, 22751 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22752 sizeof(tdIORequestBody_t) 22753 ); 22754 return; 22755 } 22756 else 22757 { 22758 TI_DBG3(("tdsaDiscoveryStartIDDevCB: Internal, TD generated\n")); 22759 satOrgIOContext = satIOContext->satOrgIOContext; 22760 if (satOrgIOContext == agNULL) 22761 { 22762 TI_DBG6(("tdsaDiscoveryStartIDDevCB: satOrgIOContext is NULL\n")); 22763 return; 22764 } 22765 else 22766 { 22767 TI_DBG6(("tdsaDiscoveryStartIDDevCB: satOrgIOContext is NOT NULL\n")); 22768 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody; 22769 sglVirtualAddr = satIntIo->satIntTiScsiXchg.sglVirtualAddr; 22770 } 22771 } 22772 22773 tiOrgIORequest = tdIORequestBody->tiIORequest; 22774 tdIORequestBody->ioCompleted = agTRUE; 22775 tdIORequestBody->ioStarted = agFALSE; 22776 22777 TI_DBG3(("tdsaDiscoveryStartIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid)); 22778 22779 /* protect against double completion for old port */ 22780 if (satOrgIOContext->pid != oneDeviceData->tdPortContext->id) 22781 { 22782 TI_DBG3(("tdsaDiscoveryStartIDDevCB: incorrect pid\n")); 22783 TI_DBG3(("tdsaDiscoveryStartIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid)); 22784 TI_DBG3(("tdsaDiscoveryStartIDDevCB: tiPortalContext pid %d\n", oneDeviceData->tdPortContext->id)); 22785 22786 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22787 22788 satFreeIntIoResource( tiRoot, 22789 satDevData, 22790 satIntIo); 22791 22792 /* clean up TD layer's IORequestBody */ 22793 ostiFreeMemory( 22794 tiRoot, 22795 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22796 sizeof(tdIORequestBody_t) 22797 ); 22798 22799 return; 22800 } 22801 22802 /* completion after portcontext is invalidated */ 22803 if (onePortContext != agNULL) 22804 { 22805 if (onePortContext->valid == agFALSE) 22806 { 22807 TI_DBG1(("tdsaDiscoveryStartIDDevCB: portcontext is invalid\n")); 22808 TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext->id pid %d\n", onePortContext->id)); 22809 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22810 22811 satFreeIntIoResource( tiRoot, 22812 satDevData, 22813 satIntIo); 22814 22815 /* clean up TD layer's IORequestBody */ 22816 ostiFreeMemory( 22817 tiRoot, 22818 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22819 sizeof(tdIORequestBody_t) 22820 ); 22821 22822 /* no notification to OS layer */ 22823 return; 22824 } 22825 } 22826 22827 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS) 22828 { 22829 TI_DBG1(("tdsaDiscoveryStartIDDevCB: agFirstDword is NULL when error, status %d\n", agIOStatus)); 22830 TI_DBG1(("tdsaDiscoveryStartIDDevCB: did %d\n", oneDeviceData->id)); 22831 22832 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES) 22833 { 22834 satIOContext->pSatDevData->satPendingNONNCQIO--; 22835 satIOContext->pSatDevData->satPendingIO--; 22836 retry_status = sataLLIOStart(tiRoot, 22837 &satIntIo->satIntTiIORequest, 22838 &(oneDeviceData->tiDeviceHandle), 22839 satIOContext->tiScsiXchg, 22840 satIOContext); 22841 if (retry_status != tiSuccess) 22842 { 22843 /* simply give up */ 22844 satDevData->ID_Retries = 0; 22845 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22846 22847 satFreeIntIoResource( tiRoot, 22848 satDevData, 22849 satIntIo); 22850 22851 /* clean up TD layer's IORequestBody */ 22852 ostiFreeMemory( 22853 tiRoot, 22854 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22855 sizeof(tdIORequestBody_t) 22856 ); 22857 return; 22858 } 22859 satDevData->ID_Retries++; 22860 tdIORequestBody->ioCompleted = agFALSE; 22861 tdIORequestBody->ioStarted = agTRUE; 22862 return; 22863 } 22864 else 22865 { 22866 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22867 satFreeIntIoResource( tiRoot, 22868 satDevData, 22869 satIntIo); 22870 22871 /* clean up TD layer's IORequestBody */ 22872 ostiFreeMemory( 22873 tiRoot, 22874 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22875 sizeof(tdIORequestBody_t) 22876 ); 22877 if (tdsaAllShared->ResetInDiscovery != 0) 22878 { 22879 /* ResetInDiscovery in on */ 22880 if (satDevData->NumOfIDRetries <= 0) 22881 { 22882 satDevData->NumOfIDRetries++; 22883 satDevData->ID_Retries = 0; 22884 /* send link reset */ 22885 tdsaPhyControlSend(tiRoot, 22886 oneDeviceData, 22887 SMP_PHY_CONTROL_HARD_RESET, 22888 agNULL, 22889 tdsaRotateQnumber(tiRoot, oneDeviceData) 22890 ); 22891 } 22892 } 22893 return; 22894 } 22895 } 22896 22897 if (agIOStatus == OSSA_IO_ABORTED || 22898 agIOStatus == OSSA_IO_UNDERFLOW || 22899 agIOStatus == OSSA_IO_XFER_ERROR_BREAK || 22900 agIOStatus == OSSA_IO_XFER_ERROR_PHY_NOT_READY || 22901 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED || 22902 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK || 22903 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS || 22904 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION || 22905 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED || 22906 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY || 22907 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION || 22908 agIOStatus == OSSA_IO_XFER_ERROR_NAK_RECEIVED || 22909 agIOStatus == OSSA_IO_XFER_ERROR_DMA || 22910 agIOStatus == OSSA_IO_XFER_ERROR_SATA_LINK_TIMEOUT || 22911 agIOStatus == OSSA_IO_XFER_ERROR_REJECTED_NCQ_MODE || 22912 agIOStatus == OSSA_IO_XFER_OPEN_RETRY_TIMEOUT || 22913 agIOStatus == OSSA_IO_NO_DEVICE || 22914 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION || 22915 agIOStatus == OSSA_IO_PORT_IN_RESET || 22916 agIOStatus == OSSA_IO_DS_NON_OPERATIONAL || 22917 agIOStatus == OSSA_IO_DS_IN_RECOVERY || 22918 agIOStatus == OSSA_IO_DS_IN_ERROR 22919 ) 22920 { 22921 TI_DBG1(("tdsaDiscoveryStartIDDevCB: OSSA_IO_OPEN_CNX_ERROR 0x%x\n", agIOStatus)); 22922 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES) 22923 { 22924 satIOContext->pSatDevData->satPendingNONNCQIO--; 22925 satIOContext->pSatDevData->satPendingIO--; 22926 retry_status = sataLLIOStart(tiRoot, 22927 &satIntIo->satIntTiIORequest, 22928 &(oneDeviceData->tiDeviceHandle), 22929 satIOContext->tiScsiXchg, 22930 satIOContext); 22931 if (retry_status != tiSuccess) 22932 { 22933 /* simply give up */ 22934 satDevData->ID_Retries = 0; 22935 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22936 22937 satFreeIntIoResource( tiRoot, 22938 satDevData, 22939 satIntIo); 22940 22941 /* clean up TD layer's IORequestBody */ 22942 ostiFreeMemory( 22943 tiRoot, 22944 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22945 sizeof(tdIORequestBody_t) 22946 ); 22947 return; 22948 } 22949 satDevData->ID_Retries++; 22950 tdIORequestBody->ioCompleted = agFALSE; 22951 tdIORequestBody->ioStarted = agTRUE; 22952 return; 22953 } 22954 else 22955 { 22956 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 22957 satFreeIntIoResource( tiRoot, 22958 satDevData, 22959 satIntIo); 22960 22961 /* clean up TD layer's IORequestBody */ 22962 ostiFreeMemory( 22963 tiRoot, 22964 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 22965 sizeof(tdIORequestBody_t) 22966 ); 22967 if (tdsaAllShared->ResetInDiscovery != 0) 22968 { 22969 /* ResetInDiscovery in on */ 22970 if (satDevData->NumOfIDRetries <= 0) 22971 { 22972 satDevData->NumOfIDRetries++; 22973 satDevData->ID_Retries = 0; 22974 /* send link reset */ 22975 tdsaPhyControlSend(tiRoot, 22976 oneDeviceData, 22977 SMP_PHY_CONTROL_HARD_RESET, 22978 agNULL, 22979 tdsaRotateQnumber(tiRoot, oneDeviceData) 22980 ); 22981 } 22982 } 22983 return; 22984 } 22985 } 22986 22987 if ( agIOStatus != OSSA_IO_SUCCESS || 22988 (agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0) 22989 ) 22990 { 22991 #ifdef TD_DEBUG_ENABLE 22992 /* only agsaFisPioSetup_t is expected */ 22993 satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup); 22994 ataStatus = satPIOSetupHeader->status; /* ATA Status register */ 22995 ataError = satPIOSetupHeader->error; /* ATA Eror register */ 22996 #endif 22997 TI_DBG1(("tdsaDiscoveryStartIDDevCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError)); 22998 22999 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES) 23000 { 23001 satIOContext->pSatDevData->satPendingNONNCQIO--; 23002 satIOContext->pSatDevData->satPendingIO--; 23003 retry_status = sataLLIOStart(tiRoot, 23004 &satIntIo->satIntTiIORequest, 23005 &(oneDeviceData->tiDeviceHandle), 23006 satIOContext->tiScsiXchg, 23007 satIOContext); 23008 if (retry_status != tiSuccess) 23009 { 23010 /* simply give up */ 23011 satDevData->ID_Retries = 0; 23012 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 23013 23014 satFreeIntIoResource( tiRoot, 23015 satDevData, 23016 satIntIo); 23017 23018 /* clean up TD layer's IORequestBody */ 23019 ostiFreeMemory( 23020 tiRoot, 23021 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 23022 sizeof(tdIORequestBody_t) 23023 ); 23024 return; 23025 } 23026 satDevData->ID_Retries++; 23027 tdIORequestBody->ioCompleted = agFALSE; 23028 tdIORequestBody->ioStarted = agTRUE; 23029 return; 23030 } 23031 else 23032 { 23033 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 23034 satFreeIntIoResource( tiRoot, 23035 satDevData, 23036 satIntIo); 23037 23038 /* clean up TD layer's IORequestBody */ 23039 ostiFreeMemory( 23040 tiRoot, 23041 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 23042 sizeof(tdIORequestBody_t) 23043 ); 23044 if (tdsaAllShared->ResetInDiscovery != 0) 23045 { 23046 /* ResetInDiscovery in on */ 23047 if (satDevData->NumOfIDRetries <= 0) 23048 { 23049 satDevData->NumOfIDRetries++; 23050 satDevData->ID_Retries = 0; 23051 /* send link reset */ 23052 tdsaPhyControlSend(tiRoot, 23053 oneDeviceData, 23054 SMP_PHY_CONTROL_HARD_RESET, 23055 agNULL, 23056 tdsaRotateQnumber(tiRoot, oneDeviceData) 23057 ); 23058 } 23059 } 23060 return; 23061 } 23062 } 23063 23064 23065 /* success */ 23066 TI_DBG3(("tdsaDiscoveryStartIDDevCB: Success\n")); 23067 TI_DBG3(("tdsaDiscoveryStartIDDevCB: Success did %d\n", oneDeviceData->id)); 23068 23069 /* Convert to host endian */ 23070 tmpptr = (bit16*)sglVirtualAddr; 23071 for (x=0; x < sizeof(agsaSATAIdentifyData_t)/sizeof(bit16); x++) 23072 { 23073 OSSA_READ_LE_16(AGROOT, &tmpptr_tmp, tmpptr, 0); 23074 *tmpptr = tmpptr_tmp; 23075 tmpptr++; 23076 } 23077 23078 pSATAIdData = (agsaSATAIdentifyData_t *)sglVirtualAddr; 23079 //tdhexdump("satAddSATAIDDevCB before", (bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t)); 23080 23081 TI_DBG5(("tdsaDiscoveryStartIDDevCB: OS satOrgIOContext %p \n", satOrgIOContext)); 23082 TI_DBG5(("tdsaDiscoveryStartIDDevCB: TD satIOContext %p \n", satIOContext)); 23083 TI_DBG5(("tdsaDiscoveryStartIDDevCB: OS tiScsiXchg %p \n", satOrgIOContext->tiScsiXchg)); 23084 TI_DBG5(("tdsaDiscoveryStartIDDevCB: TD tiScsiXchg %p \n", satIOContext->tiScsiXchg)); 23085 23086 23087 /* copy ID Dev data to satDevData */ 23088 satDevData->satIdentifyData = *pSATAIdData; 23089 satDevData->IDDeviceValid = agTRUE; 23090 23091 #ifdef TD_INTERNAL_DEBUG 23092 tdhexdump("tdsaDiscoveryStartIDDevCB ID Dev data",(bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t)); 23093 tdhexdump("tdsaDiscoveryStartIDDevCB Device ID Dev data",(bit8 *)&satDevData->satIdentifyData, sizeof(agsaSATAIdentifyData_t)); 23094 #endif 23095 23096 /* set satDevData fields from IndentifyData */ 23097 satSetDevInfo(satDevData,pSATAIdData); 23098 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext); 23099 23100 satFreeIntIoResource( tiRoot, 23101 satDevData, 23102 satIntIo); 23103 23104 if (satDevData->satDeviceType == SATA_ATAPI_DEVICE) 23105 { 23106 /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/ 23107 satNewIntIo = satAllocIntIoResource( tiRoot, 23108 tiOrgIORequest, 23109 satDevData, 23110 0, 23111 satNewIntIo); 23112 23113 if (satNewIntIo == agNULL) 23114 { 23115 TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n")); 23116 /* clean up TD layer's IORequestBody */ 23117 ostiFreeMemory( 23118 tiRoot, 23119 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 23120 sizeof(tdIORequestBody_t) 23121 ); 23122 return; 23123 } /* end memory allocation */ 23124 23125 satNewIOContext = satPrepareNewIO(satNewIntIo, 23126 tiOrgIORequest, 23127 satDevData, 23128 agNULL, 23129 satOrgIOContext 23130 ); 23131 /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/ 23132 retry_status = satSetFeatures(tiRoot, 23133 &satNewIntIo->satIntTiIORequest, 23134 satNewIOContext->ptiDeviceHandle, 23135 &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */ 23136 satNewIOContext, 23137 agFALSE); 23138 if (retry_status != tiSuccess) 23139 { 23140 satFreeIntIoResource(tiRoot, satDevData, satIntIo); 23141 /* clean up TD layer's IORequestBody */ 23142 ostiFreeMemory( 23143 tiRoot, 23144 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 23145 sizeof(tdIORequestBody_t) 23146 ); 23147 } 23148 } 23149 else 23150 { 23151 /* clean up TD layer's IORequestBody */ 23152 ostiFreeMemory( 23153 tiRoot, 23154 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle, 23155 sizeof(tdIORequestBody_t) 23156 ); 23157 if (onePortContext != agNULL) 23158 { 23159 if (onePortContext->DiscoveryState == ITD_DSTATE_COMPLETED) 23160 { 23161 TI_DBG1(("tdsaDiscoveryStartIDDevCB: ID completed after discovery is done; tiDeviceArrival\n")); 23162 /* in case registration is finished after discovery is finished */ 23163 ostiInitiatorEvent( 23164 tiRoot, 23165 tiPortalContext, 23166 agNULL, 23167 tiIntrEventTypeDeviceChange, 23168 tiDeviceArrival, 23169 agNULL 23170 ); 23171 } 23172 } 23173 else 23174 { 23175 TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext is NULL, wrong\n")); 23176 } 23177 } 23178 TI_DBG3(("tdsaDiscoveryStartIDDevCB: end\n")); 23179 return; 23180 } 23181 /***************************************************************************** 23182 *! \brief satAbort 23183 * 23184 * This routine does local abort for outstanding FIS. 23185 * 23186 * \param agRoot: Handles for this instance of SAS/SATA hardware 23187 * \param satIOContext: Pointer to satIOContext_t. 23188 * 23189 * \return: none 23190 * 23191 *****************************************************************************/ 23192 GLOBAL void satAbort(agsaRoot_t *agRoot, 23193 satIOContext_t *satIOContext) 23194 { 23195 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; 23196 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; 23197 tdIORequestBody_t *tdIORequestBody; /* io to be aborted */ 23198 tdIORequestBody_t *tdAbortIORequestBody; /* abort io itself */ 23199 agsaIORequest_t *agToBeAbortedIORequest; /* io to be aborted */ 23200 agsaIORequest_t *agAbortIORequest; /* abort io itself */ 23201 bit32 PhysUpper32; 23202 bit32 PhysLower32; 23203 bit32 memAllocStatus; 23204 void *osMemHandle; 23205 23206 TI_DBG1(("satAbort: start\n")); 23207 23208 if (satIOContext == agNULL) 23209 { 23210 TI_DBG1(("satAbort: satIOContext is NULL, wrong\n")); 23211 return; 23212 } 23213 tdIORequestBody = (tdIORequestBody_t *)satIOContext->tiRequestBody; 23214 agToBeAbortedIORequest = (agsaIORequest_t *)&(tdIORequestBody->agIORequest); 23215 /* allocating agIORequest for abort itself */ 23216 memAllocStatus = ostiAllocMemory( 23217 tiRoot, 23218 &osMemHandle, 23219 (void **)&tdAbortIORequestBody, 23220 &PhysUpper32, 23221 &PhysLower32, 23222 8, 23223 sizeof(tdIORequestBody_t), 23224 agTRUE 23225 ); 23226 23227 if (memAllocStatus != tiSuccess) 23228 { 23229 /* let os process IO */ 23230 TI_DBG1(("satAbort: ostiAllocMemory failed...\n")); 23231 return; 23232 } 23233 23234 if (tdAbortIORequestBody == agNULL) 23235 { 23236 /* let os process IO */ 23237 TI_DBG1(("satAbort: ostiAllocMemory returned NULL tdAbortIORequestBody\n")); 23238 return; 23239 } 23240 /* setup task management structure */ 23241 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 23242 tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle; 23243 23244 /* initialize agIORequest */ 23245 agAbortIORequest = &(tdAbortIORequestBody->agIORequest); 23246 agAbortIORequest->osData = (void *) tdAbortIORequestBody; 23247 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */ 23248 23249 23250 /* 23251 * Issue abort 23252 */ 23253 saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agToBeAbortedIORequest, agNULL ); 23254 23255 23256 TI_DBG1(("satAbort: end\n")); 23257 return; 23258 } 23259 23260 /***************************************************************************** 23261 *! \brief satSATADeviceReset 23262 * 23263 * This routine is called to reset all phys of port which a device belongs to 23264 * 23265 * \param tiRoot: Pointer to TISA initiator driver/port instance. 23266 * \param oneDeviceData: Pointer to the device data. 23267 * \param flag: reset flag 23268 * 23269 * \return: 23270 * 23271 * none 23272 * 23273 *****************************************************************************/ 23274 osGLOBAL void 23275 satSATADeviceReset( tiRoot_t *tiRoot, 23276 tdsaDeviceData_t *oneDeviceData, 23277 bit32 flag) 23278 { 23279 agsaRoot_t *agRoot; 23280 tdsaPortContext_t *onePortContext; 23281 bit32 i; 23282 23283 TI_DBG1(("satSATADeviceReset: start\n")); 23284 agRoot = oneDeviceData->agRoot; 23285 onePortContext = oneDeviceData->tdPortContext; 23286 23287 if (agRoot == agNULL) 23288 { 23289 TI_DBG1(("satSATADeviceReset: Error!!! agRoot is NULL\n")); 23290 return; 23291 } 23292 if (onePortContext == agNULL) 23293 { 23294 TI_DBG1(("satSATADeviceReset: Error!!! onePortContext is NULL\n")); 23295 return; 23296 } 23297 23298 for(i=0;i<TD_MAX_NUM_PHYS;i++) 23299 { 23300 if (onePortContext->PhyIDList[i] == agTRUE) 23301 { 23302 saLocalPhyControl(agRoot, agNULL, tdsaRotateQnumber(tiRoot, agNULL), i, flag, agNULL); 23303 } 23304 } 23305 23306 return; 23307 } 23308 23309 #endif /* #ifdef SATA_ENABLE */ 23310