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 #include <sys/cdefs.h> 23 #include <dev/pms/config.h> 24 25 #include <dev/pms/freebsd/driver/common/osenv.h> 26 #include <dev/pms/freebsd/driver/common/ostypes.h> 27 #include <dev/pms/freebsd/driver/common/osdebug.h> 28 29 #include <dev/pms/RefTisa/tisa/api/titypes.h> 30 31 #include <dev/pms/RefTisa/sallsdk/api/sa.h> 32 #include <dev/pms/RefTisa/sallsdk/api/saapi.h> 33 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h> 34 35 #include <dev/pms/RefTisa/sat/api/sm.h> 36 #include <dev/pms/RefTisa/sat/api/smapi.h> 37 #include <dev/pms/RefTisa/sat/api/tdsmapi.h> 38 39 #include <dev/pms/RefTisa/sat/src/smdefs.h> 40 #include <dev/pms/RefTisa/sat/src/smproto.h> 41 #include <dev/pms/RefTisa/sat/src/smtypes.h> 42 43 /* start smapi defined APIs */ 44 osGLOBAL bit32 45 smRegisterDevice( 46 smRoot_t *smRoot, 47 agsaDevHandle_t *agDevHandle, 48 smDeviceHandle_t *smDeviceHandle, 49 agsaDevHandle_t *agExpDevHandle, 50 bit32 phyID, 51 bit32 DeviceType 52 ) 53 { 54 smDeviceData_t *oneDeviceData = agNULL; 55 56 SM_DBG2(("smRegisterDevice: start\n")); 57 58 if (smDeviceHandle == agNULL) 59 { 60 SM_DBG1(("smRegisterDevice: smDeviceHandle is NULL!!!\n")); 61 return SM_RC_FAILURE; 62 } 63 64 if (agDevHandle == agNULL) 65 { 66 SM_DBG1(("smRegisterDevice: agDevHandle is NULL!!!\n")); 67 return SM_RC_FAILURE; 68 } 69 70 oneDeviceData = smAddToSharedcontext(smRoot, agDevHandle, smDeviceHandle, agExpDevHandle, phyID); 71 if (oneDeviceData != agNULL) 72 { 73 oneDeviceData->satDeviceType = DeviceType; 74 return SM_RC_SUCCESS; 75 } 76 else 77 { 78 return SM_RC_FAILURE; 79 } 80 81 } 82 83 osGLOBAL bit32 84 smDeregisterDevice( 85 smRoot_t *smRoot, 86 agsaDevHandle_t *agDevHandle, 87 smDeviceHandle_t *smDeviceHandle 88 ) 89 { 90 bit32 status = SM_RC_FAILURE; 91 92 SM_DBG2(("smDeregisterDevice: start\n")); 93 94 if (smDeviceHandle == agNULL) 95 { 96 SM_DBG1(("smDeregisterDevice: smDeviceHandle is NULL!!!\n")); 97 return SM_RC_FAILURE; 98 } 99 100 if (agDevHandle == agNULL) 101 { 102 SM_DBG1(("smDeregisterDevice: agDevHandle is NULL!!!\n")); 103 return SM_RC_FAILURE; 104 } 105 106 status = smRemoveFromSharedcontext(smRoot, agDevHandle, smDeviceHandle); 107 108 return status; 109 } 110 111 osGLOBAL bit32 112 smIOAbort( 113 smRoot_t *smRoot, 114 smIORequest_t *tasktag 115 ) 116 117 { 118 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData; 119 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 120 agsaRoot_t *agRoot; 121 smIORequestBody_t *smIORequestBody = agNULL; 122 smIORequestBody_t *smIONewRequestBody = agNULL; 123 agsaIORequest_t *agIORequest = agNULL; /* IO to be aborted */ 124 bit32 status = SM_RC_FAILURE; 125 agsaIORequest_t *agAbortIORequest; /* abort IO itself */ 126 smIORequestBody_t *smAbortIORequestBody; 127 #if 1 128 bit32 PhysUpper32; 129 bit32 PhysLower32; 130 bit32 memAllocStatus; 131 void *osMemHandle; 132 #endif 133 smSatIOContext_t *satIOContext; 134 smSatInternalIo_t *satIntIo; 135 smSatIOContext_t *satAbortIOContext; 136 137 SM_DBG1(("smIOAbort: start\n")); 138 SM_DBG2(("smIOAbort: tasktag %p\n", tasktag)); 139 /* 140 alloc smIORequestBody for abort itself 141 call saSATAAbort() 142 */ 143 144 agRoot = smAllShared->agRoot; 145 smIORequestBody = (smIORequestBody_t *)tasktag->smData; 146 147 if (smIORequestBody == agNULL) 148 { 149 SM_DBG1(("smIOAbort: smIORequestBody is NULL!!!\n")); 150 return SM_RC_FAILURE; 151 } 152 153 /* needs to distinguish internally generated or externally generated */ 154 satIOContext = &(smIORequestBody->transport.SATA.satIOContext); 155 satIntIo = satIOContext->satIntIoContext; 156 if (satIntIo == agNULL) 157 { 158 SM_DBG2(("smIOAbort: External, OS generated\n")); 159 agIORequest = &(smIORequestBody->agIORequest); 160 } 161 else 162 { 163 SM_DBG2(("smIOAbort: Internal, SM generated\n")); 164 smIONewRequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody; 165 agIORequest = &(smIONewRequestBody->agIORequest); 166 } 167 168 /* 169 allocate smAbortIORequestBody for abort request itself 170 */ 171 172 #if 1 173 /* allocating agIORequest for abort itself */ 174 memAllocStatus = tdsmAllocMemory( 175 smRoot, 176 &osMemHandle, 177 (void **)&smAbortIORequestBody, 178 &PhysUpper32, 179 &PhysLower32, 180 8, 181 sizeof(smIORequestBody_t), 182 agTRUE 183 ); 184 if (memAllocStatus != SM_RC_SUCCESS) 185 { 186 /* let os process IO */ 187 SM_DBG1(("smIOAbort: tdsmAllocMemory failed...!!!\n")); 188 return SM_RC_FAILURE; 189 } 190 191 if (smAbortIORequestBody == agNULL) 192 { 193 /* let os process IO */ 194 SM_DBG1(("smIOAbort: tdsmAllocMemory returned NULL smAbortIORequestBody!!!\n")); 195 return SM_RC_FAILURE; 196 } 197 198 smIOReInit(smRoot, smAbortIORequestBody); 199 200 /* setup task management structure */ 201 smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 202 satAbortIOContext = &(smAbortIORequestBody->transport.SATA.satIOContext); 203 satAbortIOContext->smRequestBody = smAbortIORequestBody; 204 205 smAbortIORequestBody->smDevHandle = smIORequestBody->smDevHandle; 206 207 /* initialize agIORequest */ 208 agAbortIORequest = &(smAbortIORequestBody->agIORequest); 209 agAbortIORequest->osData = (void *) smAbortIORequestBody; 210 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */ 211 212 /* remember IO to be aborted */ 213 smAbortIORequestBody->smIOToBeAbortedRequest = tasktag; 214 215 status = saSATAAbort(agRoot, agAbortIORequest, 0, agNULL, 0, agIORequest, smaSATAAbortCB); 216 217 SM_DBG2(("smIOAbort: return status=0x%x\n", status)); 218 219 #endif /* 1 */ 220 221 222 if (status == AGSA_RC_SUCCESS) 223 { 224 return SM_RC_SUCCESS; 225 } 226 else 227 { 228 SM_DBG1(("smIOAbort: failed to call saSATAAbort, status=%d!!!\n", status)); 229 tdsmFreeMemory(smRoot, 230 smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle, 231 sizeof(smIORequestBody_t) 232 ); 233 return SM_RC_FAILURE; 234 } 235 } 236 237 osGLOBAL bit32 238 smIOAbortAll( 239 smRoot_t *smRoot, 240 smDeviceHandle_t *smDeviceHandle 241 ) 242 { 243 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData; 244 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 245 agsaRoot_t *agRoot; 246 bit32 status = SM_RC_FAILURE; 247 agsaIORequest_t *agAbortIORequest; 248 smIORequestBody_t *smAbortIORequestBody; 249 smSatIOContext_t *satAbortIOContext; 250 smDeviceData_t *oneDeviceData = agNULL; 251 agsaDevHandle_t *agDevHandle; 252 253 bit32 PhysUpper32; 254 bit32 PhysLower32; 255 bit32 memAllocStatus; 256 void *osMemHandle; 257 258 259 SM_DBG2(("smIOAbortAll: start\n")); 260 261 agRoot = smAllShared->agRoot; 262 263 if (smDeviceHandle == agNULL) 264 { 265 SM_DBG1(("smIOAbortAll: smDeviceHandle is NULL!!!\n")); 266 return SM_RC_FAILURE; 267 } 268 269 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData; 270 if (oneDeviceData == agNULL) 271 { 272 SM_DBG1(("smIOAbortAll: oneDeviceData is NULL!!!\n")); 273 return SM_RC_FAILURE; 274 } 275 if (oneDeviceData->valid == agFALSE) 276 { 277 SM_DBG1(("smIOAbortAll: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id)); 278 return SM_RC_FAILURE; 279 } 280 281 agDevHandle = oneDeviceData->agDevHandle; 282 if (agDevHandle == agNULL) 283 { 284 SM_DBG1(("smIOAbortAll: agDevHandle is NULL!!!\n")); 285 return SM_RC_FAILURE; 286 } 287 /* 288 smAbortIORequestBody = smDequeueIO(smRoot); 289 if (smAbortIORequestBody == agNULL) 290 { 291 SM_DBG1(("smIOAbortAll: empty freeIOList!!!\n")); 292 return SM_RC_FAILURE; 293 } 294 */ 295 /* allocating agIORequest for abort itself */ 296 memAllocStatus = tdsmAllocMemory( 297 smRoot, 298 &osMemHandle, 299 (void **)&smAbortIORequestBody, 300 &PhysUpper32, 301 &PhysLower32, 302 8, 303 sizeof(smIORequestBody_t), 304 agTRUE 305 ); 306 if (memAllocStatus != SM_RC_SUCCESS) 307 { 308 /* let os process IO */ 309 SM_DBG1(("smIOAbortAll: tdsmAllocMemory failed...!!!\n")); 310 return SM_RC_FAILURE; 311 } 312 313 if (smAbortIORequestBody == agNULL) 314 { 315 /* let os process IO */ 316 SM_DBG1(("smIOAbortAll: tdsmAllocMemory returned NULL smAbortIORequestBody!!!\n")); 317 return SM_RC_FAILURE; 318 } 319 320 smIOReInit(smRoot, smAbortIORequestBody); 321 322 /* setup task management structure */ 323 smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 324 325 satAbortIOContext = &(smAbortIORequestBody->transport.SATA.satIOContext); 326 satAbortIOContext->smRequestBody = smAbortIORequestBody; 327 smAbortIORequestBody->smDevHandle = smDeviceHandle; 328 329 /* initialize agIORequest */ 330 agAbortIORequest = &(smAbortIORequestBody->agIORequest); 331 agAbortIORequest->osData = (void *) smAbortIORequestBody; 332 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */ 333 334 oneDeviceData->OSAbortAll = agTRUE; 335 /* abort all */ 336 status = saSATAAbort(agRoot, agAbortIORequest, tdsmRotateQnumber(smRoot, smDeviceHandle), agDevHandle, 1, agNULL, smaSATAAbortCB); 337 if (status != AGSA_RC_SUCCESS) 338 { 339 SM_DBG1(("smIOAbortAll: failed to call saSATAAbort, status=%d!!!\n", status)); 340 tdsmFreeMemory(smRoot, 341 smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle, 342 sizeof(smIORequestBody_t) 343 ); 344 } 345 346 return status; 347 } 348 349 osGLOBAL bit32 350 smSuperIOStart( 351 smRoot_t *smRoot, 352 smIORequest_t *smIORequest, 353 smDeviceHandle_t *smDeviceHandle, 354 smSuperScsiInitiatorRequest_t *smSCSIRequest, 355 bit32 AddrHi, 356 bit32 AddrLo, 357 bit32 interruptContext 358 ) 359 { 360 smDeviceData_t *oneDeviceData = agNULL; 361 smIORequestBody_t *smIORequestBody = agNULL; 362 smSatIOContext_t *satIOContext = agNULL; 363 bit32 status = SM_RC_FAILURE; 364 365 SM_DBG2(("smSuperIOStart: start\n")); 366 367 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData; 368 if (oneDeviceData == agNULL) 369 { 370 SM_DBG1(("smSuperIOStart: oneDeviceData is NULL!!!\n")); 371 return SM_RC_FAILURE; 372 } 373 if (oneDeviceData->valid == agFALSE) 374 { 375 SM_DBG1(("smSuperIOStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id)); 376 return SM_RC_FAILURE; 377 } 378 smIORequestBody = (smIORequestBody_t*)smIORequest->smData;//smDequeueIO(smRoot); 379 380 if (smIORequestBody == agNULL) 381 { 382 SM_DBG1(("smSuperIOStart: smIORequestBody is NULL!!!\n")); 383 return SM_RC_FAILURE; 384 } 385 386 smIOReInit(smRoot, smIORequestBody); 387 388 SM_DBG3(("smSuperIOStart: io ID %d!!!\n", smIORequestBody->id )); 389 390 oneDeviceData->sasAddressHi = AddrHi; 391 oneDeviceData->sasAddressLo = AddrLo; 392 393 smIORequestBody->smIORequest = smIORequest; 394 smIORequestBody->smDevHandle = smDeviceHandle; 395 396 satIOContext = &(smIORequestBody->transport.SATA.satIOContext); 397 398 /* 399 * Need to initialize all the fields within satIOContext except 400 * reqType and satCompleteCB which will be set later in SM. 401 */ 402 smIORequestBody->transport.SATA.smSenseData.senseData = agNULL; 403 smIORequestBody->transport.SATA.smSenseData.senseLen = 0; 404 satIOContext->pSatDevData = oneDeviceData; 405 satIOContext->pFis = 406 &smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev; 407 satIOContext->pScsiCmnd = &smSCSIRequest->scsiCmnd; 408 satIOContext->pSense = &smIORequestBody->transport.SATA.sensePayload; 409 satIOContext->pSmSenseData = &smIORequestBody->transport.SATA.smSenseData; 410 satIOContext->pSmSenseData->senseData = satIOContext->pSense; 411 /* satIOContext->pSense = (scsiRspSense_t *)satIOContext->pSmSenseData->senseData; */ 412 satIOContext->smRequestBody = smIORequestBody; 413 satIOContext->interruptContext = interruptContext; 414 satIOContext->psmDeviceHandle = smDeviceHandle; 415 satIOContext->smScsiXchg = smSCSIRequest; 416 satIOContext->superIOFlag = agTRUE; 417 // satIOContext->superIOFlag = agFALSE; 418 419 satIOContext->satIntIoContext = agNULL; 420 satIOContext->satOrgIOContext = agNULL; 421 /* satIOContext->tiIORequest = tiIORequest; */ 422 423 /* save context if we need to abort later */ 424 /*smIORequest->smData = smIORequestBody;*/ 425 426 /* followings are used only for internal IO */ 427 satIOContext->currentLBA = 0; 428 satIOContext->OrgTL = 0; 429 430 status = smsatIOStart(smRoot, smIORequest, smDeviceHandle, (smScsiInitiatorRequest_t *)smSCSIRequest, satIOContext); 431 432 return status; 433 } 434 435 /* 436 osGLOBAL bit32 437 tiINIIOStart( 438 tiRoot_t *tiRoot, 439 tiIORequest_t *tiIORequest, 440 tiDeviceHandle_t *tiDeviceHandle, 441 tiScsiInitiatorRequest_t *tiScsiRequest, 442 void *tiRequestBody, 443 bit32 interruptContext 444 ) 445 446 GLOBAL bit32 satIOStart( 447 tiRoot_t *tiRoot, 448 tiIORequest_t *tiIORequest, 449 tiDeviceHandle_t *tiDeviceHandle, 450 tiScsiInitiatorRequest_t *tiScsiRequest, 451 smSatIOContext_t *satIOContext 452 ) 453 smIOStart( 454 smRoot_t *smRoot, 455 smIORequest_t *smIORequest, 456 smDeviceHandle_t *smDeviceHandle, 457 smScsiInitiatorRequest_t *smSCSIRequest, 458 smIORequestBody_t *smRequestBody, 459 bit32 interruptContext 460 ) 461 462 463 */ 464 FORCEINLINE bit32 465 smIOStart( 466 smRoot_t *smRoot, 467 smIORequest_t *smIORequest, 468 smDeviceHandle_t *smDeviceHandle, 469 smScsiInitiatorRequest_t *smSCSIRequest, 470 bit32 interruptContext 471 ) 472 { 473 smDeviceData_t *oneDeviceData = agNULL; 474 smIORequestBody_t *smIORequestBody = agNULL; 475 smSatIOContext_t *satIOContext = agNULL; 476 bit32 status = SM_RC_FAILURE; 477 478 SM_DBG2(("smIOStart: start\n")); 479 480 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData; 481 if (oneDeviceData == agNULL) 482 { 483 SM_DBG1(("smIOStart: oneDeviceData is NULL!!!\n")); 484 return SM_RC_FAILURE; 485 } 486 if (oneDeviceData->valid == agFALSE) 487 { 488 SM_DBG1(("smIOStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id)); 489 return SM_RC_FAILURE; 490 } 491 smIORequestBody = (smIORequestBody_t*)smIORequest->smData;//smDequeueIO(smRoot); 492 493 if (smIORequestBody == agNULL) 494 { 495 SM_DBG1(("smIOStart: smIORequestBody is NULL!!!\n")); 496 return SM_RC_FAILURE; 497 } 498 499 smIOReInit(smRoot, smIORequestBody); 500 501 SM_DBG3(("smIOStart: io ID %d!!!\n", smIORequestBody->id )); 502 503 smIORequestBody->smIORequest = smIORequest; 504 smIORequestBody->smDevHandle = smDeviceHandle; 505 506 satIOContext = &(smIORequestBody->transport.SATA.satIOContext); 507 508 /* 509 * Need to initialize all the fields within satIOContext except 510 * reqType and satCompleteCB which will be set later in SM. 511 */ 512 smIORequestBody->transport.SATA.smSenseData.senseData = agNULL; 513 smIORequestBody->transport.SATA.smSenseData.senseLen = 0; 514 satIOContext->pSatDevData = oneDeviceData; 515 satIOContext->pFis = 516 &smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev; 517 satIOContext->pScsiCmnd = &smSCSIRequest->scsiCmnd; 518 satIOContext->pSense = &smIORequestBody->transport.SATA.sensePayload; 519 satIOContext->pSmSenseData = &smIORequestBody->transport.SATA.smSenseData; 520 satIOContext->pSmSenseData->senseData = satIOContext->pSense; 521 /* satIOContext->pSense = (scsiRspSense_t *)satIOContext->pSmSenseData->senseData; */ 522 satIOContext->smRequestBody = smIORequestBody; 523 satIOContext->interruptContext = interruptContext; 524 satIOContext->psmDeviceHandle = smDeviceHandle; 525 satIOContext->smScsiXchg = smSCSIRequest; 526 satIOContext->superIOFlag = agFALSE; 527 528 satIOContext->satIntIoContext = agNULL; 529 satIOContext->satOrgIOContext = agNULL; 530 satIOContext->currentLBA = 0; 531 satIOContext->OrgTL = 0; 532 533 status = smsatIOStart(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext); 534 535 return status; 536 537 } 538 539 540 541 osGLOBAL bit32 542 smTaskManagement( 543 smRoot_t *smRoot, 544 smDeviceHandle_t *smDeviceHandle, 545 bit32 task, 546 smLUN_t *lun, 547 smIORequest_t *taskTag, /* io to be aborted */ 548 smIORequest_t *currentTaskTag /* task management */ 549 ) 550 { 551 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData; 552 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 553 agsaRoot_t *agRoot = smAllShared->agRoot; 554 smDeviceData_t *oneDeviceData = agNULL; 555 smIORequestBody_t *smIORequestBody = agNULL; 556 bit32 status; 557 agsaContext_t *agContext = agNULL; 558 smSatIOContext_t *satIOContext; 559 560 SM_DBG1(("smTaskManagement: start\n")); 561 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData; 562 563 if (task == SM_LOGICAL_UNIT_RESET || task == SM_TARGET_WARM_RESET || task == SM_ABORT_TASK) 564 { 565 if (task == AG_LOGICAL_UNIT_RESET) 566 { 567 if ( (lun->lun[0] | lun->lun[1] | lun->lun[2] | lun->lun[3] | 568 lun->lun[4] | lun->lun[5] | lun->lun[6] | lun->lun[7] ) != 0 ) 569 { 570 SM_DBG1(("smTaskManagement: *** REJECT *** LUN not zero, did %d!!!\n", 571 oneDeviceData->id)); 572 return SM_RC_FAILURE; 573 } 574 } 575 576 oneDeviceData->satDriveState = SAT_DEV_STATE_IN_RECOVERY; 577 oneDeviceData->satAbortAfterReset = agFALSE; 578 579 saSetDeviceState(agRoot, 580 agNULL, 581 tdsmRotateQnumber(smRoot, smDeviceHandle), 582 oneDeviceData->agDevHandle, 583 SA_DS_IN_RECOVERY 584 ); 585 586 if (oneDeviceData->directlyAttached == agFALSE) 587 { 588 /* expander attached */ 589 SM_DBG1(("smTaskManagement: LUN reset or device reset expander attached!!!\n")); 590 status = smPhyControlSend(smRoot, 591 oneDeviceData, 592 SMP_PHY_CONTROL_HARD_RESET, 593 currentTaskTag, 594 tdsmRotateQnumber(smRoot, smDeviceHandle) 595 ); 596 return status; 597 } 598 else 599 { 600 SM_DBG1(("smTaskManagement: LUN reset or device reset directly attached\n")); 601 602 smIORequestBody = (smIORequestBody_t*)currentTaskTag->smData;//smDequeueIO(smRoot); 603 604 if (smIORequestBody == agNULL) 605 { 606 SM_DBG1(("smTaskManagement: smIORequestBody is NULL!!!\n")); 607 return SM_RC_FAILURE; 608 } 609 610 smIOReInit(smRoot, smIORequestBody); 611 612 satIOContext = &(smIORequestBody->transport.SATA.satIOContext); 613 satIOContext->smRequestBody = smIORequestBody; 614 smIORequestBody->smDevHandle = smDeviceHandle; 615 616 agContext = &(oneDeviceData->agDeviceResetContext); 617 agContext->osData = currentTaskTag; 618 619 status = saLocalPhyControl(agRoot, 620 agContext, 621 tdsmRotateQnumber(smRoot, smDeviceHandle) &0xFFFF, 622 oneDeviceData->phyID, 623 AGSA_PHY_HARD_RESET, 624 smLocalPhyControlCB 625 ); 626 627 if ( status == AGSA_RC_SUCCESS) 628 { 629 return SM_RC_SUCCESS; 630 } 631 else if (status == AGSA_RC_BUSY) 632 { 633 return SM_RC_BUSY; 634 } 635 else if (status == AGSA_RC_FAILURE) 636 { 637 return SM_RC_FAILURE; 638 } 639 else 640 { 641 SM_DBG1(("smTaskManagement: unknown status %d\n",status)); 642 return SM_RC_FAILURE; 643 } 644 } 645 } 646 else 647 { 648 /* smsatsmTaskManagement() which is satTM() */ 649 smIORequestBody = (smIORequestBody_t*)currentTaskTag->smData;//smDequeueIO(smRoot); 650 651 if (smIORequestBody == agNULL) 652 { 653 SM_DBG1(("smTaskManagement: smIORequestBody is NULL!!!\n")); 654 return SM_RC_FAILURE; 655 } 656 657 smIOReInit(smRoot, smIORequestBody); 658 /*currentTaskTag->smData = smIORequestBody;*/ 659 660 status = smsatTaskManagement(smRoot, 661 smDeviceHandle, 662 task, 663 lun, 664 taskTag, 665 currentTaskTag, 666 smIORequestBody 667 ); 668 669 return status; 670 } 671 return SM_RC_SUCCESS; 672 } 673 674 675 676 /********************************************************* end smapi defined APIS */ 677 /* counterpart is 678 smEnqueueIO(smRoot_t *smRoot, 679 smSatIOContext_t *satIOContext) 680 */ 681 osGLOBAL smIORequestBody_t * 682 smDequeueIO(smRoot_t *smRoot) 683 { 684 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData; 685 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 686 smIORequestBody_t *smIORequestBody = agNULL; 687 smList_t *IOListList; 688 689 SM_DBG2(("smDequeueIO: start\n")); 690 691 tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK); 692 if (SMLIST_EMPTY(&(smAllShared->freeIOList))) 693 { 694 SM_DBG1(("smDequeueIO: empty freeIOList!!!\n")); 695 tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 696 return agNULL; 697 } 698 699 SMLIST_DEQUEUE_FROM_HEAD(&IOListList, &(smAllShared->freeIOList)); 700 smIORequestBody = SMLIST_OBJECT_BASE(smIORequestBody_t, satIoBodyLink, IOListList); 701 SMLIST_DEQUEUE_THIS(&(smIORequestBody->satIoBodyLink)); 702 SMLIST_ENQUEUE_AT_TAIL(&(smIORequestBody->satIoBodyLink), &(smAllShared->mainIOList)); 703 tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 704 705 if (smIORequestBody->InUse == agTRUE) 706 { 707 SM_DBG1(("smDequeueIO: wrong. already in USE ID %d!!!!\n", smIORequestBody->id)); 708 } 709 smIOReInit(smRoot, smIORequestBody); 710 711 712 SM_DBG2(("smDequeueIO: io ID %d!\n", smIORequestBody->id)); 713 714 /* debugging */ 715 if (smIORequestBody->satIoBodyLink.flink == agNULL) 716 { 717 SM_DBG1(("smDequeueIO: io ID %d, flink is NULL!!!\n", smIORequestBody->id)); 718 } 719 if (smIORequestBody->satIoBodyLink.blink == agNULL) 720 { 721 SM_DBG1(("smDequeueIO: io ID %d, blink is NULL!!!\n", smIORequestBody->id)); 722 } 723 724 return smIORequestBody; 725 } 726 727 //start here 728 //compare with ossaSATAAbortCB() 729 //qqq1 730 osGLOBAL void 731 smsatAbort( 732 smRoot_t *smRoot, 733 agsaRoot_t *agRoot, 734 smSatIOContext_t *satIOContext 735 ) 736 { 737 smIORequestBody_t *smIORequestBody = agNULL; /* abort itself */ 738 smIORequestBody_t *smToBeAbortedIORequestBody; /* io to be aborted */ 739 agsaIORequest_t *agToBeAbortedIORequest; /* io to be aborted */ 740 agsaIORequest_t *agAbortIORequest; /* abort io itself */ 741 smSatIOContext_t *satAbortIOContext; 742 bit32 PhysUpper32; 743 bit32 PhysLower32; 744 bit32 memAllocStatus; 745 void *osMemHandle; 746 747 748 SM_DBG2(("smsatAbort: start\n")); 749 750 if (satIOContext == agNULL) 751 { 752 SM_DBG1(("smsatAbort: satIOContext is NULL, wrong!!!\n")); 753 return; 754 } 755 756 smToBeAbortedIORequestBody = (smIORequestBody_t *)satIOContext->smRequestBody; 757 agToBeAbortedIORequest = (agsaIORequest_t *)&(smToBeAbortedIORequestBody->agIORequest); 758 /* 759 smIORequestBody = smDequeueIO(smRoot); 760 761 if (smIORequestBody == agNULL) 762 { 763 SM_DBG1(("smsatAbort: empty freeIOList!!!\n")); 764 return; 765 } 766 */ 767 /* allocating agIORequest for abort itself */ 768 memAllocStatus = tdsmAllocMemory( 769 smRoot, 770 &osMemHandle, 771 (void **)&smIORequestBody, 772 &PhysUpper32, 773 &PhysLower32, 774 8, 775 sizeof(smIORequestBody_t), 776 agTRUE 777 ); 778 if (memAllocStatus != tiSuccess) 779 { 780 /* let os process IO */ 781 SM_DBG1(("smsatAbort: ostiAllocMemory failed...\n")); 782 return; 783 } 784 785 if (smIORequestBody == agNULL) 786 { 787 /* let os process IO */ 788 SM_DBG1(("smsatAbort: ostiAllocMemory returned NULL smIORequestBody\n")); 789 return; 790 } 791 smIOReInit(smRoot, smIORequestBody); 792 793 smIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 794 smIORequestBody->smDevHandle = smToBeAbortedIORequestBody->smDevHandle; 795 /* initialize agIORequest */ 796 satAbortIOContext = &(smIORequestBody->transport.SATA.satIOContext); 797 satAbortIOContext->smRequestBody = smIORequestBody; 798 799 agAbortIORequest = &(smIORequestBody->agIORequest); 800 agAbortIORequest->osData = (void *) smIORequestBody; 801 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */ 802 803 /* 804 * Issue abort 805 */ 806 saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agToBeAbortedIORequest, smaSATAAbortCB); 807 808 809 SM_DBG1(("satAbort: end!!!\n")); 810 811 return; 812 } 813 814 osGLOBAL bit32 815 smsatStartCheckPowerMode( 816 smRoot_t *smRoot, 817 smIORequest_t *currentTaskTag, 818 smDeviceHandle_t *smDeviceHandle, 819 smScsiInitiatorRequest_t *smScsiRequest, 820 smSatIOContext_t *satIOContext 821 ) 822 { 823 smSatInternalIo_t *satIntIo = agNULL; 824 smDeviceData_t *oneDeviceData = agNULL; 825 smSatIOContext_t *satNewIOContext; 826 bit32 status; 827 828 SM_DBG1(("smsatStartCheckPowerMode: start\n")); 829 830 oneDeviceData = satIOContext->pSatDevData; 831 832 SM_DBG6(("smsatStartCheckPowerMode: before alloc\n")); 833 834 /* allocate any fis for seting SRT bit in device control */ 835 satIntIo = smsatAllocIntIoResource( smRoot, 836 currentTaskTag, 837 oneDeviceData, 838 0, 839 satIntIo); 840 841 SM_DBG6(("smsatStartCheckPowerMode: before after\n")); 842 843 if (satIntIo == agNULL) 844 { 845 SM_DBG1(("smsatStartCheckPowerMode: can't alloacate!!!\n")); 846 /*smEnqueueIO(smRoot, satIOContext);*/ 847 return SM_RC_FAILURE; 848 } 849 850 satNewIOContext = smsatPrepareNewIO(satIntIo, 851 currentTaskTag, 852 oneDeviceData, 853 agNULL, 854 satIOContext); 855 856 SM_DBG6(("smsatStartCheckPowerMode: TD satIOContext %p \n", satIOContext)); 857 SM_DBG6(("smsatStartCheckPowerMode: SM satNewIOContext %p \n", satNewIOContext)); 858 SM_DBG6(("smsatStartCheckPowerMode: TD smScsiXchg %p \n", satIOContext->smScsiXchg)); 859 SM_DBG6(("smsatStartCheckPowerMode: SM smScsiXchg %p \n", satNewIOContext->smScsiXchg)); 860 861 862 863 SM_DBG2(("smsatStartCheckPowerMode: satNewIOContext %p \n", satNewIOContext)); 864 865 status = smsatCheckPowerMode(smRoot, 866 &satIntIo->satIntSmIORequest, /* New smIORequest */ 867 smDeviceHandle, 868 satNewIOContext->smScsiXchg, /* New tiScsiInitiatorRequest_t *smScsiRequest, */ 869 satNewIOContext); 870 871 if (status != SM_RC_SUCCESS) 872 { 873 SM_DBG1(("smsatStartCheckPowerMode: failed in sending!!!\n")); 874 875 smsatFreeIntIoResource( smRoot, 876 oneDeviceData, 877 satIntIo); 878 879 /*smEnqueueIO(smRoot, satIOContext);*/ 880 881 return SM_RC_FAILURE; 882 } 883 884 885 SM_DBG6(("smsatStartCheckPowerMode: end\n")); 886 887 return status; 888 } 889 890 osGLOBAL bit32 891 smsatStartResetDevice( 892 smRoot_t *smRoot, 893 smIORequest_t *currentTaskTag, 894 smDeviceHandle_t *smDeviceHandle, 895 smScsiInitiatorRequest_t *smScsiRequest, 896 smSatIOContext_t *satIOContext 897 ) 898 { 899 smSatInternalIo_t *satIntIo = agNULL; 900 smDeviceData_t *oneDeviceData = agNULL; 901 smSatIOContext_t *satNewIOContext; 902 bit32 status; 903 904 SM_DBG1(("smsatStartResetDevice: start\n")); 905 906 oneDeviceData = satIOContext->pSatDevData; 907 908 SM_DBG6(("smsatStartResetDevice: before alloc\n")); 909 910 /* allocate any fis for seting SRT bit in device control */ 911 satIntIo = smsatAllocIntIoResource( smRoot, 912 currentTaskTag, 913 oneDeviceData, 914 0, 915 satIntIo); 916 917 SM_DBG6(("smsatStartResetDevice: before after\n")); 918 919 if (satIntIo == agNULL) 920 { 921 SM_DBG1(("smsatStartResetDevice: can't alloacate!!!\n")); 922 /*smEnqueueIO(smRoot, satIOContext);*/ 923 return SM_RC_FAILURE; 924 } 925 926 satNewIOContext = smsatPrepareNewIO(satIntIo, 927 currentTaskTag, 928 oneDeviceData, 929 agNULL, 930 satIOContext); 931 932 SM_DBG6(("smsatStartResetDevice: TD satIOContext %p \n", satIOContext)); 933 SM_DBG6(("smsatStartResetDevice: SM satNewIOContext %p \n", satNewIOContext)); 934 SM_DBG6(("smsatStartResetDevice: TD smScsiXchg %p \n", satIOContext->smScsiXchg)); 935 SM_DBG6(("smsatStartResetDevice: SM smScsiXchg %p \n", satNewIOContext->smScsiXchg)); 936 937 938 939 SM_DBG6(("smsatStartResetDevice: satNewIOContext %p \n", satNewIOContext)); 940 941 if (oneDeviceData->satDeviceType == SATA_ATAPI_DEVICE) 942 { 943 /*if ATAPI device, send DEVICE RESET command to ATAPI device*/ 944 status = smsatDeviceReset(smRoot, 945 &satIntIo->satIntSmIORequest, /* New smIORequest */ 946 smDeviceHandle, 947 satNewIOContext->smScsiXchg, /* New smScsiInitiatorRequest_t *smScsiRequest, NULL */ 948 satNewIOContext); 949 } 950 else 951 { 952 status = smsatResetDevice(smRoot, 953 &satIntIo->satIntSmIORequest, /* New smIORequest */ 954 smDeviceHandle, 955 satNewIOContext->smScsiXchg, /* New smScsiInitiatorRequest_t *smScsiRequest, NULL */ 956 satNewIOContext); 957 } 958 959 if (status != SM_RC_SUCCESS) 960 { 961 SM_DBG1(("smsatStartResetDevice: failed in sending!!!\n")); 962 963 smsatFreeIntIoResource( smRoot, 964 oneDeviceData, 965 satIntIo); 966 967 /*smEnqueueIO(smRoot, satIOContext);*/ 968 969 return SM_RC_FAILURE; 970 } 971 972 973 SM_DBG6(("smsatStartResetDevice: end\n")); 974 975 return status; 976 } 977 978 osGLOBAL bit32 979 smsatTmAbortTask( 980 smRoot_t *smRoot, 981 smIORequest_t *currentTaskTag, /* task management */ 982 smDeviceHandle_t *smDeviceHandle, 983 smScsiInitiatorRequest_t *smScsiRequest, /* NULL */ 984 smSatIOContext_t *satIOContext, /* task management */ 985 smIORequest_t *taskTag) /* io to be aborted */ 986 { 987 smDeviceData_t *oneDeviceData = agNULL; 988 smSatIOContext_t *satTempIOContext = agNULL; 989 smList_t *elementHdr; 990 bit32 found = agFALSE; 991 smIORequestBody_t *smIORequestBody = agNULL; 992 smIORequest_t *smIOReq = agNULL; 993 bit32 status; 994 995 SM_DBG1(("smsatTmAbortTask: start\n")); 996 997 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData; 998 999 /* 1000 * Check that the only pending I/O matches taskTag. If not return tiError. 1001 */ 1002 tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK); 1003 1004 elementHdr = oneDeviceData->satIoLinkList.flink; 1005 1006 while (elementHdr != &oneDeviceData->satIoLinkList) 1007 { 1008 satTempIOContext = SMLIST_OBJECT_BASE( smSatIOContext_t, 1009 satIoContextLink, 1010 elementHdr ); 1011 1012 if ( satTempIOContext != agNULL) 1013 { 1014 smIORequestBody = (smIORequestBody_t *) satTempIOContext->smRequestBody; 1015 smIOReq = smIORequestBody->smIORequest; 1016 } 1017 1018 elementHdr = elementHdr->flink; /* for the next while loop */ 1019 1020 /* 1021 * Check if the tag matches 1022 */ 1023 if ( smIOReq == taskTag) 1024 { 1025 found = agTRUE; 1026 satIOContext->satToBeAbortedIOContext = satTempIOContext; 1027 SM_DBG1(("smsatTmAbortTask: found matching tag.\n")); 1028 1029 break; 1030 1031 } /* if matching tag */ 1032 1033 } /* while loop */ 1034 1035 tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 1036 1037 if (found == agFALSE ) 1038 { 1039 SM_DBG1(("smsatTmAbortTask: *** REJECT *** no match!!!\n")); 1040 1041 /*smEnqueueIO(smRoot, satIOContext);*/ 1042 /* clean up TD layer's smIORequestBody */ 1043 if (smIORequestBody) 1044 { 1045 if (smIORequestBody->IOType.InitiatorTMIO.osMemHandle != agNULL) 1046 { 1047 tdsmFreeMemory( 1048 smRoot, 1049 smIORequestBody->IOType.InitiatorTMIO.osMemHandle, 1050 sizeof(smIORequestBody_t) 1051 ); 1052 } 1053 } 1054 else 1055 { 1056 SM_DBG1(("smsatTmAbortTask: smIORequestBody is NULL!!!\n")); 1057 } 1058 1059 return SM_RC_FAILURE; 1060 } 1061 1062 if (satTempIOContext == agNULL) 1063 { 1064 SM_DBG1(("smsatTmAbortTask: satTempIOContext is NULL!!!\n")); 1065 return SM_RC_FAILURE; 1066 } 1067 1068 /* 1069 * Save smIORequest, will be returned at device reset completion to return 1070 * the TM completion. 1071 */ 1072 oneDeviceData->satTmTaskTag = currentTaskTag; 1073 1074 /* 1075 * Set flag to indicate device in recovery mode. 1076 */ 1077 oneDeviceData->satDriveState = SAT_DEV_STATE_IN_RECOVERY; 1078 1079 1080 /* 1081 * Issue SATA device reset or check power mode.. Set flag to to automatically abort 1082 * at the completion of SATA device reset. 1083 * SAT r09 p25 1084 */ 1085 oneDeviceData->satAbortAfterReset = agTRUE; 1086 1087 if ( (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) || 1088 (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) 1089 ) 1090 { 1091 SM_DBG1(("smsatTmAbortTask: calling satStartCheckPowerMode!!!\n")); 1092 /* send check power mode */ 1093 status = smsatStartCheckPowerMode( 1094 smRoot, 1095 currentTaskTag, /* currentTaskTag */ 1096 smDeviceHandle, 1097 smScsiRequest, /* NULL */ 1098 satIOContext 1099 ); 1100 } 1101 else 1102 { 1103 SM_DBG1(("smsatTmAbortTask: calling satStartResetDevice!!!\n")); 1104 /* send AGSA_SATA_PROTOCOL_SRST_ASSERT */ 1105 status = smsatStartResetDevice( 1106 smRoot, 1107 currentTaskTag, /* currentTaskTag */ 1108 smDeviceHandle, 1109 smScsiRequest, /* NULL */ 1110 satIOContext 1111 ); 1112 } 1113 return status; 1114 } 1115 1116 /* satTM() */ 1117 osGLOBAL bit32 1118 smsatTaskManagement( 1119 smRoot_t *smRoot, 1120 smDeviceHandle_t *smDeviceHandle, 1121 bit32 task, 1122 smLUN_t *lun, 1123 smIORequest_t *taskTag, /* io to be aborted */ 1124 smIORequest_t *currentTaskTag, /* task management */ 1125 smIORequestBody_t *smIORequestBody 1126 ) 1127 { 1128 smSatIOContext_t *satIOContext = agNULL; 1129 smDeviceData_t *oneDeviceData = agNULL; 1130 bit32 status; 1131 1132 SM_DBG1(("smsatTaskManagement: start\n")); 1133 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData; 1134 1135 satIOContext = &(smIORequestBody->transport.SATA.satIOContext); 1136 1137 satIOContext->pSatDevData = oneDeviceData; 1138 satIOContext->pFis = 1139 &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 1140 1141 1142 satIOContext->smRequestBody = smIORequestBody; 1143 satIOContext->psmDeviceHandle = smDeviceHandle; 1144 satIOContext->satIntIoContext = agNULL; 1145 satIOContext->satOrgIOContext = agNULL; 1146 1147 /* followings are used only for internal IO */ 1148 satIOContext->currentLBA = 0; 1149 satIOContext->OrgTL = 0; 1150 1151 /* saving task in satIOContext */ 1152 satIOContext->TMF = task; 1153 1154 satIOContext->satToBeAbortedIOContext = agNULL; 1155 1156 if (task == AG_ABORT_TASK) 1157 { 1158 status = smsatTmAbortTask( smRoot, 1159 currentTaskTag, 1160 smDeviceHandle, 1161 agNULL, 1162 satIOContext, 1163 taskTag); 1164 1165 return status; 1166 } 1167 else 1168 { 1169 SM_DBG1(("smsatTaskManagement: UNSUPPORTED TM task=0x%x!!!\n", task )); 1170 1171 /*smEnqueueIO(smRoot, satIOContext);*/ 1172 1173 return SM_RC_FAILURE; 1174 } 1175 1176 return SM_RC_SUCCESS; 1177 } 1178 1179 1180 osGLOBAL bit32 1181 smPhyControlSend( 1182 smRoot_t *smRoot, 1183 smDeviceData_t *oneDeviceData, /* sata disk itself */ 1184 bit8 phyOp, 1185 smIORequest_t *CurrentTaskTag, 1186 bit32 queueNumber 1187 ) 1188 { 1189 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData; 1190 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 1191 agsaRoot_t *agRoot = smAllShared->agRoot; 1192 agsaDevHandle_t *agExpDevHandle; 1193 smpReqPhyControl_t smpPhyControlReq; 1194 void *osMemHandle; 1195 bit32 PhysUpper32; 1196 bit32 PhysLower32; 1197 bit32 memAllocStatus; 1198 bit32 expectedRspLen = 0; 1199 smSMPRequestBody_t *smSMPRequestBody; 1200 agsaSASRequestBody_t *agSASRequestBody; 1201 agsaSMPFrame_t *agSMPFrame; 1202 agsaIORequest_t *agIORequest; 1203 // agsaDevHandle_t *agDevHandle; 1204 smSMPFrameHeader_t smSMPFrameHeader; 1205 bit32 status; 1206 bit8 *pSmpBody; /* smp payload itself w/o first 4 bytes(header) */ 1207 bit32 smpBodySize; /* smp payload size w/o first 4 bytes(header) */ 1208 bit32 agRequestType; 1209 1210 SM_DBG2(("smPhyControlSend: start\n")); 1211 1212 agExpDevHandle = oneDeviceData->agExpDevHandle; 1213 1214 if (agExpDevHandle == agNULL) 1215 { 1216 SM_DBG1(("smPhyControlSend: agExpDevHandle is NULL!!!\n")); 1217 return SM_RC_FAILURE; 1218 } 1219 1220 SM_DBG5(("smPhyControlSend: phyID %d\n", oneDeviceData->phyID)); 1221 1222 sm_memset(&smpPhyControlReq, 0, sizeof(smpReqPhyControl_t)); 1223 1224 /* fill in SMP payload */ 1225 smpPhyControlReq.phyIdentifier = (bit8)oneDeviceData->phyID; 1226 smpPhyControlReq.phyOperation = phyOp; 1227 1228 /* allocate smp and send it */ 1229 memAllocStatus = tdsmAllocMemory( 1230 smRoot, 1231 &osMemHandle, 1232 (void **)&smSMPRequestBody, 1233 &PhysUpper32, 1234 &PhysLower32, 1235 8, 1236 sizeof(smSMPRequestBody_t), 1237 agTRUE 1238 ); 1239 1240 if (memAllocStatus != SM_RC_SUCCESS) 1241 { 1242 SM_DBG1(("smPhyControlSend: tdsmAllocMemory failed...!!!\n")); 1243 return SM_RC_FAILURE; 1244 } 1245 1246 if (smSMPRequestBody == agNULL) 1247 { 1248 SM_DBG1(("smPhyControlSend: tdsmAllocMemory returned NULL smSMPRequestBody!!!\n")); 1249 return SM_RC_FAILURE; 1250 } 1251 1252 /* saves mem handle for freeing later */ 1253 smSMPRequestBody->osMemHandle = osMemHandle; 1254 1255 /* saves oneDeviceData */ 1256 smSMPRequestBody->smDeviceData = oneDeviceData; /* sata disk */ 1257 1258 /* saves oneDeviceData */ 1259 smSMPRequestBody->smDevHandle = oneDeviceData->smDevHandle; 1260 1261 // agDevHandle = oneDeviceData->agDevHandle; 1262 1263 /* save the callback funtion */ 1264 smSMPRequestBody->SMPCompletionFunc = smSMPCompleted; /* in satcb.c */ 1265 1266 /* for simulate warm target reset */ 1267 smSMPRequestBody->CurrentTaskTag = CurrentTaskTag; 1268 1269 if (CurrentTaskTag != agNULL) 1270 { 1271 CurrentTaskTag->smData = smSMPRequestBody; 1272 } 1273 1274 /* initializes the number of SMP retries */ 1275 smSMPRequestBody->retries = 0; 1276 1277 #ifdef TD_INTERNAL_DEBUG /* debugging */ 1278 SM_DBG4(("smPhyControlSend: SMPRequestbody %p\n", smSMPRequestBody)); 1279 SM_DBG4(("smPhyControlSend: callback fn %p\n", smSMPRequestBody->SMPCompletionFunc)); 1280 #endif 1281 1282 agIORequest = &(smSMPRequestBody->agIORequest); 1283 agIORequest->osData = (void *) smSMPRequestBody; 1284 agIORequest->sdkData = agNULL; /* SALL takes care of this */ 1285 1286 1287 agSASRequestBody = &(smSMPRequestBody->agSASRequestBody); 1288 agSMPFrame = &(agSASRequestBody->smpFrame); 1289 1290 SM_DBG3(("smPhyControlSend: agIORequest %p\n", agIORequest)); 1291 SM_DBG3(("smPhyControlSend: SMPRequestbody %p\n", smSMPRequestBody)); 1292 1293 expectedRspLen = 4; 1294 1295 pSmpBody = (bit8 *)&smpPhyControlReq; 1296 smpBodySize = sizeof(smpReqPhyControl_t); 1297 agRequestType = AGSA_SMP_INIT_REQ; 1298 1299 if (SMIsSPC(agRoot)) 1300 { 1301 if ( (smpBodySize + 4) <= SMP_DIRECT_PAYLOAD_LIMIT) /* 48 */ 1302 { 1303 SM_DBG3(("smPhyControlSend: DIRECT smp payload\n")); 1304 sm_memset(&smSMPFrameHeader, 0, sizeof(smSMPFrameHeader_t)); 1305 sm_memset(smSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT); 1306 1307 /* SMP header */ 1308 smSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */ 1309 smSMPFrameHeader.smpFunction = (bit8)SMP_PHY_CONTROL; 1310 smSMPFrameHeader.smpFunctionResult = 0; 1311 smSMPFrameHeader.smpReserved = 0; 1312 1313 sm_memcpy(smSMPRequestBody->smpPayload, &smSMPFrameHeader, 4); 1314 sm_memcpy((smSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize); 1315 1316 /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */ 1317 agSMPFrame->outFrameBuf = smSMPRequestBody->smpPayload; 1318 agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */ 1319 /* to specify DIRECT SMP response */ 1320 agSMPFrame->inFrameLen = 0; 1321 1322 /* temporary solution for T2D Combo*/ 1323 #if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER) 1324 /* force smp repsonse to be direct */ 1325 agSMPFrame->expectedRespLen = 0; 1326 #else 1327 agSMPFrame->expectedRespLen = expectedRspLen; 1328 #endif 1329 // smhexdump("smPhyControlSend", (bit8*)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen); 1330 // smhexdump("smPhyControlSend new", (bit8*)smSMPRequestBody->smpPayload, agSMPFrame->outFrameLen); 1331 // smhexdump("smPhyControlSend - smSMPRequestBody", (bit8*)smSMPRequestBody, sizeof(smSMPRequestBody_t)); 1332 } 1333 else 1334 { 1335 SM_DBG1(("smPhyControlSend: INDIRECT smp payload, not supported!!!\n")); 1336 tdsmFreeMemory( 1337 smRoot, 1338 osMemHandle, 1339 sizeof(smSMPRequestBody_t) 1340 ); 1341 1342 return SM_RC_FAILURE; 1343 } 1344 } 1345 else /* SPCv controller */ 1346 { 1347 /* only direct mode for both request and response */ 1348 SM_DBG3(("smPhyControlSend: DIRECT smp payload\n")); 1349 agSMPFrame->flag = 0; 1350 sm_memset(&smSMPFrameHeader, 0, sizeof(smSMPFrameHeader_t)); 1351 sm_memset(smSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT); 1352 1353 /* SMP header */ 1354 smSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */ 1355 smSMPFrameHeader.smpFunction = (bit8)SMP_PHY_CONTROL; 1356 smSMPFrameHeader.smpFunctionResult = 0; 1357 smSMPFrameHeader.smpReserved = 0; 1358 1359 sm_memcpy(smSMPRequestBody->smpPayload, &smSMPFrameHeader, 4); 1360 sm_memcpy((smSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize); 1361 1362 /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */ 1363 agSMPFrame->outFrameBuf = smSMPRequestBody->smpPayload; 1364 agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */ 1365 /* to specify DIRECT SMP response */ 1366 agSMPFrame->inFrameLen = 0; 1367 1368 /* temporary solution for T2D Combo*/ 1369 #if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER) 1370 /* force smp repsonse to be direct */ 1371 agSMPFrame->expectedRespLen = 0; 1372 #else 1373 agSMPFrame->expectedRespLen = expectedRspLen; 1374 #endif 1375 // smhexdump("smPhyControlSend", (bit8*)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen); 1376 // smhexdump("smPhyControlSend new", (bit8*)smSMPRequestBody->smpPayload, agSMPFrame->outFrameLen); 1377 // smhexdump("smPhyControlSend - smSMPRequestBody", (bit8*)smSMPRequestBody, sizeof(smSMPRequestBody_t)); 1378 } 1379 1380 status = saSMPStart( 1381 agRoot, 1382 agIORequest, 1383 queueNumber, 1384 agExpDevHandle, 1385 agRequestType, 1386 agSASRequestBody, 1387 &smSMPCompletedCB 1388 ); 1389 1390 if (status == AGSA_RC_SUCCESS) 1391 { 1392 return SM_RC_SUCCESS; 1393 } 1394 else if (status == AGSA_RC_BUSY) 1395 { 1396 SM_DBG1(("smPhyControlSend: saSMPStart is busy!!!\n")); 1397 tdsmFreeMemory( 1398 smRoot, 1399 osMemHandle, 1400 sizeof(smSMPRequestBody_t) 1401 ); 1402 1403 return SM_RC_BUSY; 1404 } 1405 else /* AGSA_RC_FAILURE */ 1406 { 1407 SM_DBG1(("smPhyControlSend: saSMPStart is failed. status %d!!!\n", status)); 1408 tdsmFreeMemory( 1409 smRoot, 1410 osMemHandle, 1411 sizeof(smSMPRequestBody_t) 1412 ); 1413 1414 return SM_RC_FAILURE; 1415 } 1416 } 1417 1418 /* free IO which are internally completed within SM 1419 counterpart is 1420 osGLOBAL smIORequestBody_t * 1421 smDequeueIO(smRoot_t *smRoot) 1422 */ 1423 osGLOBAL void 1424 smEnqueueIO( 1425 smRoot_t *smRoot, 1426 smSatIOContext_t *satIOContext 1427 ) 1428 { 1429 smIntRoot_t *smIntRoot = agNULL; 1430 smIntContext_t *smAllShared = agNULL; 1431 smIORequestBody_t *smIORequestBody; 1432 1433 SM_DBG3(("smEnqueueIO: start\n")); 1434 smIORequestBody = (smIORequestBody_t *)satIOContext->smRequestBody; 1435 smIntRoot = (smIntRoot_t *)smRoot->smData; 1436 smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 1437 1438 /* enque back to smAllShared->freeIOList */ 1439 if (satIOContext->satIntIoContext == agNULL) 1440 { 1441 SM_DBG2(("smEnqueueIO: external command!!!, io ID %d!!!\n", smIORequestBody->id)); 1442 /* debugging only */ 1443 if (smIORequestBody->satIoBodyLink.flink == agNULL) 1444 { 1445 SM_DBG1(("smEnqueueIO: external command!!!, io ID %d, flink is NULL!!!\n", smIORequestBody->id)); 1446 } 1447 if (smIORequestBody->satIoBodyLink.blink == agNULL) 1448 { 1449 SM_DBG1(("smEnqueueIO: external command!!!, io ID %d, blink is NULL!!!\n", smIORequestBody->id)); 1450 } 1451 } 1452 else 1453 { 1454 SM_DBG2(("smEnqueueIO: internal command!!!, io ID %d!!!\n", smIORequestBody->id)); 1455 /* debugging only */ 1456 if (smIORequestBody->satIoBodyLink.flink == agNULL) 1457 { 1458 SM_DBG1(("smEnqueueIO: internal command!!!, io ID %d, flink is NULL!!!\n", smIORequestBody->id)); 1459 } 1460 if (smIORequestBody->satIoBodyLink.blink == agNULL) 1461 { 1462 SM_DBG1(("smEnqueueIO: internal command!!!, io ID %d, blink is NULL!!!\n", smIORequestBody->id)); 1463 } 1464 } 1465 1466 if (smIORequestBody->smIORequest == agNULL) 1467 { 1468 SM_DBG1(("smEnqueueIO: smIORequest is NULL, io ID %d!!!\n", smIORequestBody->id)); 1469 } 1470 1471 if (smIORequestBody->InUse == agTRUE) 1472 { 1473 smIORequestBody->InUse = agFALSE; 1474 tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK); 1475 SMLIST_DEQUEUE_THIS(&(smIORequestBody->satIoBodyLink)); 1476 SMLIST_ENQUEUE_AT_TAIL(&(smIORequestBody->satIoBodyLink), &(smAllShared->freeIOList)); 1477 tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 1478 } 1479 else 1480 { 1481 SM_DBG2(("smEnqueueIO: check!!!, io ID %d!!!\n", smIORequestBody->id)); 1482 } 1483 1484 1485 return; 1486 } 1487 1488 FORCEINLINE void 1489 smsatFreeIntIoResource( 1490 smRoot_t *smRoot, 1491 smDeviceData_t *satDevData, 1492 smSatInternalIo_t *satIntIo 1493 ) 1494 { 1495 SM_DBG3(("smsatFreeIntIoResource: start\n")); 1496 1497 if (satIntIo == agNULL) 1498 { 1499 SM_DBG2(("smsatFreeIntIoResource: allowed call\n")); 1500 return; 1501 } 1502 1503 /* sets the original smIOrequest to agNULL for internally generated ATA cmnd */ 1504 satIntIo->satOrgSmIORequest = agNULL; 1505 1506 /* 1507 * Free DMA memory if previosly alocated 1508 */ 1509 if (satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength != 0) 1510 { 1511 SM_DBG3(("smsatFreeIntIoResource: DMA len %d\n", satIntIo->satIntDmaMem.totalLength)); 1512 SM_DBG3(("smsatFreeIntIoResource: pointer %p\n", satIntIo->satIntDmaMem.osHandle)); 1513 1514 tdsmFreeMemory( smRoot, 1515 satIntIo->satIntDmaMem.osHandle, 1516 satIntIo->satIntDmaMem.totalLength); 1517 satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = 0; 1518 } 1519 1520 if (satIntIo->satIntReqBodyMem.totalLength != 0) 1521 { 1522 SM_DBG3(("smsatFreeIntIoResource: req body len %d\n", satIntIo->satIntReqBodyMem.totalLength)); 1523 /* 1524 * Free mem allocated for Req body 1525 */ 1526 tdsmFreeMemory( smRoot, 1527 satIntIo->satIntReqBodyMem.osHandle, 1528 satIntIo->satIntReqBodyMem.totalLength); 1529 1530 satIntIo->satIntReqBodyMem.totalLength = 0; 1531 } 1532 1533 SM_DBG3(("smsatFreeIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id)); 1534 /* 1535 * Return satIntIo to the free list 1536 */ 1537 tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK); 1538 SMLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink)); 1539 SMLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satFreeIntIoLinkList)); 1540 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK); 1541 1542 return; 1543 } 1544 //start here 1545 osGLOBAL smSatInternalIo_t * 1546 smsatAllocIntIoResource( 1547 smRoot_t *smRoot, 1548 smIORequest_t *smIORequest, 1549 smDeviceData_t *satDevData, 1550 bit32 dmaAllocLength, 1551 smSatInternalIo_t *satIntIo) 1552 { 1553 smList_t *smList = agNULL; 1554 bit32 memAllocStatus; 1555 1556 SM_DBG3(("smsatAllocIntIoResource: start\n")); 1557 SM_DBG3(("smsatAllocIntIoResource: satIntIo %p\n", satIntIo)); 1558 if (satDevData == agNULL) 1559 { 1560 SM_DBG1(("smsatAllocIntIoResource: ***** ASSERT satDevData is null!!!\n")); 1561 return agNULL; 1562 } 1563 1564 tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK); 1565 if (!SMLIST_EMPTY(&(satDevData->satFreeIntIoLinkList))) 1566 { 1567 SMLIST_DEQUEUE_FROM_HEAD(&smList, &(satDevData->satFreeIntIoLinkList)); 1568 } 1569 else 1570 { 1571 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK); 1572 SM_DBG1(("smsatAllocIntIoResource() no more internal free link!!!\n")); 1573 return agNULL; 1574 } 1575 1576 if (smList == agNULL) 1577 { 1578 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK); 1579 SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc satIntIo!!!\n")); 1580 return agNULL; 1581 } 1582 1583 satIntIo = SMLIST_OBJECT_BASE( smSatInternalIo_t, satIntIoLink, smList); 1584 SM_DBG3(("smsatAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id)); 1585 1586 /* Put in active list */ 1587 SMLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink)); 1588 SMLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satActiveIntIoLinkList)); 1589 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK); 1590 1591 #ifdef REMOVED 1592 /* Put in active list */ 1593 tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK); 1594 SMLIST_DEQUEUE_THIS (smList); 1595 SMLIST_ENQUEUE_AT_TAIL (smList, &(satDevData->satActiveIntIoLinkList)); 1596 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK); 1597 1598 satIntIo = SMLIST_OBJECT_BASE( smSatInternalIo_t, satIntIoLink, smList); 1599 SM_DBG3(("smsatAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id)); 1600 #endif 1601 1602 /* 1603 typedef struct 1604 { 1605 tdList_t satIntIoLink; 1606 smIORequest_t satIntSmIORequest; 1607 void *satIntRequestBody; 1608 smScsiInitiatorRequest_t satIntSmScsiXchg; 1609 smMem_t satIntDmaMem; 1610 smMem_t satIntReqBodyMem; 1611 bit32 satIntFlag; 1612 } smSatInternalIo_t; 1613 */ 1614 1615 /* 1616 * Allocate mem for Request Body 1617 */ 1618 satIntIo->satIntReqBodyMem.totalLength = sizeof(smIORequestBody_t); 1619 1620 memAllocStatus = tdsmAllocMemory( smRoot, 1621 &satIntIo->satIntReqBodyMem.osHandle, 1622 (void **)&satIntIo->satIntRequestBody, 1623 &satIntIo->satIntReqBodyMem.physAddrUpper, 1624 &satIntIo->satIntReqBodyMem.physAddrLower, 1625 8, 1626 satIntIo->satIntReqBodyMem.totalLength, 1627 agTRUE ); 1628 1629 if (memAllocStatus != SM_RC_SUCCESS) 1630 { 1631 SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc mem for Req Body!!!\n")); 1632 /* 1633 * Return satIntIo to the free list 1634 */ 1635 tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK); 1636 SMLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink); 1637 SMLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList); 1638 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK); 1639 1640 return agNULL; 1641 } 1642 1643 /* 1644 * Allocate DMA memory if required 1645 */ 1646 if (dmaAllocLength != 0) 1647 { 1648 satIntIo->satIntDmaMem.totalLength = dmaAllocLength; 1649 1650 memAllocStatus = tdsmAllocMemory( smRoot, 1651 &satIntIo->satIntDmaMem.osHandle, 1652 (void **)&satIntIo->satIntDmaMem.virtPtr, 1653 &satIntIo->satIntDmaMem.physAddrUpper, 1654 &satIntIo->satIntDmaMem.physAddrLower, 1655 8, 1656 satIntIo->satIntDmaMem.totalLength, 1657 agFALSE); 1658 SM_DBG3(("smsatAllocIntIoResource: len %d \n", satIntIo->satIntDmaMem.totalLength)); 1659 SM_DBG3(("smsatAllocIntIoResource: pointer %p \n", satIntIo->satIntDmaMem.osHandle)); 1660 1661 if (memAllocStatus != SM_RC_SUCCESS) 1662 { 1663 SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc mem for DMA mem!!!\n")); 1664 /* 1665 * Return satIntIo to the free list 1666 */ 1667 tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK); 1668 SMLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink); 1669 SMLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList); 1670 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK); 1671 1672 /* 1673 * Free mem allocated for Req body 1674 */ 1675 tdsmFreeMemory( smRoot, 1676 satIntIo->satIntReqBodyMem.osHandle, 1677 satIntIo->satIntReqBodyMem.totalLength); 1678 1679 return agNULL; 1680 } 1681 } 1682 1683 /* 1684 typedef struct 1685 { 1686 smList_t satIntIoLink; 1687 smIORequest_t satIntSmIORequest; 1688 void *satIntRequestBody; 1689 smScsiInitiatorRequest_t satIntSmScsiXchg; 1690 smMem_t satIntDmaMem; 1691 smMem_t satIntReqBodyMem; 1692 bit32 satIntFlag; 1693 } smSatInternalIo_t; 1694 */ 1695 1696 /* 1697 * Initialize satIntSmIORequest field 1698 */ 1699 satIntIo->satIntSmIORequest.tdData = agNULL; /* Not used for internal SAT I/O */ 1700 satIntIo->satIntSmIORequest.smData = satIntIo->satIntRequestBody; 1701 1702 /* 1703 * saves the original smIOrequest 1704 */ 1705 satIntIo->satOrgSmIORequest = smIORequest; 1706 /* 1707 typedef struct tiIniScsiCmnd 1708 { 1709 tiLUN_t lun; 1710 bit32 expDataLength; 1711 bit32 taskAttribute; 1712 bit32 crn; 1713 bit8 cdb[16]; 1714 } tiIniScsiCmnd_t; 1715 1716 typedef struct tiScsiInitiatorExchange 1717 { 1718 void *sglVirtualAddr; 1719 tiIniScsiCmnd_t scsiCmnd; 1720 tiSgl_t agSgl1; 1721 tiSgl_t agSgl2; 1722 tiDataDirection_t dataDirection; 1723 } tiScsiInitiatorRequest_t; 1724 1725 */ 1726 1727 /* 1728 * Initialize satIntSmScsiXchg. Since the internal SAT request is NOT 1729 * originated from SCSI request, only the following fields are initialized: 1730 * - sglVirtualAddr if DMA transfer is involved 1731 * - agSgl1 if DMA transfer is involved 1732 * - expDataLength in scsiCmnd since this field is read by smsataLLIOStart() 1733 */ 1734 if (dmaAllocLength != 0) 1735 { 1736 satIntIo->satIntSmScsiXchg.sglVirtualAddr = satIntIo->satIntDmaMem.virtPtr; 1737 1738 OSSA_WRITE_LE_32(agNULL, &satIntIo->satIntSmScsiXchg.smSgl1.len, 0, 1739 satIntIo->satIntDmaMem.totalLength); 1740 satIntIo->satIntSmScsiXchg.smSgl1.lower = satIntIo->satIntDmaMem.physAddrLower; 1741 satIntIo->satIntSmScsiXchg.smSgl1.upper = satIntIo->satIntDmaMem.physAddrUpper; 1742 satIntIo->satIntSmScsiXchg.smSgl1.type = tiSgl; 1743 1744 satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = satIntIo->satIntDmaMem.totalLength; 1745 } 1746 else 1747 { 1748 satIntIo->satIntSmScsiXchg.sglVirtualAddr = agNULL; 1749 1750 satIntIo->satIntSmScsiXchg.smSgl1.len = 0; 1751 satIntIo->satIntSmScsiXchg.smSgl1.lower = 0; 1752 satIntIo->satIntSmScsiXchg.smSgl1.upper = 0; 1753 satIntIo->satIntSmScsiXchg.smSgl1.type = tiSgl; 1754 1755 satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = 0; 1756 } 1757 1758 SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.len %d\n", satIntIo->satIntSmScsiXchg.smSgl1.len)); 1759 1760 SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.upper %d\n", satIntIo->satIntSmScsiXchg.smSgl1.upper)); 1761 1762 SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.lower %d\n", satIntIo->satIntSmScsiXchg.smSgl1.lower)); 1763 1764 SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.type %d\n", satIntIo->satIntSmScsiXchg.smSgl1.type)); 1765 SM_DBG5(("smsatAllocIntIoResource: return satIntIo %p\n", satIntIo)); 1766 return satIntIo; 1767 } 1768 1769 osGLOBAL smDeviceData_t * 1770 smAddToSharedcontext( 1771 smRoot_t *smRoot, 1772 agsaDevHandle_t *agDevHandle, 1773 smDeviceHandle_t *smDeviceHandle, 1774 agsaDevHandle_t *agExpDevHandle, 1775 bit32 phyID 1776 ) 1777 { 1778 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData; 1779 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 1780 smDeviceData_t *oneDeviceData = agNULL; 1781 smList_t *DeviceListList; 1782 bit32 new_device = agTRUE; 1783 1784 SM_DBG2(("smAddToSharedcontext: start\n")); 1785 1786 /* find a device's existence */ 1787 DeviceListList = smAllShared->MainDeviceList.flink; 1788 while (DeviceListList != &(smAllShared->MainDeviceList)) 1789 { 1790 oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, MainLink, DeviceListList); 1791 if (oneDeviceData == agNULL) 1792 { 1793 SM_DBG1(("smAddToSharedcontext: oneDeviceData is NULL!!!\n")); 1794 return agNULL; 1795 } 1796 if (oneDeviceData->agDevHandle == agDevHandle) 1797 { 1798 SM_DBG2(("smAddToSharedcontext: did %d\n", oneDeviceData->id)); 1799 new_device = agFALSE; 1800 break; 1801 } 1802 DeviceListList = DeviceListList->flink; 1803 } 1804 1805 /* new device */ 1806 if (new_device == agTRUE) 1807 { 1808 SM_DBG2(("smAddToSharedcontext: new device\n")); 1809 tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK); 1810 if (SMLIST_EMPTY(&(smAllShared->FreeDeviceList))) 1811 { 1812 tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK); 1813 SM_DBG1(("smAddToSharedcontext: empty DeviceData FreeLink!!!\n")); 1814 smDeviceHandle->smData = agNULL; 1815 return agNULL; 1816 } 1817 1818 SMLIST_DEQUEUE_FROM_HEAD(&DeviceListList, &(smAllShared->FreeDeviceList)); 1819 tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK); 1820 oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, FreeLink, DeviceListList); 1821 oneDeviceData->smRoot = smRoot; 1822 oneDeviceData->agDevHandle = agDevHandle; 1823 oneDeviceData->valid = agTRUE; 1824 smDeviceHandle->smData = oneDeviceData; 1825 oneDeviceData->smDevHandle = smDeviceHandle; 1826 if (agExpDevHandle == agNULL) 1827 { 1828 oneDeviceData->directlyAttached = agTRUE; 1829 } 1830 else 1831 { 1832 oneDeviceData->directlyAttached = agFALSE; 1833 } 1834 oneDeviceData->agExpDevHandle = agExpDevHandle; 1835 oneDeviceData->phyID = phyID; 1836 oneDeviceData->satPendingIO = 0; 1837 oneDeviceData->satPendingNCQIO = 0; 1838 oneDeviceData->satPendingNONNCQIO = 0; 1839 /* add the devicedata to the portcontext */ 1840 tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK); 1841 SMLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->MainLink), &(smAllShared->MainDeviceList)); 1842 tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK); 1843 SM_DBG2(("smAddToSharedcontext: new case did %d\n", oneDeviceData->id)); 1844 } 1845 else 1846 { 1847 SM_DBG2(("smAddToSharedcontext: old device\n")); 1848 oneDeviceData->smRoot = smRoot; 1849 oneDeviceData->agDevHandle = agDevHandle; 1850 oneDeviceData->valid = agTRUE; 1851 smDeviceHandle->smData = oneDeviceData; 1852 oneDeviceData->smDevHandle = smDeviceHandle; 1853 if (agExpDevHandle == agNULL) 1854 { 1855 oneDeviceData->directlyAttached = agTRUE; 1856 } 1857 else 1858 { 1859 oneDeviceData->directlyAttached = agFALSE; 1860 } 1861 oneDeviceData->agExpDevHandle = agExpDevHandle; 1862 oneDeviceData->phyID = phyID; 1863 oneDeviceData->satPendingIO = 0; 1864 oneDeviceData->satPendingNCQIO = 0; 1865 oneDeviceData->satPendingNONNCQIO = 0; 1866 SM_DBG2(("smAddToSharedcontext: old case did %d\n", oneDeviceData->id)); 1867 } 1868 1869 return oneDeviceData; 1870 } 1871 1872 osGLOBAL bit32 1873 smRemoveFromSharedcontext( 1874 smRoot_t *smRoot, 1875 agsaDevHandle_t *agDevHandle, 1876 smDeviceHandle_t *smDeviceHandle 1877 ) 1878 { 1879 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData; 1880 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 1881 smDeviceData_t *oneDeviceData = agNULL; 1882 1883 SM_DBG2(("smRemoveFromSharedcontext: start\n")); 1884 1885 //due to device all and completion 1886 //smDeviceHandle->smData = agNULL; 1887 1888 /* find oneDeviceData from MainLink */ 1889 oneDeviceData = smFindInSharedcontext(smRoot, agDevHandle); 1890 1891 if (oneDeviceData == agNULL) 1892 { 1893 return SM_RC_FAILURE; 1894 } 1895 else 1896 { 1897 if (oneDeviceData->valid == agTRUE) 1898 { 1899 smDeviceDataReInit(smRoot, oneDeviceData); 1900 tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK); 1901 SMLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink)); 1902 SMLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(smAllShared->FreeDeviceList)); 1903 tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK); 1904 return SM_RC_SUCCESS; 1905 } 1906 else 1907 { 1908 SM_DBG1(("smRemoveFromSharedcontext: did %d bad case!!!\n", oneDeviceData->id)); 1909 return SM_RC_FAILURE; 1910 } 1911 } 1912 1913 } 1914 1915 osGLOBAL smDeviceData_t * 1916 smFindInSharedcontext( 1917 smRoot_t *smRoot, 1918 agsaDevHandle_t *agDevHandle 1919 ) 1920 { 1921 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData; 1922 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 1923 smDeviceData_t *oneDeviceData = agNULL; 1924 smList_t *DeviceListList; 1925 1926 SM_DBG2(("smFindInSharedcontext: start\n")); 1927 1928 tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK); 1929 if (SMLIST_EMPTY(&(smAllShared->MainDeviceList))) 1930 { 1931 SM_DBG1(("smFindInSharedcontext: empty MainDeviceList!!!\n")); 1932 tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK); 1933 return agNULL; 1934 } 1935 else 1936 { 1937 tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK); 1938 } 1939 1940 DeviceListList = smAllShared->MainDeviceList.flink; 1941 while (DeviceListList != &(smAllShared->MainDeviceList)) 1942 { 1943 oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, MainLink, DeviceListList); 1944 if (oneDeviceData == agNULL) 1945 { 1946 SM_DBG1(("smFindInSharedcontext: oneDeviceData is NULL!!!\n")); 1947 return agNULL; 1948 } 1949 if ((oneDeviceData->agDevHandle == agDevHandle) && 1950 (oneDeviceData->valid == agTRUE) 1951 ) 1952 { 1953 SM_DBG2(("smFindInSharedcontext: found, did %d\n", oneDeviceData->id)); 1954 return oneDeviceData; 1955 } 1956 DeviceListList = DeviceListList->flink; 1957 } 1958 SM_DBG2(("smFindInSharedcontext: not found\n")); 1959 return agNULL; 1960 } 1961 1962 osGLOBAL smSatIOContext_t * 1963 smsatPrepareNewIO( 1964 smSatInternalIo_t *satNewIntIo, 1965 smIORequest_t *smOrgIORequest, 1966 smDeviceData_t *satDevData, 1967 smIniScsiCmnd_t *scsiCmnd, 1968 smSatIOContext_t *satOrgIOContext 1969 ) 1970 { 1971 smSatIOContext_t *satNewIOContext; 1972 smIORequestBody_t *smNewIORequestBody; 1973 1974 SM_DBG3(("smsatPrepareNewIO: start\n")); 1975 1976 /* the one to be used; good 8/2/07 */ 1977 satNewIntIo->satOrgSmIORequest = smOrgIORequest; /* this is already done in 1978 smsatAllocIntIoResource() */ 1979 1980 smNewIORequestBody = (smIORequestBody_t *)satNewIntIo->satIntRequestBody; 1981 satNewIOContext = &(smNewIORequestBody->transport.SATA.satIOContext); 1982 1983 satNewIOContext->pSatDevData = satDevData; 1984 satNewIOContext->pFis = &(smNewIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 1985 satNewIOContext->pScsiCmnd = &(satNewIntIo->satIntSmScsiXchg.scsiCmnd); 1986 if (scsiCmnd != agNULL) 1987 { 1988 /* saves only CBD; not scsi command for LBA and number of blocks */ 1989 sm_memcpy(satNewIOContext->pScsiCmnd->cdb, scsiCmnd->cdb, 16); 1990 } 1991 satNewIOContext->pSense = &(smNewIORequestBody->transport.SATA.sensePayload); 1992 satNewIOContext->pSmSenseData = &(smNewIORequestBody->transport.SATA.smSenseData); 1993 satNewIOContext->pSmSenseData->senseData = satNewIOContext->pSense; 1994 satNewIOContext->smRequestBody = satNewIntIo->satIntRequestBody; 1995 satNewIOContext->interruptContext = satNewIOContext->interruptContext; 1996 satNewIOContext->satIntIoContext = satNewIntIo; 1997 satNewIOContext->psmDeviceHandle = satOrgIOContext->psmDeviceHandle; 1998 satNewIOContext->satOrgIOContext = satOrgIOContext; 1999 /* saves tiScsiXchg; only for writesame10() */ 2000 satNewIOContext->smScsiXchg = satOrgIOContext->smScsiXchg; 2001 2002 return satNewIOContext; 2003 } 2004 2005 2006 osGLOBAL void 2007 smsatSetDevInfo( 2008 smDeviceData_t *oneDeviceData, 2009 agsaSATAIdentifyData_t *SATAIdData 2010 ) 2011 { 2012 SM_DBG3(("smsatSetDevInfo: start\n")); 2013 2014 oneDeviceData->satDriveState = SAT_DEV_STATE_NORMAL; 2015 oneDeviceData->satFormatState = agFALSE; 2016 oneDeviceData->satDeviceFaultState = agFALSE; 2017 oneDeviceData->satTmTaskTag = agNULL; 2018 oneDeviceData->satAbortAfterReset = agFALSE; 2019 oneDeviceData->satAbortCalled = agFALSE; 2020 oneDeviceData->satSectorDone = 0; 2021 2022 /* Qeueu depth, Word 75 */ 2023 oneDeviceData->satNCQMaxIO = SATAIdData->queueDepth + 1; 2024 SM_DBG3(("smsatSetDevInfo: max queue depth %d\n",oneDeviceData->satNCQMaxIO)); 2025 2026 /* Support NCQ, if Word 76 bit 8 is set */ 2027 if (SATAIdData->sataCapabilities & 0x100) 2028 { 2029 SM_DBG3(("smsatSetDevInfo: device supports NCQ\n")); 2030 oneDeviceData->satNCQ = agTRUE; 2031 } 2032 else 2033 { 2034 SM_DBG3(("smsatSetDevInfo: no NCQ\n")); 2035 oneDeviceData->satNCQ = agFALSE; 2036 } 2037 2038 /* Support 48 bit addressing, if Word 83 bit 10 and Word 86 bit 10 are set */ 2039 if ((SATAIdData->commandSetSupported1 & 0x400) && 2040 (SATAIdData->commandSetFeatureEnabled1 & 0x400) ) 2041 { 2042 SM_DBG3(("smsatSetDevInfo: support 48 bit addressing\n")); 2043 oneDeviceData->sat48BitSupport = agTRUE; 2044 } 2045 else 2046 { 2047 SM_DBG3(("smsatSetDevInfo: NO 48 bit addressing\n")); 2048 oneDeviceData->sat48BitSupport = agFALSE; 2049 } 2050 2051 /* Support SMART Self Test, word84 bit 1 */ 2052 if (SATAIdData->commandSetFeatureSupportedExt & 0x02) 2053 { 2054 SM_DBG3(("smsatSetDevInfo: SMART self-test supported \n")); 2055 oneDeviceData->satSMARTSelfTest = agTRUE; 2056 } 2057 else 2058 { 2059 SM_DBG3(("smsatSetDevInfo: no SMART self-test suppored\n")); 2060 oneDeviceData->satSMARTSelfTest = agFALSE; 2061 } 2062 2063 /* Support SMART feature set, word82 bit 0 */ 2064 if (SATAIdData->commandSetSupported & 0x01) 2065 { 2066 SM_DBG3(("smsatSetDevInfo: SMART feature set supported \n")); 2067 oneDeviceData->satSMARTFeatureSet = agTRUE; 2068 } 2069 else 2070 { 2071 SM_DBG3(("smsatSetDevInfo: no SMART feature set suppored\n")); 2072 oneDeviceData->satSMARTFeatureSet = agFALSE; 2073 } 2074 2075 /* Support SMART enabled, word85 bit 0 */ 2076 if (SATAIdData->commandSetFeatureEnabled & 0x01) 2077 { 2078 SM_DBG3(("smsatSetDevInfo: SMART enabled \n")); 2079 oneDeviceData->satSMARTEnabled = agTRUE; 2080 } 2081 else 2082 { 2083 SM_DBG3(("smsatSetDevInfo: no SMART enabled\n")); 2084 oneDeviceData->satSMARTEnabled = agFALSE; 2085 } 2086 2087 oneDeviceData->satVerifyState = 0; 2088 2089 /* Removable Media feature set support, word82 bit 2 */ 2090 if (SATAIdData->commandSetSupported & 0x4) 2091 { 2092 SM_DBG3(("smsatSetDevInfo: Removable Media supported \n")); 2093 oneDeviceData->satRemovableMedia = agTRUE; 2094 } 2095 else 2096 { 2097 SM_DBG3(("smsatSetDevInfo: no Removable Media suppored\n")); 2098 oneDeviceData->satRemovableMedia = agFALSE; 2099 } 2100 2101 /* Removable Media feature set enabled, word 85, bit 2 */ 2102 if (SATAIdData->commandSetFeatureEnabled & 0x4) 2103 { 2104 SM_DBG3(("smsatSetDevInfo: Removable Media enabled\n")); 2105 oneDeviceData->satRemovableMediaEnabled = agTRUE; 2106 } 2107 else 2108 { 2109 SM_DBG3(("smsatSetDevInfo: no Removable Media enabled\n")); 2110 oneDeviceData->satRemovableMediaEnabled = agFALSE; 2111 } 2112 2113 /* DMA Support, word49 bit8 */ 2114 if (SATAIdData->dma_lba_iod_ios_stimer & 0x100) 2115 { 2116 SM_DBG3(("smsatSetDevInfo: DMA supported \n")); 2117 oneDeviceData->satDMASupport = agTRUE; 2118 } 2119 else 2120 { 2121 SM_DBG3(("smsatSetDevInfo: no DMA suppored\n")); 2122 oneDeviceData->satDMASupport = agFALSE; 2123 } 2124 2125 /* Support DMADIR, if Word 62 bit 8 is set */ 2126 if (SATAIdData->word62_74[0] & 0x8000) 2127 { 2128 SM_DBG3(("satSetDevInfo: DMADIR enabled\n")); 2129 oneDeviceData->satDMADIRSupport = agTRUE; 2130 } 2131 else 2132 { 2133 SM_DBG3(("satSetDevInfo: DMADIR disabled\n")); 2134 oneDeviceData->satDMADIRSupport = agFALSE; 2135 } 2136 2137 /* DMA Enabled, word88 bit0-6, bit8-14*/ 2138 /* 0x7F7F = 0111 1111 0111 1111*/ 2139 if (SATAIdData->ultraDMAModes & 0x7F7F) 2140 { 2141 SM_DBG3(("smsatSetDevInfo: DMA enabled \n")); 2142 oneDeviceData->satDMAEnabled = agTRUE; 2143 if (SATAIdData->ultraDMAModes & 0x40) 2144 { 2145 oneDeviceData->satUltraDMAMode = 6; 2146 } 2147 else if (SATAIdData->ultraDMAModes & 0x20) 2148 { 2149 oneDeviceData->satUltraDMAMode = 5; 2150 } 2151 else if (SATAIdData->ultraDMAModes & 0x10) 2152 { 2153 oneDeviceData->satUltraDMAMode = 4; 2154 } 2155 else if (SATAIdData->ultraDMAModes & 0x08) 2156 { 2157 oneDeviceData->satUltraDMAMode = 3; 2158 } 2159 else if (SATAIdData->ultraDMAModes & 0x04) 2160 { 2161 oneDeviceData->satUltraDMAMode = 2; 2162 } 2163 else if (SATAIdData->ultraDMAModes & 0x01) 2164 { 2165 oneDeviceData->satUltraDMAMode = 1; 2166 } 2167 } 2168 else 2169 { 2170 SM_DBG3(("smsatSetDevInfo: no DMA enabled\n")); 2171 oneDeviceData->satDMAEnabled = agFALSE; 2172 oneDeviceData->satUltraDMAMode = 0; 2173 } 2174 2175 /* 2176 setting MaxUserAddrSectors: max user addressable setctors 2177 word60 - 61, should be 0x 0F FF FF FF 2178 */ 2179 oneDeviceData->satMaxUserAddrSectors 2180 = (SATAIdData->numOfUserAddressableSectorsHi << (8*2) ) 2181 + SATAIdData->numOfUserAddressableSectorsLo; 2182 SM_DBG3(("smsatSetDevInfo: MaxUserAddrSectors 0x%x decimal %d\n", oneDeviceData->satMaxUserAddrSectors, oneDeviceData->satMaxUserAddrSectors)); 2183 2184 /* Read Look-ahead is supported */ 2185 if (SATAIdData->commandSetSupported & 0x40) 2186 { 2187 SM_DBG3(("smsatSetDevInfo: Read Look-ahead is supported\n")); 2188 oneDeviceData->satReadLookAheadSupport= agTRUE; 2189 } 2190 else 2191 { 2192 SM_DBG3(("smsatSetDevInfo: Read Look-ahead is not supported\n")); 2193 oneDeviceData->satReadLookAheadSupport= agFALSE; 2194 } 2195 2196 /* Volatile Write Cache is supported */ 2197 if (SATAIdData->commandSetSupported & 0x20) 2198 { 2199 SM_DBG3(("smsatSetDevInfo: Volatile Write Cache is supported\n")); 2200 oneDeviceData->satVolatileWriteCacheSupport = agTRUE; 2201 } 2202 else 2203 { 2204 SM_DBG3(("smsatSetDevInfo: Volatile Write Cache is not supported\n")); 2205 oneDeviceData->satVolatileWriteCacheSupport = agFALSE; 2206 } 2207 2208 /* write cache enabled for caching mode page SAT Table 67 p69, word85 bit5 */ 2209 if (SATAIdData->commandSetFeatureEnabled & 0x20) 2210 { 2211 SM_DBG3(("smsatSetDevInfo: write cache enabled\n")); 2212 oneDeviceData->satWriteCacheEnabled = agTRUE; 2213 } 2214 else 2215 { 2216 SM_DBG3(("smsatSetDevInfo: no write cache enabled\n")); 2217 oneDeviceData->satWriteCacheEnabled = agFALSE; 2218 } 2219 2220 /* look ahead enabled for caching mode page SAT Table 67 p69, word85 bit6 */ 2221 if (SATAIdData->commandSetFeatureEnabled & 0x40) 2222 { 2223 SM_DBG3(("smsatSetDevInfo: look ahead enabled\n")); 2224 oneDeviceData->satLookAheadEnabled = agTRUE; 2225 } 2226 else 2227 { 2228 SM_DBG3(("smsatSetDevInfo: no look ahead enabled\n")); 2229 oneDeviceData->satLookAheadEnabled = agFALSE; 2230 } 2231 2232 /* Support WWN, if Word 87 bit 8 is set */ 2233 if (SATAIdData->commandSetFeatureDefault & 0x100) 2234 { 2235 SM_DBG3(("smsatSetDevInfo: device supports WWN\n")); 2236 oneDeviceData->satWWNSupport = agTRUE; 2237 } 2238 else 2239 { 2240 SM_DBG3(("smsatSetDevInfo: no WWN\n")); 2241 oneDeviceData->satWWNSupport = agFALSE; 2242 } 2243 2244 /* Support DMA Setup Auto-Activate, if Word 78 bit 2 is set */ 2245 if (SATAIdData->sataFeaturesSupported & 0x4) 2246 { 2247 SM_DBG3(("smsatSetDevInfo: device supports DMA Setup Auto-Activate\n")); 2248 oneDeviceData->satDMASetupAA = agTRUE; 2249 } 2250 else 2251 { 2252 SM_DBG3(("smsatSetDevInfo: no DMA Setup Auto-Activate\n")); 2253 oneDeviceData->satDMASetupAA = agFALSE; 2254 } 2255 2256 /* Support NCQ Queue Management Command, if Word 77 bit 5 is set */ 2257 if (SATAIdData->word77 & 0x10) 2258 { 2259 SM_DBG3(("smsatSetDevInfo: device supports NCQ Queue Management Command\n")); 2260 oneDeviceData->satNCQQMgntCmd = agTRUE; 2261 } 2262 else 2263 { 2264 SM_DBG3(("smsatSetDevInfo: no NCQ Queue Management Command\n")); 2265 oneDeviceData->satNCQQMgntCmd = agFALSE; 2266 } 2267 return; 2268 } 2269 2270 2271 osGLOBAL void 2272 smsatInquiryStandard( 2273 bit8 *pInquiry, 2274 agsaSATAIdentifyData_t *pSATAIdData, 2275 smIniScsiCmnd_t *scsiCmnd 2276 ) 2277 { 2278 smLUN_t *pLun; 2279 pLun = &scsiCmnd->lun; 2280 2281 /* 2282 Assumption: Basic Task Mangement is supported 2283 -> BQUE 1 and CMDQUE 0, SPC-4, Table96, p147 2284 */ 2285 /* 2286 See SPC-4, 6.4.2, p 143 2287 and SAT revision 8, 8.1.2, p 28 2288 */ 2289 SM_DBG5(("smsatInquiryStandard: start\n")); 2290 2291 if (pInquiry == agNULL) 2292 { 2293 SM_DBG1(("smsatInquiryStandard: pInquiry is NULL, wrong\n")); 2294 return; 2295 } 2296 else 2297 { 2298 SM_DBG5(("smsatInquiryStandard: pInquiry is NOT NULL\n")); 2299 } 2300 /* 2301 * Reject all other LUN other than LUN 0. 2302 */ 2303 if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] | 2304 pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) ) 2305 { 2306 /* SAT Spec Table 8, p27, footnote 'a' */ 2307 pInquiry[0] = 0x7F; 2308 2309 } 2310 else 2311 { 2312 pInquiry[0] = 0x00; 2313 } 2314 2315 if (pSATAIdData->rm_ataDevice & ATA_REMOVABLE_MEDIA_DEVICE_MASK ) 2316 { 2317 pInquiry[1] = 0x80; 2318 } 2319 else 2320 { 2321 pInquiry[1] = 0x00; 2322 } 2323 pInquiry[2] = 0x05; /* SPC-3 */ 2324 pInquiry[3] = 0x12; /* set HiSup 1; resp data format set to 2 */ 2325 pInquiry[4] = 0x1F; /* 35 - 4 = 31; Additional length */ 2326 pInquiry[5] = 0x00; 2327 /* The following two are for task management. SAT Rev8, p20 */ 2328 if (pSATAIdData->sataCapabilities & 0x100) 2329 { 2330 /* NCQ supported; multiple outstanding SCSI IO are supported */ 2331 pInquiry[6] = 0x00; /* BQUE bit is not set */ 2332 pInquiry[7] = 0x02; /* CMDQUE bit is set */ 2333 } 2334 else 2335 { 2336 pInquiry[6] = 0x80; /* BQUE bit is set */ 2337 pInquiry[7] = 0x00; /* CMDQUE bit is not set */ 2338 } 2339 /* 2340 * Vendor ID. 2341 */ 2342 sm_strncpy((char*)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8); /* 8 bytes */ 2343 2344 /* 2345 * Product ID 2346 */ 2347 /* when flipped by LL */ 2348 pInquiry[16] = pSATAIdData->modelNumber[1]; 2349 pInquiry[17] = pSATAIdData->modelNumber[0]; 2350 pInquiry[18] = pSATAIdData->modelNumber[3]; 2351 pInquiry[19] = pSATAIdData->modelNumber[2]; 2352 pInquiry[20] = pSATAIdData->modelNumber[5]; 2353 pInquiry[21] = pSATAIdData->modelNumber[4]; 2354 pInquiry[22] = pSATAIdData->modelNumber[7]; 2355 pInquiry[23] = pSATAIdData->modelNumber[6]; 2356 pInquiry[24] = pSATAIdData->modelNumber[9]; 2357 pInquiry[25] = pSATAIdData->modelNumber[8]; 2358 pInquiry[26] = pSATAIdData->modelNumber[11]; 2359 pInquiry[27] = pSATAIdData->modelNumber[10]; 2360 pInquiry[28] = pSATAIdData->modelNumber[13]; 2361 pInquiry[29] = pSATAIdData->modelNumber[12]; 2362 pInquiry[30] = pSATAIdData->modelNumber[15]; 2363 pInquiry[31] = pSATAIdData->modelNumber[14]; 2364 2365 /* when flipped */ 2366 /* 2367 * Product Revision level. 2368 */ 2369 2370 /* 2371 * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA 2372 * device are ASCII spaces (20h), do this translation. 2373 */ 2374 if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) && 2375 (pSATAIdData->firmwareVersion[5] == 0x20 ) && 2376 (pSATAIdData->firmwareVersion[6] == 0x20 ) && 2377 (pSATAIdData->firmwareVersion[7] == 0x20 ) 2378 ) 2379 { 2380 pInquiry[32] = pSATAIdData->firmwareVersion[1]; 2381 pInquiry[33] = pSATAIdData->firmwareVersion[0]; 2382 pInquiry[34] = pSATAIdData->firmwareVersion[3]; 2383 pInquiry[35] = pSATAIdData->firmwareVersion[2]; 2384 } 2385 else 2386 { 2387 pInquiry[32] = pSATAIdData->firmwareVersion[5]; 2388 pInquiry[33] = pSATAIdData->firmwareVersion[4]; 2389 pInquiry[34] = pSATAIdData->firmwareVersion[7]; 2390 pInquiry[35] = pSATAIdData->firmwareVersion[6]; 2391 } 2392 2393 2394 #ifdef REMOVED 2395 /* 2396 * Product ID 2397 */ 2398 /* when flipped by LL */ 2399 pInquiry[16] = pSATAIdData->modelNumber[0]; 2400 pInquiry[17] = pSATAIdData->modelNumber[1]; 2401 pInquiry[18] = pSATAIdData->modelNumber[2]; 2402 pInquiry[19] = pSATAIdData->modelNumber[3]; 2403 pInquiry[20] = pSATAIdData->modelNumber[4]; 2404 pInquiry[21] = pSATAIdData->modelNumber[5]; 2405 pInquiry[22] = pSATAIdData->modelNumber[6]; 2406 pInquiry[23] = pSATAIdData->modelNumber[7]; 2407 pInquiry[24] = pSATAIdData->modelNumber[8]; 2408 pInquiry[25] = pSATAIdData->modelNumber[9]; 2409 pInquiry[26] = pSATAIdData->modelNumber[10]; 2410 pInquiry[27] = pSATAIdData->modelNumber[11]; 2411 pInquiry[28] = pSATAIdData->modelNumber[12]; 2412 pInquiry[29] = pSATAIdData->modelNumber[13]; 2413 pInquiry[30] = pSATAIdData->modelNumber[14]; 2414 pInquiry[31] = pSATAIdData->modelNumber[15]; 2415 2416 /* when flipped */ 2417 /* 2418 * Product Revision level. 2419 */ 2420 2421 /* 2422 * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA 2423 * device are ASCII spaces (20h), do this translation. 2424 */ 2425 if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) && 2426 (pSATAIdData->firmwareVersion[5] == 0x20 ) && 2427 (pSATAIdData->firmwareVersion[6] == 0x20 ) && 2428 (pSATAIdData->firmwareVersion[7] == 0x20 ) 2429 ) 2430 { 2431 pInquiry[32] = pSATAIdData->firmwareVersion[0]; 2432 pInquiry[33] = pSATAIdData->firmwareVersion[1]; 2433 pInquiry[34] = pSATAIdData->firmwareVersion[2]; 2434 pInquiry[35] = pSATAIdData->firmwareVersion[3]; 2435 } 2436 else 2437 { 2438 pInquiry[32] = pSATAIdData->firmwareVersion[4]; 2439 pInquiry[33] = pSATAIdData->firmwareVersion[5]; 2440 pInquiry[34] = pSATAIdData->firmwareVersion[6]; 2441 pInquiry[35] = pSATAIdData->firmwareVersion[7]; 2442 } 2443 #endif 2444 2445 SM_DBG5(("smsatInquiryStandard: end\n")); 2446 2447 return; 2448 } 2449 2450 osGLOBAL void 2451 smsatInquiryPage0( 2452 bit8 *pInquiry, 2453 agsaSATAIdentifyData_t *pSATAIdData 2454 ) 2455 { 2456 SM_DBG5(("smsatInquiryPage0: start\n")); 2457 2458 /* 2459 See SPC-4, 7.6.9, p 345 2460 and SAT revision 8, 10.3.2, p 77 2461 */ 2462 pInquiry[0] = 0x00; 2463 pInquiry[1] = 0x00; /* page code */ 2464 pInquiry[2] = 0x00; /* reserved */ 2465 pInquiry[3] = 8 - 3; /* last index(in this case, 6) - 3; page length */ 2466 2467 /* supported vpd page list */ 2468 pInquiry[4] = 0x00; /* page 0x00 supported */ 2469 pInquiry[5] = 0x80; /* page 0x80 supported */ 2470 pInquiry[6] = 0x83; /* page 0x83 supported */ 2471 pInquiry[7] = 0x89; /* page 0x89 supported */ 2472 pInquiry[8] = 0xB1; /* page 0xB1 supported */ 2473 2474 return; 2475 } 2476 2477 osGLOBAL void 2478 smsatInquiryPage83( 2479 bit8 *pInquiry, 2480 agsaSATAIdentifyData_t *pSATAIdData, 2481 smDeviceData_t *oneDeviceData 2482 ) 2483 { 2484 satSimpleSATAIdentifyData_t *pSimpleData; 2485 2486 /* 2487 * When translating the fields, in some cases using the simple form of SATA 2488 * Identify Device Data is easier. So we define it here. 2489 * Both pSimpleData and pSATAIdData points to the same data. 2490 */ 2491 pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData; 2492 2493 SM_DBG5(("smsatInquiryPage83: start\n")); 2494 2495 pInquiry[0] = 0x00; 2496 pInquiry[1] = 0x83; /* page code */ 2497 pInquiry[2] = 0; /* Reserved */ 2498 /* 2499 * If the ATA device returns word 87 bit 8 set to one in its IDENTIFY DEVICE 2500 * data indicating that it supports the WORLD WIDE NAME field 2501 * (i.e., words 108-111), the SATL shall include an identification descriptor 2502 * containing a logical unit name. 2503 */ 2504 if ( oneDeviceData->satWWNSupport) 2505 { 2506 #ifndef PMC_FREEBSD 2507 /* Fill in SAT Rev8 Table85 */ 2508 /* 2509 * Logical unit name derived from the world wide name. 2510 */ 2511 pInquiry[3] = 12; /* 15-3; page length, no addition ID descriptor assumed*/ 2512 2513 /* 2514 * Identifier descriptor 2515 */ 2516 pInquiry[4] = 0x01; /* Code set: binary codes */ 2517 pInquiry[5] = 0x03; /* Identifier type : NAA */ 2518 pInquiry[6] = 0x00; /* Reserved */ 2519 pInquiry[7] = 0x08; /* Identifier length */ 2520 2521 /* Bit 4-7 NAA field, bit 0-3 MSB of IEEE Company ID */ 2522 pInquiry[8] = (bit8)((pSATAIdData->namingAuthority) >> 8); 2523 pInquiry[9] = (bit8)((pSATAIdData->namingAuthority) & 0xFF); /* IEEE Company ID */ 2524 pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8); /* IEEE Company ID */ 2525 /* Bit 4-7 LSB of IEEE Company ID, bit 0-3 MSB of Vendor Specific ID */ 2526 pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF); 2527 pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8); /* Vendor Specific ID */ 2528 pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF); /* Vendor Specific ID */ 2529 pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8); /* Vendor Specific ID */ 2530 pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF); /* Vendor Specific ID */ 2531 2532 #else 2533 2534 /* For FreeBSD */ 2535 2536 /* Fill in SAT Rev8 Table85 */ 2537 /* 2538 * Logical unit name derived from the world wide name. 2539 */ 2540 pInquiry[3] = 24; /* 35-3; page length, no addition ID descriptor assumed*/ 2541 /* 2542 * Identifier descriptor 2543 */ 2544 pInquiry[4] = 0x01; /* Code set: binary codes; this is proto_codeset in FreeBSD */ 2545 pInquiry[5] = 0x03; /* Identifier type : NAA ; this is id_type in FreeBSD*/ 2546 pInquiry[6] = 0x00; /* Reserved */ 2547 pInquiry[7] = 0x08; /* Identifier length */ 2548 2549 /* Bit 4-7 NAA field, bit 0-3 MSB of IEEE Company ID */ 2550 pInquiry[8] = (bit8)((pSATAIdData->namingAuthority) >> 8); 2551 pInquiry[9] = (bit8)((pSATAIdData->namingAuthority) & 0xFF); /* IEEE Company ID */ 2552 pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8); /* IEEE Company ID */ 2553 /* Bit 4-7 LSB of IEEE Company ID, bit 0-3 MSB of Vendor Specific ID */ 2554 pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF); 2555 pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8); /* Vendor Specific ID */ 2556 pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF); /* Vendor Specific ID */ 2557 pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8); /* Vendor Specific ID */ 2558 pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF); /* Vendor Specific ID */ 2559 2560 pInquiry[16] = 0x61; /* Code set: binary codes; this is proto_codeset in FreeBSD; SCSI_PROTO_SAS and SVPD_ID_CODESET_BINARY */ 2561 pInquiry[17] = 0x93; /* Identifier type : NAA ; this is id_type in FreeBSD; PIV set, ASSOCIATION is 01b and NAA (3h) */ 2562 pInquiry[18] = 0x00; /* Reserved */ 2563 pInquiry[19] = 0x08; /* Identifier length */ 2564 2565 SM_DBG5(("smsatInquiryPage83: sasAddressHi 0x%08x\n", oneDeviceData->sasAddressHi)); 2566 SM_DBG5(("smsatInquiryPage83: sasAddressLo 0x%08x\n", oneDeviceData->sasAddressLo)); 2567 2568 /* SAS address of SATA */ 2569 pInquiry[20] = ((oneDeviceData->sasAddressHi) & 0xFF000000 ) >> 24; 2570 pInquiry[21] = ((oneDeviceData->sasAddressHi) & 0xFF0000 ) >> 16; 2571 pInquiry[22] = ((oneDeviceData->sasAddressHi) & 0xFF00 ) >> 8; 2572 pInquiry[23] = (oneDeviceData->sasAddressHi) & 0xFF; 2573 pInquiry[24] = ((oneDeviceData->sasAddressLo) & 0xFF000000 ) >> 24; 2574 pInquiry[25] = ((oneDeviceData->sasAddressLo) & 0xFF0000 ) >> 16; 2575 pInquiry[26] = ((oneDeviceData->sasAddressLo) & 0xFF00 ) >> 8; 2576 pInquiry[27] = (oneDeviceData->sasAddressLo) & 0xFF; 2577 #endif 2578 } 2579 else 2580 { 2581 #ifndef PMC_FREEBSD 2582 /* Fill in SAT Rev8 Table86 */ 2583 /* 2584 * Logical unit name derived from the model number and serial number. 2585 */ 2586 pInquiry[3] = 72; /* 75 - 3; page length */ 2587 2588 /* 2589 * Identifier descriptor 2590 */ 2591 pInquiry[4] = 0x02; /* Code set: ASCII codes */ 2592 pInquiry[5] = 0x01; /* Identifier type : T10 vendor ID based */ 2593 pInquiry[6] = 0x00; /* Reserved */ 2594 pInquiry[7] = 0x44; /* 0x44, 68 Identifier length */ 2595 2596 /* Byte 8 to 15 is the vendor id string 'ATA '. */ 2597 sm_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8); 2598 2599 2600 /* 2601 * Byte 16 to 75 is vendor specific id 2602 */ 2603 pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8); 2604 pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff); 2605 pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8); 2606 pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff); 2607 pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8); 2608 pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff); 2609 pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8); 2610 pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff); 2611 pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8); 2612 pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff); 2613 pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8); 2614 pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff); 2615 pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8); 2616 pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff); 2617 pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8); 2618 pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff); 2619 pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8); 2620 pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff); 2621 pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8); 2622 pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff); 2623 pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8); 2624 pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff); 2625 pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8); 2626 pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff); 2627 pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8); 2628 pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff); 2629 pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8); 2630 pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff); 2631 pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8); 2632 pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff); 2633 pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8); 2634 pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff); 2635 pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8); 2636 pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff); 2637 pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8); 2638 pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff); 2639 pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8); 2640 pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff); 2641 pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8); 2642 pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff); 2643 2644 pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8); 2645 pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff); 2646 pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8); 2647 pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff); 2648 pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8); 2649 pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff); 2650 pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8); 2651 pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff); 2652 pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8); 2653 pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff); 2654 pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8); 2655 pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff); 2656 pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8); 2657 pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff); 2658 pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8); 2659 pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff); 2660 pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8); 2661 pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff); 2662 pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8); 2663 pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff); 2664 #else 2665 /* for the FreeBSD */ 2666 /* Fill in SAT Rev8 Table86 */ 2667 /* 2668 * Logical unit name derived from the model number and serial number. 2669 */ 2670 pInquiry[3] = 84; /* 87 - 3; page length */ 2671 2672 /* 2673 * Identifier descriptor 2674 */ 2675 pInquiry[4] = 0x02; /* Code set: ASCII codes */ 2676 pInquiry[5] = 0x01; /* Identifier type : T10 vendor ID based */ 2677 pInquiry[6] = 0x00; /* Reserved */ 2678 pInquiry[7] = 0x44; /* 0x44, 68 Identifier length */ 2679 2680 /* Byte 8 to 15 is the vendor id string 'ATA '. */ 2681 sm_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8); 2682 2683 2684 /* 2685 * Byte 16 to 75 is vendor specific id 2686 */ 2687 pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8); 2688 pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff); 2689 pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8); 2690 pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff); 2691 pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8); 2692 pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff); 2693 pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8); 2694 pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff); 2695 pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8); 2696 pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff); 2697 pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8); 2698 pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff); 2699 pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8); 2700 pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff); 2701 pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8); 2702 pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff); 2703 pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8); 2704 pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff); 2705 pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8); 2706 pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff); 2707 pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8); 2708 pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff); 2709 pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8); 2710 pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff); 2711 pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8); 2712 pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff); 2713 pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8); 2714 pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff); 2715 pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8); 2716 pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff); 2717 pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8); 2718 pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff); 2719 pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8); 2720 pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff); 2721 pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8); 2722 pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff); 2723 pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8); 2724 pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff); 2725 pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8); 2726 pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff); 2727 2728 pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8); 2729 pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff); 2730 pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8); 2731 pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff); 2732 pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8); 2733 pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff); 2734 pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8); 2735 pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff); 2736 pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8); 2737 pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff); 2738 pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8); 2739 pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff); 2740 pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8); 2741 pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff); 2742 pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8); 2743 pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff); 2744 pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8); 2745 pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff); 2746 pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8); 2747 pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff); 2748 2749 pInquiry[76] = 0x61; /* Code set: binary codes; this is proto_codeset in FreeBSD; SCSI_PROTO_SAS and SVPD_ID_CODESET_BINARY */ 2750 pInquiry[77] = 0x93; /* Identifier type : NAA ; this is id_type in FreeBSD; PIV set, ASSOCIATION is 01b and NAA (3h) */ 2751 pInquiry[78] = 0x00; /* Reserved */ 2752 pInquiry[79] = 0x08; /* Identifier length */ 2753 2754 SM_DBG5(("smsatInquiryPage83: NO WWN sasAddressHi 0x%08x\n", oneDeviceData->sasAddressHi)); 2755 SM_DBG5(("smsatInquiryPage83: No WWN sasAddressLo 0x%08x\n", oneDeviceData->sasAddressLo)); 2756 2757 /* SAS address of SATA */ 2758 pInquiry[80] = ((oneDeviceData->sasAddressHi) & 0xFF000000 ) >> 24; 2759 pInquiry[81] = ((oneDeviceData->sasAddressHi) & 0xFF0000 ) >> 16; 2760 pInquiry[82] = ((oneDeviceData->sasAddressHi) & 0xFF00 ) >> 8; 2761 pInquiry[83] = (oneDeviceData->sasAddressHi) & 0xFF; 2762 pInquiry[84] = ((oneDeviceData->sasAddressLo) & 0xFF000000 ) >> 24; 2763 pInquiry[85] = ((oneDeviceData->sasAddressLo) & 0xFF0000 ) >> 16; 2764 pInquiry[86] = ((oneDeviceData->sasAddressLo) & 0xFF00 ) >> 8; 2765 pInquiry[87] = (oneDeviceData->sasAddressLo) & 0xFF; 2766 2767 #endif 2768 } 2769 2770 return; 2771 } 2772 2773 osGLOBAL void 2774 smsatInquiryPage89( 2775 bit8 *pInquiry, 2776 agsaSATAIdentifyData_t *pSATAIdData, 2777 smDeviceData_t *oneDeviceData, 2778 bit32 len 2779 ) 2780 { 2781 /* 2782 SAT revision 8, 10.3.5, p 83 2783 */ 2784 satSimpleSATAIdentifyData_t *pSimpleData; 2785 2786 /* 2787 * When translating the fields, in some cases using the simple form of SATA 2788 * Identify Device Data is easier. So we define it here. 2789 * Both pSimpleData and pSATAIdData points to the same data. 2790 */ 2791 pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData; 2792 2793 SM_DBG5(("smsatInquiryPage89: start\n")); 2794 2795 pInquiry[0] = 0x00; /* Peripheral Qualifier and Peripheral Device Type */ 2796 pInquiry[1] = 0x89; /* page code */ 2797 2798 /* Page length 0x238 */ 2799 pInquiry[2] = 0x02; 2800 pInquiry[3] = 0x38; 2801 2802 pInquiry[4] = 0x0; /* reserved */ 2803 pInquiry[5] = 0x0; /* reserved */ 2804 pInquiry[6] = 0x0; /* reserved */ 2805 pInquiry[7] = 0x0; /* reserved */ 2806 2807 /* SAT Vendor Identification */ 2808 sm_strncpy((char*)&pInquiry[8], "PMC-SIERRA", 8); /* 8 bytes */ 2809 2810 /* SAT Product Idetification */ 2811 sm_strncpy((char*)&pInquiry[16], "Tachyon-SPC ", 16); /* 16 bytes */ 2812 2813 /* SAT Product Revision Level */ 2814 sm_strncpy((char*)&pInquiry[32], "01", 4); /* 4 bytes */ 2815 2816 /* Signature, SAT revision8, Table88, p85 */ 2817 2818 2819 pInquiry[36] = 0x34; /* FIS type */ 2820 if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE) 2821 { 2822 /* interrupt assume to be 0 */ 2823 pInquiry[37] = (bit8)((oneDeviceData->satPMField) >> (4 * 7)); /* first four bits of PM field */ 2824 } 2825 else 2826 { 2827 /* interrupt assume to be 1 */ 2828 pInquiry[37] = (bit8)(0x40 + (bit8)(((oneDeviceData->satPMField) >> (4 * 7)))); /* first four bits of PM field */ 2829 } 2830 pInquiry[38] = 0; 2831 pInquiry[39] = 0; 2832 2833 if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE) 2834 { 2835 pInquiry[40] = 0x01; /* LBA Low */ 2836 pInquiry[41] = 0x00; /* LBA Mid */ 2837 pInquiry[42] = 0x00; /* LBA High */ 2838 pInquiry[43] = 0x00; /* Device */ 2839 pInquiry[44] = 0x00; /* LBA Low Exp */ 2840 pInquiry[45] = 0x00; /* LBA Mid Exp */ 2841 pInquiry[46] = 0x00; /* LBA High Exp */ 2842 pInquiry[47] = 0x00; /* Reserved */ 2843 pInquiry[48] = 0x01; /* Sector Count */ 2844 pInquiry[49] = 0x00; /* Sector Count Exp */ 2845 } 2846 else 2847 { 2848 pInquiry[40] = 0x01; /* LBA Low */ 2849 pInquiry[41] = 0x00; /* LBA Mid */ 2850 pInquiry[42] = 0x00; /* LBA High */ 2851 pInquiry[43] = 0x00; /* Device */ 2852 pInquiry[44] = 0x00; /* LBA Low Exp */ 2853 pInquiry[45] = 0x00; /* LBA Mid Exp */ 2854 pInquiry[46] = 0x00; /* LBA High Exp */ 2855 pInquiry[47] = 0x00; /* Reserved */ 2856 pInquiry[48] = 0x01; /* Sector Count */ 2857 pInquiry[49] = 0x00; /* Sector Count Exp */ 2858 } 2859 2860 /* Reserved */ 2861 pInquiry[50] = 0x00; 2862 pInquiry[51] = 0x00; 2863 pInquiry[52] = 0x00; 2864 pInquiry[53] = 0x00; 2865 pInquiry[54] = 0x00; 2866 pInquiry[55] = 0x00; 2867 2868 /* Command Code */ 2869 if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE) 2870 { 2871 pInquiry[56] = 0xEC; /* IDENTIFY DEVICE */ 2872 } 2873 else 2874 { 2875 pInquiry[56] = 0xA1; /* IDENTIFY PACKET DEVICE */ 2876 } 2877 /* Reserved */ 2878 pInquiry[57] = 0x0; 2879 pInquiry[58] = 0x0; 2880 pInquiry[59] = 0x0; 2881 2882 /* check the length; len is assumed to be at least 60 */ 2883 if (len < SATA_PAGE89_INQUIRY_SIZE) 2884 { 2885 /* Identify Device */ 2886 sm_memcpy(&pInquiry[60], pSimpleData, MIN((len - 60), sizeof(satSimpleSATAIdentifyData_t))); 2887 } 2888 else 2889 { 2890 /* Identify Device */ 2891 sm_memcpy(&pInquiry[60], pSimpleData, sizeof(satSimpleSATAIdentifyData_t)); 2892 } 2893 2894 return; 2895 } 2896 2897 osGLOBAL void 2898 smsatInquiryPage80( 2899 bit8 *pInquiry, 2900 agsaSATAIdentifyData_t *pSATAIdData 2901 ) 2902 { 2903 SM_DBG5(("smsatInquiryPage89: start\n")); 2904 /* 2905 See SPC-4, 7.6.9, p 345 2906 and SAT revision 8, 10.3.3, p 77 2907 */ 2908 pInquiry[0] = 0x00; 2909 pInquiry[1] = 0x80; /* page code */ 2910 pInquiry[2] = 0x00; /* reserved */ 2911 pInquiry[3] = 0x14; /* page length */ 2912 2913 /* product serial number */ 2914 pInquiry[4] = pSATAIdData->serialNumber[1]; 2915 pInquiry[5] = pSATAIdData->serialNumber[0]; 2916 pInquiry[6] = pSATAIdData->serialNumber[3]; 2917 pInquiry[7] = pSATAIdData->serialNumber[2]; 2918 pInquiry[8] = pSATAIdData->serialNumber[5]; 2919 pInquiry[9] = pSATAIdData->serialNumber[4]; 2920 pInquiry[10] = pSATAIdData->serialNumber[7]; 2921 pInquiry[11] = pSATAIdData->serialNumber[6]; 2922 pInquiry[12] = pSATAIdData->serialNumber[9]; 2923 pInquiry[13] = pSATAIdData->serialNumber[8]; 2924 pInquiry[14] = pSATAIdData->serialNumber[11]; 2925 pInquiry[15] = pSATAIdData->serialNumber[10]; 2926 pInquiry[16] = pSATAIdData->serialNumber[13]; 2927 pInquiry[17] = pSATAIdData->serialNumber[12]; 2928 pInquiry[18] = pSATAIdData->serialNumber[15]; 2929 pInquiry[19] = pSATAIdData->serialNumber[14]; 2930 pInquiry[20] = pSATAIdData->serialNumber[17]; 2931 pInquiry[21] = pSATAIdData->serialNumber[16]; 2932 pInquiry[22] = pSATAIdData->serialNumber[19]; 2933 pInquiry[23] = pSATAIdData->serialNumber[18]; 2934 2935 return; 2936 } 2937 2938 osGLOBAL void 2939 smsatInquiryPageB1( 2940 bit8 *pInquiry, 2941 agsaSATAIdentifyData_t *pSATAIdData 2942 ) 2943 { 2944 bit32 i; 2945 satSimpleSATAIdentifyData_t *pSimpleData; 2946 2947 SM_DBG5(("smsatInquiryPageB1: start\n")); 2948 2949 pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData; 2950 /* 2951 See SBC-3, revision31, Table193, p273 2952 and SAT-3 revision 3, 10.3.6, p141 2953 */ 2954 pInquiry[0] = 0x00; /* Peripheral Qualifier and Peripheral Device Type */ 2955 pInquiry[1] = 0xB1; /* page code */ 2956 2957 /* page length */ 2958 pInquiry[2] = 0x0; 2959 pInquiry[3] = 0x3C; 2960 2961 /* medium rotation rate */ 2962 pInquiry[4] = (bit8) ((pSimpleData->word[217]) >> 8); 2963 pInquiry[5] = (bit8) ((pSimpleData->word[217]) & 0xFF); 2964 2965 /* reserved */ 2966 pInquiry[6] = 0x0; 2967 2968 /* nominal form factor bits 3:0 */ 2969 pInquiry[7] = (bit8) ((pSimpleData->word[168]) & 0xF); 2970 2971 2972 /* reserved */ 2973 for (i=8;i<64;i++) 2974 { 2975 pInquiry[i] = 0x0; 2976 } 2977 return; 2978 } 2979 2980 osGLOBAL void 2981 smsatDefaultTranslation( 2982 smRoot_t *smRoot, 2983 smIORequest_t *smIORequest, 2984 smSatIOContext_t *satIOContext, 2985 smScsiRspSense_t *pSense, 2986 bit8 ataStatus, 2987 bit8 ataError, 2988 bit32 interruptContext 2989 ) 2990 { 2991 SM_DBG5(("smsatDefaultTranslation: start\n")); 2992 /* 2993 * Check for device fault case 2994 */ 2995 if ( ataStatus & DF_ATA_STATUS_MASK ) 2996 { 2997 smsatSetSensePayload( pSense, 2998 SCSI_SNSKEY_HARDWARE_ERROR, 2999 0, 3000 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE, 3001 satIOContext); 3002 3003 tdsmIOCompletedCB( smRoot, 3004 smIORequest, 3005 smIOSuccess, 3006 SCSI_STAT_CHECK_CONDITION, 3007 satIOContext->pSmSenseData, 3008 interruptContext ); 3009 return; 3010 } 3011 3012 /* 3013 * If status error bit it set, need to check the error register 3014 */ 3015 if ( ataStatus & ERR_ATA_STATUS_MASK ) 3016 { 3017 if ( ataError & NM_ATA_ERROR_MASK ) 3018 { 3019 SM_DBG1(("smsatDefaultTranslation: NM_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n", 3020 ataError, smIORequest)); 3021 smsatSetSensePayload( pSense, 3022 SCSI_SNSKEY_NOT_READY, 3023 0, 3024 SCSI_SNSCODE_MEDIUM_NOT_PRESENT, 3025 satIOContext); 3026 } 3027 3028 else if (ataError & UNC_ATA_ERROR_MASK) 3029 { 3030 SM_DBG1(("smsatDefaultTranslation: UNC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n", 3031 ataError, smIORequest)); 3032 smsatSetSensePayload( pSense, 3033 SCSI_SNSKEY_MEDIUM_ERROR, 3034 0, 3035 SCSI_SNSCODE_UNRECOVERED_READ_ERROR, 3036 satIOContext); 3037 } 3038 3039 else if (ataError & IDNF_ATA_ERROR_MASK) 3040 { 3041 SM_DBG1(("smsatDefaultTranslation: IDNF_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n", 3042 ataError, smIORequest)); 3043 smsatSetSensePayload( pSense, 3044 SCSI_SNSKEY_MEDIUM_ERROR, 3045 0, 3046 SCSI_SNSCODE_RECORD_NOT_FOUND, 3047 satIOContext); 3048 } 3049 3050 else if (ataError & MC_ATA_ERROR_MASK) 3051 { 3052 SM_DBG1(("smsatDefaultTranslation: MC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n", 3053 ataError, smIORequest)); 3054 smsatSetSensePayload( pSense, 3055 SCSI_SNSKEY_UNIT_ATTENTION, 3056 0, 3057 SCSI_SNSCODE_NOT_READY_TO_READY_CHANGE, 3058 satIOContext); 3059 } 3060 3061 else if (ataError & MCR_ATA_ERROR_MASK) 3062 { 3063 SM_DBG1(("smsatDefaultTranslation: MCR_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n", 3064 ataError, smIORequest)); 3065 smsatSetSensePayload( pSense, 3066 SCSI_SNSKEY_UNIT_ATTENTION, 3067 0, 3068 SCSI_SNSCODE_OPERATOR_MEDIUM_REMOVAL_REQUEST, 3069 satIOContext); 3070 } 3071 3072 else if (ataError & ICRC_ATA_ERROR_MASK) 3073 { 3074 SM_DBG1(("smsatDefaultTranslation: ICRC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n", 3075 ataError, smIORequest)); 3076 smsatSetSensePayload( pSense, 3077 SCSI_SNSKEY_ABORTED_COMMAND, 3078 0, 3079 SCSI_SNSCODE_INFORMATION_UNIT_CRC_ERROR, 3080 satIOContext); 3081 } 3082 3083 else if (ataError & ABRT_ATA_ERROR_MASK) 3084 { 3085 SM_DBG1(("smsatDefaultTranslation: ABRT_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n", 3086 ataError, smIORequest)); 3087 smsatSetSensePayload( pSense, 3088 SCSI_SNSKEY_ABORTED_COMMAND, 3089 0, 3090 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 3091 satIOContext); 3092 } 3093 3094 else 3095 { 3096 SM_DBG1(("smsatDefaultTranslation: **** UNEXPECTED ATA_ERROR **** ataError= 0x%x, smIORequest=%p!!!\n", 3097 ataError, smIORequest)); 3098 smsatSetSensePayload( pSense, 3099 SCSI_SNSKEY_HARDWARE_ERROR, 3100 0, 3101 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE, 3102 satIOContext); 3103 } 3104 3105 /* Send the completion response now */ 3106 tdsmIOCompletedCB( smRoot, 3107 smIORequest, 3108 smIOSuccess, 3109 SCSI_STAT_CHECK_CONDITION, 3110 satIOContext->pSmSenseData, 3111 interruptContext ); 3112 return; 3113 3114 3115 } 3116 3117 else /* (ataStatus & ERR_ATA_STATUS_MASK ) is false */ 3118 { 3119 /* This case should never happen */ 3120 SM_DBG1(("smsatDefaultTranslation: *** UNEXPECTED ATA status 0x%x *** smIORequest=%p!!!\n", 3121 ataStatus, smIORequest)); 3122 smsatSetSensePayload( pSense, 3123 SCSI_SNSKEY_HARDWARE_ERROR, 3124 0, 3125 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE, 3126 satIOContext); 3127 3128 tdsmIOCompletedCB( smRoot, 3129 smIORequest, 3130 smIOSuccess, 3131 SCSI_STAT_CHECK_CONDITION, 3132 satIOContext->pSmSenseData, 3133 interruptContext ); 3134 return; 3135 3136 } 3137 3138 return; 3139 } 3140 3141 osGLOBAL bit32 3142 smIDStart( 3143 smRoot_t *smRoot, 3144 smIORequest_t *smIORequest, 3145 smDeviceHandle_t *smDeviceHandle 3146 ) 3147 { 3148 smDeviceData_t *oneDeviceData = agNULL; 3149 smIORequestBody_t *smIORequestBody = agNULL; 3150 smSatIOContext_t *satIOContext = agNULL; 3151 bit32 status = SM_RC_FAILURE; 3152 3153 SM_DBG2(("smIDStart: start, smIORequest %p\n", smIORequest)); 3154 3155 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData; 3156 if (oneDeviceData == agNULL) 3157 { 3158 SM_DBG1(("smIDStart: oneDeviceData is NULL!!!\n")); 3159 return SM_RC_FAILURE; 3160 } 3161 if (oneDeviceData->valid == agFALSE) 3162 { 3163 SM_DBG1(("smIDStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id)); 3164 return SM_RC_FAILURE; 3165 } 3166 3167 smIORequestBody = (smIORequestBody_t*)smIORequest->smData;//smDequeueIO(smRoot); 3168 3169 if (smIORequestBody == agNULL) 3170 { 3171 SM_DBG1(("smIDStart: smIORequestBody is NULL!!!\n")); 3172 return SM_RC_FAILURE; 3173 } 3174 3175 smIOReInit(smRoot, smIORequestBody); 3176 3177 SM_DBG3(("smIDStart: io ID %d!!!\n", smIORequestBody->id )); 3178 3179 smIORequestBody->smIORequest = smIORequest; 3180 smIORequestBody->smDevHandle = smDeviceHandle; 3181 satIOContext = &(smIORequestBody->transport.SATA.satIOContext); 3182 3183 /* setting up satIOContext */ 3184 satIOContext->pSatDevData = oneDeviceData; 3185 satIOContext->pFis = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 3186 satIOContext->smRequestBody = smIORequestBody; 3187 satIOContext->psmDeviceHandle = smDeviceHandle; 3188 satIOContext->smScsiXchg = agNULL; 3189 3190 /*smIORequest->smData = smIORequestBody;*/ 3191 SM_DBG3(("smIDStart: smIORequestBody %p smIORequestBody->smIORequest %p!!!\n", smIORequestBody, smIORequestBody->smIORequest)); 3192 SM_DBG1(("smIDStart: did %d\n", oneDeviceData->id)); 3193 3194 status = smsatIDSubStart( smRoot, 3195 smIORequest, 3196 smDeviceHandle, 3197 agNULL, 3198 satIOContext); 3199 3200 if (status != SM_RC_SUCCESS) 3201 { 3202 SM_DBG1(("smIDStart: smsatIDSubStart failure %d!!!\n", status)); 3203 /*smEnqueueIO(smRoot, satIOContext);*/ 3204 } 3205 SM_DBG2(("smIDStart: exit\n")); 3206 3207 return status; 3208 } 3209 3210 /* 3211 SM generated IO, needs to call smsatAllocIntIoResource() 3212 allocating using smsatAllocIntIoResource 3213 */ 3214 osGLOBAL bit32 3215 smsatIDSubStart( 3216 smRoot_t *smRoot, 3217 smIORequest_t *smIORequest, 3218 smDeviceHandle_t *smDeviceHandle, 3219 smScsiInitiatorRequest_t *smSCSIRequest, /* agNULL */ 3220 smSatIOContext_t *satIOContext 3221 ) 3222 { 3223 smSatInternalIo_t *satIntIo = agNULL; 3224 smDeviceData_t *satDevData = agNULL; 3225 smIORequestBody_t *smIORequestBody; 3226 smSatIOContext_t *satNewIOContext; 3227 bit32 status; 3228 SM_DBG2(("smsatIDSubStart: start\n")); 3229 3230 satDevData = satIOContext->pSatDevData; 3231 3232 /* allocate identify device command */ 3233 satIntIo = smsatAllocIntIoResource( smRoot, 3234 smIORequest, 3235 satDevData, 3236 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */ 3237 satIntIo); 3238 3239 if (satIntIo == agNULL) 3240 { 3241 SM_DBG1(("smsatIDSubStart: can't alloacate!!!\n")); 3242 return SM_RC_FAILURE; 3243 } 3244 3245 satIOContext->satIntIoContext = satIntIo; 3246 3247 /* fill in fields */ 3248 /* real ttttttthe one worked and the same; 5/21/07/ */ 3249 satIntIo->satOrgSmIORequest = smIORequest; /* changed */ 3250 smIORequestBody = satIntIo->satIntRequestBody; 3251 satNewIOContext = &(smIORequestBody->transport.SATA.satIOContext); 3252 3253 satNewIOContext->pSatDevData = satDevData; 3254 satNewIOContext->pFis = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 3255 satNewIOContext->pScsiCmnd = &(satIntIo->satIntSmScsiXchg.scsiCmnd); 3256 satNewIOContext->pSense = &(smIORequestBody->transport.SATA.sensePayload); 3257 satNewIOContext->pSmSenseData = &(smIORequestBody->transport.SATA.smSenseData); 3258 satNewIOContext->smRequestBody = satIntIo->satIntRequestBody; /* key fix */ 3259 // satNewIOContext->interruptContext = tiInterruptContext; 3260 satNewIOContext->satIntIoContext = satIntIo; 3261 3262 satNewIOContext->psmDeviceHandle = smDeviceHandle; 3263 satNewIOContext->satOrgIOContext = satIOContext; /* changed */ 3264 3265 /* this is valid only for TD layer generated (not triggered by OS at all) IO */ 3266 satNewIOContext->smScsiXchg = &(satIntIo->satIntSmScsiXchg); 3267 3268 3269 SM_DBG6(("smsatIDSubStart: SM satIOContext %p \n", satIOContext)); 3270 SM_DBG6(("smsatIDSubStart: SM satNewIOContext %p \n", satNewIOContext)); 3271 SM_DBG6(("smsatIDSubStart: SM tiScsiXchg %p \n", satIOContext->smScsiXchg)); 3272 SM_DBG6(("smsatIDSubStart: SM tiScsiXchg %p \n", satNewIOContext->smScsiXchg)); 3273 3274 3275 3276 SM_DBG3(("smsatIDSubStart: satNewIOContext %p smIORequestBody %p\n", satNewIOContext, smIORequestBody)); 3277 3278 status = smsatIDStart(smRoot, 3279 &satIntIo->satIntSmIORequest, /* New smIORequest */ 3280 smDeviceHandle, 3281 satNewIOContext->smScsiXchg, /* New smScsiInitiatorRequest_t *smScsiRequest, */ 3282 satNewIOContext); 3283 3284 if (status != SM_RC_SUCCESS) 3285 { 3286 SM_DBG1(("smsatIDSubStart: failed in sending %d!!!\n", status)); 3287 3288 smsatFreeIntIoResource( smRoot, 3289 satDevData, 3290 satIntIo); 3291 3292 return SM_RC_FAILURE; 3293 } 3294 3295 3296 SM_DBG2(("smsatIDSubStart: end\n")); 3297 3298 return status; 3299 3300 } 3301 3302 3303 osGLOBAL bit32 3304 smsatIDStart( 3305 smRoot_t *smRoot, 3306 smIORequest_t *smIORequest, 3307 smDeviceHandle_t *smDeviceHandle, 3308 smScsiInitiatorRequest_t *smSCSIRequest, 3309 smSatIOContext_t *satIOContext 3310 ) 3311 { 3312 bit32 status; 3313 bit32 agRequestType; 3314 smDeviceData_t *pSatDevData; 3315 agsaFisRegHostToDevice_t *fis; 3316 #ifdef SM_INTERNAL_DEBUG 3317 smIORequestBody_t *smIORequestBody; 3318 smSatInternalIo_t *satIntIoContext; 3319 #endif 3320 3321 pSatDevData = satIOContext->pSatDevData; 3322 fis = satIOContext->pFis; 3323 SM_DBG2(("smsatIDStart: start\n")); 3324 #ifdef SM_INTERNAL_DEBUG 3325 satIntIoContext = satIOContext->satIntIoContext; 3326 smIORequestBody = satIntIoContext->satIntRequestBody; 3327 #endif 3328 fis->h.fisType = 0x27; /* Reg host to device */ 3329 fis->h.c_pmPort = 0x80; /* C Bit is set */ 3330 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE) 3331 { 3332 SM_DBG2(("smsatIDStart: IDENTIFY_PACKET_DEVICE\n")); 3333 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0x40 */ 3334 } 3335 else 3336 { 3337 SM_DBG2(("smsatIDStart: IDENTIFY_DEVICE\n")); 3338 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */ 3339 } 3340 fis->h.features = 0; /* FIS reserve */ 3341 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 3342 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 3343 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 3344 fis->d.device = 0; /* FIS LBA mode */ 3345 fis->d.lbaLowExp = 0; 3346 fis->d.lbaMidExp = 0; 3347 fis->d.lbaHighExp = 0; 3348 fis->d.featuresExp = 0; 3349 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 3350 fis->d.sectorCountExp = 0; 3351 fis->d.reserved4 = 0; 3352 fis->d.control = 0; /* FIS HOB bit clear */ 3353 fis->d.reserved5 = 0; 3354 3355 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 3356 3357 /* Initialize CB for SATA completion. 3358 */ 3359 satIOContext->satCompleteCB = &smsatIDStartCB; 3360 3361 /* 3362 * Prepare SGL and send FIS to LL layer. 3363 */ 3364 satIOContext->reqType = agRequestType; /* Save it */ 3365 3366 #ifdef SM_INTERNAL_DEBUG 3367 smhexdump("smsatIDStart", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 3368 smhexdump("smsatIDStart LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t)); 3369 #endif 3370 status = smsataLLIOStart( smRoot, 3371 smIORequest, 3372 smDeviceHandle, 3373 smSCSIRequest, 3374 satIOContext); 3375 3376 SM_DBG2(("smsatIDStart: end status %d\n", status)); 3377 3378 return status; 3379 } 3380 3381 3382 osGLOBAL FORCEINLINE bit32 3383 smsatIOStart( 3384 smRoot_t *smRoot, 3385 smIORequest_t *smIORequest, 3386 smDeviceHandle_t *smDeviceHandle, 3387 smScsiInitiatorRequest_t *smSCSIRequest, 3388 smSatIOContext_t *satIOContext 3389 ) 3390 { 3391 smDeviceData_t *pSatDevData = satIOContext->pSatDevData; 3392 smScsiRspSense_t *pSense = satIOContext->pSense; 3393 smIniScsiCmnd_t *scsiCmnd = &smSCSIRequest->scsiCmnd; 3394 smLUN_t *pLun = &scsiCmnd->lun; 3395 smSatInternalIo_t *pSatIntIo = agNULL; 3396 bit32 status = SM_RC_FAILURE; 3397 3398 SM_DBG2(("smsatIOStart: start\n")); 3399 3400 /* 3401 * Reject all other LUN other than LUN 0. 3402 */ 3403 if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] | 3404 pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) && 3405 (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY) 3406 ) 3407 { 3408 SM_DBG1(("smsatIOStart: *** REJECT *** LUN not zero, cdb[0]=0x%x did %d !!!\n", 3409 scsiCmnd->cdb[0], pSatDevData->id)); 3410 smsatSetSensePayload( pSense, 3411 SCSI_SNSKEY_ILLEGAL_REQUEST, 3412 0, 3413 SCSI_SNSCODE_LOGICAL_NOT_SUPPORTED, 3414 satIOContext); 3415 3416 /*smEnqueueIO(smRoot, satIOContext);*/ 3417 3418 tdsmIOCompletedCB( smRoot, 3419 smIORequest, 3420 smIOSuccess, 3421 SCSI_STAT_CHECK_CONDITION, 3422 satIOContext->pSmSenseData, 3423 satIOContext->interruptContext ); 3424 3425 return SM_RC_SUCCESS; 3426 } 3427 3428 SM_DBG2(("smsatIOStart: satPendingIO %d satNCQMaxIO %d\n",pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO )); 3429 3430 /* this may happen after tiCOMReset until OS sends inquiry */ 3431 if (pSatDevData->IDDeviceValid == agFALSE && (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY)) 3432 { 3433 SM_DBG1(("smsatIOStart: invalid identify device data did %d !!!\n", pSatDevData->id)); 3434 SM_DBG1(("smsatIOStart: satPendingIO %d satNCQMaxIO %d\n", pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO )); 3435 SM_DBG1(("smsatIOStart: satPendingNCQIO %d satPendingNONNCQIO %d\n", pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO)); 3436 3437 /*smEnqueueIO(smRoot, satIOContext);*/ 3438 3439 return SM_RC_NODEVICE; 3440 } 3441 3442 /* 3443 * Check if we need to return BUSY, i.e. recovery in progress 3444 */ 3445 if (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY) 3446 { 3447 SM_DBG1(("smsatIOStart: IN RECOVERY STATE cdb[0]=0x%x did=%d !!!\n", 3448 scsiCmnd->cdb[0], pSatDevData->id)); 3449 SM_DBG2(("smsatIOStart: device %p satPendingIO %d satNCQMaxIO %d\n", pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO )); 3450 SM_DBG2(("smsatIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO)); 3451 3452 /*smEnqueueIO(smRoot, satIOContext);*/ 3453 3454 // return SM_RC_FAILURE; 3455 return SM_RC_DEVICE_BUSY; 3456 } 3457 3458 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE) 3459 { 3460 if (scsiCmnd->cdb[0] == SCSIOPC_REPORT_LUN) 3461 { 3462 return smsatReportLun(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext); 3463 } 3464 else 3465 { 3466 return smsatPacket(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext); 3467 } 3468 } 3469 else 3470 { 3471 /* Parse CDB */ 3472 switch(scsiCmnd->cdb[0]) 3473 { 3474 case SCSIOPC_READ_10: 3475 status = smsatRead10( smRoot, 3476 smIORequest, 3477 smDeviceHandle, 3478 smSCSIRequest, 3479 satIOContext); 3480 break; 3481 3482 case SCSIOPC_WRITE_10: 3483 status = smsatWrite10( smRoot, 3484 smIORequest, 3485 smDeviceHandle, 3486 smSCSIRequest, 3487 satIOContext); 3488 break; 3489 3490 case SCSIOPC_READ_6: 3491 status = smsatRead6( smRoot, 3492 smIORequest, 3493 smDeviceHandle, 3494 smSCSIRequest, 3495 satIOContext); 3496 break; 3497 3498 case SCSIOPC_READ_12: 3499 SM_DBG5(("smsatIOStart: SCSIOPC_READ_12\n")); 3500 status = smsatRead12( smRoot, 3501 smIORequest, 3502 smDeviceHandle, 3503 smSCSIRequest, 3504 satIOContext); 3505 break; 3506 3507 case SCSIOPC_READ_16: 3508 status = smsatRead16( smRoot, 3509 smIORequest, 3510 smDeviceHandle, 3511 smSCSIRequest, 3512 satIOContext); 3513 break; 3514 3515 case SCSIOPC_WRITE_6: 3516 status = smsatWrite6( smRoot, 3517 smIORequest, 3518 smDeviceHandle, 3519 smSCSIRequest, 3520 satIOContext); 3521 break; 3522 3523 case SCSIOPC_WRITE_12: 3524 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_12 \n")); 3525 status = smsatWrite12( smRoot, 3526 smIORequest, 3527 smDeviceHandle, 3528 smSCSIRequest, 3529 satIOContext); 3530 break; 3531 3532 case SCSIOPC_WRITE_16: 3533 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_16 \n")); 3534 status = smsatWrite16( smRoot, 3535 smIORequest, 3536 smDeviceHandle, 3537 smSCSIRequest, 3538 satIOContext); 3539 break; 3540 3541 case SCSIOPC_VERIFY_10: 3542 status = smsatVerify10( smRoot, 3543 smIORequest, 3544 smDeviceHandle, 3545 smSCSIRequest, 3546 satIOContext); 3547 break; 3548 3549 case SCSIOPC_VERIFY_12: 3550 SM_DBG5(("smsatIOStart: SCSIOPC_VERIFY_12\n")); 3551 status = smsatVerify12( smRoot, 3552 smIORequest, 3553 smDeviceHandle, 3554 smSCSIRequest, 3555 satIOContext); 3556 break; 3557 3558 case SCSIOPC_VERIFY_16: 3559 SM_DBG5(("smsatIOStart: SCSIOPC_VERIFY_16\n")); 3560 status = smsatVerify16( smRoot, 3561 smIORequest, 3562 smDeviceHandle, 3563 smSCSIRequest, 3564 satIOContext); 3565 break; 3566 3567 case SCSIOPC_TEST_UNIT_READY: 3568 status = smsatTestUnitReady( smRoot, 3569 smIORequest, 3570 smDeviceHandle, 3571 smSCSIRequest, 3572 satIOContext); 3573 break; 3574 3575 case SCSIOPC_INQUIRY: 3576 status = smsatInquiry( smRoot, 3577 smIORequest, 3578 smDeviceHandle, 3579 smSCSIRequest, 3580 satIOContext); 3581 break; 3582 3583 case SCSIOPC_REQUEST_SENSE: 3584 status = smsatRequestSense( smRoot, 3585 smIORequest, 3586 smDeviceHandle, 3587 smSCSIRequest, 3588 satIOContext); 3589 break; 3590 3591 case SCSIOPC_MODE_SENSE_6: 3592 status = smsatModeSense6( smRoot, 3593 smIORequest, 3594 smDeviceHandle, 3595 smSCSIRequest, 3596 satIOContext); 3597 break; 3598 3599 case SCSIOPC_MODE_SENSE_10: 3600 status = smsatModeSense10( smRoot, 3601 smIORequest, 3602 smDeviceHandle, 3603 smSCSIRequest, 3604 satIOContext); 3605 break; 3606 3607 case SCSIOPC_READ_CAPACITY_10: 3608 status = smsatReadCapacity10( smRoot, 3609 smIORequest, 3610 smDeviceHandle, 3611 smSCSIRequest, 3612 satIOContext); 3613 break; 3614 3615 case SCSIOPC_READ_CAPACITY_16: 3616 status = smsatReadCapacity16( smRoot, 3617 smIORequest, 3618 smDeviceHandle, 3619 smSCSIRequest, 3620 satIOContext); 3621 break; 3622 3623 3624 case SCSIOPC_REPORT_LUN: 3625 status = smsatReportLun( smRoot, 3626 smIORequest, 3627 smDeviceHandle, 3628 smSCSIRequest, 3629 satIOContext); 3630 break; 3631 3632 case SCSIOPC_FORMAT_UNIT: 3633 SM_DBG5(("smsatIOStart: SCSIOPC_FORMAT_UNIT\n")); 3634 status = smsatFormatUnit( smRoot, 3635 smIORequest, 3636 smDeviceHandle, 3637 smSCSIRequest, 3638 satIOContext); 3639 break; 3640 3641 case SCSIOPC_SEND_DIAGNOSTIC: 3642 SM_DBG5(("smsatIOStart: SCSIOPC_SEND_DIAGNOSTIC\n")); 3643 status = smsatSendDiagnostic( smRoot, 3644 smIORequest, 3645 smDeviceHandle, 3646 smSCSIRequest, 3647 satIOContext); 3648 break; 3649 3650 case SCSIOPC_START_STOP_UNIT: 3651 SM_DBG5(("smsatIOStart: SCSIOPC_START_STOP_UNIT\n")); 3652 status = smsatStartStopUnit( smRoot, 3653 smIORequest, 3654 smDeviceHandle, 3655 smSCSIRequest, 3656 satIOContext); 3657 break; 3658 3659 case SCSIOPC_WRITE_SAME_10: 3660 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_SAME_10\n")); 3661 status = smsatWriteSame10( smRoot, 3662 smIORequest, 3663 smDeviceHandle, 3664 smSCSIRequest, 3665 satIOContext); 3666 break; 3667 3668 case SCSIOPC_WRITE_SAME_16: /* no support due to transfer length(sector count) */ 3669 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_SAME_16\n")); 3670 status = smsatWriteSame16( smRoot, 3671 smIORequest, 3672 smDeviceHandle, 3673 smSCSIRequest, 3674 satIOContext); 3675 break; 3676 3677 case SCSIOPC_LOG_SENSE: 3678 SM_DBG5(("smsatIOStart: SCSIOPC_LOG_SENSE\n")); 3679 status = smsatLogSense( smRoot, 3680 smIORequest, 3681 smDeviceHandle, 3682 smSCSIRequest, 3683 satIOContext); 3684 break; 3685 3686 case SCSIOPC_MODE_SELECT_6: 3687 SM_DBG5(("smsatIOStart: SCSIOPC_MODE_SELECT_6\n")); 3688 status = smsatModeSelect6( smRoot, 3689 smIORequest, 3690 smDeviceHandle, 3691 smSCSIRequest, 3692 satIOContext); 3693 break; 3694 3695 case SCSIOPC_MODE_SELECT_10: 3696 SM_DBG5(("smsatIOStart: SCSIOPC_MODE_SELECT_10\n")); 3697 status = smsatModeSelect10( smRoot, 3698 smIORequest, 3699 smDeviceHandle, 3700 smSCSIRequest, 3701 satIOContext); 3702 break; 3703 3704 case SCSIOPC_SYNCHRONIZE_CACHE_10: /* on error what to return, sharing CB with 3705 satSynchronizeCache16 */ 3706 SM_DBG5(("smsatIOStart: SCSIOPC_SYNCHRONIZE_CACHE_10\n")); 3707 status = smsatSynchronizeCache10( smRoot, 3708 smIORequest, 3709 smDeviceHandle, 3710 smSCSIRequest, 3711 satIOContext); 3712 break; 3713 3714 case SCSIOPC_SYNCHRONIZE_CACHE_16:/* on error what to return, sharing CB with 3715 satSynchronizeCache16 */ 3716 3717 SM_DBG5(("smsatIOStart: SCSIOPC_SYNCHRONIZE_CACHE_16\n")); 3718 status = smsatSynchronizeCache16( smRoot, 3719 smIORequest, 3720 smDeviceHandle, 3721 smSCSIRequest, 3722 satIOContext); 3723 break; 3724 3725 case SCSIOPC_WRITE_AND_VERIFY_10: /* single write and multiple writes */ 3726 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_10\n")); 3727 status = smsatWriteAndVerify10( smRoot, 3728 smIORequest, 3729 smDeviceHandle, 3730 smSCSIRequest, 3731 satIOContext); 3732 break; 3733 3734 case SCSIOPC_WRITE_AND_VERIFY_12: 3735 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_12\n")); 3736 status = smsatWriteAndVerify12( smRoot, 3737 smIORequest, 3738 smDeviceHandle, 3739 smSCSIRequest, 3740 satIOContext); 3741 break; 3742 3743 case SCSIOPC_WRITE_AND_VERIFY_16: 3744 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_16\n")); 3745 status = smsatWriteAndVerify16( smRoot, 3746 smIORequest, 3747 smDeviceHandle, 3748 smSCSIRequest, 3749 satIOContext); 3750 3751 break; 3752 3753 case SCSIOPC_READ_MEDIA_SERIAL_NUMBER: 3754 SM_DBG5(("smsatIOStart: SCSIOPC_READ_MEDIA_SERIAL_NUMBER\n")); 3755 status = smsatReadMediaSerialNumber( smRoot, 3756 smIORequest, 3757 smDeviceHandle, 3758 smSCSIRequest, 3759 satIOContext); 3760 3761 break; 3762 3763 case SCSIOPC_READ_BUFFER: 3764 SM_DBG5(("smsatIOStart: SCSIOPC_READ_BUFFER\n")); 3765 status = smsatReadBuffer( smRoot, 3766 smIORequest, 3767 smDeviceHandle, 3768 smSCSIRequest, 3769 satIOContext); 3770 3771 break; 3772 3773 case SCSIOPC_WRITE_BUFFER: 3774 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_BUFFER\n")); 3775 status = smsatWriteBuffer( smRoot, 3776 smIORequest, 3777 smDeviceHandle, 3778 smSCSIRequest, 3779 satIOContext); 3780 3781 break; 3782 3783 case SCSIOPC_REASSIGN_BLOCKS: 3784 SM_DBG5(("smsatIOStart: SCSIOPC_REASSIGN_BLOCKS\n")); 3785 status = smsatReassignBlocks( smRoot, 3786 smIORequest, 3787 smDeviceHandle, 3788 smSCSIRequest, 3789 satIOContext); 3790 3791 break; 3792 3793 case SCSIOPC_ATA_PASS_THROUGH12: /* fall through */ 3794 case SCSIOPC_ATA_PASS_THROUGH16: 3795 SM_DBG5(("smsatIOStart: SCSIOPC_ATA_PASS_THROUGH\n")); 3796 status = smsatPassthrough( smRoot, 3797 smIORequest, 3798 smDeviceHandle, 3799 smSCSIRequest, 3800 satIOContext); 3801 break; 3802 3803 default: 3804 /* Not implemented SCSI cmd, set up error response */ 3805 SM_DBG1(("smsatIOStart: unsupported SCSI cdb[0]=0x%x did=%d !!!\n", 3806 scsiCmnd->cdb[0], pSatDevData->id)); 3807 3808 smsatSetSensePayload( pSense, 3809 SCSI_SNSKEY_ILLEGAL_REQUEST, 3810 0, 3811 SCSI_SNSCODE_INVALID_COMMAND, 3812 satIOContext); 3813 3814 /*smEnqueueIO(smRoot, satIOContext);*/ 3815 3816 tdsmIOCompletedCB( smRoot, 3817 smIORequest, 3818 smIOSuccess, 3819 SCSI_STAT_CHECK_CONDITION, 3820 satIOContext->pSmSenseData, 3821 satIOContext->interruptContext ); 3822 status = SM_RC_SUCCESS; 3823 3824 break; 3825 3826 } /* end switch */ 3827 } 3828 3829 if (status == SM_RC_BUSY || status == SM_RC_DEVICE_BUSY) 3830 { 3831 SM_DBG1(("smsatIOStart: BUSY did %d!!!\n", pSatDevData->id)); 3832 SM_DBG2(("smsatIOStart: LL is busy or target queue is full\n")); 3833 SM_DBG2(("smsatIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO )); 3834 SM_DBG2(("smsatIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO)); 3835 pSatIntIo = satIOContext->satIntIoContext; 3836 3837 /*smEnqueueIO(smRoot, satIOContext);*/ 3838 3839 /* interal structure free */ 3840 smsatFreeIntIoResource( smRoot, 3841 pSatDevData, 3842 pSatIntIo); 3843 } 3844 3845 return status; 3846 } 3847 3848 osGLOBAL void 3849 smsatSetSensePayload( 3850 smScsiRspSense_t *pSense, 3851 bit8 SnsKey, 3852 bit32 SnsInfo, 3853 bit16 SnsCode, 3854 smSatIOContext_t *satIOContext) 3855 { 3856 /* for fixed format sense data, SPC-4, p37 */ 3857 bit32 i; 3858 bit32 senseLength; 3859 bit8 tmp = 0; 3860 3861 SM_DBG2(("smsatSetSensePayload: start\n")); 3862 3863 senseLength = sizeof(smScsiRspSense_t); 3864 3865 /* zero out the data area */ 3866 for (i=0;i< senseLength;i++) 3867 { 3868 ((bit8*)pSense)[i] = 0; 3869 } 3870 3871 /* 3872 * SCSI Sense Data part of response data 3873 */ 3874 pSense->snsRespCode = 0x70; /* 0xC0 == vendor specific */ 3875 /* 0x70 == standard current error */ 3876 pSense->senseKey = SnsKey; 3877 /* 3878 * Put sense info in scsi order format 3879 */ 3880 pSense->info[0] = (bit8)((SnsInfo >> 24) & 0xff); 3881 pSense->info[1] = (bit8)((SnsInfo >> 16) & 0xff); 3882 pSense->info[2] = (bit8)((SnsInfo >> 8) & 0xff); 3883 pSense->info[3] = (bit8)((SnsInfo) & 0xff); 3884 pSense->addSenseLen = 11; /* fixed size of sense data = 18 */ 3885 pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF); 3886 pSense->senseQual = (bit8)(SnsCode & 0xFF); 3887 /* 3888 * Set pointer in scsi status 3889 */ 3890 switch(SnsKey) 3891 { 3892 /* 3893 * set illegal request sense key specific error in cdb, no bit pointer 3894 */ 3895 case SCSI_SNSKEY_ILLEGAL_REQUEST: 3896 pSense->skeySpecific[0] = 0xC8; 3897 break; 3898 3899 default: 3900 break; 3901 } 3902 /* setting sense data length */ 3903 if (satIOContext != agNULL) 3904 { 3905 satIOContext->pSmSenseData->senseLen = 18; 3906 } 3907 else 3908 { 3909 SM_DBG1(("smsatSetSensePayload: satIOContext is NULL!!!\n")); 3910 } 3911 3912 /* Only for SCSI_SNSCODE_ATA_PASS_THROUGH_INFORMATION_AVAILABLE */ 3913 if (SnsCode == SCSI_SNSCODE_ATA_PASS_THROUGH_INFORMATION_AVAILABLE) 3914 { 3915 /* filling in COMMAND-SPECIFIC INFORMATION */ 3916 tmp = satIOContext->extend << 7 | satIOContext->Sector_Cnt_Upper_Nonzero << 6 | satIOContext->LBA_Upper_Nonzero << 5; 3917 SM_DBG3(("smsatSetSensePayload: extend 0x%x Sector_Cnt_Upper_Nonzero 0x%x LBA_Upper_Nonzero 0x%x\n", 3918 satIOContext->extend, satIOContext->Sector_Cnt_Upper_Nonzero, satIOContext->LBA_Upper_Nonzero)); 3919 SM_DBG3(("smsatSetSensePayload: tmp 0x%x\n", tmp)); 3920 pSense->cmdSpecific[0] = tmp; 3921 pSense->cmdSpecific[1] = satIOContext->LBAHigh07; 3922 pSense->cmdSpecific[2] = satIOContext->LBAMid07; 3923 pSense->cmdSpecific[3] = satIOContext->LBALow07; 3924 // smhexdump("smsatSetSensePayload: cmdSpecific",(bit8 *)pSense->cmdSpecific, 4); 3925 // smhexdump("smsatSetSensePayload: info",(bit8 *)pSense->info, 4); 3926 3927 } 3928 return; 3929 } 3930 3931 /***************************************************************************** 3932 *! \brief smsatDecodeSATADeviceType 3933 * 3934 * This routine decodes ATA signature 3935 * 3936 * \param pSignature: ATA signature 3937 * 3938 * 3939 * \return: 3940 * TRUE if ATA signature 3941 * FALSE otherwise 3942 * 3943 *****************************************************************************/ 3944 /* 3945 ATA p65 3946 PM p65 3947 SATAII p79, p80 3948 */ 3949 GLOBAL bit32 3950 smsatDecodeSATADeviceType( 3951 bit8 *pSignature 3952 ) 3953 { 3954 bit32 deviceType = UNKNOWN_DEVICE; 3955 3956 if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01 3957 && (pSignature)[2] == 0x00 && (pSignature)[3] == 0x00 3958 && (pSignature)[4] == 0xA0 ) /* this is the signature of a Hitachi SATA HDD*/ 3959 { 3960 deviceType = SATA_ATA_DEVICE; 3961 } 3962 else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01 3963 && (pSignature)[2] == 0x00 && (pSignature)[3] == 0x00 3964 && (pSignature)[4] == 0x00 ) 3965 { 3966 deviceType = SATA_ATA_DEVICE; 3967 } 3968 else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01 3969 && (pSignature)[2] == 0x14 && (pSignature)[3] == 0xEB 3970 && ( (pSignature)[4] == 0x00 || (pSignature)[4] == 0x10) ) 3971 { 3972 deviceType = SATA_ATAPI_DEVICE; 3973 } 3974 else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01 3975 && (pSignature)[2] == 0x69 && (pSignature)[3] == 0x96 3976 && (pSignature)[4] == 0x00 ) 3977 { 3978 deviceType = SATA_PM_DEVICE; 3979 } 3980 else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01 3981 && (pSignature)[2] == 0x3C && (pSignature)[3] == 0xC3 3982 && (pSignature)[4] == 0x00 ) 3983 { 3984 deviceType = SATA_SEMB_DEVICE; 3985 } 3986 else if ( (pSignature)[0] == 0xFF && (pSignature)[1] == 0xFF 3987 && (pSignature)[2] == 0xFF && (pSignature)[3] == 0xFF 3988 && (pSignature)[4] == 0xFF ) 3989 { 3990 deviceType = SATA_SEMB_WO_SEP_DEVICE; 3991 } 3992 3993 return deviceType; 3994 } 3995 3996 3997 /*****************************************************************************/ 3998 /*! \brief SAT implementation for ATAPI Packet Command. 3999 * 4000 * SAT implementation for ATAPI Packet and send FIS request to LL layer. 4001 * 4002 * \param tiRoot: Pointer to TISA initiator driver/port instance. 4003 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 4004 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 4005 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 4006 * \param smSatIOContext_t: Pointer to the SAT IO Context 4007 * 4008 * \return If command is started successfully 4009 * - \e smIOSuccess: I/O request successfully initiated. 4010 * - \e smIOBusy: No resources available, try again later. 4011 * - \e smIONoDevice: Invalid device handle. 4012 * - \e smIOError: Other errors. 4013 */ 4014 /*****************************************************************************/ 4015 osGLOBAL bit32 4016 smsatPacket( 4017 smRoot_t *smRoot, 4018 smIORequest_t *smIORequest, 4019 smDeviceHandle_t *smDeviceHandle, 4020 smScsiInitiatorRequest_t *smScsiRequest, 4021 smSatIOContext_t *satIOContext 4022 ) 4023 { 4024 bit32 status; 4025 bit32 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT; 4026 smDeviceData_t *pSatDevData; 4027 smIniScsiCmnd_t *scsiCmnd; 4028 agsaFisRegHostToDevice_t *fis; 4029 4030 pSatDevData = satIOContext->pSatDevData; 4031 scsiCmnd = &smScsiRequest->scsiCmnd; 4032 fis = satIOContext->pFis; 4033 4034 SM_DBG3(("smsatPacket: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n", 4035 scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3], 4036 scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7], 4037 scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11])); 4038 4039 fis->h.fisType = 0x27; /* Reg host to device */ 4040 fis->h.c_pmPort = 0x80; /* C Bit is set 1*/ 4041 fis->h.command = SAT_PACKET; /* 0xA0 */ 4042 if (pSatDevData->satDMADIRSupport) /* DMADIR enabled*/ 4043 { 4044 fis->h.features = (smScsiRequest->dataDirection == smDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */ 4045 } 4046 else 4047 { 4048 fis->h.features = 0; /* FIS reserve */ 4049 } 4050 4051 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 4052 { 4053 /*DMA transfer mode*/ 4054 fis->h.features |= 0x01; 4055 } 4056 else 4057 { 4058 /*PIO transfer mode*/ 4059 fis->h.features |= 0x0; 4060 } 4061 /* Byte count low and byte count high */ 4062 if ( scsiCmnd->expDataLength > 0xFFFF ) 4063 { 4064 fis->d.lbaMid = 0xFF; /* FIS LBA (15:8 ) */ 4065 fis->d.lbaHigh = 0xFF; /* FIS LBA (23:16) */ 4066 } 4067 else 4068 { 4069 fis->d.lbaMid = (bit8)scsiCmnd->expDataLength; /* FIS LBA (15:8 ) */ 4070 fis->d.lbaHigh = (bit8)(scsiCmnd->expDataLength>>8); /* FIS LBA (23:16) */ 4071 } 4072 4073 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 4074 fis->d.device = 0; /* FIS LBA (27:24) and FIS LBA mode */ 4075 fis->d.lbaLowExp = 0; 4076 fis->d.lbaMidExp = 0; 4077 fis->d.lbaHighExp = 0; 4078 fis->d.featuresExp = 0; 4079 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 4080 fis->d.sectorCountExp = 0; 4081 fis->d.reserved4 = 0; 4082 fis->d.control = 0; /* FIS HOB bit clear */ 4083 fis->d.reserved5 = 0; 4084 4085 satIOContext->ATACmd = SAT_PACKET; 4086 4087 if (smScsiRequest->dataDirection == smDirectionIn) 4088 { 4089 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT; 4090 } 4091 else 4092 { 4093 agRequestType = AGSA_SATA_PROTOCOL_H2D_PKT; 4094 } 4095 4096 satIOContext->satCompleteCB = &smsatPacketCB; 4097 4098 /* 4099 * Prepare SGL and send FIS to LL layer. 4100 */ 4101 satIOContext->reqType = agRequestType; /* Save it */ 4102 4103 status = smsataLLIOStart(smRoot, 4104 smIORequest, 4105 smDeviceHandle, 4106 smScsiRequest, 4107 satIOContext); 4108 4109 SM_DBG3(("smsatPacket: return\n")); 4110 return (status); 4111 } 4112 4113 /*****************************************************************************/ 4114 /*! \brief SAT implementation for smsatSetFeaturePIO. 4115 * 4116 * This function creates Set Features fis and sends the request to LL layer 4117 * 4118 * \param tiRoot: Pointer to TISA initiator driver/port instance. 4119 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 4120 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 4121 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 4122 * \param smSatIOContext_t: Pointer to the SAT IO Context 4123 * 4124 * \return If command is started successfully 4125 * - \e smIOSuccess: I/O request successfully initiated. 4126 * - \e smIOBusy: No resources available, try again later. 4127 * - \e smIONoDevice: Invalid device handle. 4128 * - \e smIOError: Other errors. 4129 */ 4130 /*****************************************************************************/ 4131 osGLOBAL bit32 4132 smsatSetFeaturesPIO( 4133 smRoot_t *smRoot, 4134 smIORequest_t *smIORequest, 4135 smDeviceHandle_t *smDeviceHandle, 4136 smScsiInitiatorRequest_t *smScsiRequest, 4137 smSatIOContext_t *satIOContext 4138 ) 4139 { 4140 bit32 status = SM_RC_FAILURE; 4141 bit32 agRequestType; 4142 agsaFisRegHostToDevice_t *fis; 4143 4144 fis = satIOContext->pFis; 4145 SM_DBG2(("smsatSetFeaturesPIO: start\n")); 4146 /* 4147 * Send the Set Features command. 4148 */ 4149 fis->h.fisType = 0x27; /* Reg host to device */ 4150 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4151 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 4152 fis->h.features = 0x03; /* set transfer mode */ 4153 fis->d.lbaLow = 0; 4154 fis->d.lbaMid = 0; 4155 fis->d.lbaHigh = 0; 4156 fis->d.device = 0; 4157 fis->d.lbaLowExp = 0; 4158 fis->d.lbaMidExp = 0; 4159 fis->d.lbaHighExp = 0; 4160 fis->d.featuresExp = 0; 4161 fis->d.sectorCountExp = 0; 4162 fis->d.reserved4 = 0; 4163 fis->d.control = 0; /* FIS HOB bit clear */ 4164 fis->d.reserved5 = 0; 4165 4166 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 4167 4168 /* Initialize CB for SATA completion. 4169 */ 4170 fis->d.sectorCount = 0x0C; /*enable PIO transfer mode */ 4171 satIOContext->satCompleteCB = &smsatSetFeaturesPIOCB; 4172 4173 /* 4174 * Prepare SGL and send FIS to LL layer. 4175 */ 4176 satIOContext->reqType = agRequestType; /* Save it */ 4177 4178 status = smsataLLIOStart( smRoot, 4179 smIORequest, 4180 smDeviceHandle, 4181 smScsiRequest, 4182 satIOContext); 4183 4184 SM_DBG2(("smsatSetFeaturesPIO: return\n")); 4185 /* debugging code */ 4186 if (smIORequest->tdData == smIORequest->smData) 4187 { 4188 SM_DBG1(("smsatSetFeaturesPIO: incorrect smIORequest\n")); 4189 } 4190 4191 return status; 4192 } 4193 /*****************************************************************************/ 4194 /*! \brief SAT implementation for SCSI REQUEST SENSE to ATAPI device. 4195 * 4196 * SAT implementation for SCSI REQUEST SENSE. 4197 * 4198 * \param tiRoot: Pointer to TISA initiator driver/port instance. 4199 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 4200 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 4201 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 4202 * \param smSatIOContext_t: Pointer to the SAT IO Context 4203 * 4204 * \return If command is started successfully 4205 * - \e smIOSuccess: I/O request successfully initiated. 4206 * - \e smIOBusy: No resources available, try again later. 4207 * - \e smIONoDevice: Invalid device handle. 4208 * - \e smIOError: Other errors. 4209 */ 4210 /*****************************************************************************/ 4211 osGLOBAL bit32 4212 smsatRequestSenseForATAPI( 4213 smRoot_t *smRoot, 4214 smIORequest_t *smIORequest, 4215 smDeviceHandle_t *smDeviceHandle, 4216 smScsiInitiatorRequest_t *smScsiRequest, 4217 smSatIOContext_t *satIOContext 4218 ) 4219 { 4220 bit32 status; 4221 bit32 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT; 4222 smDeviceData_t *pSatDevData; 4223 smIniScsiCmnd_t *scsiCmnd; 4224 agsaFisRegHostToDevice_t *fis; 4225 4226 pSatDevData = satIOContext->pSatDevData; 4227 scsiCmnd = &smScsiRequest->scsiCmnd; 4228 fis = satIOContext->pFis; 4229 4230 scsiCmnd->cdb[0] = SCSIOPC_REQUEST_SENSE; 4231 scsiCmnd->cdb[1] = 0; 4232 scsiCmnd->cdb[2] = 0; 4233 scsiCmnd->cdb[3] = 0; 4234 scsiCmnd->cdb[4] = (bit8)scsiCmnd->expDataLength; 4235 scsiCmnd->cdb[5] = 0; 4236 SM_DBG3(("smsatRequestSenseForATAPI: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n", 4237 scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3], 4238 scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7], 4239 scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11])); 4240 4241 fis->h.fisType = 0x27; /* Reg host to device */ 4242 fis->h.c_pmPort = 0x80; /* C Bit is set 1*/ 4243 fis->h.command = SAT_PACKET; /* 0xA0 */ 4244 if (pSatDevData->satDMADIRSupport) /* DMADIR enabled*/ 4245 { 4246 fis->h.features = (smScsiRequest->dataDirection == smDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */ 4247 } 4248 else 4249 { 4250 fis->h.features = 0; /* FIS reserve */ 4251 } 4252 4253 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 4254 { 4255 fis->h.features |= 0x01; 4256 } 4257 else 4258 { 4259 fis->h.features |= 0x0; 4260 } 4261 4262 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 4263 fis->d.lbaMid = (bit8)scsiCmnd->expDataLength; /* FIS LBA (15:8 ) */ 4264 fis->d.lbaHigh = (bit8)(scsiCmnd->expDataLength>>8); /* FIS LBA (23:16) */ 4265 fis->d.device = 0; /* FIS LBA (27:24) and FIS LBA mode */ 4266 fis->d.lbaLowExp = 0; 4267 fis->d.lbaMidExp = 0; 4268 fis->d.lbaHighExp = 0; 4269 fis->d.featuresExp = 0; 4270 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 4271 fis->d.sectorCountExp = 0; 4272 fis->d.reserved4 = 0; 4273 fis->d.control = 0; /* FIS HOB bit clear */ 4274 fis->d.reserved5 = 0; 4275 4276 satIOContext->ATACmd = SAT_PACKET; 4277 4278 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT; 4279 4280 4281 satIOContext->satCompleteCB = &smsatRequestSenseForATAPICB; 4282 4283 /* 4284 * Prepare SGL and send FIS to LL layer. 4285 */ 4286 satIOContext->reqType = agRequestType; /* Save it */ 4287 4288 status = smsataLLIOStart( smRoot, 4289 smIORequest, 4290 smDeviceHandle, 4291 smScsiRequest, 4292 satIOContext); 4293 4294 SM_DBG3(("smsatRequestSenseForATAPI: return\n")); 4295 return (status); 4296 } 4297 /*****************************************************************************/ 4298 /*! \brief SAT implementation for smsatDeviceReset. 4299 * 4300 * This function creates DEVICE RESET fis and sends the request to LL layer 4301 * 4302 * \param smRoot: Pointer to TISA initiator driver/port instance. 4303 * \param smIORequest: Pointer to TISA I/O request context for this I/O. 4304 * \param smDeviceHandle: Pointer to TISA device handle for this I/O. 4305 * \param smScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 4306 * \param smSatIOContext_t: Pointer to the SAT IO Context 4307 * 4308 * \return If command is started successfully 4309 * - \e smIOSuccess: I/O request successfully initiated. 4310 * - \e smIOBusy: No resources available, try again later. 4311 * - \e smIONoDevice: Invalid device handle. 4312 * - \e smIOError: Other errors. 4313 */ 4314 /*****************************************************************************/ 4315 osGLOBAL bit32 4316 smsatDeviceReset( 4317 smRoot_t *smRoot, 4318 smIORequest_t *smIORequest, 4319 smDeviceHandle_t *smDeviceHandle, 4320 smScsiInitiatorRequest_t *smScsiRequest, 4321 smSatIOContext_t *satIOContext 4322 ) 4323 { 4324 bit32 status; 4325 bit32 agRequestType; 4326 agsaFisRegHostToDevice_t *fis; 4327 4328 fis = satIOContext->pFis; 4329 SM_DBG3(("smsatDeviceReset: start\n")); 4330 /* 4331 * Send the Execute Device Diagnostic command. 4332 */ 4333 fis->h.fisType = 0x27; /* Reg host to device */ 4334 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4335 fis->h.command = SAT_DEVICE_RESET; /* 0x08 */ 4336 fis->h.features = 0; 4337 fis->d.lbaLow = 0; 4338 fis->d.lbaMid = 0; 4339 fis->d.lbaHigh = 0; 4340 fis->d.device = 0; 4341 fis->d.lbaLowExp = 0; 4342 fis->d.lbaMidExp = 0; 4343 fis->d.lbaHighExp = 0; 4344 fis->d.featuresExp = 0; 4345 fis->d.sectorCount = 0; 4346 fis->d.sectorCountExp = 0; 4347 fis->d.reserved4 = 0; 4348 fis->d.control = 0; /* FIS HOB bit clear */ 4349 fis->d.reserved5 = 0; 4350 4351 agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET; 4352 4353 /* Initialize CB for SATA completion. 4354 */ 4355 satIOContext->satCompleteCB = &smsatDeviceResetCB; 4356 4357 /* 4358 * Prepare SGL and send FIS to LL layer. 4359 */ 4360 satIOContext->reqType = agRequestType; /* Save it */ 4361 4362 status = smsataLLIOStart( smRoot, 4363 smIORequest, 4364 smDeviceHandle, 4365 smScsiRequest, 4366 satIOContext); 4367 4368 SM_DBG3(("smsatDeviceReset: return\n")); 4369 4370 return status; 4371 } 4372 4373 4374 /*****************************************************************************/ 4375 /*! \brief SAT implementation for smsatExecuteDeviceDiagnostic. 4376 * 4377 * This function creates Execute Device Diagnostic fis and sends the request to LL layer 4378 * 4379 * \param smRoot: Pointer to TISA initiator driver/port instance. 4380 * \param smIORequest: Pointer to TISA I/O request context for this I/O. 4381 * \param smDeviceHandle: Pointer to TISA device handle for this I/O. 4382 * \param smScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 4383 * \param smSatIOContext_t: Pointer to the SAT IO Context 4384 * 4385 * \return If command is started successfully 4386 * - \e smIOSuccess: I/O request successfully initiated. 4387 * - \e smIOBusy: No resources available, try again later. 4388 * - \e smIONoDevice: Invalid device handle. 4389 * - \e smIOError: Other errors. 4390 */ 4391 /*****************************************************************************/ 4392 osGLOBAL bit32 4393 smsatExecuteDeviceDiagnostic( 4394 smRoot_t *smRoot, 4395 smIORequest_t *smIORequest, 4396 smDeviceHandle_t *smDeviceHandle, 4397 smScsiInitiatorRequest_t *smScsiRequest, 4398 smSatIOContext_t *satIOContext 4399 ) 4400 { 4401 bit32 status; 4402 bit32 agRequestType; 4403 agsaFisRegHostToDevice_t *fis; 4404 4405 fis = satIOContext->pFis; 4406 SM_DBG3(("smsatExecuteDeviceDiagnostic: start\n")); 4407 /* 4408 * Send the Execute Device Diagnostic command. 4409 */ 4410 fis->h.fisType = 0x27; /* Reg host to device */ 4411 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4412 fis->h.command = SAT_EXECUTE_DEVICE_DIAGNOSTIC; /* 0x90 */ 4413 fis->h.features = 0; 4414 fis->d.lbaLow = 0; 4415 fis->d.lbaMid = 0; 4416 fis->d.lbaHigh = 0; 4417 fis->d.device = 0; 4418 fis->d.lbaLowExp = 0; 4419 fis->d.lbaMidExp = 0; 4420 fis->d.lbaHighExp = 0; 4421 fis->d.featuresExp = 0; 4422 fis->d.sectorCount = 0; 4423 fis->d.sectorCountExp = 0; 4424 fis->d.reserved4 = 0; 4425 fis->d.control = 0; /* FIS HOB bit clear */ 4426 fis->d.reserved5 = 0; 4427 4428 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 4429 4430 /* Initialize CB for SATA completion. 4431 */ 4432 satIOContext->satCompleteCB = &smsatExecuteDeviceDiagnosticCB; 4433 4434 /* 4435 * Prepare SGL and send FIS to LL layer. 4436 */ 4437 satIOContext->reqType = agRequestType; /* Save it */ 4438 4439 status = smsataLLIOStart( smRoot, 4440 smIORequest, 4441 smDeviceHandle, 4442 smScsiRequest, 4443 satIOContext); 4444 4445 SM_DBG3(("smsatExecuteDeviceDiagnostic: return\n")); 4446 4447 return status; 4448 } 4449 4450 4451 osGLOBAL void 4452 smsatSetDeferredSensePayload( 4453 smScsiRspSense_t *pSense, 4454 bit8 SnsKey, 4455 bit32 SnsInfo, 4456 bit16 SnsCode, 4457 smSatIOContext_t *satIOContext 4458 ) 4459 { 4460 SM_DBG2(("smsatSetDeferredSensePayload: start\n")); 4461 return; 4462 } 4463 4464 4465 GLOBAL bit32 4466 smsatRead6( 4467 smRoot_t *smRoot, 4468 smIORequest_t *smIORequest, 4469 smDeviceHandle_t *smDeviceHandle, 4470 smScsiInitiatorRequest_t *smScsiRequest, 4471 smSatIOContext_t *satIOContext 4472 ) 4473 { 4474 bit32 status; 4475 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 4476 smDeviceData_t *pSatDevData; 4477 smScsiRspSense_t *pSense; 4478 smIniScsiCmnd_t *scsiCmnd; 4479 agsaFisRegHostToDevice_t *fis; 4480 bit32 lba = 0; 4481 bit16 tl = 0; 4482 4483 pSense = satIOContext->pSense; 4484 pSatDevData = satIOContext->pSatDevData; 4485 scsiCmnd = &smScsiRequest->scsiCmnd; 4486 fis = satIOContext->pFis; 4487 4488 SM_DBG2(("smsatRead6: start\n")); 4489 4490 /* no FUA checking since read6 */ 4491 4492 4493 /* checking CONTROL */ 4494 /* NACA == 1 or LINK == 1*/ 4495 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 4496 { 4497 smsatSetSensePayload( pSense, 4498 SCSI_SNSKEY_ILLEGAL_REQUEST, 4499 0, 4500 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 4501 satIOContext); 4502 4503 /*smEnqueueIO(smRoot, satIOContext);*/ 4504 4505 tdsmIOCompletedCB( smRoot, 4506 smIORequest, 4507 smIOSuccess, 4508 SCSI_STAT_CHECK_CONDITION, 4509 satIOContext->pSmSenseData, 4510 satIOContext->interruptContext ); 4511 4512 SM_DBG1(("smsatRead6: return control!!!\n")); 4513 return SM_RC_SUCCESS; 4514 } 4515 4516 /* cbd6; computing LBA and transfer length */ 4517 lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2)) 4518 + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3]; 4519 tl = scsiCmnd->cdb[4]; 4520 4521 /* Table 34, 9.1, p 46 */ 4522 /* 4523 note: As of 2/10/2006, no support for DMA QUEUED 4524 */ 4525 4526 /* 4527 Table 34, 9.1, p 46, b 4528 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 4529 return check condition 4530 */ 4531 if (pSatDevData->satNCQ != agTRUE && 4532 pSatDevData->sat48BitSupport != agTRUE 4533 ) 4534 { 4535 if (lba > SAT_TR_LBA_LIMIT - 1) 4536 { 4537 smsatSetSensePayload( pSense, 4538 SCSI_SNSKEY_ILLEGAL_REQUEST, 4539 0, 4540 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 4541 satIOContext); 4542 4543 /*smEnqueueIO(smRoot, satIOContext);*/ 4544 4545 tdsmIOCompletedCB( smRoot, 4546 smIORequest, 4547 smIOSuccess, 4548 SCSI_STAT_CHECK_CONDITION, 4549 satIOContext->pSmSenseData, 4550 satIOContext->interruptContext ); 4551 4552 SM_DBG1(("smsatRead6: return LBA out of range!!!\n")); 4553 return SM_RC_SUCCESS; 4554 } 4555 } 4556 4557 /* case 1 and 2 */ 4558 if (lba + tl <= SAT_TR_LBA_LIMIT) 4559 { 4560 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 4561 { 4562 /* case 2 */ 4563 /* READ DMA*/ 4564 SM_DBG5(("smsatRead6: case 2\n")); 4565 4566 4567 fis->h.fisType = 0x27; /* Reg host to device */ 4568 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4569 fis->h.command = SAT_READ_DMA; /* 0xC8 */ 4570 fis->h.features = 0; /* FIS reserve */ 4571 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 4572 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 4573 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 4574 fis->d.device = 0x40; /* FIS LBA mode */ 4575 fis->d.lbaLowExp = 0; 4576 fis->d.lbaMidExp = 0; 4577 fis->d.lbaHighExp = 0; 4578 fis->d.featuresExp = 0; 4579 if (tl == 0) 4580 { 4581 /* temporary fix */ 4582 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */ 4583 } 4584 else 4585 { 4586 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 4587 } 4588 fis->d.sectorCountExp = 0; 4589 fis->d.reserved4 = 0; 4590 fis->d.control = 0; /* FIS HOB bit clear */ 4591 fis->d.reserved5 = 0; 4592 4593 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 4594 } 4595 else 4596 { 4597 /* case 1 */ 4598 /* READ SECTORS for easier implemetation */ 4599 SM_DBG5(("smsatRead6: case 1\n")); 4600 4601 fis->h.fisType = 0x27; /* Reg host to device */ 4602 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4603 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 4604 fis->h.features = 0; /* FIS reserve */ 4605 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 4606 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 4607 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 4608 fis->d.device = 0x40; /* FIS LBA mode */ 4609 fis->d.lbaLowExp = 0; 4610 fis->d.lbaMidExp = 0; 4611 fis->d.lbaHighExp = 0; 4612 fis->d.featuresExp = 0; 4613 if (tl == 0) 4614 { 4615 /* temporary fix */ 4616 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */ 4617 } 4618 else 4619 { 4620 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 4621 } 4622 fis->d.sectorCountExp = 0; 4623 fis->d.reserved4 = 0; 4624 fis->d.control = 0; /* FIS HOB bit clear */ 4625 fis->d.reserved5 = 0; 4626 4627 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 4628 4629 } 4630 } 4631 4632 /* case 3 and 4 */ 4633 if (pSatDevData->sat48BitSupport == agTRUE) 4634 { 4635 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 4636 { 4637 /* case 3 */ 4638 /* READ DMA EXT only */ 4639 SM_DBG5(("smsatRead6: case 3\n")); 4640 fis->h.fisType = 0x27; /* Reg host to device */ 4641 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4642 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */ 4643 fis->h.features = 0; /* FIS reserve */ 4644 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 4645 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 4646 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 4647 fis->d.device = 0x40; /* FIS LBA mode set */ 4648 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 4649 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4650 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4651 fis->d.featuresExp = 0; /* FIS reserve */ 4652 if (tl == 0) 4653 { 4654 /* sector count is 256, 0x100*/ 4655 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 4656 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */ 4657 } 4658 else 4659 { 4660 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 4661 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 4662 } 4663 fis->d.reserved4 = 0; 4664 fis->d.control = 0; /* FIS HOB bit clear */ 4665 fis->d.reserved5 = 0; 4666 4667 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 4668 } 4669 else 4670 { 4671 /* case 4 */ 4672 /* READ SECTORS EXT for easier implemetation */ 4673 SM_DBG5(("smsatRead6: case 4\n")); 4674 4675 fis->h.fisType = 0x27; /* Reg host to device */ 4676 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4677 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 4678 fis->h.features = 0; /* FIS reserve */ 4679 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 4680 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 4681 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 4682 fis->d.device = 0x40; /* FIS LBA mode set */ 4683 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 4684 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4685 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4686 fis->d.featuresExp = 0; /* FIS reserve */ 4687 if (tl == 0) 4688 { 4689 /* sector count is 256, 0x100*/ 4690 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 4691 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */ 4692 } 4693 else 4694 { 4695 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 4696 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 4697 } 4698 fis->d.reserved4 = 0; 4699 fis->d.control = 0; /* FIS HOB bit clear */ 4700 fis->d.reserved5 = 0; 4701 4702 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 4703 } 4704 } 4705 4706 /* case 5 */ 4707 if (pSatDevData->satNCQ == agTRUE) 4708 { 4709 /* READ FPDMA QUEUED */ 4710 if (pSatDevData->sat48BitSupport != agTRUE) 4711 { 4712 /* sanity check */ 4713 SM_DBG1(("smsatRead6: case 5 !!! error NCQ but 28 bit address support!!!\n")); 4714 smsatSetSensePayload( pSense, 4715 SCSI_SNSKEY_ILLEGAL_REQUEST, 4716 0, 4717 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 4718 satIOContext); 4719 4720 /*smEnqueueIO(smRoot, satIOContext);*/ 4721 4722 tdsmIOCompletedCB( smRoot, 4723 smIORequest, 4724 smIOSuccess, 4725 SCSI_STAT_CHECK_CONDITION, 4726 satIOContext->pSmSenseData, 4727 satIOContext->interruptContext ); 4728 return SM_RC_SUCCESS; 4729 } 4730 SM_DBG5(("smsatRead6: case 5\n")); 4731 4732 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */ 4733 4734 fis->h.fisType = 0x27; /* Reg host to device */ 4735 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4736 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */ 4737 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 4738 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 4739 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 4740 fis->d.device = 0x40; /* FIS FUA clear */ 4741 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 4742 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4743 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4744 if (tl == 0) 4745 { 4746 /* sector count is 256, 0x100*/ 4747 fis->h.features = 0; /* FIS sector count (7:0) */ 4748 fis->d.featuresExp = 0x01; /* FIS sector count (15:8) */ 4749 } 4750 else 4751 { 4752 fis->h.features = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 4753 fis->d.featuresExp = 0; /* FIS sector count (15:8) */ 4754 } 4755 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 4756 fis->d.sectorCountExp = 0; 4757 fis->d.reserved4 = 0; 4758 fis->d.control = 0; /* FIS HOB bit clear */ 4759 fis->d.reserved5 = 0; 4760 4761 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ; 4762 } 4763 4764 /* Initialize CB for SATA completion. 4765 */ 4766 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB; 4767 4768 /* 4769 * Prepare SGL and send FIS to LL layer. 4770 */ 4771 satIOContext->reqType = agRequestType; /* Save it */ 4772 4773 status = smsataLLIOStart( smRoot, 4774 smIORequest, 4775 smDeviceHandle, 4776 smScsiRequest, 4777 satIOContext); 4778 return (status); 4779 4780 } 4781 4782 osGLOBAL FORCEINLINE bit32 4783 smsatRead10( 4784 smRoot_t *smRoot, 4785 smIORequest_t *smIORequest, 4786 smDeviceHandle_t *smDeviceHandle, 4787 smScsiInitiatorRequest_t *smScsiRequest, 4788 smSatIOContext_t *satIOContext 4789 ) 4790 { 4791 smDeviceData_t *pSatDevData = satIOContext->pSatDevData; 4792 smScsiRspSense_t *pSense = satIOContext->pSense; 4793 smIniScsiCmnd_t *scsiCmnd = &smScsiRequest->scsiCmnd; 4794 agsaFisRegHostToDevice_t *fis = satIOContext->pFis; 4795 4796 bit32 status; 4797 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 4798 bit32 lba = 0; 4799 bit32 tl = 0; 4800 bit32 LoopNum = 1; 4801 bit8 LBA[8]; 4802 bit8 TL[8]; 4803 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 4804 4805 SM_DBG2(("smsatRead10: start\n")); 4806 SM_DBG2(("smsatRead10: pSatDevData did=%d\n", pSatDevData->id)); 4807 // smhexdump("smsatRead10", (bit8 *)scsiCmnd->cdb, 10); 4808 4809 /* checking FUA_NV */ 4810 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 4811 { 4812 smsatSetSensePayload( pSense, 4813 SCSI_SNSKEY_ILLEGAL_REQUEST, 4814 0, 4815 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 4816 satIOContext); 4817 4818 /*smEnqueueIO(smRoot, satIOContext);*/ 4819 4820 tdsmIOCompletedCB( smRoot, 4821 smIORequest, 4822 smIOSuccess, 4823 SCSI_STAT_CHECK_CONDITION, 4824 satIOContext->pSmSenseData, 4825 satIOContext->interruptContext ); 4826 4827 SM_DBG1(("smsatRead10: return FUA_NV!!!\n")); 4828 return SM_RC_SUCCESS; 4829 4830 } 4831 4832 /* checking CONTROL */ 4833 /* NACA == 1 or LINK == 1*/ 4834 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 4835 { 4836 smsatSetSensePayload( pSense, 4837 SCSI_SNSKEY_ILLEGAL_REQUEST, 4838 0, 4839 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 4840 satIOContext); 4841 4842 /*smEnqueueIO(smRoot, satIOContext);*/ 4843 4844 tdsmIOCompletedCB( smRoot, 4845 smIORequest, 4846 smIOSuccess, 4847 SCSI_STAT_CHECK_CONDITION, 4848 satIOContext->pSmSenseData, 4849 satIOContext->interruptContext ); 4850 4851 SM_DBG1(("smsatRead10: return control!!!\n")); 4852 return SM_RC_SUCCESS; 4853 } 4854 /* 4855 sm_memset(LBA, 0, sizeof(LBA)); 4856 sm_memset(TL, 0, sizeof(TL)); 4857 */ 4858 /* do not use memcpy due to indexing in LBA and TL */ 4859 LBA[0] = 0; /* MSB */ 4860 LBA[1] = 0; 4861 LBA[2] = 0; 4862 LBA[3] = 0; 4863 LBA[4] = scsiCmnd->cdb[2]; 4864 LBA[5] = scsiCmnd->cdb[3]; 4865 LBA[6] = scsiCmnd->cdb[4]; 4866 LBA[7] = scsiCmnd->cdb[5]; /* LSB */ 4867 4868 TL[0] = 0; 4869 TL[1] = 0; 4870 TL[2] = 0; 4871 TL[3] = 0; 4872 TL[4] = 0; 4873 TL[5] = 0; 4874 TL[6] = scsiCmnd->cdb[7]; 4875 TL[7] = scsiCmnd->cdb[8]; /* LSB */ 4876 4877 4878 /* cbd10; computing LBA and transfer length */ 4879 lba = (scsiCmnd->cdb[2] << 24) + (scsiCmnd->cdb[3] << 16) 4880 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 4881 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 4882 4883 4884 SM_DBG5(("smsatRead10: lba %d functioned lba %d\n", lba, smsatComputeCDB10LBA(satIOContext))); 4885 SM_DBG5(("smsatRead10: lba 0x%x functioned lba 0x%x\n", lba, smsatComputeCDB10LBA(satIOContext))); 4886 SM_DBG5(("smsatRead10: tl %d functioned tl %d\n", tl, smsatComputeCDB10TL(satIOContext))); 4887 4888 /* Table 34, 9.1, p 46 */ 4889 /* 4890 note: As of 2/10/2006, no support for DMA QUEUED 4891 */ 4892 4893 /* 4894 Table 34, 9.1, p 46, b 4895 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 4896 return check condition 4897 */ 4898 4899 if (pSatDevData->satNCQ != agTRUE && 4900 pSatDevData->sat48BitSupport != agTRUE 4901 ) 4902 { 4903 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 4904 if (AllChk) 4905 { 4906 SM_DBG1(("smsatRead10: return LBA out of range, not EXT!!!\n")); 4907 smsatSetSensePayload( pSense, 4908 SCSI_SNSKEY_ILLEGAL_REQUEST, 4909 0, 4910 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 4911 satIOContext); 4912 4913 /*smEnqueueIO(smRoot, satIOContext);*/ 4914 4915 tdsmIOCompletedCB( smRoot, 4916 smIORequest, 4917 smIOSuccess, 4918 SCSI_STAT_CHECK_CONDITION, 4919 satIOContext->pSmSenseData, 4920 satIOContext->interruptContext ); 4921 4922 return SM_RC_SUCCESS; 4923 } 4924 } 4925 else 4926 { 4927 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 4928 if (AllChk) 4929 { 4930 SM_DBG1(("smsatRead10: return LBA out of range, EXT!!!\n")); 4931 smsatSetSensePayload( pSense, 4932 SCSI_SNSKEY_ILLEGAL_REQUEST, 4933 0, 4934 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 4935 satIOContext); 4936 4937 /*smEnqueueIO(smRoot, satIOContext);*/ 4938 4939 tdsmIOCompletedCB( smRoot, 4940 smIORequest, 4941 smIOSuccess, 4942 SCSI_STAT_CHECK_CONDITION, 4943 satIOContext->pSmSenseData, 4944 satIOContext->interruptContext ); 4945 4946 return SM_RC_SUCCESS; 4947 } 4948 } 4949 /* case 5 */ 4950 if (pSatDevData->satNCQ == agTRUE) 4951 { 4952 /* READ FPDMA QUEUED */ 4953 if (pSatDevData->sat48BitSupport != agTRUE) 4954 { 4955 SM_DBG1(("smsatRead10: case 5 !!! error NCQ but 28 bit address support!!!\n")); 4956 smsatSetSensePayload( pSense, 4957 SCSI_SNSKEY_ILLEGAL_REQUEST, 4958 0, 4959 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 4960 satIOContext); 4961 4962 /*smEnqueueIO(smRoot, satIOContext);*/ 4963 4964 tdsmIOCompletedCB( smRoot, 4965 smIORequest, 4966 smIOSuccess, 4967 SCSI_STAT_CHECK_CONDITION, 4968 satIOContext->pSmSenseData, 4969 satIOContext->interruptContext ); 4970 return SM_RC_SUCCESS; 4971 } 4972 4973 SM_DBG6(("smsatRead10: case 5\n")); 4974 4975 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */ 4976 4977 fis->h.fisType = 0x27; /* Reg host to device */ 4978 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4979 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */ 4980 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 4981 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 4982 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 4983 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 4984 4985 /* Check FUA bit */ 4986 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK) 4987 fis->d.device = 0xC0; /* FIS FUA set */ 4988 else 4989 fis->d.device = 0x40; /* FIS FUA clear */ 4990 4991 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 4992 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4993 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4994 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 4995 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 4996 fis->d.sectorCountExp = 0; 4997 fis->d.reserved4 = 0; 4998 fis->d.control = 0; /* FIS HOB bit clear */ 4999 fis->d.reserved5 = 0; 5000 5001 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ; 5002 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED; 5003 } 5004 else if (pSatDevData->sat48BitSupport == agTRUE) /* case 3 and 4 */ 5005 { 5006 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 5007 { 5008 /* case 3 */ 5009 /* READ DMA EXT */ 5010 SM_DBG5(("smsatRead10: case 3\n")); 5011 fis->h.fisType = 0x27; /* Reg host to device */ 5012 5013 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5014 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */ 5015 fis->h.features = 0; /* FIS reserve */ 5016 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 5017 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 5018 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 5019 fis->d.device = 0x40; /* FIS LBA mode set */ 5020 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 5021 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 5022 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 5023 fis->d.featuresExp = 0; /* FIS reserve */ 5024 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 5025 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 5026 fis->d.reserved4 = 0; 5027 fis->d.control = 0; /* FIS HOB bit clear */ 5028 fis->d.reserved5 = 0; 5029 5030 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 5031 satIOContext->ATACmd = SAT_READ_DMA_EXT; 5032 5033 } 5034 else 5035 { 5036 /* case 4 */ 5037 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/ 5038 /* READ SECTORS EXT for easier implemetation */ 5039 SM_DBG5(("smsatRead10: case 4\n")); 5040 fis->h.fisType = 0x27; /* Reg host to device */ 5041 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5042 5043 /* Check FUA bit */ 5044 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK) 5045 { 5046 5047 /* for now, no support for FUA */ 5048 smsatSetSensePayload( pSense, 5049 SCSI_SNSKEY_ILLEGAL_REQUEST, 5050 0, 5051 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5052 satIOContext); 5053 5054 /*smEnqueueIO(smRoot, satIOContext);*/ 5055 5056 tdsmIOCompletedCB( smRoot, 5057 smIORequest, 5058 smIOSuccess, 5059 SCSI_STAT_CHECK_CONDITION, 5060 satIOContext->pSmSenseData, 5061 satIOContext->interruptContext ); 5062 return SM_RC_SUCCESS; 5063 } 5064 5065 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 5066 5067 fis->h.features = 0; /* FIS reserve */ 5068 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 5069 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 5070 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 5071 fis->d.device = 0x40; /* FIS LBA mode set */ 5072 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 5073 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 5074 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 5075 fis->d.featuresExp = 0; /* FIS reserve */ 5076 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 5077 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 5078 fis->d.reserved4 = 0; 5079 fis->d.control = 0; /* FIS HOB bit clear */ 5080 fis->d.reserved5 = 0; 5081 5082 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 5083 satIOContext->ATACmd = SAT_READ_SECTORS_EXT; 5084 } 5085 } 5086 else/* case 1 and 2 */ 5087 { 5088 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 5089 { 5090 /* case 2 */ 5091 /* READ DMA*/ 5092 /* in case that we can't fit the transfer length, we need to make it fit by sending multiple ATA cmnds */ 5093 SM_DBG5(("smsatRead10: case 2\n")); 5094 5095 5096 fis->h.fisType = 0x27; /* Reg host to device */ 5097 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5098 fis->h.command = SAT_READ_DMA; /* 0xC8 */ 5099 fis->h.features = 0; /* FIS reserve */ 5100 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 5101 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 5102 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 5103 fis->d.device = 5104 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 5105 fis->d.lbaLowExp = 0; 5106 fis->d.lbaMidExp = 0; 5107 fis->d.lbaHighExp = 0; 5108 fis->d.featuresExp = 0; 5109 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 5110 fis->d.sectorCountExp = 0; 5111 fis->d.reserved4 = 0; 5112 fis->d.control = 0; /* FIS HOB bit clear */ 5113 fis->d.reserved5 = 0; 5114 5115 5116 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 5117 satIOContext->ATACmd = SAT_READ_DMA; 5118 } 5119 else 5120 { 5121 /* case 1 */ 5122 /* READ MULTIPLE or READ SECTOR(S) */ 5123 /* READ SECTORS for easier implemetation */ 5124 /* in case that we can't fit the transfer length, we need to make it fit by sending multiple ATA cmnds */ 5125 SM_DBG5(("smsatRead10: case 1\n")); 5126 5127 fis->h.fisType = 0x27; /* Reg host to device */ 5128 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5129 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 5130 fis->h.features = 0; /* FIS reserve */ 5131 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 5132 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 5133 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 5134 fis->d.device = 5135 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 5136 fis->d.lbaLowExp = 0; 5137 fis->d.lbaMidExp = 0; 5138 fis->d.lbaHighExp = 0; 5139 fis->d.featuresExp = 0; 5140 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 5141 fis->d.sectorCountExp = 0; 5142 fis->d.reserved4 = 0; 5143 fis->d.control = 0; /* FIS HOB bit clear */ 5144 fis->d.reserved5 = 0; 5145 5146 5147 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 5148 satIOContext->ATACmd = SAT_READ_SECTORS; 5149 } 5150 } 5151 // smhexdump("satRead10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t)); 5152 5153 /* saves the current LBA and orginal TL */ 5154 satIOContext->currentLBA = lba; 5155 satIOContext->OrgTL = tl; 5156 5157 /* 5158 computing number of loop and remainder for tl 5159 0xFF in case not ext 5160 0xFFFF in case EXT 5161 */ 5162 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 5163 { 5164 LoopNum = smsatComputeLoopNum(tl, 0x100); 5165 } 5166 else 5167 { 5168 /* SAT_READ_FPDMA_QUEUED */ 5169 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 5170 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 5171 } 5172 5173 satIOContext->LoopNum = LoopNum; 5174 5175 /* Initialize CB for SATA completion. 5176 */ 5177 if (LoopNum == 1) 5178 { 5179 SM_DBG5(("smsatRead10: NON CHAINED data\n")); 5180 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB; 5181 } 5182 else 5183 { 5184 SM_DBG2(("smsatRead10: CHAINED data!!!\n")); 5185 5186 /* re-setting tl */ 5187 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 5188 { 5189 fis->d.sectorCount = 0x0; 5190 smsatSplitSGL(smRoot, 5191 smIORequest, 5192 smDeviceHandle, 5193 smScsiRequest, 5194 satIOContext, 5195 NON_BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0x100 * 0x200 */ 5196 (satIOContext->OrgTL)*SATA_SECTOR_SIZE, 5197 agTRUE); 5198 } 5199 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 5200 { 5201 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 5202 fis->d.sectorCount = 0xFF; 5203 fis->d.sectorCountExp = 0xFF; 5204 smsatSplitSGL(smRoot, 5205 smIORequest, 5206 smDeviceHandle, 5207 smScsiRequest, 5208 satIOContext, 5209 BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */ 5210 (satIOContext->OrgTL)*SATA_SECTOR_SIZE, 5211 agTRUE); 5212 } 5213 else 5214 { 5215 /* SAT_READ_FPDMA_QUEUED */ 5216 fis->h.features = 0xFF; 5217 fis->d.featuresExp = 0xFF; 5218 smsatSplitSGL(smRoot, 5219 smIORequest, 5220 smDeviceHandle, 5221 smScsiRequest, 5222 satIOContext, 5223 BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */ 5224 (satIOContext->OrgTL)*SATA_SECTOR_SIZE, 5225 agTRUE); 5226 } 5227 5228 /* chained data */ 5229 satIOContext->satCompleteCB = &smsatChainedDataIOCB; 5230 5231 } 5232 5233 /* 5234 * Prepare SGL and send FIS to LL layer. 5235 */ 5236 satIOContext->reqType = agRequestType; /* Save it */ 5237 5238 status = smsataLLIOStart( smRoot, 5239 smIORequest, 5240 smDeviceHandle, 5241 smScsiRequest, 5242 satIOContext); 5243 5244 SM_DBG5(("smsatRead10: return\n")); 5245 return (status); 5246 5247 } 5248 5249 osGLOBAL bit32 5250 smsatRead12( 5251 smRoot_t *smRoot, 5252 smIORequest_t *smIORequest, 5253 smDeviceHandle_t *smDeviceHandle, 5254 smScsiInitiatorRequest_t *smScsiRequest, 5255 smSatIOContext_t *satIOContext 5256 ) 5257 { 5258 bit32 status; 5259 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 5260 smDeviceData_t *pSatDevData; 5261 smScsiRspSense_t *pSense; 5262 smIniScsiCmnd_t *scsiCmnd; 5263 agsaFisRegHostToDevice_t *fis; 5264 bit32 lba = 0; 5265 bit32 tl = 0; 5266 bit32 LoopNum = 1; 5267 bit8 LBA[8]; 5268 bit8 TL[8]; 5269 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 5270 5271 pSense = satIOContext->pSense; 5272 pSatDevData = satIOContext->pSatDevData; 5273 scsiCmnd = &smScsiRequest->scsiCmnd; 5274 fis = satIOContext->pFis; 5275 5276 SM_DBG5(("smsatRead12: start\n")); 5277 5278 /* checking FUA_NV */ 5279 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 5280 { 5281 smsatSetSensePayload( pSense, 5282 SCSI_SNSKEY_ILLEGAL_REQUEST, 5283 0, 5284 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5285 satIOContext); 5286 5287 /*smEnqueueIO(smRoot, satIOContext);*/ 5288 5289 tdsmIOCompletedCB( smRoot, 5290 smIORequest, 5291 smIOSuccess, 5292 SCSI_STAT_CHECK_CONDITION, 5293 satIOContext->pSmSenseData, 5294 satIOContext->interruptContext ); 5295 5296 SM_DBG1(("smsatRead12: return FUA_NV!!!\n")); 5297 return SM_RC_SUCCESS; 5298 5299 } 5300 5301 /* checking CONTROL */ 5302 /* NACA == 1 or LINK == 1*/ 5303 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) ) 5304 { 5305 smsatSetSensePayload( pSense, 5306 SCSI_SNSKEY_ILLEGAL_REQUEST, 5307 0, 5308 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5309 satIOContext); 5310 5311 /*smEnqueueIO(smRoot, satIOContext);*/ 5312 5313 tdsmIOCompletedCB( smRoot, 5314 smIORequest, 5315 smIOSuccess, 5316 SCSI_STAT_CHECK_CONDITION, 5317 satIOContext->pSmSenseData, 5318 satIOContext->interruptContext ); 5319 5320 SM_DBG1(("smsatRead12: return control!!!\n")); 5321 return SM_RC_SUCCESS; 5322 } 5323 5324 sm_memset(LBA, 0, sizeof(LBA)); 5325 sm_memset(TL, 0, sizeof(TL)); 5326 5327 /* do not use memcpy due to indexing in LBA and TL */ 5328 LBA[0] = 0; /* MSB */ 5329 LBA[1] = 0; 5330 LBA[2] = 0; 5331 LBA[3] = 0; 5332 LBA[4] = scsiCmnd->cdb[2]; 5333 LBA[5] = scsiCmnd->cdb[3]; 5334 LBA[6] = scsiCmnd->cdb[4]; 5335 LBA[7] = scsiCmnd->cdb[5]; /* LSB */ 5336 5337 TL[0] = 0; /* MSB */ 5338 TL[1] = 0; 5339 TL[2] = 0; 5340 TL[3] = 0; 5341 TL[4] = scsiCmnd->cdb[6]; 5342 TL[5] = scsiCmnd->cdb[7]; 5343 TL[6] = scsiCmnd->cdb[8]; 5344 TL[7] = scsiCmnd->cdb[9]; /* LSB */ 5345 5346 5347 lba = smsatComputeCDB12LBA(satIOContext); 5348 tl = smsatComputeCDB12TL(satIOContext); 5349 5350 /* Table 34, 9.1, p 46 */ 5351 /* 5352 note: As of 2/10/2006, no support for DMA QUEUED 5353 */ 5354 5355 /* 5356 Table 34, 9.1, p 46, b 5357 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 5358 return check condition 5359 */ 5360 if (pSatDevData->satNCQ != agTRUE && 5361 pSatDevData->sat48BitSupport != agTRUE 5362 ) 5363 { 5364 5365 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 5366 if (AllChk) 5367 { 5368 SM_DBG1(("smsatRead12: return LBA out of range, not EXT!!!\n")); 5369 smsatSetSensePayload( pSense, 5370 SCSI_SNSKEY_ILLEGAL_REQUEST, 5371 0, 5372 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 5373 satIOContext); 5374 5375 /*smEnqueueIO(smRoot, satIOContext);*/ 5376 5377 tdsmIOCompletedCB( smRoot, 5378 smIORequest, 5379 smIOSuccess, 5380 SCSI_STAT_CHECK_CONDITION, 5381 satIOContext->pSmSenseData, 5382 satIOContext->interruptContext ); 5383 5384 return SM_RC_SUCCESS; 5385 } 5386 } 5387 else 5388 { 5389 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 5390 if (AllChk) 5391 { 5392 SM_DBG1(("smsatRead12: return LBA out of range, EXT!!!\n")); 5393 smsatSetSensePayload( pSense, 5394 SCSI_SNSKEY_ILLEGAL_REQUEST, 5395 0, 5396 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 5397 satIOContext); 5398 5399 /*smEnqueueIO(smRoot, satIOContext);*/ 5400 5401 tdsmIOCompletedCB( smRoot, 5402 smIORequest, 5403 smIOSuccess, 5404 SCSI_STAT_CHECK_CONDITION, 5405 satIOContext->pSmSenseData, 5406 satIOContext->interruptContext ); 5407 5408 return SM_RC_SUCCESS; 5409 } 5410 } 5411 5412 /* case 1 and 2 */ 5413 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 5414 { 5415 /* case 2 */ 5416 /* READ DMA*/ 5417 /* in case that we can't fit the transfer length, 5418 we need to make it fit by sending multiple ATA cmnds */ 5419 SM_DBG5(("smsatRead12: case 2\n")); 5420 5421 5422 fis->h.fisType = 0x27; /* Reg host to device */ 5423 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5424 fis->h.command = SAT_READ_DMA; /* 0xC8 */ 5425 fis->h.features = 0; /* FIS reserve */ 5426 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 5427 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 5428 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 5429 fis->d.device = 5430 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 5431 fis->d.lbaLowExp = 0; 5432 fis->d.lbaMidExp = 0; 5433 fis->d.lbaHighExp = 0; 5434 fis->d.featuresExp = 0; 5435 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 5436 fis->d.sectorCountExp = 0; 5437 fis->d.reserved4 = 0; 5438 fis->d.control = 0; /* FIS HOB bit clear */ 5439 fis->d.reserved5 = 0; 5440 5441 5442 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 5443 satIOContext->ATACmd = SAT_READ_DMA; 5444 } 5445 else 5446 { 5447 /* case 1 */ 5448 /* READ MULTIPLE or READ SECTOR(S) */ 5449 /* READ SECTORS for easier implemetation */ 5450 /* can't fit the transfer length but need to make it fit by sending multiple*/ 5451 SM_DBG5(("smsatRead12: case 1\n")); 5452 5453 fis->h.fisType = 0x27; /* Reg host to device */ 5454 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5455 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 5456 fis->h.features = 0; /* FIS reserve */ 5457 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 5458 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 5459 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 5460 fis->d.device = 5461 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 5462 fis->d.lbaLowExp = 0; 5463 fis->d.lbaMidExp = 0; 5464 fis->d.lbaHighExp = 0; 5465 fis->d.featuresExp = 0; 5466 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 5467 fis->d.sectorCountExp = 0; 5468 fis->d.reserved4 = 0; 5469 fis->d.control = 0; /* FIS HOB bit clear */ 5470 fis->d.reserved5 = 0; 5471 5472 5473 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 5474 satIOContext->ATACmd = SAT_READ_SECTORS; 5475 } 5476 5477 /* case 3 and 4 */ 5478 if (pSatDevData->sat48BitSupport == agTRUE) 5479 { 5480 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 5481 { 5482 /* case 3 */ 5483 /* READ DMA EXT */ 5484 SM_DBG5(("smsatRead12: case 3\n")); 5485 fis->h.fisType = 0x27; /* Reg host to device */ 5486 5487 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5488 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */ 5489 fis->h.features = 0; /* FIS reserve */ 5490 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 5491 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 5492 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 5493 fis->d.device = 0x40; /* FIS LBA mode set */ 5494 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 5495 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 5496 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 5497 fis->d.featuresExp = 0; /* FIS reserve */ 5498 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 5499 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 5500 fis->d.reserved4 = 0; 5501 fis->d.control = 0; /* FIS HOB bit clear */ 5502 fis->d.reserved5 = 0; 5503 5504 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 5505 satIOContext->ATACmd = SAT_READ_DMA_EXT; 5506 5507 } 5508 else 5509 { 5510 /* case 4 */ 5511 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/ 5512 /* READ SECTORS EXT for easier implemetation */ 5513 SM_DBG5(("smsatRead12: case 4\n")); 5514 fis->h.fisType = 0x27; /* Reg host to device */ 5515 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5516 5517 /* Check FUA bit */ 5518 if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK) 5519 { 5520 5521 /* for now, no support for FUA */ 5522 smsatSetSensePayload( pSense, 5523 SCSI_SNSKEY_ILLEGAL_REQUEST, 5524 0, 5525 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5526 satIOContext); 5527 5528 /*smEnqueueIO(smRoot, satIOContext);*/ 5529 5530 tdsmIOCompletedCB( smRoot, 5531 smIORequest, 5532 smIOSuccess, 5533 SCSI_STAT_CHECK_CONDITION, 5534 satIOContext->pSmSenseData, 5535 satIOContext->interruptContext ); 5536 return SM_RC_SUCCESS; 5537 } 5538 5539 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 5540 5541 fis->h.features = 0; /* FIS reserve */ 5542 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 5543 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 5544 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 5545 fis->d.device = 0x40; /* FIS LBA mode set */ 5546 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 5547 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 5548 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 5549 fis->d.featuresExp = 0; /* FIS reserve */ 5550 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 5551 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 5552 fis->d.reserved4 = 0; 5553 fis->d.control = 0; /* FIS HOB bit clear */ 5554 fis->d.reserved5 = 0; 5555 5556 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 5557 satIOContext->ATACmd = SAT_READ_SECTORS_EXT; 5558 } 5559 } 5560 5561 /* case 5 */ 5562 if (pSatDevData->satNCQ == agTRUE) 5563 { 5564 /* READ FPDMA QUEUED */ 5565 if (pSatDevData->sat48BitSupport != agTRUE) 5566 { 5567 SM_DBG1(("smsatRead12: case 5 !!! error NCQ but 28 bit address support!!!\n")); 5568 smsatSetSensePayload( pSense, 5569 SCSI_SNSKEY_ILLEGAL_REQUEST, 5570 0, 5571 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5572 satIOContext); 5573 5574 /*smEnqueueIO(smRoot, satIOContext);*/ 5575 5576 tdsmIOCompletedCB( smRoot, 5577 smIORequest, 5578 smIOSuccess, 5579 SCSI_STAT_CHECK_CONDITION, 5580 satIOContext->pSmSenseData, 5581 satIOContext->interruptContext ); 5582 return SM_RC_SUCCESS; 5583 } 5584 5585 SM_DBG6(("smsatRead12: case 5\n")); 5586 5587 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */ 5588 5589 fis->h.fisType = 0x27; /* Reg host to device */ 5590 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5591 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */ 5592 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 5593 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 5594 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 5595 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 5596 5597 /* Check FUA bit */ 5598 if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK) 5599 fis->d.device = 0xC0; /* FIS FUA set */ 5600 else 5601 fis->d.device = 0x40; /* FIS FUA clear */ 5602 5603 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 5604 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 5605 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 5606 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 5607 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 5608 fis->d.sectorCountExp = 0; 5609 fis->d.reserved4 = 0; 5610 fis->d.control = 0; /* FIS HOB bit clear */ 5611 fis->d.reserved5 = 0; 5612 5613 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ; 5614 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED; 5615 } 5616 5617 /* saves the current LBA and orginal TL */ 5618 satIOContext->currentLBA = lba; 5619 satIOContext->OrgTL = tl; 5620 5621 /* 5622 computing number of loop and remainder for tl 5623 0xFF in case not ext 5624 0xFFFF in case EXT 5625 */ 5626 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 5627 { 5628 LoopNum = smsatComputeLoopNum(tl, 0xFF); 5629 } 5630 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 5631 { 5632 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 5633 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 5634 } 5635 else 5636 { 5637 /* SAT_READ_FPDMA_QUEUEDK */ 5638 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 5639 } 5640 5641 satIOContext->LoopNum = LoopNum; 5642 5643 if (LoopNum == 1) 5644 { 5645 SM_DBG5(("smsatRead12: NON CHAINED data\n")); 5646 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB; 5647 } 5648 else 5649 { 5650 SM_DBG1(("smsatRead12: CHAINED data\n")); 5651 /* re-setting tl */ 5652 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 5653 { 5654 fis->d.sectorCount = 0xFF; 5655 } 5656 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 5657 { 5658 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 5659 fis->d.sectorCount = 0xFF; 5660 fis->d.sectorCountExp = 0xFF; 5661 } 5662 else 5663 { 5664 /* SAT_READ_FPDMA_QUEUED */ 5665 fis->h.features = 0xFF; 5666 fis->d.featuresExp = 0xFF; 5667 } 5668 5669 /* chained data */ 5670 satIOContext->satCompleteCB = &smsatChainedDataIOCB; 5671 } 5672 5673 /* 5674 * Prepare SGL and send FIS to LL layer. 5675 */ 5676 satIOContext->reqType = agRequestType; /* Save it */ 5677 5678 status = smsataLLIOStart( smRoot, 5679 smIORequest, 5680 smDeviceHandle, 5681 smScsiRequest, 5682 satIOContext); 5683 5684 SM_DBG5(("smsatRead12: return\n")); 5685 return (status); 5686 } 5687 5688 osGLOBAL bit32 5689 smsatRead16( 5690 smRoot_t *smRoot, 5691 smIORequest_t *smIORequest, 5692 smDeviceHandle_t *smDeviceHandle, 5693 smScsiInitiatorRequest_t *smScsiRequest, 5694 smSatIOContext_t *satIOContext 5695 ) 5696 { 5697 bit32 status; 5698 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 5699 smDeviceData_t *pSatDevData; 5700 smScsiRspSense_t *pSense; 5701 smIniScsiCmnd_t *scsiCmnd; 5702 agsaFisRegHostToDevice_t *fis; 5703 bit32 lba = 0; 5704 bit32 tl = 0; 5705 bit32 LoopNum = 1; 5706 bit8 LBA[8]; 5707 bit8 TL[8]; 5708 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 5709 // bit32 limitExtChk = agFALSE; /* lba limit check for bit48 addressing check */ 5710 5711 pSense = satIOContext->pSense; 5712 pSatDevData = satIOContext->pSatDevData; 5713 scsiCmnd = &smScsiRequest->scsiCmnd; 5714 fis = satIOContext->pFis; 5715 5716 SM_DBG5(("smsatRead16: start\n")); 5717 5718 /* checking FUA_NV */ 5719 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 5720 { 5721 smsatSetSensePayload( pSense, 5722 SCSI_SNSKEY_ILLEGAL_REQUEST, 5723 0, 5724 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5725 satIOContext); 5726 5727 /*smEnqueueIO(smRoot, satIOContext);*/ 5728 5729 tdsmIOCompletedCB( smRoot, 5730 smIORequest, 5731 smIOSuccess, 5732 SCSI_STAT_CHECK_CONDITION, 5733 satIOContext->pSmSenseData, 5734 satIOContext->interruptContext ); 5735 5736 SM_DBG1(("smsatRead16: return FUA_NV!!!\n")); 5737 return SM_RC_SUCCESS; 5738 5739 } 5740 5741 /* checking CONTROL */ 5742 /* NACA == 1 or LINK == 1*/ 5743 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 5744 { 5745 smsatSetSensePayload( pSense, 5746 SCSI_SNSKEY_ILLEGAL_REQUEST, 5747 0, 5748 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5749 satIOContext); 5750 5751 /*smEnqueueIO(smRoot, satIOContext);*/ 5752 5753 tdsmIOCompletedCB( smRoot, 5754 smIORequest, 5755 smIOSuccess, 5756 SCSI_STAT_CHECK_CONDITION, 5757 satIOContext->pSmSenseData, 5758 satIOContext->interruptContext ); 5759 5760 SM_DBG1(("smsatRead16: return control!!!\n")); 5761 return SM_RC_SUCCESS; 5762 } 5763 5764 5765 sm_memset(LBA, 0, sizeof(LBA)); 5766 sm_memset(TL, 0, sizeof(TL)); 5767 5768 5769 /* do not use memcpy due to indexing in LBA and TL */ 5770 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 5771 LBA[1] = scsiCmnd->cdb[3]; 5772 LBA[2] = scsiCmnd->cdb[4]; 5773 LBA[3] = scsiCmnd->cdb[5]; 5774 LBA[4] = scsiCmnd->cdb[6]; 5775 LBA[5] = scsiCmnd->cdb[7]; 5776 LBA[6] = scsiCmnd->cdb[8]; 5777 LBA[7] = scsiCmnd->cdb[9]; /* LSB */ 5778 5779 TL[0] = 0; 5780 TL[1] = 0; 5781 TL[2] = 0; 5782 TL[3] = 0; 5783 TL[4] = scsiCmnd->cdb[10]; /* MSB */ 5784 TL[5] = scsiCmnd->cdb[11]; 5785 TL[6] = scsiCmnd->cdb[12]; 5786 TL[7] = scsiCmnd->cdb[13]; /* LSB */ 5787 5788 5789 5790 5791 lba = smsatComputeCDB16LBA(satIOContext); 5792 tl = smsatComputeCDB16TL(satIOContext); 5793 5794 5795 /* Table 34, 9.1, p 46 */ 5796 /* 5797 note: As of 2/10/2006, no support for DMA QUEUED 5798 */ 5799 5800 /* 5801 Table 34, 9.1, p 46, b 5802 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 5803 return check condition 5804 */ 5805 if (pSatDevData->satNCQ != agTRUE && 5806 pSatDevData->sat48BitSupport != agTRUE 5807 ) 5808 { 5809 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 5810 if (AllChk) 5811 { 5812 SM_DBG1(("smsatRead16: return LBA out of range, not EXT!!!\n")); 5813 5814 /*smEnqueueIO(smRoot, satIOContext);*/ 5815 5816 5817 smsatSetSensePayload( pSense, 5818 SCSI_SNSKEY_ILLEGAL_REQUEST, 5819 0, 5820 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 5821 satIOContext); 5822 5823 /*smEnqueueIO(smRoot, satIOContext);*/ 5824 5825 tdsmIOCompletedCB( smRoot, 5826 smIORequest, 5827 smIOSuccess, 5828 SCSI_STAT_CHECK_CONDITION, 5829 satIOContext->pSmSenseData, 5830 satIOContext->interruptContext ); 5831 5832 return SM_RC_SUCCESS; 5833 } 5834 } 5835 else 5836 { 5837 // rangeChk = smsatAddNComparebit64(LBA, TL); 5838 5839 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 5840 5841 5842 if (AllChk) 5843 { 5844 SM_DBG1(("smsatRead16: return LBA out of range, EXT!!!\n")); 5845 smsatSetSensePayload( pSense, 5846 SCSI_SNSKEY_ILLEGAL_REQUEST, 5847 0, 5848 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 5849 satIOContext); 5850 5851 /*smEnqueueIO(smRoot, satIOContext);*/ 5852 5853 tdsmIOCompletedCB( smRoot, 5854 smIORequest, 5855 smIOSuccess, 5856 SCSI_STAT_CHECK_CONDITION, 5857 satIOContext->pSmSenseData, 5858 satIOContext->interruptContext ); 5859 5860 return SM_RC_SUCCESS; 5861 } 5862 } 5863 5864 /* case 1 and 2 */ 5865 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 5866 { 5867 /* case 2 */ 5868 /* READ DMA*/ 5869 /* in case that we can't fit the transfer length, 5870 we need to make it fit by sending multiple ATA cmnds */ 5871 SM_DBG5(("smsatRead16: case 2\n")); 5872 5873 5874 fis->h.fisType = 0x27; /* Reg host to device */ 5875 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5876 fis->h.command = SAT_READ_DMA; /* 0xC8 */ 5877 fis->h.features = 0; /* FIS reserve */ 5878 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 5879 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 5880 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 5881 fis->d.device = 5882 (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 5883 fis->d.lbaLowExp = 0; 5884 fis->d.lbaMidExp = 0; 5885 fis->d.lbaHighExp = 0; 5886 fis->d.featuresExp = 0; 5887 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 5888 fis->d.sectorCountExp = 0; 5889 fis->d.reserved4 = 0; 5890 fis->d.control = 0; /* FIS HOB bit clear */ 5891 fis->d.reserved5 = 0; 5892 5893 5894 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 5895 satIOContext->ATACmd = SAT_READ_DMA; 5896 } 5897 else 5898 { 5899 /* case 1 */ 5900 /* READ MULTIPLE or READ SECTOR(S) */ 5901 /* READ SECTORS for easier implemetation */ 5902 /* can't fit the transfer length but need to make it fit by sending multiple*/ 5903 SM_DBG5(("smsatRead16: case 1\n")); 5904 5905 fis->h.fisType = 0x27; /* Reg host to device */ 5906 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5907 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 5908 fis->h.features = 0; /* FIS reserve */ 5909 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 5910 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 5911 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 5912 fis->d.device = 5913 (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 5914 fis->d.lbaLowExp = 0; 5915 fis->d.lbaMidExp = 0; 5916 fis->d.lbaHighExp = 0; 5917 fis->d.featuresExp = 0; 5918 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 5919 fis->d.sectorCountExp = 0; 5920 fis->d.reserved4 = 0; 5921 fis->d.control = 0; /* FIS HOB bit clear */ 5922 fis->d.reserved5 = 0; 5923 5924 5925 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 5926 satIOContext->ATACmd = SAT_READ_SECTORS; 5927 } 5928 5929 /* case 3 and 4 */ 5930 if (pSatDevData->sat48BitSupport == agTRUE) 5931 { 5932 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 5933 { 5934 /* case 3 */ 5935 /* READ DMA EXT */ 5936 SM_DBG5(("smsatRead16: case 3\n")); 5937 fis->h.fisType = 0x27; /* Reg host to device */ 5938 5939 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5940 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */ 5941 fis->h.features = 0; /* FIS reserve */ 5942 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 5943 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 5944 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 5945 fis->d.device = 0x40; /* FIS LBA mode set */ 5946 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 5947 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 5948 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 5949 fis->d.featuresExp = 0; /* FIS reserve */ 5950 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 5951 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 5952 fis->d.reserved4 = 0; 5953 fis->d.control = 0; /* FIS HOB bit clear */ 5954 fis->d.reserved5 = 0; 5955 5956 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 5957 satIOContext->ATACmd = SAT_READ_DMA_EXT; 5958 5959 } 5960 else 5961 { 5962 /* case 4 */ 5963 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/ 5964 /* READ SECTORS EXT for easier implemetation */ 5965 SM_DBG5(("smsatRead16: case 4\n")); 5966 fis->h.fisType = 0x27; /* Reg host to device */ 5967 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5968 5969 /* Check FUA bit */ 5970 if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK) 5971 { 5972 /* for now, no support for FUA */ 5973 smsatSetSensePayload( pSense, 5974 SCSI_SNSKEY_ILLEGAL_REQUEST, 5975 0, 5976 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5977 satIOContext); 5978 5979 /*smEnqueueIO(smRoot, satIOContext);*/ 5980 5981 tdsmIOCompletedCB( smRoot, 5982 smIORequest, 5983 smIOSuccess, 5984 SCSI_STAT_CHECK_CONDITION, 5985 satIOContext->pSmSenseData, 5986 satIOContext->interruptContext ); 5987 return SM_RC_SUCCESS; 5988 } 5989 5990 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 5991 5992 fis->h.features = 0; /* FIS reserve */ 5993 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 5994 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 5995 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 5996 fis->d.device = 0x40; /* FIS LBA mode set */ 5997 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 5998 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 5999 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 6000 fis->d.featuresExp = 0; /* FIS reserve */ 6001 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 6002 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 6003 fis->d.reserved4 = 0; 6004 fis->d.control = 0; /* FIS HOB bit clear */ 6005 fis->d.reserved5 = 0; 6006 6007 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 6008 satIOContext->ATACmd = SAT_READ_SECTORS_EXT; 6009 } 6010 } 6011 6012 6013 /* case 5 */ 6014 if (pSatDevData->satNCQ == agTRUE) 6015 { 6016 /* READ FPDMA QUEUED */ 6017 if (pSatDevData->sat48BitSupport != agTRUE) 6018 { 6019 SM_DBG1(("smsatRead16: case 5 !!! error NCQ but 28 bit address support!!!\n")); 6020 smsatSetSensePayload( pSense, 6021 SCSI_SNSKEY_ILLEGAL_REQUEST, 6022 0, 6023 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6024 satIOContext); 6025 6026 /*smEnqueueIO(smRoot, satIOContext);*/ 6027 6028 tdsmIOCompletedCB( smRoot, 6029 smIORequest, 6030 smIOSuccess, 6031 SCSI_STAT_CHECK_CONDITION, 6032 satIOContext->pSmSenseData, 6033 satIOContext->interruptContext ); 6034 return SM_RC_SUCCESS; 6035 } 6036 6037 SM_DBG6(("smsatRead16: case 5\n")); 6038 6039 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */ 6040 6041 fis->h.fisType = 0x27; /* Reg host to device */ 6042 fis->h.c_pmPort = 0x80; /* C Bit is set */ 6043 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */ 6044 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 6045 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 6046 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 6047 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 6048 6049 /* Check FUA bit */ 6050 if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK) 6051 fis->d.device = 0xC0; /* FIS FUA set */ 6052 else 6053 fis->d.device = 0x40; /* FIS FUA clear */ 6054 6055 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 6056 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 6057 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 6058 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 6059 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 6060 fis->d.sectorCountExp = 0; 6061 fis->d.reserved4 = 0; 6062 fis->d.control = 0; /* FIS HOB bit clear */ 6063 fis->d.reserved5 = 0; 6064 6065 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ; 6066 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED; 6067 } 6068 6069 /* saves the current LBA and orginal TL */ 6070 satIOContext->currentLBA = lba; 6071 satIOContext->OrgTL = tl; 6072 6073 /* 6074 computing number of loop and remainder for tl 6075 0xFF in case not ext 6076 0xFFFF in case EXT 6077 */ 6078 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 6079 { 6080 LoopNum = smsatComputeLoopNum(tl, 0xFF); 6081 } 6082 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 6083 { 6084 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 6085 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 6086 } 6087 else 6088 { 6089 /* SAT_READ_FPDMA_QUEUEDK */ 6090 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 6091 } 6092 satIOContext->LoopNum = LoopNum; 6093 6094 if (LoopNum == 1) 6095 { 6096 SM_DBG5(("smsatRead16: NON CHAINED data\n")); 6097 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB; 6098 } 6099 else 6100 { 6101 SM_DBG1(("smsatRead16: CHAINED data!!!\n")); 6102 /* re-setting tl */ 6103 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 6104 { 6105 fis->d.sectorCount = 0xFF; 6106 } 6107 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 6108 { 6109 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 6110 fis->d.sectorCount = 0xFF; 6111 fis->d.sectorCountExp = 0xFF; 6112 } 6113 else 6114 { 6115 /* SAT_READ_FPDMA_QUEUED */ 6116 fis->h.features = 0xFF; 6117 fis->d.featuresExp = 0xFF; 6118 } 6119 6120 /* chained data */ 6121 satIOContext->satCompleteCB = &smsatChainedDataIOCB; 6122 } 6123 6124 /* 6125 * Prepare SGL and send FIS to LL layer. 6126 */ 6127 satIOContext->reqType = agRequestType; /* Save it */ 6128 6129 status = smsataLLIOStart( smRoot, 6130 smIORequest, 6131 smDeviceHandle, 6132 smScsiRequest, 6133 satIOContext); 6134 6135 SM_DBG5(("smsatRead16: return\n")); 6136 return (status); 6137 6138 } 6139 6140 osGLOBAL bit32 6141 smsatWrite6( 6142 smRoot_t *smRoot, 6143 smIORequest_t *smIORequest, 6144 smDeviceHandle_t *smDeviceHandle, 6145 smScsiInitiatorRequest_t *smScsiRequest, 6146 smSatIOContext_t *satIOContext 6147 ) 6148 { 6149 6150 bit32 status; 6151 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 6152 smDeviceData_t *pSatDevData; 6153 smScsiRspSense_t *pSense; 6154 smIniScsiCmnd_t *scsiCmnd; 6155 agsaFisRegHostToDevice_t *fis; 6156 bit32 lba = 0; 6157 bit16 tl = 0; 6158 6159 pSense = satIOContext->pSense; 6160 pSatDevData = satIOContext->pSatDevData; 6161 scsiCmnd = &smScsiRequest->scsiCmnd; 6162 fis = satIOContext->pFis; 6163 6164 SM_DBG5(("smsatWrite6: start\n")); 6165 6166 /* checking CONTROL */ 6167 /* NACA == 1 or LINK == 1*/ 6168 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 6169 { 6170 smsatSetSensePayload( pSense, 6171 SCSI_SNSKEY_ILLEGAL_REQUEST, 6172 0, 6173 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6174 satIOContext); 6175 6176 /*smEnqueueIO(smRoot, satIOContext);*/ 6177 6178 tdsmIOCompletedCB( smRoot, 6179 smIORequest, 6180 smIOSuccess, 6181 SCSI_STAT_CHECK_CONDITION, 6182 satIOContext->pSmSenseData, 6183 satIOContext->interruptContext ); 6184 6185 SM_DBG1(("smsatWrite6: return control!!!\n")); 6186 return SM_RC_SUCCESS; 6187 } 6188 6189 6190 /* cbd6; computing LBA and transfer length */ 6191 lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2)) 6192 + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3]; 6193 tl = scsiCmnd->cdb[4]; 6194 6195 6196 /* Table 34, 9.1, p 46 */ 6197 /* 6198 note: As of 2/10/2006, no support for DMA QUEUED 6199 */ 6200 6201 /* 6202 Table 34, 9.1, p 46, b 6203 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 6204 return check condition 6205 */ 6206 if (pSatDevData->satNCQ != agTRUE && 6207 pSatDevData->sat48BitSupport != agTRUE 6208 ) 6209 { 6210 if (lba > SAT_TR_LBA_LIMIT - 1) 6211 { 6212 smsatSetSensePayload( pSense, 6213 SCSI_SNSKEY_ILLEGAL_REQUEST, 6214 0, 6215 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 6216 satIOContext); 6217 6218 /*smEnqueueIO(smRoot, satIOContext);*/ 6219 6220 tdsmIOCompletedCB( smRoot, 6221 smIORequest, 6222 smIOSuccess, 6223 SCSI_STAT_CHECK_CONDITION, 6224 satIOContext->pSmSenseData, 6225 satIOContext->interruptContext ); 6226 6227 SM_DBG1(("smsatWrite6: return LBA out of range!!!\n")); 6228 return SM_RC_SUCCESS; 6229 } 6230 } 6231 6232 /* case 1 and 2 */ 6233 if (lba + tl <= SAT_TR_LBA_LIMIT) 6234 { 6235 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 6236 { 6237 /* case 2 */ 6238 /* WRITE DMA*/ 6239 SM_DBG5(("smsatWrite6: case 2\n")); 6240 6241 6242 fis->h.fisType = 0x27; /* Reg host to device */ 6243 fis->h.c_pmPort = 0x80; /* C Bit is set */ 6244 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 6245 fis->h.features = 0; /* FIS reserve */ 6246 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 6247 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 6248 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 6249 fis->d.device = 0x40; /* FIS LBA mode */ 6250 fis->d.lbaLowExp = 0; 6251 fis->d.lbaMidExp = 0; 6252 fis->d.lbaHighExp = 0; 6253 fis->d.featuresExp = 0; 6254 if (tl == 0) 6255 { 6256 /* temporary fix */ 6257 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */ 6258 } 6259 else 6260 { 6261 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 6262 } 6263 fis->d.sectorCountExp = 0; 6264 fis->d.reserved4 = 0; 6265 fis->d.control = 0; /* FIS HOB bit clear */ 6266 fis->d.reserved5 = 0; 6267 6268 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 6269 } 6270 else 6271 { 6272 /* case 1 */ 6273 /* WRITE SECTORS for easier implemetation */ 6274 SM_DBG5(("smsatWrite6: case 1\n")); 6275 6276 fis->h.fisType = 0x27; /* Reg host to device */ 6277 fis->h.c_pmPort = 0x80; /* C Bit is set */ 6278 fis->h.command = SAT_WRITE_SECTORS; /* 0xCA */ 6279 fis->h.features = 0; /* FIS reserve */ 6280 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 6281 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 6282 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 6283 fis->d.device = 0x40; /* FIS LBA mode */ 6284 fis->d.lbaLowExp = 0; 6285 fis->d.lbaMidExp = 0; 6286 fis->d.lbaHighExp = 0; 6287 fis->d.featuresExp = 0; 6288 if (tl == 0) 6289 { 6290 /* temporary fix */ 6291 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */ 6292 } 6293 else 6294 { 6295 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 6296 } 6297 fis->d.sectorCountExp = 0; 6298 fis->d.reserved4 = 0; 6299 fis->d.control = 0; /* FIS HOB bit clear */ 6300 fis->d.reserved5 = 0; 6301 6302 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 6303 6304 } 6305 } 6306 6307 /* case 3 and 4 */ 6308 if (pSatDevData->sat48BitSupport == agTRUE) 6309 { 6310 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 6311 { 6312 /* case 3 */ 6313 /* WRITE DMA EXT only */ 6314 SM_DBG5(("smsatWrite6: case 3\n")); 6315 fis->h.fisType = 0x27; /* Reg host to device */ 6316 fis->h.c_pmPort = 0x80; /* C Bit is set */ 6317 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 6318 fis->h.features = 0; /* FIS reserve */ 6319 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 6320 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 6321 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 6322 fis->d.device = 0x40; /* FIS LBA mode set */ 6323 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 6324 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 6325 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 6326 fis->d.featuresExp = 0; /* FIS reserve */ 6327 if (tl == 0) 6328 { 6329 /* sector count is 256, 0x100*/ 6330 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 6331 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */ 6332 } 6333 else 6334 { 6335 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 6336 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 6337 } 6338 fis->d.reserved4 = 0; 6339 fis->d.control = 0; /* FIS HOB bit clear */ 6340 fis->d.reserved5 = 0; 6341 6342 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 6343 } 6344 else 6345 { 6346 /* case 4 */ 6347 /* WRITE SECTORS EXT for easier implemetation */ 6348 SM_DBG5(("smsatWrite6: case 4\n")); 6349 6350 fis->h.fisType = 0x27; /* Reg host to device */ 6351 fis->h.c_pmPort = 0x80; /* C Bit is set */ 6352 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 6353 fis->h.features = 0; /* FIS reserve */ 6354 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 6355 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 6356 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 6357 fis->d.device = 0x40; /* FIS LBA mode set */ 6358 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 6359 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 6360 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 6361 fis->d.featuresExp = 0; /* FIS reserve */ 6362 if (tl == 0) 6363 { 6364 /* sector count is 256, 0x100*/ 6365 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 6366 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */ 6367 } 6368 else 6369 { 6370 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 6371 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 6372 } 6373 fis->d.reserved4 = 0; 6374 fis->d.control = 0; /* FIS HOB bit clear */ 6375 fis->d.reserved5 = 0; 6376 6377 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 6378 } 6379 } 6380 6381 /* case 5 */ 6382 if (pSatDevData->satNCQ == agTRUE) 6383 { 6384 /* WRITE FPDMA QUEUED */ 6385 if (pSatDevData->sat48BitSupport != agTRUE) 6386 { 6387 /* sanity check */ 6388 SM_DBG5(("smsatWrite6: case 5 !!! error NCQ but 28 bit address support!!!\n")); 6389 smsatSetSensePayload( pSense, 6390 SCSI_SNSKEY_ILLEGAL_REQUEST, 6391 0, 6392 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6393 satIOContext); 6394 6395 /*smEnqueueIO(smRoot, satIOContext);*/ 6396 6397 tdsmIOCompletedCB( smRoot, 6398 smIORequest, 6399 smIOSuccess, 6400 SCSI_STAT_CHECK_CONDITION, 6401 satIOContext->pSmSenseData, 6402 satIOContext->interruptContext ); 6403 return SM_RC_SUCCESS; 6404 } 6405 SM_DBG5(("smsatWrite6: case 5\n")); 6406 6407 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 6408 6409 fis->h.fisType = 0x27; /* Reg host to device */ 6410 fis->h.c_pmPort = 0x80; /* C Bit is set */ 6411 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 6412 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 6413 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 6414 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 6415 fis->d.device = 0x40; /* FIS FUA clear */ 6416 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 6417 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 6418 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 6419 if (tl == 0) 6420 { 6421 /* sector count is 256, 0x100*/ 6422 fis->h.features = 0; /* FIS sector count (7:0) */ 6423 fis->d.featuresExp = 0x01; /* FIS sector count (15:8) */ 6424 } 6425 else 6426 { 6427 fis->h.features = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 6428 fis->d.featuresExp = 0; /* FIS sector count (15:8) */ 6429 } 6430 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 6431 fis->d.sectorCountExp = 0; 6432 fis->d.reserved4 = 0; 6433 fis->d.control = 0; /* FIS HOB bit clear */ 6434 fis->d.reserved5 = 0; 6435 6436 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 6437 } 6438 6439 /* Initialize CB for SATA completion. 6440 */ 6441 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB; 6442 6443 /* 6444 * Prepare SGL and send FIS to LL layer. 6445 */ 6446 satIOContext->reqType = agRequestType; /* Save it */ 6447 6448 status = smsataLLIOStart( smRoot, 6449 smIORequest, 6450 smDeviceHandle, 6451 smScsiRequest, 6452 satIOContext); 6453 return (status); 6454 } 6455 6456 osGLOBAL FORCEINLINE bit32 6457 smsatWrite10( 6458 smRoot_t *smRoot, 6459 smIORequest_t *smIORequest, 6460 smDeviceHandle_t *smDeviceHandle, 6461 smScsiInitiatorRequest_t *smScsiRequest, 6462 smSatIOContext_t *satIOContext 6463 ) 6464 { 6465 smDeviceData_t *pSatDevData = satIOContext->pSatDevData; 6466 smScsiRspSense_t *pSense = satIOContext->pSense; 6467 smIniScsiCmnd_t *scsiCmnd = &smScsiRequest->scsiCmnd; 6468 agsaFisRegHostToDevice_t *fis = satIOContext->pFis; 6469 bit32 status = SM_RC_FAILURE; 6470 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 6471 bit32 lba = 0; 6472 bit32 tl = 0; 6473 bit32 LoopNum = 1; 6474 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 6475 bit8 LBA[8]; 6476 bit8 TL[8]; 6477 6478 SM_DBG2(("smsatWrite10: start\n")); 6479 6480 /* checking FUA_NV */ 6481 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 6482 { 6483 smsatSetSensePayload( pSense, 6484 SCSI_SNSKEY_ILLEGAL_REQUEST, 6485 0, 6486 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6487 satIOContext); 6488 6489 /*smEnqueueIO(smRoot, satIOContext);*/ 6490 6491 tdsmIOCompletedCB( smRoot, 6492 smIORequest, 6493 smIOSuccess, 6494 SCSI_STAT_CHECK_CONDITION, 6495 satIOContext->pSmSenseData, 6496 satIOContext->interruptContext ); 6497 6498 SM_DBG1(("smsatWrite10: return FUA_NV!!!\n")); 6499 return SM_RC_SUCCESS; 6500 6501 } 6502 6503 /* checking CONTROL */ 6504 /* NACA == 1 or LINK == 1*/ 6505 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 6506 { 6507 smsatSetSensePayload( pSense, 6508 SCSI_SNSKEY_ILLEGAL_REQUEST, 6509 0, 6510 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6511 satIOContext); 6512 6513 /*smEnqueueIO(smRoot, satIOContext);*/ 6514 6515 tdsmIOCompletedCB( smRoot, 6516 smIORequest, 6517 smIOSuccess, 6518 SCSI_STAT_CHECK_CONDITION, 6519 satIOContext->pSmSenseData, 6520 satIOContext->interruptContext ); 6521 6522 SM_DBG1(("smsatWrite10: return control!!!\n")); 6523 return SM_RC_SUCCESS; 6524 } 6525 /* 6526 sm_memset(LBA, 0, sizeof(LBA)); 6527 sm_memset(TL, 0, sizeof(TL)); 6528 */ 6529 /* do not use memcpy due to indexing in LBA and TL */ 6530 LBA[0] = 0; /* MSB */ 6531 LBA[1] = 0; 6532 LBA[2] = 0; 6533 LBA[3] = 0; 6534 LBA[4] = scsiCmnd->cdb[2]; 6535 LBA[5] = scsiCmnd->cdb[3]; 6536 LBA[6] = scsiCmnd->cdb[4]; 6537 LBA[7] = scsiCmnd->cdb[5]; /* LSB */ 6538 6539 TL[0] = 0; 6540 TL[1] = 0; 6541 TL[2] = 0; 6542 TL[3] = 0; 6543 TL[4] = 0; 6544 TL[5] = 0; 6545 TL[6] = scsiCmnd->cdb[7]; 6546 TL[7] = scsiCmnd->cdb[8]; /* LSB */ 6547 6548 6549 6550 /* cbd10; computing LBA and transfer length */ 6551 lba = (scsiCmnd->cdb[2] << (24)) + (scsiCmnd->cdb[3] << (16)) 6552 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 6553 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 6554 6555 SM_DBG5(("smsatWrite10: lba %d functioned lba %d\n", lba, smsatComputeCDB10LBA(satIOContext))); 6556 SM_DBG5(("smsatWrite10: tl %d functioned tl %d\n", tl, smsatComputeCDB10TL(satIOContext))); 6557 6558 /* Table 34, 9.1, p 46 */ 6559 /* 6560 note: As of 2/10/2006, no support for DMA QUEUED 6561 */ 6562 6563 /* 6564 Table 34, 9.1, p 46, b 6565 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 6566 return check condition 6567 */ 6568 if (pSatDevData->satNCQ != agTRUE && 6569 pSatDevData->sat48BitSupport != agTRUE 6570 ) 6571 { 6572 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 6573 if (AllChk) 6574 { 6575 SM_DBG1(("smsatWrite10: return LBA out of range, not EXT!!!\n")); 6576 SM_DBG1(("smsatWrite10: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3], 6577 scsiCmnd->cdb[4], scsiCmnd->cdb[5])); 6578 SM_DBG1(("smsatWrite10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT)); 6579 smsatSetSensePayload( pSense, 6580 SCSI_SNSKEY_ILLEGAL_REQUEST, 6581 0, 6582 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 6583 satIOContext); 6584 6585 /*smEnqueueIO(smRoot, satIOContext);*/ 6586 6587 tdsmIOCompletedCB( smRoot, 6588 smIORequest, 6589 smIOSuccess, 6590 SCSI_STAT_CHECK_CONDITION, 6591 satIOContext->pSmSenseData, 6592 satIOContext->interruptContext ); 6593 6594 return SM_RC_SUCCESS; 6595 } 6596 } 6597 else 6598 { 6599 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 6600 if (AllChk) 6601 { 6602 SM_DBG1(("smsatWrite10: return LBA out of range, EXT!!!\n")); 6603 smsatSetSensePayload( pSense, 6604 SCSI_SNSKEY_ILLEGAL_REQUEST, 6605 0, 6606 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 6607 satIOContext); 6608 6609 /*smEnqueueIO(smRoot, satIOContext);*/ 6610 6611 tdsmIOCompletedCB( smRoot, 6612 smIORequest, 6613 smIOSuccess, 6614 SCSI_STAT_CHECK_CONDITION, 6615 satIOContext->pSmSenseData, 6616 satIOContext->interruptContext ); 6617 6618 return SM_RC_SUCCESS; 6619 } 6620 6621 } 6622 6623 /* case 5 */ 6624 if (pSatDevData->satNCQ == agTRUE) 6625 { 6626 /* WRITE FPDMA QUEUED */ 6627 if (pSatDevData->sat48BitSupport != agTRUE) 6628 { 6629 SM_DBG1(("smsatWrite10: case 5 !!! error NCQ but 28 bit address support!!!\n")); 6630 smsatSetSensePayload( pSense, 6631 SCSI_SNSKEY_ILLEGAL_REQUEST, 6632 0, 6633 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6634 satIOContext); 6635 6636 /*smEnqueueIO(smRoot, satIOContext);*/ 6637 6638 tdsmIOCompletedCB( smRoot, 6639 smIORequest, 6640 smIOSuccess, 6641 SCSI_STAT_CHECK_CONDITION, 6642 satIOContext->pSmSenseData, 6643 satIOContext->interruptContext ); 6644 return SM_RC_SUCCESS; 6645 } 6646 SM_DBG6(("smsatWrite10: case 5\n")); 6647 6648 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 6649 6650 fis->h.fisType = 0x27; /* Reg host to device */ 6651 fis->h.c_pmPort = 0x80; /* C Bit is set */ 6652 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 6653 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 6654 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 6655 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 6656 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 6657 6658 /* Check FUA bit */ 6659 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK) 6660 fis->d.device = 0xC0; /* FIS FUA set */ 6661 else 6662 fis->d.device = 0x40; /* FIS FUA clear */ 6663 6664 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 6665 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 6666 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 6667 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 6668 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 6669 fis->d.sectorCountExp = 0; 6670 fis->d.reserved4 = 0; 6671 fis->d.control = 0; /* FIS HOB bit clear */ 6672 fis->d.reserved5 = 0; 6673 6674 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 6675 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 6676 } 6677 /* case 3 and 4 */ 6678 else if (pSatDevData->sat48BitSupport == agTRUE) 6679 { 6680 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 6681 { 6682 /* case 3 */ 6683 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 6684 SM_DBG5(("smsatWrite10: case 3\n")); 6685 fis->h.fisType = 0x27; /* Reg host to device */ 6686 fis->h.c_pmPort = 0x80; /* C Bit is set */ 6687 6688 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 6689 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 6690 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 6691 6692 fis->h.features = 0; /* FIS reserve */ 6693 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 6694 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 6695 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 6696 fis->d.device = 0x40; /* FIS LBA mode set */ 6697 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 6698 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 6699 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 6700 fis->d.featuresExp = 0; /* FIS reserve */ 6701 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 6702 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 6703 fis->d.reserved4 = 0; 6704 fis->d.control = 0; /* FIS HOB bit clear */ 6705 fis->d.reserved5 = 0; 6706 6707 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 6708 } 6709 else 6710 { 6711 /* case 4 */ 6712 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 6713 /* WRITE SECTORS EXT for easier implemetation */ 6714 SM_DBG5(("smsatWrite10: case 4\n")); 6715 fis->h.fisType = 0x27; /* Reg host to device */ 6716 fis->h.c_pmPort = 0x80; /* C Bit is set */ 6717 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 6718 6719 fis->h.features = 0; /* FIS reserve */ 6720 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 6721 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 6722 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 6723 fis->d.device = 0x40; /* FIS LBA mode set */ 6724 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 6725 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 6726 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 6727 fis->d.featuresExp = 0; /* FIS reserve */ 6728 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 6729 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 6730 fis->d.reserved4 = 0; 6731 fis->d.control = 0; /* FIS HOB bit clear */ 6732 fis->d.reserved5 = 0; 6733 6734 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 6735 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 6736 } 6737 } 6738 else /* case 1 and 2 */ 6739 { 6740 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 6741 { 6742 /* case 2 */ 6743 /* WRITE DMA*/ 6744 /* can't fit the transfer length */ 6745 SM_DBG5(("smsatWrite10: case 2\n")); 6746 fis->h.fisType = 0x27; /* Reg host to device */ 6747 fis->h.c_pmPort = 0x80; /* C bit is set */ 6748 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 6749 fis->h.features = 0; /* FIS reserve */ 6750 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 6751 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 6752 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 6753 6754 /* FIS LBA mode set LBA (27:24) */ 6755 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 6756 6757 fis->d.lbaLowExp = 0; 6758 fis->d.lbaMidExp = 0; 6759 fis->d.lbaHighExp = 0; 6760 fis->d.featuresExp = 0; 6761 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 6762 fis->d.sectorCountExp = 0; 6763 fis->d.reserved4 = 0; 6764 fis->d.control = 0; /* FIS HOB bit clear */ 6765 fis->d.reserved5 = 0; 6766 6767 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 6768 satIOContext->ATACmd = SAT_WRITE_DMA; 6769 } 6770 else 6771 { 6772 /* case 1 */ 6773 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 6774 /* WRITE SECTORS for easier implemetation */ 6775 /* can't fit the transfer length */ 6776 SM_DBG5(("smsatWrite10: case 1\n")); 6777 fis->h.fisType = 0x27; /* Reg host to device */ 6778 fis->h.c_pmPort = 0x80; /* C bit is set */ 6779 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 6780 fis->h.features = 0; /* FIS reserve */ 6781 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 6782 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 6783 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 6784 6785 /* FIS LBA mode set LBA (27:24) */ 6786 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 6787 6788 fis->d.lbaLowExp = 0; 6789 fis->d.lbaMidExp = 0; 6790 fis->d.lbaHighExp = 0; 6791 fis->d.featuresExp = 0; 6792 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 6793 fis->d.sectorCountExp = 0; 6794 fis->d.reserved4 = 0; 6795 fis->d.control = 0; /* FIS HOB bit clear */ 6796 fis->d.reserved5 = 0; 6797 6798 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 6799 satIOContext->ATACmd = SAT_WRITE_SECTORS; 6800 } 6801 } 6802 6803 // smhexdump("satWrite10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t)); 6804 6805 satIOContext->currentLBA = lba; 6806 satIOContext->OrgTL = tl; 6807 6808 /* 6809 computing number of loop and remainder for tl 6810 0xFF in case not ext 6811 0xFFFF in case EXT 6812 */ 6813 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 6814 { 6815 LoopNum = smsatComputeLoopNum(tl, 0x100); 6816 } 6817 else 6818 { 6819 /* SAT_WRITE_FPDMA_QUEUEDK */ 6820 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 6821 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 6822 } 6823 6824 satIOContext->LoopNum = LoopNum; 6825 6826 6827 if (LoopNum == 1) 6828 { 6829 SM_DBG5(("smsatWrite10: NON CHAINED data\n")); 6830 /* Initialize CB for SATA completion. 6831 */ 6832 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB; 6833 } 6834 else 6835 { 6836 SM_DBG2(("smsatWrite10: CHAINED data!!!\n")); 6837 /* re-setting tl */ 6838 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 6839 { 6840 fis->d.sectorCount = 0x0; 6841 smsatSplitSGL(smRoot, 6842 smIORequest, 6843 smDeviceHandle, 6844 smScsiRequest, 6845 satIOContext, 6846 NON_BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0x100 * 0x200 */ 6847 (satIOContext->OrgTL)*SATA_SECTOR_SIZE, 6848 agTRUE); 6849 } 6850 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 6851 fis->h.command == SAT_WRITE_DMA_EXT || 6852 fis->h.command == SAT_WRITE_DMA_FUA_EXT 6853 ) 6854 { 6855 fis->d.sectorCount = 0xFF; 6856 fis->d.sectorCountExp = 0xFF; 6857 smsatSplitSGL(smRoot, 6858 smIORequest, 6859 smDeviceHandle, 6860 smScsiRequest, 6861 satIOContext, 6862 BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */ 6863 (satIOContext->OrgTL)*SATA_SECTOR_SIZE, 6864 agTRUE); 6865 } 6866 else 6867 { 6868 /* SAT_WRITE_FPDMA_QUEUED */ 6869 fis->h.features = 0xFF; 6870 fis->d.featuresExp = 0xFF; 6871 smsatSplitSGL(smRoot, 6872 smIORequest, 6873 smDeviceHandle, 6874 smScsiRequest, 6875 satIOContext, 6876 BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */ 6877 (satIOContext->OrgTL)*SATA_SECTOR_SIZE, 6878 agTRUE); 6879 } 6880 6881 /* Initialize CB for SATA completion. 6882 */ 6883 satIOContext->satCompleteCB = &smsatChainedDataIOCB; 6884 } 6885 6886 6887 /* 6888 * Prepare SGL and send FIS to LL layer. 6889 */ 6890 satIOContext->reqType = agRequestType; /* Save it */ 6891 6892 status = smsataLLIOStart( smRoot, 6893 smIORequest, 6894 smDeviceHandle, 6895 smScsiRequest, 6896 satIOContext); 6897 return (status); 6898 } 6899 6900 osGLOBAL bit32 6901 smsatWrite12( 6902 smRoot_t *smRoot, 6903 smIORequest_t *smIORequest, 6904 smDeviceHandle_t *smDeviceHandle, 6905 smScsiInitiatorRequest_t *smScsiRequest, 6906 smSatIOContext_t *satIOContext 6907 ) 6908 { 6909 bit32 status; 6910 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 6911 smDeviceData_t *pSatDevData; 6912 smScsiRspSense_t *pSense; 6913 smIniScsiCmnd_t *scsiCmnd; 6914 agsaFisRegHostToDevice_t *fis; 6915 bit32 lba = 0; 6916 bit32 tl = 0; 6917 bit32 LoopNum = 1; 6918 bit8 LBA[8]; 6919 bit8 TL[8]; 6920 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 6921 6922 pSense = satIOContext->pSense; 6923 pSatDevData = satIOContext->pSatDevData; 6924 scsiCmnd = &smScsiRequest->scsiCmnd; 6925 fis = satIOContext->pFis; 6926 6927 SM_DBG5(("smsatWrite12: start\n")); 6928 6929 /* checking FUA_NV */ 6930 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 6931 { 6932 smsatSetSensePayload( pSense, 6933 SCSI_SNSKEY_ILLEGAL_REQUEST, 6934 0, 6935 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6936 satIOContext); 6937 6938 /*smEnqueueIO(smRoot, satIOContext);*/ 6939 6940 tdsmIOCompletedCB( smRoot, 6941 smIORequest, 6942 smIOSuccess, 6943 SCSI_STAT_CHECK_CONDITION, 6944 satIOContext->pSmSenseData, 6945 satIOContext->interruptContext ); 6946 6947 SM_DBG1(("smsatWrite12: return FUA_NV!!!\n")); 6948 return SM_RC_SUCCESS; 6949 6950 } 6951 6952 6953 /* checking CONTROL */ 6954 /* NACA == 1 or LINK == 1*/ 6955 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) ) 6956 { 6957 smsatSetSensePayload( pSense, 6958 SCSI_SNSKEY_ILLEGAL_REQUEST, 6959 0, 6960 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6961 satIOContext); 6962 6963 /*smEnqueueIO(smRoot, satIOContext);*/ 6964 6965 tdsmIOCompletedCB( smRoot, 6966 smIORequest, 6967 smIOSuccess, 6968 SCSI_STAT_CHECK_CONDITION, 6969 satIOContext->pSmSenseData, 6970 satIOContext->interruptContext ); 6971 6972 SM_DBG1(("smsatWrite10: return control!!!\n")); 6973 return SM_RC_SUCCESS; 6974 } 6975 6976 6977 sm_memset(LBA, 0, sizeof(LBA)); 6978 sm_memset(TL, 0, sizeof(TL)); 6979 6980 /* do not use memcpy due to indexing in LBA and TL */ 6981 LBA[0] = 0; /* MSB */ 6982 LBA[1] = 0; 6983 LBA[2] = 0; 6984 LBA[3] = 0; 6985 LBA[4] = scsiCmnd->cdb[2]; 6986 LBA[5] = scsiCmnd->cdb[3]; 6987 LBA[6] = scsiCmnd->cdb[4]; 6988 LBA[7] = scsiCmnd->cdb[5]; /* LSB */ 6989 6990 TL[0] = 0; /* MSB */ 6991 TL[1] = 0; 6992 TL[2] = 0; 6993 TL[3] = 0; 6994 TL[4] = scsiCmnd->cdb[6]; 6995 TL[5] = scsiCmnd->cdb[7]; 6996 TL[6] = scsiCmnd->cdb[8]; 6997 TL[7] = scsiCmnd->cdb[9]; /* LSB */ 6998 6999 7000 lba = smsatComputeCDB12LBA(satIOContext); 7001 tl = smsatComputeCDB12TL(satIOContext); 7002 7003 7004 /* Table 34, 9.1, p 46 */ 7005 /* 7006 note: As of 2/10/2006, no support for DMA QUEUED 7007 */ 7008 7009 /* 7010 Table 34, 9.1, p 46, b 7011 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 7012 return check condition 7013 */ 7014 if (pSatDevData->satNCQ != agTRUE && 7015 pSatDevData->sat48BitSupport != agTRUE 7016 ) 7017 { 7018 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 7019 7020 /*smEnqueueIO(smRoot, satIOContext);*/ 7021 7022 7023 7024 if (AllChk) 7025 { 7026 SM_DBG1(("smsatWrite12: return LBA out of range, not EXT!!!\n")); 7027 smsatSetSensePayload( pSense, 7028 SCSI_SNSKEY_ILLEGAL_REQUEST, 7029 0, 7030 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 7031 satIOContext); 7032 7033 /*smEnqueueIO(smRoot, satIOContext);*/ 7034 7035 tdsmIOCompletedCB( smRoot, 7036 smIORequest, 7037 smIOSuccess, 7038 SCSI_STAT_CHECK_CONDITION, 7039 satIOContext->pSmSenseData, 7040 satIOContext->interruptContext ); 7041 7042 return SM_RC_SUCCESS; 7043 } 7044 } 7045 else 7046 { 7047 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 7048 if (AllChk) 7049 { 7050 SM_DBG1(("smsatWrite12: return LBA out of range, EXT!!!\n")); 7051 smsatSetSensePayload( pSense, 7052 SCSI_SNSKEY_ILLEGAL_REQUEST, 7053 0, 7054 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 7055 satIOContext); 7056 tdsmIOCompletedCB( smRoot, 7057 smIORequest, 7058 smIOSuccess, 7059 SCSI_STAT_CHECK_CONDITION, 7060 satIOContext->pSmSenseData, 7061 satIOContext->interruptContext ); 7062 return SM_RC_SUCCESS; 7063 } 7064 } 7065 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 7066 { 7067 /* case 2 */ 7068 /* WRITE DMA*/ 7069 /* In case that we can't fit the transfer length, we loop */ 7070 SM_DBG5(("smsatWrite10: case 2\n")); 7071 fis->h.fisType = 0x27; /* Reg host to device */ 7072 fis->h.c_pmPort = 0x80; /* C bit is set */ 7073 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 7074 fis->h.features = 0; /* FIS reserve */ 7075 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 7076 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 7077 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 7078 7079 /* FIS LBA mode set LBA (27:24) */ 7080 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 7081 7082 fis->d.lbaLowExp = 0; 7083 fis->d.lbaMidExp = 0; 7084 fis->d.lbaHighExp = 0; 7085 fis->d.featuresExp = 0; 7086 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 7087 fis->d.sectorCountExp = 0; 7088 fis->d.reserved4 = 0; 7089 fis->d.control = 0; /* FIS HOB bit clear */ 7090 fis->d.reserved5 = 0; 7091 7092 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 7093 satIOContext->ATACmd = SAT_WRITE_DMA; 7094 } 7095 else 7096 { 7097 /* case 1 */ 7098 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 7099 /* WRITE SECTORS for easier implemetation */ 7100 /* In case that we can't fit the transfer length, we loop */ 7101 SM_DBG5(("smsatWrite10: case 1\n")); 7102 fis->h.fisType = 0x27; /* Reg host to device */ 7103 fis->h.c_pmPort = 0x80; /* C bit is set */ 7104 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 7105 fis->h.features = 0; /* FIS reserve */ 7106 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 7107 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 7108 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 7109 7110 /* FIS LBA mode set LBA (27:24) */ 7111 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 7112 7113 fis->d.lbaLowExp = 0; 7114 fis->d.lbaMidExp = 0; 7115 fis->d.lbaHighExp = 0; 7116 fis->d.featuresExp = 0; 7117 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 7118 fis->d.sectorCountExp = 0; 7119 fis->d.reserved4 = 0; 7120 fis->d.control = 0; /* FIS HOB bit clear */ 7121 fis->d.reserved5 = 0; 7122 7123 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 7124 satIOContext->ATACmd = SAT_WRITE_SECTORS; 7125 } 7126 7127 /* case 3 and 4 */ 7128 if (pSatDevData->sat48BitSupport == agTRUE) 7129 { 7130 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 7131 { 7132 /* case 3 */ 7133 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 7134 SM_DBG5(("smsatWrite10: case 3\n")); 7135 fis->h.fisType = 0x27; /* Reg host to device */ 7136 fis->h.c_pmPort = 0x80; /* C Bit is set */ 7137 7138 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 7139 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 7140 7141 fis->h.features = 0; /* FIS reserve */ 7142 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 7143 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 7144 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 7145 fis->d.device = 0x40; /* FIS LBA mode set */ 7146 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 7147 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 7148 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 7149 fis->d.featuresExp = 0; /* FIS reserve */ 7150 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 7151 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 7152 fis->d.reserved4 = 0; 7153 fis->d.control = 0; /* FIS HOB bit clear */ 7154 fis->d.reserved5 = 0; 7155 7156 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 7157 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 7158 } 7159 else 7160 { 7161 /* case 4 */ 7162 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 7163 /* WRITE SECTORS EXT for easier implemetation */ 7164 SM_DBG5(("smsatWrite10: case 4\n")); 7165 fis->h.fisType = 0x27; /* Reg host to device */ 7166 fis->h.c_pmPort = 0x80; /* C Bit is set */ 7167 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 7168 7169 fis->h.features = 0; /* FIS reserve */ 7170 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 7171 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 7172 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 7173 fis->d.device = 0x40; /* FIS LBA mode set */ 7174 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 7175 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 7176 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 7177 fis->d.featuresExp = 0; /* FIS reserve */ 7178 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 7179 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 7180 fis->d.reserved4 = 0; 7181 fis->d.control = 0; /* FIS HOB bit clear */ 7182 fis->d.reserved5 = 0; 7183 7184 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 7185 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 7186 } 7187 } 7188 7189 /* case 5 */ 7190 if (pSatDevData->satNCQ == agTRUE) 7191 { 7192 /* WRITE FPDMA QUEUED */ 7193 if (pSatDevData->sat48BitSupport != agTRUE) 7194 { 7195 SM_DBG5(("smsatWrite10: case 5 !!! error NCQ but 28 bit address support!!!\n")); 7196 smsatSetSensePayload( pSense, 7197 SCSI_SNSKEY_ILLEGAL_REQUEST, 7198 0, 7199 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 7200 satIOContext); 7201 7202 /*smEnqueueIO(smRoot, satIOContext);*/ 7203 7204 tdsmIOCompletedCB( smRoot, 7205 smIORequest, 7206 smIOSuccess, 7207 SCSI_STAT_CHECK_CONDITION, 7208 satIOContext->pSmSenseData, 7209 satIOContext->interruptContext ); 7210 return SM_RC_SUCCESS; 7211 } 7212 SM_DBG6(("smsatWrite10: case 5\n")); 7213 7214 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 7215 7216 fis->h.fisType = 0x27; /* Reg host to device */ 7217 fis->h.c_pmPort = 0x80; /* C Bit is set */ 7218 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 7219 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 7220 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 7221 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 7222 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 7223 7224 /* Check FUA bit */ 7225 if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK) 7226 fis->d.device = 0xC0; /* FIS FUA set */ 7227 else 7228 fis->d.device = 0x40; /* FIS FUA clear */ 7229 7230 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 7231 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 7232 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 7233 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 7234 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 7235 fis->d.sectorCountExp = 0; 7236 fis->d.reserved4 = 0; 7237 fis->d.control = 0; /* FIS HOB bit clear */ 7238 fis->d.reserved5 = 0; 7239 7240 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 7241 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 7242 } 7243 7244 satIOContext->currentLBA = lba; 7245 satIOContext->OrgTL = tl; 7246 7247 /* 7248 computing number of loop and remainder for tl 7249 0xFF in case not ext 7250 0xFFFF in case EXT 7251 */ 7252 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 7253 { 7254 LoopNum = smsatComputeLoopNum(tl, 0xFF); 7255 } 7256 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 7257 fis->h.command == SAT_WRITE_DMA_EXT || 7258 fis->h.command == SAT_WRITE_DMA_FUA_EXT 7259 ) 7260 { 7261 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 7262 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 7263 } 7264 else 7265 { 7266 /* SAT_WRITE_FPDMA_QUEUEDK */ 7267 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 7268 } 7269 7270 satIOContext->LoopNum = LoopNum; 7271 7272 7273 if (LoopNum == 1) 7274 { 7275 SM_DBG5(("smsatWrite10: NON CHAINED data\n")); 7276 /* Initialize CB for SATA completion. 7277 */ 7278 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB; 7279 } 7280 else 7281 { 7282 SM_DBG1(("smsatWrite10: CHAINED data\n")); 7283 /* re-setting tl */ 7284 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 7285 { 7286 fis->d.sectorCount = 0xFF; 7287 } 7288 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 7289 fis->h.command == SAT_WRITE_DMA_EXT || 7290 fis->h.command == SAT_WRITE_DMA_FUA_EXT 7291 ) 7292 { 7293 fis->d.sectorCount = 0xFF; 7294 fis->d.sectorCountExp = 0xFF; 7295 } 7296 else 7297 { 7298 /* SAT_WRITE_FPDMA_QUEUED */ 7299 fis->h.features = 0xFF; 7300 fis->d.featuresExp = 0xFF; 7301 } 7302 7303 /* Initialize CB for SATA completion. 7304 */ 7305 satIOContext->satCompleteCB = &smsatChainedDataIOCB; 7306 } 7307 7308 7309 /* 7310 * Prepare SGL and send FIS to LL layer. 7311 */ 7312 satIOContext->reqType = agRequestType; /* Save it */ 7313 7314 status = smsataLLIOStart( smRoot, 7315 smIORequest, 7316 smDeviceHandle, 7317 smScsiRequest, 7318 satIOContext); 7319 return (status); 7320 } 7321 7322 osGLOBAL bit32 7323 smsatWrite16( 7324 smRoot_t *smRoot, 7325 smIORequest_t *smIORequest, 7326 smDeviceHandle_t *smDeviceHandle, 7327 smScsiInitiatorRequest_t *smScsiRequest, 7328 smSatIOContext_t *satIOContext 7329 ) 7330 { 7331 bit32 status; 7332 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 7333 smDeviceData_t *pSatDevData; 7334 smScsiRspSense_t *pSense; 7335 smIniScsiCmnd_t *scsiCmnd; 7336 agsaFisRegHostToDevice_t *fis; 7337 bit32 lba = 0; 7338 bit32 tl = 0; 7339 bit32 LoopNum = 1; 7340 bit8 LBA[8]; 7341 bit8 TL[8]; 7342 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 7343 7344 pSense = satIOContext->pSense; 7345 pSatDevData = satIOContext->pSatDevData; 7346 scsiCmnd = &smScsiRequest->scsiCmnd; 7347 fis = satIOContext->pFis; 7348 7349 SM_DBG5(("smsatWrite16: start\n")); 7350 7351 /* checking FUA_NV */ 7352 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 7353 { 7354 smsatSetSensePayload( pSense, 7355 SCSI_SNSKEY_ILLEGAL_REQUEST, 7356 0, 7357 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 7358 satIOContext); 7359 7360 /*smEnqueueIO(smRoot, satIOContext);*/ 7361 7362 tdsmIOCompletedCB( smRoot, 7363 smIORequest, 7364 smIOSuccess, 7365 SCSI_STAT_CHECK_CONDITION, 7366 satIOContext->pSmSenseData, 7367 satIOContext->interruptContext ); 7368 7369 SM_DBG1(("smsatWrite16: return FUA_NV!!!\n")); 7370 return SM_RC_SUCCESS; 7371 7372 } 7373 7374 /* checking CONTROL */ 7375 /* NACA == 1 or LINK == 1*/ 7376 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 7377 { 7378 smsatSetSensePayload( pSense, 7379 SCSI_SNSKEY_ILLEGAL_REQUEST, 7380 0, 7381 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 7382 satIOContext); 7383 7384 /*smEnqueueIO(smRoot, satIOContext);*/ 7385 7386 tdsmIOCompletedCB( smRoot, 7387 smIORequest, 7388 smIOSuccess, 7389 SCSI_STAT_CHECK_CONDITION, 7390 satIOContext->pSmSenseData, 7391 satIOContext->interruptContext ); 7392 7393 SM_DBG1(("smsatWrite16: return control!!!\n")); 7394 return SM_RC_SUCCESS; 7395 } 7396 7397 7398 sm_memset(LBA, 0, sizeof(LBA)); 7399 sm_memset(TL, 0, sizeof(TL)); 7400 7401 7402 /* do not use memcpy due to indexing in LBA and TL */ 7403 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 7404 LBA[1] = scsiCmnd->cdb[3]; 7405 LBA[2] = scsiCmnd->cdb[4]; 7406 LBA[3] = scsiCmnd->cdb[5]; 7407 LBA[4] = scsiCmnd->cdb[6]; 7408 LBA[5] = scsiCmnd->cdb[7]; 7409 LBA[6] = scsiCmnd->cdb[8]; 7410 LBA[7] = scsiCmnd->cdb[9]; /* LSB */ 7411 7412 TL[0] = 0; 7413 TL[1] = 0; 7414 TL[2] = 0; 7415 TL[3] = 0; 7416 TL[4] = scsiCmnd->cdb[10]; /* MSB */ 7417 TL[5] = scsiCmnd->cdb[11]; 7418 TL[6] = scsiCmnd->cdb[12]; 7419 TL[7] = scsiCmnd->cdb[13]; /* LSB */ 7420 7421 7422 7423 lba = smsatComputeCDB16LBA(satIOContext); 7424 tl = smsatComputeCDB16TL(satIOContext); 7425 7426 7427 7428 /* Table 34, 9.1, p 46 */ 7429 /* 7430 note: As of 2/10/2006, no support for DMA QUEUED 7431 */ 7432 7433 /* 7434 Table 34, 9.1, p 46, b 7435 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 7436 return check condition 7437 */ 7438 if (pSatDevData->satNCQ != agTRUE && 7439 pSatDevData->sat48BitSupport != agTRUE 7440 ) 7441 { 7442 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 7443 if (AllChk) 7444 { 7445 SM_DBG1(("smsatWrite16: return LBA out of range, not EXT!!!\n")); 7446 smsatSetSensePayload( pSense, 7447 SCSI_SNSKEY_ILLEGAL_REQUEST, 7448 0, 7449 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 7450 satIOContext); 7451 7452 /*smEnqueueIO(smRoot, satIOContext);*/ 7453 7454 tdsmIOCompletedCB( smRoot, 7455 smIORequest, 7456 smIOSuccess, 7457 SCSI_STAT_CHECK_CONDITION, 7458 satIOContext->pSmSenseData, 7459 satIOContext->interruptContext ); 7460 7461 return SM_RC_SUCCESS; 7462 } 7463 } 7464 else 7465 { 7466 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 7467 if (AllChk) 7468 { 7469 SM_DBG1(("smsatWrite16: return LBA out of range, EXT!!!\n")); 7470 smsatSetSensePayload( pSense, 7471 SCSI_SNSKEY_ILLEGAL_REQUEST, 7472 0, 7473 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 7474 satIOContext); 7475 7476 /*smEnqueueIO(smRoot, satIOContext);*/ 7477 7478 tdsmIOCompletedCB( smRoot, 7479 smIORequest, 7480 smIOSuccess, 7481 SCSI_STAT_CHECK_CONDITION, 7482 satIOContext->pSmSenseData, 7483 satIOContext->interruptContext ); 7484 7485 return SM_RC_SUCCESS; 7486 } 7487 } 7488 7489 /* case 1 and 2 */ 7490 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 7491 { 7492 /* case 2 */ 7493 /* WRITE DMA*/ 7494 /* In case that we can't fit the transfer length, we loop */ 7495 SM_DBG5(("smsatWrite16: case 2\n")); 7496 fis->h.fisType = 0x27; /* Reg host to device */ 7497 fis->h.c_pmPort = 0x80; /* C bit is set */ 7498 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 7499 fis->h.features = 0; /* FIS reserve */ 7500 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 7501 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 7502 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 7503 7504 /* FIS LBA mode set LBA (27:24) */ 7505 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); 7506 7507 fis->d.lbaLowExp = 0; 7508 fis->d.lbaMidExp = 0; 7509 fis->d.lbaHighExp = 0; 7510 fis->d.featuresExp = 0; 7511 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 7512 fis->d.sectorCountExp = 0; 7513 fis->d.reserved4 = 0; 7514 fis->d.control = 0; /* FIS HOB bit clear */ 7515 fis->d.reserved5 = 0; 7516 7517 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 7518 satIOContext->ATACmd = SAT_WRITE_DMA; 7519 } 7520 else 7521 { 7522 /* case 1 */ 7523 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 7524 /* WRITE SECTORS for easier implemetation */ 7525 /* In case that we can't fit the transfer length, we loop */ 7526 SM_DBG5(("smsatWrite16: case 1\n")); 7527 fis->h.fisType = 0x27; /* Reg host to device */ 7528 fis->h.c_pmPort = 0x80; /* C bit is set */ 7529 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 7530 fis->h.features = 0; /* FIS reserve */ 7531 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 7532 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 7533 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 7534 7535 /* FIS LBA mode set LBA (27:24) */ 7536 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); 7537 7538 fis->d.lbaLowExp = 0; 7539 fis->d.lbaMidExp = 0; 7540 fis->d.lbaHighExp = 0; 7541 fis->d.featuresExp = 0; 7542 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 7543 fis->d.sectorCountExp = 0; 7544 fis->d.reserved4 = 0; 7545 fis->d.control = 0; /* FIS HOB bit clear */ 7546 fis->d.reserved5 = 0; 7547 7548 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 7549 satIOContext->ATACmd = SAT_WRITE_SECTORS; 7550 } 7551 7552 /* case 3 and 4 */ 7553 if (pSatDevData->sat48BitSupport == agTRUE) 7554 { 7555 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 7556 { 7557 /* case 3 */ 7558 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 7559 SM_DBG5(("smsatWrite16: case 3\n")); 7560 fis->h.fisType = 0x27; /* Reg host to device */ 7561 fis->h.c_pmPort = 0x80; /* C Bit is set */ 7562 7563 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 7564 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 7565 7566 fis->h.features = 0; /* FIS reserve */ 7567 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 7568 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 7569 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 7570 fis->d.device = 0x40; /* FIS LBA mode set */ 7571 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 7572 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 7573 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 7574 fis->d.featuresExp = 0; /* FIS reserve */ 7575 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 7576 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 7577 fis->d.reserved4 = 0; 7578 fis->d.control = 0; /* FIS HOB bit clear */ 7579 fis->d.reserved5 = 0; 7580 7581 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 7582 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 7583 } 7584 else 7585 { 7586 /* case 4 */ 7587 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 7588 /* WRITE SECTORS EXT for easier implemetation */ 7589 SM_DBG5(("smsatWrite16: case 4\n")); 7590 fis->h.fisType = 0x27; /* Reg host to device */ 7591 fis->h.c_pmPort = 0x80; /* C Bit is set */ 7592 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 7593 7594 fis->h.features = 0; /* FIS reserve */ 7595 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 7596 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 7597 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 7598 fis->d.device = 0x40; /* FIS LBA mode set */ 7599 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 7600 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 7601 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 7602 fis->d.featuresExp = 0; /* FIS reserve */ 7603 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 7604 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 7605 fis->d.reserved4 = 0; 7606 fis->d.control = 0; /* FIS HOB bit clear */ 7607 fis->d.reserved5 = 0; 7608 7609 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 7610 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 7611 } 7612 } 7613 7614 /* case 5 */ 7615 if (pSatDevData->satNCQ == agTRUE) 7616 { 7617 /* WRITE FPDMA QUEUED */ 7618 if (pSatDevData->sat48BitSupport != agTRUE) 7619 { 7620 SM_DBG5(("smsatWrite16: case 5 !!! error NCQ but 28 bit address support!!!\n")); 7621 smsatSetSensePayload( pSense, 7622 SCSI_SNSKEY_ILLEGAL_REQUEST, 7623 0, 7624 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 7625 satIOContext); 7626 7627 /*smEnqueueIO(smRoot, satIOContext);*/ 7628 7629 tdsmIOCompletedCB( smRoot, 7630 smIORequest, 7631 smIOSuccess, 7632 SCSI_STAT_CHECK_CONDITION, 7633 satIOContext->pSmSenseData, 7634 satIOContext->interruptContext ); 7635 return SM_RC_SUCCESS; 7636 } 7637 SM_DBG6(("smsatWrite16: case 5\n")); 7638 7639 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 7640 7641 fis->h.fisType = 0x27; /* Reg host to device */ 7642 fis->h.c_pmPort = 0x80; /* C Bit is set */ 7643 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 7644 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 7645 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 7646 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 7647 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 7648 7649 /* Check FUA bit */ 7650 if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK) 7651 fis->d.device = 0xC0; /* FIS FUA set */ 7652 else 7653 fis->d.device = 0x40; /* FIS FUA clear */ 7654 7655 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 7656 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 7657 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 7658 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 7659 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 7660 fis->d.sectorCountExp = 0; 7661 fis->d.reserved4 = 0; 7662 fis->d.control = 0; /* FIS HOB bit clear */ 7663 fis->d.reserved5 = 0; 7664 7665 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 7666 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 7667 } 7668 7669 satIOContext->currentLBA = lba; 7670 satIOContext->OrgTL = tl; 7671 7672 /* 7673 computing number of loop and remainder for tl 7674 0xFF in case not ext 7675 0xFFFF in case EXT 7676 */ 7677 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 7678 { 7679 LoopNum = smsatComputeLoopNum(tl, 0xFF); 7680 } 7681 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 7682 fis->h.command == SAT_WRITE_DMA_EXT || 7683 fis->h.command == SAT_WRITE_DMA_FUA_EXT 7684 ) 7685 { 7686 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 7687 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 7688 } 7689 else 7690 { 7691 /* SAT_WRITE_FPDMA_QUEUEDK */ 7692 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 7693 } 7694 7695 satIOContext->LoopNum = LoopNum; 7696 7697 7698 if (LoopNum == 1) 7699 { 7700 SM_DBG5(("smsatWrite16: NON CHAINED data\n")); 7701 /* Initialize CB for SATA completion. 7702 */ 7703 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB; 7704 } 7705 else 7706 { 7707 SM_DBG1(("smsatWrite16: CHAINED data!!!\n")); 7708 /* re-setting tl */ 7709 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 7710 { 7711 fis->d.sectorCount = 0xFF; 7712 } 7713 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 7714 fis->h.command == SAT_WRITE_DMA_EXT || 7715 fis->h.command == SAT_WRITE_DMA_FUA_EXT 7716 ) 7717 { 7718 fis->d.sectorCount = 0xFF; 7719 fis->d.sectorCountExp = 0xFF; 7720 } 7721 else 7722 { 7723 /* SAT_WRITE_FPDMA_QUEUED */ 7724 fis->h.features = 0xFF; 7725 fis->d.featuresExp = 0xFF; 7726 } 7727 7728 /* Initialize CB for SATA completion. 7729 */ 7730 satIOContext->satCompleteCB = &smsatChainedDataIOCB; 7731 } 7732 7733 7734 /* 7735 * Prepare SGL and send FIS to LL layer. 7736 */ 7737 satIOContext->reqType = agRequestType; /* Save it */ 7738 7739 status = smsataLLIOStart( smRoot, 7740 smIORequest, 7741 smDeviceHandle, 7742 smScsiRequest, 7743 satIOContext); 7744 return (status); 7745 } 7746 7747 7748 osGLOBAL bit32 7749 smsatVerify10( 7750 smRoot_t *smRoot, 7751 smIORequest_t *smIORequest, 7752 smDeviceHandle_t *smDeviceHandle, 7753 smScsiInitiatorRequest_t *smScsiRequest, 7754 smSatIOContext_t *satIOContext 7755 ) 7756 { 7757 /* 7758 For simple implementation, 7759 no byte comparison supported as of 4/5/06 7760 */ 7761 smScsiRspSense_t *pSense; 7762 smIniScsiCmnd_t *scsiCmnd; 7763 smDeviceData_t *pSatDevData; 7764 agsaFisRegHostToDevice_t *fis; 7765 bit32 status; 7766 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 7767 bit32 lba = 0; 7768 bit32 tl = 0; 7769 bit32 LoopNum = 1; 7770 bit8 LBA[8]; 7771 bit8 TL[8]; 7772 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 7773 7774 pSense = satIOContext->pSense; 7775 scsiCmnd = &smScsiRequest->scsiCmnd; 7776 pSatDevData = satIOContext->pSatDevData; 7777 fis = satIOContext->pFis; 7778 SM_DBG5(("smsatVerify10: start\n")); 7779 /* checking BYTCHK */ 7780 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK) 7781 { 7782 /* 7783 should do the byte check 7784 but not supported in this version 7785 */ 7786 smsatSetSensePayload( pSense, 7787 SCSI_SNSKEY_ILLEGAL_REQUEST, 7788 0, 7789 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 7790 satIOContext); 7791 /*smEnqueueIO(smRoot, satIOContext);*/ 7792 tdsmIOCompletedCB( smRoot, 7793 smIORequest, 7794 smIOSuccess, 7795 SCSI_STAT_CHECK_CONDITION, 7796 satIOContext->pSmSenseData, 7797 satIOContext->interruptContext ); 7798 7799 SM_DBG1(("smsatVerify10: no byte checking!!!\n")); 7800 return SM_RC_SUCCESS; 7801 } 7802 7803 /* checking CONTROL */ 7804 /* NACA == 1 or LINK == 1*/ 7805 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 7806 { 7807 smsatSetSensePayload( pSense, 7808 SCSI_SNSKEY_ILLEGAL_REQUEST, 7809 0, 7810 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 7811 satIOContext); 7812 7813 /*smEnqueueIO(smRoot, satIOContext);*/ 7814 7815 tdsmIOCompletedCB( smRoot, 7816 smIORequest, 7817 smIOSuccess, 7818 SCSI_STAT_CHECK_CONDITION, 7819 satIOContext->pSmSenseData, 7820 satIOContext->interruptContext ); 7821 7822 SM_DBG1(("smsatVerify10: return control!!!\n")); 7823 return SM_RC_SUCCESS; 7824 } 7825 7826 7827 sm_memset(LBA, 0, sizeof(LBA)); 7828 sm_memset(TL, 0, sizeof(TL)); 7829 7830 /* do not use memcpy due to indexing in LBA and TL */ 7831 LBA[0] = 0; /* MSB */ 7832 LBA[1] = 0; 7833 LBA[2] = 0; 7834 LBA[3] = 0; 7835 LBA[4] = scsiCmnd->cdb[2]; 7836 LBA[5] = scsiCmnd->cdb[3]; 7837 LBA[6] = scsiCmnd->cdb[4]; 7838 LBA[7] = scsiCmnd->cdb[5]; /* LSB */ 7839 7840 TL[0] = 0; 7841 TL[1] = 0; 7842 TL[2] = 0; 7843 TL[3] = 0; 7844 TL[4] = 0; 7845 TL[5] = 0; 7846 TL[6] = scsiCmnd->cdb[7]; 7847 TL[7] = scsiCmnd->cdb[8]; /* LSB */ 7848 7849 7850 /* cbd10; computing LBA and transfer length */ 7851 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 7852 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 7853 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 7854 7855 if (pSatDevData->satNCQ != agTRUE && 7856 pSatDevData->sat48BitSupport != agTRUE 7857 ) 7858 { 7859 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 7860 if (AllChk) 7861 { 7862 SM_DBG1(("smsatVerify10: return LBA out of range, not EXT!!!\n")); 7863 SM_DBG1(("smsatVerify10: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3], 7864 scsiCmnd->cdb[4], scsiCmnd->cdb[5])); 7865 SM_DBG1(("smsatVerify10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT)); 7866 smsatSetSensePayload( pSense, 7867 SCSI_SNSKEY_ILLEGAL_REQUEST, 7868 0, 7869 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 7870 satIOContext); 7871 7872 /*smEnqueueIO(smRoot, satIOContext);*/ 7873 7874 tdsmIOCompletedCB( smRoot, 7875 smIORequest, 7876 smIOSuccess, 7877 SCSI_STAT_CHECK_CONDITION, 7878 satIOContext->pSmSenseData, 7879 satIOContext->interruptContext ); 7880 7881 return SM_RC_SUCCESS; 7882 } 7883 } 7884 else 7885 { 7886 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 7887 if (AllChk) 7888 { 7889 SM_DBG1(("smsatVerify10: return LBA out of range, EXT!!!\n")); 7890 smsatSetSensePayload( pSense, 7891 SCSI_SNSKEY_ILLEGAL_REQUEST, 7892 0, 7893 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 7894 satIOContext); 7895 7896 /*smEnqueueIO(smRoot, satIOContext);*/ 7897 7898 tdsmIOCompletedCB( smRoot, 7899 smIORequest, 7900 smIOSuccess, 7901 SCSI_STAT_CHECK_CONDITION, 7902 satIOContext->pSmSenseData, 7903 satIOContext->interruptContext ); 7904 7905 return SM_RC_SUCCESS; 7906 } 7907 } 7908 7909 if (pSatDevData->sat48BitSupport == agTRUE) 7910 { 7911 SM_DBG5(("smsatVerify10: SAT_READ_VERIFY_SECTORS_EXT\n")); 7912 fis->h.fisType = 0x27; /* Reg host to device */ 7913 fis->h.c_pmPort = 0x80; /* C Bit is set */ 7914 7915 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 7916 fis->h.features = 0; /* FIS reserve */ 7917 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 7918 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 7919 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 7920 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 7921 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 7922 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 7923 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 7924 fis->d.featuresExp = 0; /* FIS reserve */ 7925 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 7926 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 7927 7928 fis->d.reserved4 = 0; 7929 fis->d.control = 0; /* FIS HOB bit clear */ 7930 fis->d.reserved5 = 0; 7931 7932 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 7933 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT; 7934 } 7935 else 7936 { 7937 SM_DBG5(("smsatVerify10: SAT_READ_VERIFY_SECTORS\n")); 7938 fis->h.fisType = 0x27; /* Reg host to device */ 7939 fis->h.c_pmPort = 0x80; /* C bit is set */ 7940 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 7941 fis->h.features = 0; /* FIS reserve */ 7942 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 7943 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 7944 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 7945 /* FIS LBA mode set LBA (27:24) */ 7946 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 7947 fis->d.lbaLowExp = 0; 7948 fis->d.lbaMidExp = 0; 7949 fis->d.lbaHighExp = 0; 7950 fis->d.featuresExp = 0; 7951 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 7952 fis->d.sectorCountExp = 0; 7953 fis->d.reserved4 = 0; 7954 fis->d.control = 0; /* FIS HOB bit clear */ 7955 fis->d.reserved5 = 0; 7956 7957 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 7958 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS; 7959 7960 } 7961 7962 satIOContext->currentLBA = lba; 7963 satIOContext->OrgTL = tl; 7964 7965 /* 7966 computing number of loop and remainder for tl 7967 0xFF in case not ext 7968 0xFFFF in case EXT 7969 */ 7970 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 7971 { 7972 LoopNum = smsatComputeLoopNum(tl, 0xFF); 7973 } 7974 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 7975 { 7976 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 7977 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 7978 } 7979 else 7980 { 7981 SM_DBG1(("smsatVerify10: error case 1!!!\n")); 7982 LoopNum = 1; 7983 } 7984 7985 satIOContext->LoopNum = LoopNum; 7986 7987 if (LoopNum == 1) 7988 { 7989 SM_DBG5(("smsatVerify10: NON CHAINED data\n")); 7990 /* Initialize CB for SATA completion. 7991 */ 7992 satIOContext->satCompleteCB = &smsatNonChainedVerifyCB; 7993 } 7994 else 7995 { 7996 SM_DBG1(("smsatVerify10: CHAINED data!!!\n")); 7997 /* re-setting tl */ 7998 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 7999 { 8000 fis->d.sectorCount = 0xFF; 8001 } 8002 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 8003 { 8004 fis->d.sectorCount = 0xFF; 8005 fis->d.sectorCountExp = 0xFF; 8006 } 8007 else 8008 { 8009 SM_DBG1(("smsatVerify10: error case 2!!!\n")); 8010 } 8011 8012 /* Initialize CB for SATA completion. 8013 */ 8014 satIOContext->satCompleteCB = &smsatChainedVerifyCB; 8015 } 8016 8017 8018 /* 8019 * Prepare SGL and send FIS to LL layer. 8020 */ 8021 satIOContext->reqType = agRequestType; /* Save it */ 8022 8023 status = smsataLLIOStart( smRoot, 8024 smIORequest, 8025 smDeviceHandle, 8026 smScsiRequest, 8027 satIOContext); 8028 return (status); 8029 } 8030 8031 osGLOBAL bit32 8032 smsatVerify12( 8033 smRoot_t *smRoot, 8034 smIORequest_t *smIORequest, 8035 smDeviceHandle_t *smDeviceHandle, 8036 smScsiInitiatorRequest_t *smScsiRequest, 8037 smSatIOContext_t *satIOContext 8038 ) 8039 { 8040 /* 8041 For simple implementation, 8042 no byte comparison supported as of 4/5/06 8043 */ 8044 smScsiRspSense_t *pSense; 8045 smIniScsiCmnd_t *scsiCmnd; 8046 smDeviceData_t *pSatDevData; 8047 agsaFisRegHostToDevice_t *fis; 8048 bit32 status; 8049 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8050 bit32 lba = 0; 8051 bit32 tl = 0; 8052 bit32 LoopNum = 1; 8053 bit8 LBA[8]; 8054 bit8 TL[8]; 8055 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 8056 8057 pSense = satIOContext->pSense; 8058 scsiCmnd = &smScsiRequest->scsiCmnd; 8059 pSatDevData = satIOContext->pSatDevData; 8060 fis = satIOContext->pFis; 8061 SM_DBG5(("smsatVerify12: start\n")); 8062 /* checking BYTCHK */ 8063 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK) 8064 { 8065 /* 8066 should do the byte check 8067 but not supported in this version 8068 */ 8069 smsatSetSensePayload( pSense, 8070 SCSI_SNSKEY_ILLEGAL_REQUEST, 8071 0, 8072 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8073 satIOContext); 8074 8075 /*smEnqueueIO(smRoot, satIOContext);*/ 8076 8077 tdsmIOCompletedCB( smRoot, 8078 smIORequest, 8079 smIOSuccess, 8080 SCSI_STAT_CHECK_CONDITION, 8081 satIOContext->pSmSenseData, 8082 satIOContext->interruptContext ); 8083 8084 SM_DBG1(("smsatVerify12: no byte checking!!!\n")); 8085 return SM_RC_SUCCESS; 8086 } 8087 8088 /* checking CONTROL */ 8089 /* NACA == 1 or LINK == 1*/ 8090 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) ) 8091 { 8092 smsatSetSensePayload( pSense, 8093 SCSI_SNSKEY_ILLEGAL_REQUEST, 8094 0, 8095 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8096 satIOContext); 8097 8098 /*smEnqueueIO(smRoot, satIOContext);*/ 8099 8100 tdsmIOCompletedCB( smRoot, 8101 smIORequest, 8102 smIOSuccess, 8103 SCSI_STAT_CHECK_CONDITION, 8104 satIOContext->pSmSenseData, 8105 satIOContext->interruptContext ); 8106 8107 SM_DBG1(("smsatVerify12: return control!!!\n")); 8108 return SM_RC_SUCCESS; 8109 } 8110 8111 sm_memset(LBA, 0, sizeof(LBA)); 8112 sm_memset(TL, 0, sizeof(TL)); 8113 8114 /* do not use memcpy due to indexing in LBA and TL */ 8115 LBA[0] = 0; /* MSB */ 8116 LBA[1] = 0; 8117 LBA[2] = 0; 8118 LBA[3] = 0; 8119 LBA[4] = scsiCmnd->cdb[2]; 8120 LBA[5] = scsiCmnd->cdb[3]; 8121 LBA[6] = scsiCmnd->cdb[4]; 8122 LBA[7] = scsiCmnd->cdb[5]; /* LSB */ 8123 8124 TL[0] = 0; /* MSB */ 8125 TL[1] = 0; 8126 TL[2] = 0; 8127 TL[3] = 0; 8128 TL[4] = scsiCmnd->cdb[6]; 8129 TL[5] = scsiCmnd->cdb[7]; 8130 TL[6] = scsiCmnd->cdb[8]; 8131 TL[7] = scsiCmnd->cdb[9]; /* LSB */ 8132 8133 8134 lba = smsatComputeCDB12LBA(satIOContext); 8135 tl = smsatComputeCDB12TL(satIOContext); 8136 8137 if (pSatDevData->satNCQ != agTRUE && 8138 pSatDevData->sat48BitSupport != agTRUE 8139 ) 8140 { 8141 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 8142 if (AllChk) 8143 { 8144 SM_DBG1(("smsatVerify12: return LBA out of range, not EXT!!!\n")); 8145 SM_DBG1(("smsatVerify12: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3], 8146 scsiCmnd->cdb[4], scsiCmnd->cdb[5])); 8147 SM_DBG1(("smsatVerify12: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT)); 8148 smsatSetSensePayload( pSense, 8149 SCSI_SNSKEY_ILLEGAL_REQUEST, 8150 0, 8151 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 8152 satIOContext); 8153 8154 /*smEnqueueIO(smRoot, satIOContext);*/ 8155 8156 tdsmIOCompletedCB( smRoot, 8157 smIORequest, 8158 smIOSuccess, 8159 SCSI_STAT_CHECK_CONDITION, 8160 satIOContext->pSmSenseData, 8161 satIOContext->interruptContext ); 8162 8163 return SM_RC_SUCCESS; 8164 } 8165 } 8166 else 8167 { 8168 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 8169 if (AllChk) 8170 { 8171 SM_DBG1(("smsatVerify12: return LBA out of range, EXT!!!\n")); 8172 smsatSetSensePayload( pSense, 8173 SCSI_SNSKEY_ILLEGAL_REQUEST, 8174 0, 8175 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 8176 satIOContext); 8177 8178 /*smEnqueueIO(smRoot, satIOContext);*/ 8179 8180 tdsmIOCompletedCB( smRoot, 8181 smIORequest, 8182 smIOSuccess, 8183 SCSI_STAT_CHECK_CONDITION, 8184 satIOContext->pSmSenseData, 8185 satIOContext->interruptContext ); 8186 8187 return SM_RC_SUCCESS; 8188 } 8189 } 8190 8191 if (pSatDevData->sat48BitSupport == agTRUE) 8192 { 8193 SM_DBG5(("smsatVerify12: SAT_READ_VERIFY_SECTORS_EXT\n")); 8194 fis->h.fisType = 0x27; /* Reg host to device */ 8195 fis->h.c_pmPort = 0x80; /* C Bit is set */ 8196 8197 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 8198 fis->h.features = 0; /* FIS reserve */ 8199 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 8200 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 8201 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 8202 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 8203 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 8204 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 8205 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 8206 fis->d.featuresExp = 0; /* FIS reserve */ 8207 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 8208 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 8209 8210 fis->d.reserved4 = 0; 8211 fis->d.control = 0; /* FIS HOB bit clear */ 8212 fis->d.reserved5 = 0; 8213 8214 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8215 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT; 8216 } 8217 else 8218 { 8219 SM_DBG5(("smsatVerify12: SAT_READ_VERIFY_SECTORS\n")); 8220 fis->h.fisType = 0x27; /* Reg host to device */ 8221 fis->h.c_pmPort = 0x80; /* C bit is set */ 8222 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 8223 fis->h.features = 0; /* FIS reserve */ 8224 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 8225 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 8226 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 8227 /* FIS LBA mode set LBA (27:24) */ 8228 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 8229 fis->d.lbaLowExp = 0; 8230 fis->d.lbaMidExp = 0; 8231 fis->d.lbaHighExp = 0; 8232 fis->d.featuresExp = 0; 8233 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 8234 fis->d.sectorCountExp = 0; 8235 fis->d.reserved4 = 0; 8236 fis->d.control = 0; /* FIS HOB bit clear */ 8237 fis->d.reserved5 = 0; 8238 8239 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8240 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS; 8241 8242 } 8243 8244 satIOContext->currentLBA = lba; 8245 satIOContext->OrgTL = tl; 8246 8247 /* 8248 computing number of loop and remainder for tl 8249 0xFF in case not ext 8250 0xFFFF in case EXT 8251 */ 8252 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 8253 { 8254 LoopNum = smsatComputeLoopNum(tl, 0xFF); 8255 } 8256 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 8257 { 8258 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 8259 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 8260 } 8261 else 8262 { 8263 SM_DBG1(("smsatVerify12: error case 1!!!\n")); 8264 LoopNum = 1; 8265 } 8266 8267 satIOContext->LoopNum = LoopNum; 8268 8269 if (LoopNum == 1) 8270 { 8271 SM_DBG5(("smsatVerify12: NON CHAINED data\n")); 8272 /* Initialize CB for SATA completion. 8273 */ 8274 satIOContext->satCompleteCB = &smsatNonChainedVerifyCB; 8275 } 8276 else 8277 { 8278 SM_DBG1(("smsatVerify12: CHAINED data!!!\n")); 8279 /* re-setting tl */ 8280 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 8281 { 8282 fis->d.sectorCount = 0xFF; 8283 } 8284 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 8285 { 8286 fis->d.sectorCount = 0xFF; 8287 fis->d.sectorCountExp = 0xFF; 8288 } 8289 else 8290 { 8291 SM_DBG1(("smsatVerify12: error case 2!!!\n")); 8292 } 8293 8294 /* Initialize CB for SATA completion. 8295 */ 8296 satIOContext->satCompleteCB = &smsatChainedVerifyCB; 8297 } 8298 8299 8300 /* 8301 * Prepare SGL and send FIS to LL layer. 8302 */ 8303 satIOContext->reqType = agRequestType; /* Save it */ 8304 8305 status = smsataLLIOStart( smRoot, 8306 smIORequest, 8307 smDeviceHandle, 8308 smScsiRequest, 8309 satIOContext); 8310 return (status); 8311 } 8312 8313 osGLOBAL bit32 8314 smsatVerify16( 8315 smRoot_t *smRoot, 8316 smIORequest_t *smIORequest, 8317 smDeviceHandle_t *smDeviceHandle, 8318 smScsiInitiatorRequest_t *smScsiRequest, 8319 smSatIOContext_t *satIOContext 8320 ) 8321 { 8322 /* 8323 For simple implementation, 8324 no byte comparison supported as of 4/5/06 8325 */ 8326 smScsiRspSense_t *pSense; 8327 smIniScsiCmnd_t *scsiCmnd; 8328 smDeviceData_t *pSatDevData; 8329 agsaFisRegHostToDevice_t *fis; 8330 bit32 status; 8331 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8332 bit32 lba = 0; 8333 bit32 tl = 0; 8334 bit32 LoopNum = 1; 8335 bit8 LBA[8]; 8336 bit8 TL[8]; 8337 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 8338 8339 pSense = satIOContext->pSense; 8340 scsiCmnd = &smScsiRequest->scsiCmnd; 8341 pSatDevData = satIOContext->pSatDevData; 8342 fis = satIOContext->pFis; 8343 SM_DBG5(("smsatVerify16: start\n")); 8344 /* checking BYTCHK */ 8345 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK) 8346 { 8347 /* 8348 should do the byte check 8349 but not supported in this version 8350 */ 8351 smsatSetSensePayload( pSense, 8352 SCSI_SNSKEY_ILLEGAL_REQUEST, 8353 0, 8354 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8355 satIOContext); 8356 /*smEnqueueIO(smRoot, satIOContext);*/ 8357 tdsmIOCompletedCB( smRoot, 8358 smIORequest, 8359 smIOSuccess, 8360 SCSI_STAT_CHECK_CONDITION, 8361 satIOContext->pSmSenseData, 8362 satIOContext->interruptContext ); 8363 SM_DBG1(("smsatVerify16: no byte checking!!!\n")); 8364 return SM_RC_SUCCESS; 8365 } 8366 /* checking CONTROL */ 8367 /* NACA == 1 or LINK == 1*/ 8368 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 8369 { 8370 smsatSetSensePayload( pSense, 8371 SCSI_SNSKEY_ILLEGAL_REQUEST, 8372 0, 8373 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8374 satIOContext); 8375 /*smEnqueueIO(smRoot, satIOContext);*/ 8376 tdsmIOCompletedCB( smRoot, 8377 smIORequest, 8378 smIOSuccess, 8379 SCSI_STAT_CHECK_CONDITION, 8380 satIOContext->pSmSenseData, 8381 satIOContext->interruptContext ); 8382 SM_DBG1(("smsatVerify16: return control!!!\n")); 8383 return SM_RC_SUCCESS; 8384 } 8385 sm_memset(LBA, 0, sizeof(LBA)); 8386 sm_memset(TL, 0, sizeof(TL)); 8387 8388 /* do not use memcpy due to indexing in LBA and TL */ 8389 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 8390 LBA[1] = scsiCmnd->cdb[3]; 8391 LBA[2] = scsiCmnd->cdb[4]; 8392 LBA[3] = scsiCmnd->cdb[5]; 8393 LBA[4] = scsiCmnd->cdb[6]; 8394 LBA[5] = scsiCmnd->cdb[7]; 8395 LBA[6] = scsiCmnd->cdb[8]; 8396 LBA[7] = scsiCmnd->cdb[9]; /* LSB */ 8397 8398 TL[0] = 0; 8399 TL[1] = 0; 8400 TL[2] = 0; 8401 TL[3] = 0; 8402 TL[4] = scsiCmnd->cdb[10]; /* MSB */ 8403 TL[5] = scsiCmnd->cdb[11]; 8404 TL[6] = scsiCmnd->cdb[12]; 8405 TL[7] = scsiCmnd->cdb[13]; /* LSB */ 8406 lba = smsatComputeCDB16LBA(satIOContext); 8407 tl = smsatComputeCDB16TL(satIOContext); 8408 8409 if (pSatDevData->satNCQ != agTRUE && 8410 pSatDevData->sat48BitSupport != agTRUE 8411 ) 8412 { 8413 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 8414 if (AllChk) 8415 { 8416 SM_DBG1(("smsatVerify16: return LBA out of range, not EXT!!!\n")); 8417 smsatSetSensePayload( pSense, 8418 SCSI_SNSKEY_ILLEGAL_REQUEST, 8419 0, 8420 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 8421 satIOContext); 8422 /*smEnqueueIO(smRoot, satIOContext);*/ 8423 tdsmIOCompletedCB( smRoot, 8424 smIORequest, 8425 smIOSuccess, 8426 SCSI_STAT_CHECK_CONDITION, 8427 satIOContext->pSmSenseData, 8428 satIOContext->interruptContext ); 8429 return SM_RC_SUCCESS; 8430 } 8431 } 8432 else 8433 { 8434 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 8435 if (AllChk) 8436 { 8437 SM_DBG1(("smsatVerify16: return LBA out of range, EXT!!!\n")); 8438 smsatSetSensePayload( pSense, 8439 SCSI_SNSKEY_ILLEGAL_REQUEST, 8440 0, 8441 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 8442 satIOContext); 8443 /*smEnqueueIO(smRoot, satIOContext);*/ 8444 tdsmIOCompletedCB( smRoot, 8445 smIORequest, 8446 smIOSuccess, 8447 SCSI_STAT_CHECK_CONDITION, 8448 satIOContext->pSmSenseData, 8449 satIOContext->interruptContext ); 8450 return SM_RC_SUCCESS; 8451 } 8452 } 8453 8454 if (pSatDevData->sat48BitSupport == agTRUE) 8455 { 8456 SM_DBG5(("smsatVerify16: SAT_READ_VERIFY_SECTORS_EXT\n")); 8457 fis->h.fisType = 0x27; /* Reg host to device */ 8458 fis->h.c_pmPort = 0x80; /* C Bit is set */ 8459 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 8460 fis->h.features = 0; /* FIS reserve */ 8461 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 8462 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 8463 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 8464 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 8465 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 8466 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 8467 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 8468 fis->d.featuresExp = 0; /* FIS reserve */ 8469 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 8470 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 8471 8472 fis->d.reserved4 = 0; 8473 fis->d.control = 0; /* FIS HOB bit clear */ 8474 fis->d.reserved5 = 0; 8475 8476 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8477 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT; 8478 } 8479 else 8480 { 8481 SM_DBG5(("smsatVerify16: SAT_READ_VERIFY_SECTORS\n")); 8482 fis->h.fisType = 0x27; /* Reg host to device */ 8483 fis->h.c_pmPort = 0x80; /* C bit is set */ 8484 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 8485 fis->h.features = 0; /* FIS reserve */ 8486 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 8487 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 8488 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 8489 /* FIS LBA mode set LBA (27:24) */ 8490 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); 8491 fis->d.lbaLowExp = 0; 8492 fis->d.lbaMidExp = 0; 8493 fis->d.lbaHighExp = 0; 8494 fis->d.featuresExp = 0; 8495 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 8496 fis->d.sectorCountExp = 0; 8497 fis->d.reserved4 = 0; 8498 fis->d.control = 0; /* FIS HOB bit clear */ 8499 fis->d.reserved5 = 0; 8500 8501 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8502 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS; 8503 8504 } 8505 8506 satIOContext->currentLBA = lba; 8507 satIOContext->OrgTL = tl; 8508 8509 /* 8510 computing number of loop and remainder for tl 8511 0xFF in case not ext 8512 0xFFFF in case EXT 8513 */ 8514 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 8515 { 8516 LoopNum = smsatComputeLoopNum(tl, 0xFF); 8517 } 8518 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 8519 { 8520 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 8521 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 8522 } 8523 else 8524 { 8525 SM_DBG1(("smsatVerify16: error case 1!!!\n")); 8526 LoopNum = 1; 8527 } 8528 8529 satIOContext->LoopNum = LoopNum; 8530 8531 if (LoopNum == 1) 8532 { 8533 SM_DBG5(("smsatVerify16: NON CHAINED data\n")); 8534 /* Initialize CB for SATA completion. 8535 */ 8536 satIOContext->satCompleteCB = &smsatNonChainedVerifyCB; 8537 } 8538 else 8539 { 8540 SM_DBG1(("smsatVerify16: CHAINED data!!!\n")); 8541 /* re-setting tl */ 8542 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 8543 { 8544 fis->d.sectorCount = 0xFF; 8545 } 8546 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 8547 { 8548 fis->d.sectorCount = 0xFF; 8549 fis->d.sectorCountExp = 0xFF; 8550 } 8551 else 8552 { 8553 SM_DBG1(("smsatVerify16: error case 2!!!\n")); 8554 } 8555 8556 /* Initialize CB for SATA completion. 8557 */ 8558 satIOContext->satCompleteCB = &smsatChainedVerifyCB; 8559 } 8560 8561 8562 /* 8563 * Prepare SGL and send FIS to LL layer. 8564 */ 8565 satIOContext->reqType = agRequestType; /* Save it */ 8566 8567 status = smsataLLIOStart( smRoot, 8568 smIORequest, 8569 smDeviceHandle, 8570 smScsiRequest, 8571 satIOContext); 8572 return (status); 8573 } 8574 8575 osGLOBAL bit32 8576 smsatTestUnitReady( 8577 smRoot_t *smRoot, 8578 smIORequest_t *smIORequest, 8579 smDeviceHandle_t *smDeviceHandle, 8580 smScsiInitiatorRequest_t *smScsiRequest, 8581 smSatIOContext_t *satIOContext 8582 ) 8583 { 8584 bit32 status; 8585 bit32 agRequestType; 8586 smDeviceData_t *pSatDevData; 8587 smScsiRspSense_t *pSense; 8588 smIniScsiCmnd_t *scsiCmnd; 8589 agsaFisRegHostToDevice_t *fis; 8590 8591 pSense = satIOContext->pSense; 8592 pSatDevData = satIOContext->pSatDevData; 8593 scsiCmnd = &smScsiRequest->scsiCmnd; 8594 fis = satIOContext->pFis; 8595 8596 SM_DBG5(("smsatTestUnitReady: start\n")); 8597 8598 /* checking CONTROL */ 8599 /* NACA == 1 or LINK == 1*/ 8600 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 8601 { 8602 smsatSetSensePayload( pSense, 8603 SCSI_SNSKEY_ILLEGAL_REQUEST, 8604 0, 8605 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8606 satIOContext); 8607 8608 /*smEnqueueIO(smRoot, satIOContext);*/ 8609 8610 tdsmIOCompletedCB( smRoot, 8611 smIORequest, 8612 smIOSuccess, 8613 SCSI_STAT_CHECK_CONDITION, 8614 satIOContext->pSmSenseData, 8615 satIOContext->interruptContext ); 8616 8617 SM_DBG1(("smsatTestUnitReady: return control!!!\n")); 8618 return SM_RC_SUCCESS; 8619 } 8620 8621 /* SAT revision 8, 8.11.2, p42*/ 8622 if (pSatDevData->satStopState == agTRUE) 8623 { 8624 smsatSetSensePayload( pSense, 8625 SCSI_SNSKEY_NOT_READY, 8626 0, 8627 SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED, 8628 satIOContext); 8629 8630 /*smEnqueueIO(smRoot, satIOContext);*/ 8631 8632 tdsmIOCompletedCB( smRoot, 8633 smIORequest, 8634 smIOSuccess, 8635 SCSI_STAT_CHECK_CONDITION, 8636 satIOContext->pSmSenseData, 8637 satIOContext->interruptContext ); 8638 SM_DBG1(("smsatTestUnitReady: stop state!!!\n")); 8639 return SM_RC_SUCCESS; 8640 } 8641 8642 /* 8643 * Check if format is in progress 8644 */ 8645 if (pSatDevData->satDriveState == SAT_DEV_STATE_FORMAT_IN_PROGRESS) 8646 { 8647 SM_DBG1(("smsatTestUnitReady: FORMAT_IN_PROGRESS!!!\n")); 8648 8649 smsatSetSensePayload( pSense, 8650 SCSI_SNSKEY_NOT_READY, 8651 0, 8652 SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_FORMAT_IN_PROGRESS, 8653 satIOContext); 8654 8655 /*smEnqueueIO(smRoot, satIOContext);*/ 8656 8657 tdsmIOCompletedCB( smRoot, 8658 smIORequest, 8659 smIOSuccess, 8660 SCSI_STAT_CHECK_CONDITION, 8661 satIOContext->pSmSenseData, 8662 satIOContext->interruptContext ); 8663 SM_DBG1(("smsatTestUnitReady: format in progress!!!\n")); 8664 return SM_RC_SUCCESS; 8665 } 8666 8667 /* 8668 check previously issued ATA command 8669 */ 8670 if (pSatDevData->satPendingIO != 0) 8671 { 8672 if (pSatDevData->satDeviceFaultState == agTRUE) 8673 { 8674 smsatSetSensePayload( pSense, 8675 SCSI_SNSKEY_HARDWARE_ERROR, 8676 0, 8677 SCSI_SNSCODE_LOGICAL_UNIT_FAILURE, 8678 satIOContext); 8679 8680 /*smEnqueueIO(smRoot, satIOContext);*/ 8681 8682 tdsmIOCompletedCB( smRoot, 8683 smIORequest, 8684 smIOSuccess, 8685 SCSI_STAT_CHECK_CONDITION, 8686 satIOContext->pSmSenseData, 8687 satIOContext->interruptContext ); 8688 SM_DBG1(("smsatTestUnitReady: previous command ended in error!!!\n")); 8689 return SM_RC_SUCCESS; 8690 } 8691 } 8692 8693 /* 8694 check removalbe media feature set 8695 */ 8696 if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled) 8697 { 8698 SM_DBG5(("smsatTestUnitReady: sending get media status cmnd\n")); 8699 /* send GET MEDIA STATUS command */ 8700 fis->h.fisType = 0x27; /* Reg host to device */ 8701 fis->h.c_pmPort = 0x80; /* C Bit is set */ 8702 fis->h.command = SAT_GET_MEDIA_STATUS; /* 0xDA */ 8703 fis->h.features = 0; /* FIS features NA */ 8704 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 8705 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 8706 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 8707 fis->d.device = 0; /* FIS DEV is discared in SATA */ 8708 fis->d.lbaLowExp = 0; 8709 fis->d.lbaMidExp = 0; 8710 fis->d.lbaHighExp = 0; 8711 fis->d.featuresExp = 0; 8712 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 8713 fis->d.sectorCountExp = 0; 8714 fis->d.reserved4 = 0; 8715 fis->d.control = 0; /* FIS HOB bit clear */ 8716 fis->d.reserved5 = 0; 8717 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8718 8719 /* Initialize CB for SATA completion. 8720 */ 8721 satIOContext->satCompleteCB = &smsatTestUnitReadyCB; 8722 8723 /* 8724 * Prepare SGL and send FIS to LL layer. 8725 */ 8726 satIOContext->reqType = agRequestType; /* Save it */ 8727 8728 status = smsataLLIOStart( smRoot, 8729 smIORequest, 8730 smDeviceHandle, 8731 smScsiRequest, 8732 satIOContext); 8733 8734 return (status); 8735 } 8736 /* 8737 number 6) in SAT p42 8738 send ATA CHECK POWER MODE 8739 */ 8740 SM_DBG5(("smsatTestUnitReady: sending check power mode cmnd\n")); 8741 status = smsatTestUnitReady_1( smRoot, 8742 smIORequest, 8743 smDeviceHandle, 8744 smScsiRequest, 8745 satIOContext); 8746 return (status); 8747 } 8748 8749 osGLOBAL bit32 8750 smsatTestUnitReady_1( 8751 smRoot_t *smRoot, 8752 smIORequest_t *smIORequest, 8753 smDeviceHandle_t *smDeviceHandle, 8754 smScsiInitiatorRequest_t *smScsiRequest, 8755 smSatIOContext_t *satIOContext 8756 ) 8757 { 8758 /* 8759 sends SAT_CHECK_POWER_MODE as a part of TESTUNITREADY 8760 internally generated - no directly corresponding scsi 8761 called in satIOCompleted as a part of satTestUnitReady(), SAT, revision8, 8.11.2, p42 8762 */ 8763 bit32 status; 8764 bit32 agRequestType; 8765 agsaFisRegHostToDevice_t *fis; 8766 8767 fis = satIOContext->pFis; 8768 SM_DBG5(("smsatTestUnitReady_1: start\n")); 8769 /* 8770 * Send the ATA CHECK POWER MODE command. 8771 */ 8772 fis->h.fisType = 0x27; /* Reg host to device */ 8773 fis->h.c_pmPort = 0x80; /* C Bit is set */ 8774 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */ 8775 fis->h.features = 0; 8776 fis->d.lbaLow = 0; 8777 fis->d.lbaMid = 0; 8778 fis->d.lbaHigh = 0; 8779 fis->d.device = 0; 8780 fis->d.lbaLowExp = 0; 8781 fis->d.lbaMidExp = 0; 8782 fis->d.lbaHighExp = 0; 8783 fis->d.featuresExp = 0; 8784 fis->d.sectorCount = 0; 8785 fis->d.sectorCountExp = 0; 8786 fis->d.reserved4 = 0; 8787 fis->d.control = 0; /* FIS HOB bit clear */ 8788 fis->d.reserved5 = 0; 8789 8790 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8791 8792 /* Initialize CB for SATA completion. 8793 */ 8794 satIOContext->satCompleteCB = &smsatTestUnitReadyCB; 8795 8796 /* 8797 * Prepare SGL and send FIS to LL layer. 8798 */ 8799 satIOContext->reqType = agRequestType; /* Save it */ 8800 8801 status = smsataLLIOStart( smRoot, 8802 smIORequest, 8803 smDeviceHandle, 8804 smScsiRequest, 8805 satIOContext); 8806 8807 SM_DBG5(("smsatTestUnitReady_1: return\n")); 8808 8809 return status; 8810 } 8811 8812 osGLOBAL bit32 8813 smsatInquiry( 8814 smRoot_t *smRoot, 8815 smIORequest_t *smIORequest, 8816 smDeviceHandle_t *smDeviceHandle, 8817 smScsiInitiatorRequest_t *smScsiRequest, 8818 smSatIOContext_t *satIOContext 8819 ) 8820 { 8821 /* 8822 CMDDT bit is obsolete in SPC-3 and this is assumed in SAT revision 8 8823 */ 8824 smScsiRspSense_t *pSense; 8825 smIniScsiCmnd_t *scsiCmnd; 8826 smDeviceData_t *pSatDevData; 8827 bit32 status; 8828 8829 pSense = satIOContext->pSense; 8830 scsiCmnd = &smScsiRequest->scsiCmnd; 8831 pSatDevData = satIOContext->pSatDevData; 8832 SM_DBG5(("smsatInquiry: start\n")); 8833 SM_DBG5(("smsatInquiry: pSatDevData did %d\n", pSatDevData->id)); 8834 //smhexdump("smsatInquiry", (bit8 *)scsiCmnd->cdb, 6); 8835 /* checking CONTROL */ 8836 /* NACA == 1 or LINK == 1*/ 8837 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 8838 { 8839 smsatSetSensePayload( pSense, 8840 SCSI_SNSKEY_ILLEGAL_REQUEST, 8841 0, 8842 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8843 satIOContext); 8844 /*smEnqueueIO(smRoot, satIOContext);*/ 8845 tdsmIOCompletedCB( smRoot, 8846 smIORequest, 8847 smIOSuccess, 8848 SCSI_STAT_CHECK_CONDITION, 8849 satIOContext->pSmSenseData, 8850 satIOContext->interruptContext ); 8851 SM_DBG1(("smsatInquiry: return control!!!\n")); 8852 return SM_RC_SUCCESS; 8853 } 8854 8855 /* checking EVPD and Allocation Length */ 8856 /* SPC-4 spec 6.4 p141 */ 8857 /* EVPD bit == 0 && PAGE CODE != 0 */ 8858 if ( !(scsiCmnd->cdb[1] & SCSI_EVPD_MASK) && 8859 (scsiCmnd->cdb[2] != 0) 8860 ) 8861 { 8862 smsatSetSensePayload( pSense, 8863 SCSI_SNSKEY_ILLEGAL_REQUEST, 8864 0, 8865 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8866 satIOContext); 8867 /*smEnqueueIO(smRoot, satIOContext);*/ 8868 tdsmIOCompletedCB( smRoot, 8869 smIORequest, 8870 smIOSuccess, 8871 SCSI_STAT_CHECK_CONDITION, 8872 satIOContext->pSmSenseData, 8873 satIOContext->interruptContext ); 8874 SM_DBG1(("smsatInquiry: return EVPD and PAGE CODE!!!\n")); 8875 return SM_RC_SUCCESS; 8876 } 8877 SM_DBG6(("smsatInquiry: allocation length 0x%x %d\n", ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4], ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4])); 8878 /* convert OS IO to TD internal IO */ 8879 if ( pSatDevData->IDDeviceValid == agFALSE) 8880 { 8881 status = smsatStartIDDev( 8882 smRoot, 8883 smIORequest, 8884 smDeviceHandle, 8885 smScsiRequest, 8886 satIOContext 8887 ); 8888 SM_DBG6(("smsatInquiry: end status %d\n", status)); 8889 return status; 8890 } 8891 else 8892 { 8893 SM_DBG6(("smsatInquiry: calling satInquiryIntCB\n")); 8894 smsatInquiryIntCB( 8895 smRoot, 8896 smIORequest, 8897 smDeviceHandle, 8898 smScsiRequest, 8899 satIOContext 8900 ); 8901 /*smEnqueueIO(smRoot, satIOContext);*/ 8902 return SM_RC_SUCCESS; 8903 } 8904 } 8905 8906 8907 osGLOBAL bit32 8908 smsatStartIDDev( 8909 smRoot_t *smRoot, 8910 smIORequest_t *smIORequest, 8911 smDeviceHandle_t *smDeviceHandle, 8912 smScsiInitiatorRequest_t *smScsiRequest, 8913 smSatIOContext_t *satIOContext 8914 ) 8915 { 8916 smSatInternalIo_t *satIntIo = agNULL; 8917 smDeviceData_t *satDevData = agNULL; 8918 smIORequestBody_t *smIORequestBody; 8919 smSatIOContext_t *satNewIOContext; 8920 bit32 status; 8921 8922 SM_DBG5(("smsatStartIDDev: start\n")); 8923 8924 satDevData = satIOContext->pSatDevData; 8925 8926 SM_DBG6(("smsatStartIDDev: before alloc\n")); 8927 8928 /* allocate identify device command */ 8929 satIntIo = smsatAllocIntIoResource( smRoot, 8930 smIORequest, 8931 satDevData, 8932 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */ 8933 satIntIo); 8934 8935 SM_DBG6(("smsatStartIDDev: before after\n")); 8936 8937 if (satIntIo == agNULL) 8938 { 8939 SM_DBG1(("smsatStartIDDev: can't alloacate!!!\n")); 8940 8941 /*smEnqueueIO(smRoot, satIOContext);*/ 8942 8943 return SM_RC_FAILURE; 8944 } 8945 8946 satIntIo->satOrgSmIORequest = smIORequest; /* changed */ 8947 smIORequestBody = satIntIo->satIntRequestBody; 8948 satNewIOContext = &(smIORequestBody->transport.SATA.satIOContext); 8949 8950 satNewIOContext->pSatDevData = satDevData; 8951 satNewIOContext->pFis = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 8952 satNewIOContext->pScsiCmnd = &(satIntIo->satIntSmScsiXchg.scsiCmnd); 8953 satNewIOContext->pSense = &(smIORequestBody->transport.SATA.sensePayload); 8954 satNewIOContext->pSmSenseData = &(smIORequestBody->transport.SATA.smSenseData); 8955 satNewIOContext->smRequestBody = satIntIo->satIntRequestBody; /* key fix */ 8956 satNewIOContext->interruptContext = tiInterruptContext; 8957 satNewIOContext->satIntIoContext = satIntIo; 8958 8959 satNewIOContext->psmDeviceHandle = agNULL; 8960 satNewIOContext->satOrgIOContext = satIOContext; /* changed */ 8961 8962 /* this is valid only for TD layer generated (not triggered by OS at all) IO */ 8963 satNewIOContext->smScsiXchg = &(satIntIo->satIntSmScsiXchg); 8964 8965 8966 SM_DBG6(("smsatStartIDDev: OS satIOContext %p \n", satIOContext)); 8967 SM_DBG6(("smsatStartIDDev: TD satNewIOContext %p \n", satNewIOContext)); 8968 SM_DBG6(("smsatStartIDDev: OS tiScsiXchg %p \n", satIOContext->smScsiXchg)); 8969 SM_DBG6(("smsatStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->smScsiXchg)); 8970 8971 8972 8973 SM_DBG1(("smsatStartIDDev: satNewIOContext %p smIORequestBody %p!!!\n", satNewIOContext, smIORequestBody)); 8974 8975 status = smsatSendIDDev( smRoot, 8976 &satIntIo->satIntSmIORequest, /* New smIORequest */ 8977 smDeviceHandle, 8978 satNewIOContext->smScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */ 8979 satNewIOContext); 8980 8981 if (status != SM_RC_SUCCESS) 8982 { 8983 SM_DBG1(("smsatStartIDDev: failed in sending!!!\n")); 8984 8985 smsatFreeIntIoResource( smRoot, 8986 satDevData, 8987 satIntIo); 8988 /*smEnqueueIO(smRoot, satIOContext);*/ 8989 8990 return SM_RC_FAILURE; 8991 } 8992 8993 8994 SM_DBG6(("smsatStartIDDev: end\n")); 8995 8996 return status; 8997 } 8998 8999 osGLOBAL bit32 9000 smsatSendIDDev( 9001 smRoot_t *smRoot, 9002 smIORequest_t *smIORequest, 9003 smDeviceHandle_t *smDeviceHandle, 9004 smScsiInitiatorRequest_t *smScsiRequest, 9005 smSatIOContext_t *satIOContext 9006 ) 9007 { 9008 bit32 status; 9009 bit32 agRequestType; 9010 smDeviceData_t *pSatDevData; 9011 agsaFisRegHostToDevice_t *fis; 9012 #ifdef SM_INTERNAL_DEBUG 9013 smIORequestBody_t *smIORequestBody; 9014 smSatInternalIo_t *satIntIoContext; 9015 #endif 9016 9017 pSatDevData = satIOContext->pSatDevData; 9018 fis = satIOContext->pFis; 9019 SM_DBG6(("smsatSendIDDev: start\n")); 9020 SM_DBG6(("smsatSendIDDev: did %d\n", pSatDevData->id)); 9021 #ifdef SM_INTERNAL_DEBUG 9022 satIntIoContext = satIOContext->satIntIoContext; 9023 smIORequestBody = satIntIoContext->satIntRequestBody; 9024 #endif 9025 fis->h.fisType = 0x27; /* Reg host to device */ 9026 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9027 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE) 9028 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0x40 */ 9029 else 9030 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */ 9031 fis->h.features = 0; /* FIS reserve */ 9032 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 9033 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 9034 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 9035 fis->d.device = 0; /* FIS LBA mode */ 9036 fis->d.lbaLowExp = 0; 9037 fis->d.lbaMidExp = 0; 9038 fis->d.lbaHighExp = 0; 9039 fis->d.featuresExp = 0; 9040 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 9041 fis->d.sectorCountExp = 0; 9042 fis->d.reserved4 = 0; 9043 fis->d.control = 0; /* FIS HOB bit clear */ 9044 fis->d.reserved5 = 0; 9045 9046 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 9047 9048 /* Initialize CB for SATA completion. 9049 */ 9050 satIOContext->satCompleteCB = &smsatInquiryCB; 9051 9052 /* 9053 * Prepare SGL and send FIS to LL layer. 9054 */ 9055 satIOContext->reqType = agRequestType; /* Save it */ 9056 9057 #ifdef SM_INTERNAL_DEBUG 9058 smhexdump("smsatSendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 9059 smhexdump("smsatSendIDDev LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t)); 9060 #endif 9061 status = smsataLLIOStart( smRoot, 9062 smIORequest, 9063 smDeviceHandle, 9064 smScsiRequest, 9065 satIOContext); 9066 9067 SM_DBG6(("smsatSendIDDev: end status %d\n", status)); 9068 return status; 9069 } 9070 9071 osGLOBAL bit32 9072 smsatRequestSense( 9073 smRoot_t *smRoot, 9074 smIORequest_t *smIORequest, 9075 smDeviceHandle_t *smDeviceHandle, 9076 smScsiInitiatorRequest_t *smScsiRequest, 9077 smSatIOContext_t *satIOContext 9078 ) 9079 { 9080 /* 9081 SAT Rev 8 p38, Table25 9082 sending SMART RETURN STATUS 9083 Checking SMART Treshold Exceeded Condition is done in satRequestSenseCB() 9084 Only fixed format sense data is support. In other words, we don't support DESC bit is set 9085 in Request Sense 9086 */ 9087 bit32 status; 9088 bit32 agRequestType; 9089 smScsiRspSense_t *pSense; 9090 smDeviceData_t *pSatDevData; 9091 smIniScsiCmnd_t *scsiCmnd; 9092 agsaFisRegHostToDevice_t *fis; 9093 smIORequestBody_t *smIORequestBody; 9094 smSatInternalIo_t *satIntIo = agNULL; 9095 smSatIOContext_t *satIOContext2; 9096 bit8 *pDataBuffer = agNULL; 9097 bit32 allocationLen = 0; 9098 9099 pSense = satIOContext->pSense; 9100 pSatDevData = satIOContext->pSatDevData; 9101 scsiCmnd = &smScsiRequest->scsiCmnd; 9102 fis = satIOContext->pFis; 9103 pDataBuffer = (bit8 *) smScsiRequest->sglVirtualAddr; 9104 allocationLen = scsiCmnd->cdb[4]; 9105 allocationLen = MIN(allocationLen, scsiCmnd->expDataLength); 9106 SM_DBG5(("smsatRequestSense: start\n")); 9107 9108 /* checking CONTROL */ 9109 /* NACA == 1 or LINK == 1*/ 9110 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 9111 { 9112 smsatSetSensePayload( pSense, 9113 SCSI_SNSKEY_ILLEGAL_REQUEST, 9114 0, 9115 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9116 satIOContext); 9117 sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen)); 9118 9119 /*smEnqueueIO(smRoot, satIOContext);*/ 9120 9121 tdsmIOCompletedCB( smRoot, 9122 smIORequest, 9123 smIOSuccess, 9124 SCSI_STAT_CHECK_CONDITION, 9125 satIOContext->pSmSenseData, 9126 satIOContext->interruptContext ); 9127 9128 SM_DBG1(("smsatRequestSense: return control!!!\n")); 9129 return SM_RC_SUCCESS; 9130 } 9131 9132 /* 9133 Only fixed format sense data is support. In other words, we don't support DESC bit is set 9134 in Request Sense 9135 */ 9136 if ( scsiCmnd->cdb[1] & ATA_REMOVABLE_MEDIA_DEVICE_MASK ) 9137 { 9138 smsatSetSensePayload( pSense, 9139 SCSI_SNSKEY_ILLEGAL_REQUEST, 9140 0, 9141 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9142 satIOContext); 9143 sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen)); 9144 9145 /*smEnqueueIO(smRoot, satIOContext);*/ 9146 9147 tdsmIOCompletedCB( smRoot, 9148 smIORequest, 9149 smIOSuccess, 9150 SCSI_STAT_CHECK_CONDITION, 9151 satIOContext->pSmSenseData, 9152 satIOContext->interruptContext ); 9153 9154 SM_DBG1(("smsatRequestSense: DESC bit is set, which we don't support!!!\n")); 9155 return SM_RC_SUCCESS; 9156 } 9157 9158 9159 if (pSatDevData->satSMARTEnabled == agTRUE) 9160 { 9161 /* sends SMART RETURN STATUS */ 9162 fis->h.fisType = 0x27; /* Reg host to device */ 9163 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9164 9165 fis->h.command = SAT_SMART; /* 0xB0 */ 9166 fis->h.features = SAT_SMART_RETURN_STATUS; /* FIS features */ 9167 fis->d.featuresExp = 0; /* FIS reserve */ 9168 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 9169 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 9170 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 9171 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 9172 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 9173 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 9174 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 9175 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 9176 fis->d.device = 0; /* FIS DEV is discared in SATA */ 9177 fis->d.control = 0; /* FIS HOB bit clear */ 9178 fis->d.reserved4 = 0; 9179 fis->d.reserved5 = 0; 9180 9181 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9182 /* Initialize CB for SATA completion. 9183 */ 9184 satIOContext->satCompleteCB = &smsatRequestSenseCB; 9185 9186 /* 9187 * Prepare SGL and send FIS to LL layer. 9188 */ 9189 satIOContext->reqType = agRequestType; /* Save it */ 9190 9191 status = smsataLLIOStart( smRoot, 9192 smIORequest, 9193 smDeviceHandle, 9194 smScsiRequest, 9195 satIOContext); 9196 9197 SM_DBG4(("smsatRequestSense: if return, status %d\n", status)); 9198 return (status); 9199 } 9200 else 9201 { 9202 /*allocate iocontext for xmitting xmit SAT_CHECK_POWER_MODE 9203 then call satRequestSense2 */ 9204 9205 SM_DBG4(("smsatRequestSense: before satIntIo %p\n", satIntIo)); 9206 /* allocate iocontext */ 9207 satIntIo = smsatAllocIntIoResource( smRoot, 9208 smIORequest, /* original request */ 9209 pSatDevData, 9210 smScsiRequest->scsiCmnd.expDataLength, 9211 satIntIo); 9212 9213 SM_DBG4(("smsatRequestSense: after satIntIo %p\n", satIntIo)); 9214 9215 if (satIntIo == agNULL) 9216 { 9217 /* failed during sending SMART RETURN STATUS */ 9218 smsatSetSensePayload( pSense, 9219 SCSI_SNSKEY_NO_SENSE, 9220 0, 9221 SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE, 9222 satIOContext); 9223 sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen)); 9224 9225 /*smEnqueueIO(smRoot, satIOContext);*/ 9226 9227 tdsmIOCompletedCB( smRoot, 9228 smIORequest, 9229 smIOSuccess, 9230 SCSI_STAT_GOOD, 9231 agNULL, 9232 satIOContext->interruptContext ); 9233 9234 SM_DBG1(("smsatRequestSense: else fail 1!!!\n")); 9235 return SM_RC_SUCCESS; 9236 } /* end of memory allocation failure */ 9237 9238 9239 /* 9240 * Need to initialize all the fields within satIOContext except 9241 * reqType and satCompleteCB which will be set depending on cmd. 9242 */ 9243 9244 if (satIntIo == agNULL) 9245 { 9246 SM_DBG4(("smsatRequestSense: satIntIo is NULL\n")); 9247 } 9248 else 9249 { 9250 SM_DBG4(("smsatRequestSense: satIntIo is NOT NULL\n")); 9251 } 9252 /* use this --- tttttthe one the same */ 9253 9254 9255 satIntIo->satOrgSmIORequest = smIORequest; 9256 smIORequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody; 9257 satIOContext2 = &(smIORequestBody->transport.SATA.satIOContext); 9258 9259 satIOContext2->pSatDevData = pSatDevData; 9260 satIOContext2->pFis = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 9261 satIOContext2->pScsiCmnd = &(satIntIo->satIntSmScsiXchg.scsiCmnd); 9262 satIOContext2->pSense = &(smIORequestBody->transport.SATA.sensePayload); 9263 satIOContext2->pSmSenseData = &(smIORequestBody->transport.SATA.smSenseData); 9264 satIOContext2->pSmSenseData->senseData = satIOContext2->pSense; 9265 satIOContext2->smRequestBody = satIntIo->satIntRequestBody; 9266 satIOContext2->interruptContext = satIOContext->interruptContext; 9267 satIOContext2->satIntIoContext = satIntIo; 9268 satIOContext2->psmDeviceHandle = smDeviceHandle; 9269 satIOContext2->satOrgIOContext = satIOContext; 9270 9271 SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.len %d\n", satIntIo->satIntSmScsiXchg.smSgl1.len)); 9272 9273 SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.upper %d\n", satIntIo->satIntSmScsiXchg.smSgl1.upper)); 9274 9275 SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.lower %d\n", satIntIo->satIntSmScsiXchg.smSgl1.lower)); 9276 9277 SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.type %d\n", satIntIo->satIntSmScsiXchg.smSgl1.type)); 9278 9279 status = smsatRequestSense_1( smRoot, 9280 &(satIntIo->satIntSmIORequest), 9281 smDeviceHandle, 9282 &(satIntIo->satIntSmScsiXchg), 9283 satIOContext2); 9284 9285 if (status != SM_RC_SUCCESS) 9286 { 9287 smsatFreeIntIoResource( smRoot, 9288 pSatDevData, 9289 satIntIo); 9290 9291 /* failed during sending SMART RETURN STATUS */ 9292 smsatSetSensePayload( pSense, 9293 SCSI_SNSKEY_NO_SENSE, 9294 0, 9295 SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE, 9296 satIOContext); 9297 sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen)); 9298 9299 /*smEnqueueIO(smRoot, satIOContext);*/ 9300 9301 tdsmIOCompletedCB( smRoot, 9302 smIORequest, 9303 smIOSuccess, 9304 SCSI_STAT_CHECK_CONDITION, 9305 agNULL, 9306 satIOContext->interruptContext ); 9307 9308 SM_DBG1(("smsatRequestSense: else fail 2!!!\n")); 9309 return SM_RC_SUCCESS; 9310 } 9311 SM_DBG4(("smsatRequestSense: else return success\n")); 9312 return SM_RC_SUCCESS; 9313 } 9314 } 9315 9316 osGLOBAL bit32 9317 smsatRequestSense_1( 9318 smRoot_t *smRoot, 9319 smIORequest_t *smIORequest, 9320 smDeviceHandle_t *smDeviceHandle, 9321 smScsiInitiatorRequest_t *smScsiRequest, 9322 smSatIOContext_t *satIOContext 9323 ) 9324 { 9325 /* 9326 sends SAT_CHECK_POWER_MODE 9327 */ 9328 bit32 status; 9329 bit32 agRequestType; 9330 agsaFisRegHostToDevice_t *fis; 9331 9332 fis = satIOContext->pFis; 9333 SM_DBG5(("smsatRequestSense_1: start\n")); 9334 /* 9335 * Send the ATA CHECK POWER MODE command. 9336 */ 9337 fis->h.fisType = 0x27; /* Reg host to device */ 9338 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9339 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */ 9340 fis->h.features = 0; 9341 fis->d.lbaLow = 0; 9342 fis->d.lbaMid = 0; 9343 fis->d.lbaHigh = 0; 9344 fis->d.device = 0; 9345 fis->d.lbaLowExp = 0; 9346 fis->d.lbaMidExp = 0; 9347 fis->d.lbaHighExp = 0; 9348 fis->d.featuresExp = 0; 9349 fis->d.sectorCount = 0; 9350 fis->d.sectorCountExp = 0; 9351 fis->d.reserved4 = 0; 9352 fis->d.control = 0; /* FIS HOB bit clear */ 9353 fis->d.reserved5 = 0; 9354 9355 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9356 9357 /* Initialize CB for SATA completion. 9358 */ 9359 satIOContext->satCompleteCB = &smsatRequestSenseCB; 9360 9361 /* 9362 * Prepare SGL and send FIS to LL layer. 9363 */ 9364 satIOContext->reqType = agRequestType; /* Save it */ 9365 9366 9367 SM_DBG4(("smsatRequestSense_1: smSgl1.len %d\n", smScsiRequest->smSgl1.len)); 9368 9369 SM_DBG4(("smsatRequestSense_1: smSgl1.upper %d\n", smScsiRequest->smSgl1.upper)); 9370 9371 SM_DBG4(("smsatRequestSense_1: smSgl1.lower %d\n", smScsiRequest->smSgl1.lower)); 9372 9373 SM_DBG4(("smsatRequestSense_1: smSgl1.type %d\n", smScsiRequest->smSgl1.type)); 9374 9375 // smhexdump("smsatRequestSense_1", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t)); 9376 9377 status = smsataLLIOStart( smRoot, 9378 smIORequest, 9379 smDeviceHandle, 9380 smScsiRequest, 9381 satIOContext); 9382 9383 9384 9385 return status; 9386 } 9387 9388 osGLOBAL bit32 9389 smsatModeSense6( 9390 smRoot_t *smRoot, 9391 smIORequest_t *smIORequest, 9392 smDeviceHandle_t *smDeviceHandle, 9393 smScsiInitiatorRequest_t *smScsiRequest, 9394 smSatIOContext_t *satIOContext 9395 ) 9396 { 9397 smScsiRspSense_t *pSense; 9398 bit32 allocationLen; 9399 smIniScsiCmnd_t *scsiCmnd; 9400 bit32 pageSupported; 9401 bit8 page; 9402 bit8 *pModeSense; /* Mode Sense data buffer */ 9403 smDeviceData_t *pSatDevData; 9404 bit8 PC; 9405 bit8 AllPages[MODE_SENSE6_RETURN_ALL_PAGES_LEN]; 9406 bit8 Control[MODE_SENSE6_CONTROL_PAGE_LEN]; 9407 bit8 RWErrorRecovery[MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN]; 9408 bit8 Caching[MODE_SENSE6_CACHING_LEN]; 9409 bit8 InfoExceptionCtrl[MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN]; 9410 bit8 lenRead = 0; 9411 9412 9413 pSense = satIOContext->pSense; 9414 scsiCmnd = &smScsiRequest->scsiCmnd; 9415 pModeSense = (bit8 *) smScsiRequest->sglVirtualAddr; 9416 pSatDevData = satIOContext->pSatDevData; 9417 9418 //smhexdump("smsatModeSense6", (bit8 *)scsiCmnd->cdb, 6); 9419 SM_DBG5(("smsatModeSense6: start\n")); 9420 /* checking CONTROL */ 9421 /* NACA == 1 or LINK == 1*/ 9422 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 9423 { 9424 smsatSetSensePayload( pSense, 9425 SCSI_SNSKEY_ILLEGAL_REQUEST, 9426 0, 9427 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9428 satIOContext); 9429 /*smEnqueueIO(smRoot, satIOContext);*/ 9430 tdsmIOCompletedCB( smRoot, 9431 smIORequest, 9432 smIOSuccess, 9433 SCSI_STAT_CHECK_CONDITION, 9434 satIOContext->pSmSenseData, 9435 satIOContext->interruptContext ); 9436 SM_DBG1(("smsatModeSense6: return control!!!\n")); 9437 return SM_RC_SUCCESS; 9438 } 9439 /* checking PC(Page Control) 9440 SAT revion 8, 8.5.3 p33 and 10.1.2, p66 9441 */ 9442 PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PC_MASK); 9443 if (PC != 0) 9444 { 9445 smsatSetSensePayload( pSense, 9446 SCSI_SNSKEY_ILLEGAL_REQUEST, 9447 0, 9448 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9449 satIOContext); 9450 /*smEnqueueIO(smRoot, satIOContext);*/ 9451 tdsmIOCompletedCB( smRoot, 9452 smIORequest, 9453 smIOSuccess, 9454 SCSI_STAT_CHECK_CONDITION, 9455 satIOContext->pSmSenseData, 9456 satIOContext->interruptContext ); 9457 SM_DBG1(("smsatModeSense6: return due to PC value pc 0x%x!!!\n", PC >> 6)); 9458 return SM_RC_SUCCESS; 9459 } 9460 /* reading PAGE CODE */ 9461 page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PAGE_CODE_MASK); 9462 9463 9464 SM_DBG5(("smsatModeSense6: page=0x%x\n", page)); 9465 9466 allocationLen = scsiCmnd->cdb[4]; 9467 allocationLen = MIN(allocationLen, scsiCmnd->expDataLength); 9468 /* 9469 Based on page code value, returns a corresponding mode page 9470 note: no support for subpage 9471 */ 9472 switch(page) 9473 { 9474 case MODESENSE_RETURN_ALL_PAGES: 9475 case MODESENSE_CONTROL_PAGE: /* control */ 9476 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */ 9477 case MODESENSE_CACHING: /* caching */ 9478 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/ 9479 pageSupported = agTRUE; 9480 break; 9481 case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */ 9482 default: 9483 pageSupported = agFALSE; 9484 break; 9485 } 9486 9487 if (pageSupported == agFALSE) 9488 { 9489 9490 SM_DBG1(("smsatModeSense6 *** ERROR *** not supported page 0x%x did %d!!!\n", 9491 page, pSatDevData->id)); 9492 9493 smsatSetSensePayload( pSense, 9494 SCSI_SNSKEY_ILLEGAL_REQUEST, 9495 0, 9496 SCSI_SNSCODE_INVALID_COMMAND, 9497 satIOContext); 9498 9499 /*smEnqueueIO(smRoot, satIOContext);*/ 9500 9501 tdsmIOCompletedCB( smRoot, 9502 smIORequest, 9503 smIOSuccess, 9504 SCSI_STAT_CHECK_CONDITION, 9505 satIOContext->pSmSenseData, 9506 satIOContext->interruptContext ); 9507 return SM_RC_SUCCESS; 9508 } 9509 9510 switch(page) 9511 { 9512 case MODESENSE_RETURN_ALL_PAGES: 9513 lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_RETURN_ALL_PAGES_LEN); 9514 break; 9515 case MODESENSE_CONTROL_PAGE: /* control */ 9516 lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_CONTROL_PAGE_LEN); 9517 break; 9518 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */ 9519 lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN); 9520 break; 9521 case MODESENSE_CACHING: /* caching */ 9522 lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_CACHING_LEN); 9523 break; 9524 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/ 9525 lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN); 9526 break; 9527 default: 9528 SM_DBG1(("smsatModeSense6: default error page %d!!!\n", page)); 9529 break; 9530 } 9531 9532 if (page == MODESENSE_RETURN_ALL_PAGES) 9533 { 9534 SM_DBG5(("smsatModeSense6: MODESENSE_RETURN_ALL_PAGES\n")); 9535 AllPages[0] = (bit8)(lenRead - 1); 9536 AllPages[1] = 0x00; /* default medium type (currently mounted medium type) */ 9537 AllPages[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 9538 AllPages[3] = 0x08; /* block descriptor length */ 9539 9540 /* 9541 * Fill-up direct-access device block-descriptor, SAT, Table 19 9542 */ 9543 9544 /* density code */ 9545 AllPages[4] = 0x04; /* density-code : reserved for direct-access */ 9546 /* number of blocks */ 9547 AllPages[5] = 0x00; /* unspecified */ 9548 AllPages[6] = 0x00; /* unspecified */ 9549 AllPages[7] = 0x00; /* unspecified */ 9550 /* reserved */ 9551 AllPages[8] = 0x00; /* reserved */ 9552 /* Block size */ 9553 AllPages[9] = 0x00; 9554 AllPages[10] = 0x02; /* Block size is always 512 bytes */ 9555 AllPages[11] = 0x00; 9556 9557 /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */ 9558 AllPages[12] = 0x01; /* page code */ 9559 AllPages[13] = 0x0A; /* page length */ 9560 AllPages[14] = 0x40; /* ARRE is set */ 9561 AllPages[15] = 0x00; 9562 AllPages[16] = 0x00; 9563 AllPages[17] = 0x00; 9564 AllPages[18] = 0x00; 9565 AllPages[19] = 0x00; 9566 AllPages[20] = 0x00; 9567 AllPages[21] = 0x00; 9568 AllPages[22] = 0x00; 9569 AllPages[23] = 0x00; 9570 /* MODESENSE_CACHING */ 9571 AllPages[24] = 0x08; /* page code */ 9572 AllPages[25] = 0x12; /* page length */ 9573 if (pSatDevData->satWriteCacheEnabled == agTRUE) 9574 { 9575 AllPages[26] = 0x04;/* WCE bit is set */ 9576 } 9577 else 9578 { 9579 AllPages[26] = 0x00;/* WCE bit is NOT set */ 9580 } 9581 9582 AllPages[27] = 0x00; 9583 AllPages[28] = 0x00; 9584 AllPages[29] = 0x00; 9585 AllPages[30] = 0x00; 9586 AllPages[31] = 0x00; 9587 AllPages[32] = 0x00; 9588 AllPages[33] = 0x00; 9589 AllPages[34] = 0x00; 9590 AllPages[35] = 0x00; 9591 if (pSatDevData->satLookAheadEnabled == agTRUE) 9592 { 9593 AllPages[36] = 0x00;/* DRA bit is NOT set */ 9594 } 9595 else 9596 { 9597 AllPages[36] = 0x20;/* DRA bit is set */ 9598 } 9599 AllPages[37] = 0x00; 9600 AllPages[38] = 0x00; 9601 AllPages[39] = 0x00; 9602 AllPages[40] = 0x00; 9603 AllPages[41] = 0x00; 9604 AllPages[42] = 0x00; 9605 AllPages[43] = 0x00; 9606 /* MODESENSE_CONTROL_PAGE */ 9607 AllPages[44] = 0x0A; /* page code */ 9608 AllPages[45] = 0x0A; /* page length */ 9609 AllPages[46] = 0x02; /* only GLTSD bit is set */ 9610 if (pSatDevData->satNCQ == agTRUE) 9611 { 9612 AllPages[47] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/ 9613 } 9614 else 9615 { 9616 AllPages[47] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */ 9617 } 9618 AllPages[48] = 0x00; 9619 AllPages[49] = 0x00; 9620 AllPages[50] = 0x00; /* obsolete */ 9621 AllPages[51] = 0x00; /* obsolete */ 9622 AllPages[52] = 0xFF; /* Busy Timeout Period */ 9623 AllPages[53] = 0xFF; /* Busy Timeout Period */ 9624 AllPages[54] = 0x00; /* we don't support non-000b value for the self-test code */ 9625 AllPages[55] = 0x00; /* we don't support non-000b value for the self-test code */ 9626 /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */ 9627 AllPages[56] = 0x1C; /* page code */ 9628 AllPages[57] = 0x0A; /* page length */ 9629 if (pSatDevData->satSMARTEnabled == agTRUE) 9630 { 9631 AllPages[58] = 0x00;/* DEXCPT bit is NOT set */ 9632 } 9633 else 9634 { 9635 AllPages[58] = 0x08;/* DEXCPT bit is set */ 9636 } 9637 AllPages[59] = 0x00; /* We don't support MRIE */ 9638 AllPages[60] = 0x00; /* Interval timer vendor-specific */ 9639 AllPages[61] = 0x00; 9640 AllPages[62] = 0x00; 9641 AllPages[63] = 0x00; 9642 AllPages[64] = 0x00; /* REPORT-COUNT */ 9643 AllPages[65] = 0x00; 9644 AllPages[66] = 0x00; 9645 AllPages[67] = 0x00; 9646 9647 sm_memcpy(pModeSense, &AllPages, lenRead); 9648 } 9649 else if (page == MODESENSE_CONTROL_PAGE) 9650 { 9651 SM_DBG5(("smsatModeSense6: MODESENSE_CONTROL_PAGE\n")); 9652 Control[0] = MODE_SENSE6_CONTROL_PAGE_LEN - 1; 9653 Control[1] = 0x00; /* default medium type (currently mounted medium type) */ 9654 Control[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 9655 Control[3] = 0x08; /* block descriptor length */ 9656 /* 9657 * Fill-up direct-access device block-descriptor, SAT, Table 19 9658 */ 9659 9660 /* density code */ 9661 Control[4] = 0x04; /* density-code : reserved for direct-access */ 9662 /* number of blocks */ 9663 Control[5] = 0x00; /* unspecified */ 9664 Control[6] = 0x00; /* unspecified */ 9665 Control[7] = 0x00; /* unspecified */ 9666 /* reserved */ 9667 Control[8] = 0x00; /* reserved */ 9668 /* Block size */ 9669 Control[9] = 0x00; 9670 Control[10] = 0x02; /* Block size is always 512 bytes */ 9671 Control[11] = 0x00; 9672 /* 9673 * Fill-up control mode page, SAT, Table 65 9674 */ 9675 Control[12] = 0x0A; /* page code */ 9676 Control[13] = 0x0A; /* page length */ 9677 Control[14] = 0x02; /* only GLTSD bit is set */ 9678 if (pSatDevData->satNCQ == agTRUE) 9679 { 9680 Control[15] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/ 9681 } 9682 else 9683 { 9684 Control[15] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */ 9685 } 9686 Control[16] = 0x00; 9687 Control[17] = 0x00; 9688 Control[18] = 0x00; /* obsolete */ 9689 Control[19] = 0x00; /* obsolete */ 9690 Control[20] = 0xFF; /* Busy Timeout Period */ 9691 Control[21] = 0xFF; /* Busy Timeout Period */ 9692 Control[22] = 0x00; /* we don't support non-000b value for the self-test code */ 9693 Control[23] = 0x00; /* we don't support non-000b value for the self-test code */ 9694 9695 sm_memcpy(pModeSense, &Control, lenRead); 9696 9697 } 9698 else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE) 9699 { 9700 SM_DBG5(("smsatModeSense6: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n")); 9701 RWErrorRecovery[0] = MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN - 1; 9702 RWErrorRecovery[1] = 0x00; /* default medium type (currently mounted medium type) */ 9703 RWErrorRecovery[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 9704 RWErrorRecovery[3] = 0x08; /* block descriptor length */ 9705 /* 9706 * Fill-up direct-access device block-descriptor, SAT, Table 19 9707 */ 9708 9709 /* density code */ 9710 RWErrorRecovery[4] = 0x04; /* density-code : reserved for direct-access */ 9711 /* number of blocks */ 9712 RWErrorRecovery[5] = 0x00; /* unspecified */ 9713 RWErrorRecovery[6] = 0x00; /* unspecified */ 9714 RWErrorRecovery[7] = 0x00; /* unspecified */ 9715 /* reserved */ 9716 RWErrorRecovery[8] = 0x00; /* reserved */ 9717 /* Block size */ 9718 RWErrorRecovery[9] = 0x00; 9719 RWErrorRecovery[10] = 0x02; /* Block size is always 512 bytes */ 9720 RWErrorRecovery[11] = 0x00; 9721 /* 9722 * Fill-up Read-Write Error Recovery mode page, SAT, Table 66 9723 */ 9724 RWErrorRecovery[12] = 0x01; /* page code */ 9725 RWErrorRecovery[13] = 0x0A; /* page length */ 9726 RWErrorRecovery[14] = 0x40; /* ARRE is set */ 9727 RWErrorRecovery[15] = 0x00; 9728 RWErrorRecovery[16] = 0x00; 9729 RWErrorRecovery[17] = 0x00; 9730 RWErrorRecovery[18] = 0x00; 9731 RWErrorRecovery[19] = 0x00; 9732 RWErrorRecovery[20] = 0x00; 9733 RWErrorRecovery[21] = 0x00; 9734 RWErrorRecovery[22] = 0x00; 9735 RWErrorRecovery[23] = 0x00; 9736 9737 sm_memcpy(pModeSense, &RWErrorRecovery, lenRead); 9738 9739 } 9740 else if (page == MODESENSE_CACHING) 9741 { 9742 SM_DBG5(("smsatModeSense6: MODESENSE_CACHING\n")); 9743 /* special case */ 9744 if (allocationLen == 4 && page == MODESENSE_CACHING) 9745 { 9746 SM_DBG5(("smsatModeSense6: linux 2.6.8.24 support\n")); 9747 9748 Caching[0] = 0x20 - 1; /* 32 - 1 */ 9749 Caching[1] = 0x00; /* default medium type (currently mounted medium type) */ 9750 Caching[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 9751 Caching[3] = 0x08; /* block descriptor length */ 9752 9753 sm_memcpy(pModeSense, &Caching, 4); 9754 /*smEnqueueIO(smRoot, satIOContext);*/ 9755 9756 tdsmIOCompletedCB( smRoot, 9757 smIORequest, 9758 smIOSuccess, 9759 SCSI_STAT_GOOD, 9760 agNULL, 9761 satIOContext->interruptContext); 9762 return SM_RC_SUCCESS; 9763 } 9764 Caching[0] = MODE_SENSE6_CACHING_LEN - 1; 9765 Caching[1] = 0x00; /* default medium type (currently mounted medium type) */ 9766 Caching[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 9767 Caching[3] = 0x08; /* block descriptor length */ 9768 /* 9769 * Fill-up direct-access device block-descriptor, SAT, Table 19 9770 */ 9771 9772 /* density code */ 9773 Caching[4] = 0x04; /* density-code : reserved for direct-access */ 9774 /* number of blocks */ 9775 Caching[5] = 0x00; /* unspecified */ 9776 Caching[6] = 0x00; /* unspecified */ 9777 Caching[7] = 0x00; /* unspecified */ 9778 /* reserved */ 9779 Caching[8] = 0x00; /* reserved */ 9780 /* Block size */ 9781 Caching[9] = 0x00; 9782 Caching[10] = 0x02; /* Block size is always 512 bytes */ 9783 Caching[11] = 0x00; 9784 /* 9785 * Fill-up Caching mode page, SAT, Table 67 9786 */ 9787 /* length 20 */ 9788 Caching[12] = 0x08; /* page code */ 9789 Caching[13] = 0x12; /* page length */ 9790 if (pSatDevData->satWriteCacheEnabled == agTRUE) 9791 { 9792 Caching[14] = 0x04;/* WCE bit is set */ 9793 } 9794 else 9795 { 9796 Caching[14] = 0x00;/* WCE bit is NOT set */ 9797 } 9798 9799 Caching[15] = 0x00; 9800 Caching[16] = 0x00; 9801 Caching[17] = 0x00; 9802 Caching[18] = 0x00; 9803 Caching[19] = 0x00; 9804 Caching[20] = 0x00; 9805 Caching[21] = 0x00; 9806 Caching[22] = 0x00; 9807 Caching[23] = 0x00; 9808 if (pSatDevData->satLookAheadEnabled == agTRUE) 9809 { 9810 Caching[24] = 0x00;/* DRA bit is NOT set */ 9811 } 9812 else 9813 { 9814 Caching[24] = 0x20;/* DRA bit is set */ 9815 } 9816 Caching[25] = 0x00; 9817 Caching[26] = 0x00; 9818 Caching[27] = 0x00; 9819 Caching[28] = 0x00; 9820 Caching[29] = 0x00; 9821 Caching[30] = 0x00; 9822 Caching[31] = 0x00; 9823 9824 sm_memcpy(pModeSense, &Caching, lenRead); 9825 9826 } 9827 else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE) 9828 { 9829 SM_DBG5(("smsatModeSense6: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n")); 9830 InfoExceptionCtrl[0] = MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN - 1; 9831 InfoExceptionCtrl[1] = 0x00; /* default medium type (currently mounted medium type) */ 9832 InfoExceptionCtrl[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 9833 InfoExceptionCtrl[3] = 0x08; /* block descriptor length */ 9834 /* 9835 * Fill-up direct-access device block-descriptor, SAT, Table 19 9836 */ 9837 9838 /* density code */ 9839 InfoExceptionCtrl[4] = 0x04; /* density-code : reserved for direct-access */ 9840 /* number of blocks */ 9841 InfoExceptionCtrl[5] = 0x00; /* unspecified */ 9842 InfoExceptionCtrl[6] = 0x00; /* unspecified */ 9843 InfoExceptionCtrl[7] = 0x00; /* unspecified */ 9844 /* reserved */ 9845 InfoExceptionCtrl[8] = 0x00; /* reserved */ 9846 /* Block size */ 9847 InfoExceptionCtrl[9] = 0x00; 9848 InfoExceptionCtrl[10] = 0x02; /* Block size is always 512 bytes */ 9849 InfoExceptionCtrl[11] = 0x00; 9850 /* 9851 * Fill-up informational-exceptions control mode page, SAT, Table 68 9852 */ 9853 InfoExceptionCtrl[12] = 0x1C; /* page code */ 9854 InfoExceptionCtrl[13] = 0x0A; /* page length */ 9855 if (pSatDevData->satSMARTEnabled == agTRUE) 9856 { 9857 InfoExceptionCtrl[14] = 0x00;/* DEXCPT bit is NOT set */ 9858 } 9859 else 9860 { 9861 InfoExceptionCtrl[14] = 0x08;/* DEXCPT bit is set */ 9862 } 9863 InfoExceptionCtrl[15] = 0x00; /* We don't support MRIE */ 9864 InfoExceptionCtrl[16] = 0x00; /* Interval timer vendor-specific */ 9865 InfoExceptionCtrl[17] = 0x00; 9866 InfoExceptionCtrl[18] = 0x00; 9867 InfoExceptionCtrl[19] = 0x00; 9868 InfoExceptionCtrl[20] = 0x00; /* REPORT-COUNT */ 9869 InfoExceptionCtrl[21] = 0x00; 9870 InfoExceptionCtrl[22] = 0x00; 9871 InfoExceptionCtrl[23] = 0x00; 9872 sm_memcpy(pModeSense, &InfoExceptionCtrl, lenRead); 9873 9874 } 9875 else 9876 { 9877 /* Error */ 9878 SM_DBG1(("smsatModeSense6: Error page %d!!!\n", page)); 9879 smsatSetSensePayload( pSense, 9880 SCSI_SNSKEY_ILLEGAL_REQUEST, 9881 0, 9882 SCSI_SNSCODE_INVALID_COMMAND, 9883 satIOContext); 9884 9885 /*smEnqueueIO(smRoot, satIOContext);*/ 9886 9887 tdsmIOCompletedCB( smRoot, 9888 smIORequest, 9889 smIOSuccess, 9890 SCSI_STAT_CHECK_CONDITION, 9891 satIOContext->pSmSenseData, 9892 satIOContext->interruptContext ); 9893 return SM_RC_SUCCESS; 9894 } 9895 9896 /* there can be only underrun not overrun in error case */ 9897 if (allocationLen > lenRead) 9898 { 9899 SM_DBG6(("smsatModeSense6 reporting underrun lenRead=0x%x allocationLen=0x%x\n", lenRead, allocationLen)); 9900 9901 /*smEnqueueIO(smRoot, satIOContext);*/ 9902 9903 tdsmIOCompletedCB( smRoot, 9904 smIORequest, 9905 smIOUnderRun, 9906 allocationLen - lenRead, 9907 agNULL, 9908 satIOContext->interruptContext ); 9909 9910 9911 } 9912 else 9913 { 9914 /*smEnqueueIO(smRoot, satIOContext);*/ 9915 9916 tdsmIOCompletedCB( smRoot, 9917 smIORequest, 9918 smIOSuccess, 9919 SCSI_STAT_GOOD, 9920 agNULL, 9921 satIOContext->interruptContext); 9922 } 9923 9924 return SM_RC_SUCCESS; 9925 9926 } 9927 9928 osGLOBAL bit32 9929 smsatModeSense10( 9930 smRoot_t *smRoot, 9931 smIORequest_t *smIORequest, 9932 smDeviceHandle_t *smDeviceHandle, 9933 smScsiInitiatorRequest_t *smScsiRequest, 9934 smSatIOContext_t *satIOContext 9935 ) 9936 { 9937 smScsiRspSense_t *pSense; 9938 bit32 allocationLen; 9939 smIniScsiCmnd_t *scsiCmnd; 9940 bit32 pageSupported; 9941 bit8 page; 9942 bit8 *pModeSense; /* Mode Sense data buffer */ 9943 smDeviceData_t *pSatDevData; 9944 bit8 PC; /* page control */ 9945 bit8 LLBAA; /* Long LBA Accepted */ 9946 bit32 index; 9947 bit8 AllPages[MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN]; 9948 bit8 Control[MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN]; 9949 bit8 RWErrorRecovery[MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN]; 9950 bit8 Caching[MODE_SENSE10_CACHING_LLBAA_LEN]; 9951 bit8 InfoExceptionCtrl[MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN]; 9952 bit8 lenRead = 0; 9953 9954 pSense = satIOContext->pSense; 9955 scsiCmnd = &smScsiRequest->scsiCmnd; 9956 pModeSense = (bit8 *) smScsiRequest->sglVirtualAddr; 9957 pSatDevData = satIOContext->pSatDevData; 9958 SM_DBG5(("smsatModeSense10: start\n")); 9959 /* checking CONTROL */ 9960 /* NACA == 1 or LINK == 1*/ 9961 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 9962 { 9963 smsatSetSensePayload( pSense, 9964 SCSI_SNSKEY_ILLEGAL_REQUEST, 9965 0, 9966 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9967 satIOContext); 9968 9969 /*smEnqueueIO(smRoot, satIOContext);*/ 9970 9971 tdsmIOCompletedCB( smRoot, 9972 smIORequest, 9973 smIOSuccess, 9974 SCSI_STAT_CHECK_CONDITION, 9975 satIOContext->pSmSenseData, 9976 satIOContext->interruptContext ); 9977 9978 SM_DBG1(("smsatModeSense10: return control!!!\n")); 9979 return SM_RC_SUCCESS; 9980 } 9981 9982 /* checking PC(Page Control) 9983 SAT revion 8, 8.5.3 p33 and 10.1.2, p66 9984 */ 9985 PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PC_MASK); 9986 if (PC != 0) 9987 { 9988 smsatSetSensePayload( pSense, 9989 SCSI_SNSKEY_ILLEGAL_REQUEST, 9990 0, 9991 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9992 satIOContext); 9993 9994 /*smEnqueueIO(smRoot, satIOContext);*/ 9995 9996 tdsmIOCompletedCB( smRoot, 9997 smIORequest, 9998 smIOSuccess, 9999 SCSI_STAT_CHECK_CONDITION, 10000 satIOContext->pSmSenseData, 10001 satIOContext->interruptContext ); 10002 10003 SM_DBG1(("smsatModeSense10: return due to PC value pc 0x%x!!!\n", PC)); 10004 return SM_RC_SUCCESS; 10005 } 10006 10007 /* finding LLBAA bit */ 10008 LLBAA = (bit8)((scsiCmnd->cdb[1]) & SCSI_MODE_SENSE10_LLBAA_MASK); 10009 10010 /* reading PAGE CODE */ 10011 page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PAGE_CODE_MASK); 10012 SM_DBG5(("smsatModeSense10: page=0x%x, did %d\n", page, pSatDevData->id)); 10013 allocationLen = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 10014 allocationLen = MIN(allocationLen, scsiCmnd->expDataLength); 10015 10016 /* 10017 Based on page code value, returns a corresponding mode page 10018 note: no support for subpage 10019 */ 10020 switch(page) 10021 { 10022 case MODESENSE_RETURN_ALL_PAGES: /* return all pages */ 10023 case MODESENSE_CONTROL_PAGE: /* control */ 10024 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */ 10025 case MODESENSE_CACHING: /* caching */ 10026 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/ 10027 pageSupported = agTRUE; 10028 break; 10029 case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */ 10030 default: 10031 pageSupported = agFALSE; 10032 break; 10033 } 10034 if (pageSupported == agFALSE) 10035 { 10036 SM_DBG1(("smsatModeSense10 *** ERROR *** not supported page 0x%x did %d!!!\n", page, pSatDevData->id)); 10037 10038 smsatSetSensePayload( pSense, 10039 SCSI_SNSKEY_ILLEGAL_REQUEST, 10040 0, 10041 SCSI_SNSCODE_INVALID_COMMAND, 10042 satIOContext); 10043 /*smEnqueueIO(smRoot, satIOContext);*/ 10044 tdsmIOCompletedCB( smRoot, 10045 smIORequest, 10046 smIOSuccess, 10047 SCSI_STAT_CHECK_CONDITION, 10048 satIOContext->pSmSenseData, 10049 satIOContext->interruptContext ); 10050 return SM_RC_SUCCESS; 10051 } 10052 switch(page) 10053 { 10054 case MODESENSE_RETURN_ALL_PAGES: 10055 if (LLBAA) 10056 { 10057 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN); 10058 } 10059 else 10060 { 10061 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_RETURN_ALL_PAGES_LEN); 10062 } 10063 break; 10064 case MODESENSE_CONTROL_PAGE: /* control */ 10065 if (LLBAA) 10066 { 10067 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN); 10068 } 10069 else 10070 { 10071 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CONTROL_PAGE_LEN); 10072 } 10073 break; 10074 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */ 10075 if (LLBAA) 10076 { 10077 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN); 10078 } 10079 else 10080 { 10081 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LEN); 10082 } 10083 break; 10084 case MODESENSE_CACHING: /* caching */ 10085 if (LLBAA) 10086 { 10087 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CACHING_LLBAA_LEN); 10088 } 10089 else 10090 { 10091 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CACHING_LEN); 10092 } 10093 break; 10094 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/ 10095 if (LLBAA) 10096 { 10097 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN); 10098 } 10099 else 10100 { 10101 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN); 10102 } 10103 break; 10104 default: 10105 SM_DBG1(("smsatModeSense10: default error page %d!!!\n", page)); 10106 break; 10107 } 10108 10109 if (page == MODESENSE_RETURN_ALL_PAGES) 10110 { 10111 SM_DBG5(("smsatModeSense10: MODESENSE_RETURN_ALL_PAGES\n")); 10112 AllPages[0] = 0; 10113 AllPages[1] = (bit8)(lenRead - 2); 10114 AllPages[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */ 10115 AllPages[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */ 10116 if (LLBAA) 10117 { 10118 AllPages[4] = 0x00; /* reserved and LONGLBA */ 10119 AllPages[4] = (bit8)(AllPages[4] | 0x1); /* LONGLBA is set */ 10120 } 10121 else 10122 { 10123 AllPages[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */ 10124 } 10125 AllPages[5] = 0x00; /* reserved */ 10126 AllPages[6] = 0x00; /* block descriptot length */ 10127 if (LLBAA) 10128 { 10129 AllPages[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */ 10130 } 10131 else 10132 { 10133 AllPages[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */ 10134 } 10135 10136 /* 10137 * Fill-up direct-access device block-descriptor, SAT, Table 19 10138 */ 10139 10140 if (LLBAA) 10141 { 10142 /* density code */ 10143 AllPages[8] = 0x04; /* density-code : reserved for direct-access */ 10144 /* number of blocks */ 10145 AllPages[9] = 0x00; /* unspecified */ 10146 AllPages[10] = 0x00; /* unspecified */ 10147 AllPages[11] = 0x00; /* unspecified */ 10148 AllPages[12] = 0x00; /* unspecified */ 10149 AllPages[13] = 0x00; /* unspecified */ 10150 AllPages[14] = 0x00; /* unspecified */ 10151 AllPages[15] = 0x00; /* unspecified */ 10152 /* reserved */ 10153 AllPages[16] = 0x00; /* reserved */ 10154 AllPages[17] = 0x00; /* reserved */ 10155 AllPages[18] = 0x00; /* reserved */ 10156 AllPages[19] = 0x00; /* reserved */ 10157 /* Block size */ 10158 AllPages[20] = 0x00; 10159 AllPages[21] = 0x00; 10160 AllPages[22] = 0x02; /* Block size is always 512 bytes */ 10161 AllPages[23] = 0x00; 10162 } 10163 else 10164 { 10165 /* density code */ 10166 AllPages[8] = 0x04; /* density-code : reserved for direct-access */ 10167 /* number of blocks */ 10168 AllPages[9] = 0x00; /* unspecified */ 10169 AllPages[10] = 0x00; /* unspecified */ 10170 AllPages[11] = 0x00; /* unspecified */ 10171 /* reserved */ 10172 AllPages[12] = 0x00; /* reserved */ 10173 /* Block size */ 10174 AllPages[13] = 0x00; 10175 AllPages[14] = 0x02; /* Block size is always 512 bytes */ 10176 AllPages[15] = 0x00; 10177 } 10178 10179 if (LLBAA) 10180 { 10181 index = 24; 10182 } 10183 else 10184 { 10185 index = 16; 10186 } 10187 /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */ 10188 AllPages[index+0] = 0x01; /* page code */ 10189 AllPages[index+1] = 0x0A; /* page length */ 10190 AllPages[index+2] = 0x40; /* ARRE is set */ 10191 AllPages[index+3] = 0x00; 10192 AllPages[index+4] = 0x00; 10193 AllPages[index+5] = 0x00; 10194 AllPages[index+6] = 0x00; 10195 AllPages[index+7] = 0x00; 10196 AllPages[index+8] = 0x00; 10197 AllPages[index+9] = 0x00; 10198 AllPages[index+10] = 0x00; 10199 AllPages[index+11] = 0x00; 10200 10201 /* MODESENSE_CACHING */ 10202 /* 10203 * Fill-up Caching mode page, SAT, Table 67 10204 */ 10205 /* length 20 */ 10206 AllPages[index+12] = 0x08; /* page code */ 10207 AllPages[index+13] = 0x12; /* page length */ 10208 if (pSatDevData->satWriteCacheEnabled == agTRUE) 10209 { 10210 AllPages[index+14] = 0x04;/* WCE bit is set */ 10211 } 10212 else 10213 { 10214 AllPages[index+14] = 0x00;/* WCE bit is NOT set */ 10215 } 10216 10217 AllPages[index+15] = 0x00; 10218 AllPages[index+16] = 0x00; 10219 AllPages[index+17] = 0x00; 10220 AllPages[index+18] = 0x00; 10221 AllPages[index+19] = 0x00; 10222 AllPages[index+20] = 0x00; 10223 AllPages[index+21] = 0x00; 10224 AllPages[index+22] = 0x00; 10225 AllPages[index+23] = 0x00; 10226 if (pSatDevData->satLookAheadEnabled == agTRUE) 10227 { 10228 AllPages[index+24] = 0x00;/* DRA bit is NOT set */ 10229 } 10230 else 10231 { 10232 AllPages[index+24] = 0x20;/* DRA bit is set */ 10233 } 10234 AllPages[index+25] = 0x00; 10235 AllPages[index+26] = 0x00; 10236 AllPages[index+27] = 0x00; 10237 AllPages[index+28] = 0x00; 10238 AllPages[index+29] = 0x00; 10239 AllPages[index+30] = 0x00; 10240 AllPages[index+31] = 0x00; 10241 10242 /* MODESENSE_CONTROL_PAGE */ 10243 /* 10244 * Fill-up control mode page, SAT, Table 65 10245 */ 10246 AllPages[index+32] = 0x0A; /* page code */ 10247 AllPages[index+33] = 0x0A; /* page length */ 10248 AllPages[index+34] = 0x02; /* only GLTSD bit is set */ 10249 if (pSatDevData->satNCQ == agTRUE) 10250 { 10251 AllPages[index+35] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/ 10252 } 10253 else 10254 { 10255 AllPages[index+35] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */ 10256 } 10257 AllPages[index+36] = 0x00; 10258 AllPages[index+37] = 0x00; 10259 AllPages[index+38] = 0x00; /* obsolete */ 10260 AllPages[index+39] = 0x00; /* obsolete */ 10261 AllPages[index+40] = 0xFF; /* Busy Timeout Period */ 10262 AllPages[index+41] = 0xFF; /* Busy Timeout Period */ 10263 AllPages[index+42] = 0x00; /* we don't support non-000b value for the self-test code */ 10264 AllPages[index+43] = 0x00; /* we don't support non-000b value for the self-test code */ 10265 10266 /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */ 10267 /* 10268 * Fill-up informational-exceptions control mode page, SAT, Table 68 10269 */ 10270 AllPages[index+44] = 0x1C; /* page code */ 10271 AllPages[index+45] = 0x0A; /* page length */ 10272 if (pSatDevData->satSMARTEnabled == agTRUE) 10273 { 10274 AllPages[index+46] = 0x00;/* DEXCPT bit is NOT set */ 10275 } 10276 else 10277 { 10278 AllPages[index+46] = 0x08;/* DEXCPT bit is set */ 10279 } 10280 AllPages[index+47] = 0x00; /* We don't support MRIE */ 10281 AllPages[index+48] = 0x00; /* Interval timer vendor-specific */ 10282 AllPages[index+49] = 0x00; 10283 AllPages[index+50] = 0x00; 10284 AllPages[index+51] = 0x00; 10285 AllPages[index+52] = 0x00; /* REPORT-COUNT */ 10286 AllPages[index+53] = 0x00; 10287 AllPages[index+54] = 0x00; 10288 AllPages[index+55] = 0x00; 10289 10290 sm_memcpy(pModeSense, &AllPages, lenRead); 10291 } 10292 else if (page == MODESENSE_CONTROL_PAGE) 10293 { 10294 SM_DBG5(("smsatModeSense10: MODESENSE_CONTROL_PAGE\n")); 10295 Control[0] = 0; 10296 Control[1] = (bit8)(lenRead - 2); 10297 Control[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */ 10298 Control[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */ 10299 if (LLBAA) 10300 { 10301 Control[4] = 0x00; /* reserved and LONGLBA */ 10302 Control[4] = (bit8)(Control[4] | 0x1); /* LONGLBA is set */ 10303 } 10304 else 10305 { 10306 Control[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */ 10307 } 10308 Control[5] = 0x00; /* reserved */ 10309 Control[6] = 0x00; /* block descriptot length */ 10310 if (LLBAA) 10311 { 10312 Control[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */ 10313 } 10314 else 10315 { 10316 Control[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */ 10317 } 10318 10319 /* 10320 * Fill-up direct-access device block-descriptor, SAT, Table 19 10321 */ 10322 10323 if (LLBAA) 10324 { 10325 /* density code */ 10326 Control[8] = 0x04; /* density-code : reserved for direct-access */ 10327 /* number of blocks */ 10328 Control[9] = 0x00; /* unspecified */ 10329 Control[10] = 0x00; /* unspecified */ 10330 Control[11] = 0x00; /* unspecified */ 10331 Control[12] = 0x00; /* unspecified */ 10332 Control[13] = 0x00; /* unspecified */ 10333 Control[14] = 0x00; /* unspecified */ 10334 Control[15] = 0x00; /* unspecified */ 10335 /* reserved */ 10336 Control[16] = 0x00; /* reserved */ 10337 Control[17] = 0x00; /* reserved */ 10338 Control[18] = 0x00; /* reserved */ 10339 Control[19] = 0x00; /* reserved */ 10340 /* Block size */ 10341 Control[20] = 0x00; 10342 Control[21] = 0x00; 10343 Control[22] = 0x02; /* Block size is always 512 bytes */ 10344 Control[23] = 0x00; 10345 } 10346 else 10347 { 10348 /* density code */ 10349 Control[8] = 0x04; /* density-code : reserved for direct-access */ 10350 /* number of blocks */ 10351 Control[9] = 0x00; /* unspecified */ 10352 Control[10] = 0x00; /* unspecified */ 10353 Control[11] = 0x00; /* unspecified */ 10354 /* reserved */ 10355 Control[12] = 0x00; /* reserved */ 10356 /* Block size */ 10357 Control[13] = 0x00; 10358 Control[14] = 0x02; /* Block size is always 512 bytes */ 10359 Control[15] = 0x00; 10360 } 10361 10362 if (LLBAA) 10363 { 10364 index = 24; 10365 } 10366 else 10367 { 10368 index = 16; 10369 } 10370 /* 10371 * Fill-up control mode page, SAT, Table 65 10372 */ 10373 Control[index+0] = 0x0A; /* page code */ 10374 Control[index+1] = 0x0A; /* page length */ 10375 Control[index+2] = 0x02; /* only GLTSD bit is set */ 10376 if (pSatDevData->satNCQ == agTRUE) 10377 { 10378 Control[index+3] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/ 10379 } 10380 else 10381 { 10382 Control[index+3] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */ 10383 } 10384 Control[index+4] = 0x00; 10385 Control[index+5] = 0x00; 10386 Control[index+6] = 0x00; /* obsolete */ 10387 Control[index+7] = 0x00; /* obsolete */ 10388 Control[index+8] = 0xFF; /* Busy Timeout Period */ 10389 Control[index+9] = 0xFF; /* Busy Timeout Period */ 10390 Control[index+10] = 0x00; /* we don't support non-000b value for the self-test code */ 10391 Control[index+11] = 0x00; /* we don't support non-000b value for the self-test code */ 10392 10393 sm_memcpy(pModeSense, &Control, lenRead); 10394 } 10395 else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE) 10396 { 10397 SM_DBG5(("smsatModeSense10: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n")); 10398 RWErrorRecovery[0] = 0; 10399 RWErrorRecovery[1] = (bit8)(lenRead - 2); 10400 RWErrorRecovery[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */ 10401 RWErrorRecovery[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */ 10402 if (LLBAA) 10403 { 10404 RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA */ 10405 RWErrorRecovery[4] = (bit8)(RWErrorRecovery[4] | 0x1); /* LONGLBA is set */ 10406 } 10407 else 10408 { 10409 RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */ 10410 } 10411 RWErrorRecovery[5] = 0x00; /* reserved */ 10412 RWErrorRecovery[6] = 0x00; /* block descriptot length */ 10413 if (LLBAA) 10414 { 10415 RWErrorRecovery[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */ 10416 } 10417 else 10418 { 10419 RWErrorRecovery[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */ 10420 } 10421 10422 /* 10423 * Fill-up direct-access device block-descriptor, SAT, Table 19 10424 */ 10425 10426 if (LLBAA) 10427 { 10428 /* density code */ 10429 RWErrorRecovery[8] = 0x04; /* density-code : reserved for direct-access */ 10430 /* number of blocks */ 10431 RWErrorRecovery[9] = 0x00; /* unspecified */ 10432 RWErrorRecovery[10] = 0x00; /* unspecified */ 10433 RWErrorRecovery[11] = 0x00; /* unspecified */ 10434 RWErrorRecovery[12] = 0x00; /* unspecified */ 10435 RWErrorRecovery[13] = 0x00; /* unspecified */ 10436 RWErrorRecovery[14] = 0x00; /* unspecified */ 10437 RWErrorRecovery[15] = 0x00; /* unspecified */ 10438 /* reserved */ 10439 RWErrorRecovery[16] = 0x00; /* reserved */ 10440 RWErrorRecovery[17] = 0x00; /* reserved */ 10441 RWErrorRecovery[18] = 0x00; /* reserved */ 10442 RWErrorRecovery[19] = 0x00; /* reserved */ 10443 /* Block size */ 10444 RWErrorRecovery[20] = 0x00; 10445 RWErrorRecovery[21] = 0x00; 10446 RWErrorRecovery[22] = 0x02; /* Block size is always 512 bytes */ 10447 RWErrorRecovery[23] = 0x00; 10448 } 10449 else 10450 { 10451 /* density code */ 10452 RWErrorRecovery[8] = 0x04; /* density-code : reserved for direct-access */ 10453 /* number of blocks */ 10454 RWErrorRecovery[9] = 0x00; /* unspecified */ 10455 RWErrorRecovery[10] = 0x00; /* unspecified */ 10456 RWErrorRecovery[11] = 0x00; /* unspecified */ 10457 /* reserved */ 10458 RWErrorRecovery[12] = 0x00; /* reserved */ 10459 /* Block size */ 10460 RWErrorRecovery[13] = 0x00; 10461 RWErrorRecovery[14] = 0x02; /* Block size is always 512 bytes */ 10462 RWErrorRecovery[15] = 0x00; 10463 } 10464 10465 if (LLBAA) 10466 { 10467 index = 24; 10468 } 10469 else 10470 { 10471 index = 16; 10472 } 10473 /* 10474 * Fill-up Read-Write Error Recovery mode page, SAT, Table 66 10475 */ 10476 RWErrorRecovery[index+0] = 0x01; /* page code */ 10477 RWErrorRecovery[index+1] = 0x0A; /* page length */ 10478 RWErrorRecovery[index+2] = 0x40; /* ARRE is set */ 10479 RWErrorRecovery[index+3] = 0x00; 10480 RWErrorRecovery[index+4] = 0x00; 10481 RWErrorRecovery[index+5] = 0x00; 10482 RWErrorRecovery[index+6] = 0x00; 10483 RWErrorRecovery[index+7] = 0x00; 10484 RWErrorRecovery[index+8] = 0x00; 10485 RWErrorRecovery[index+9] = 0x00; 10486 RWErrorRecovery[index+10] = 0x00; 10487 RWErrorRecovery[index+11] = 0x00; 10488 10489 sm_memcpy(pModeSense, &RWErrorRecovery, lenRead); 10490 } 10491 else if (page == MODESENSE_CACHING) 10492 { 10493 SM_DBG5(("smsatModeSense10: MODESENSE_CACHING\n")); 10494 Caching[0] = 0; 10495 Caching[1] = (bit8)(lenRead - 2); 10496 Caching[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */ 10497 Caching[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */ 10498 if (LLBAA) 10499 { 10500 Caching[4] = 0x00; /* reserved and LONGLBA */ 10501 Caching[4] = (bit8)(Caching[4] | 0x1); /* LONGLBA is set */ 10502 } 10503 else 10504 { 10505 Caching[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */ 10506 } 10507 Caching[5] = 0x00; /* reserved */ 10508 Caching[6] = 0x00; /* block descriptot length */ 10509 if (LLBAA) 10510 { 10511 Caching[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */ 10512 } 10513 else 10514 { 10515 Caching[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */ 10516 } 10517 10518 /* 10519 * Fill-up direct-access device block-descriptor, SAT, Table 19 10520 */ 10521 10522 if (LLBAA) 10523 { 10524 /* density code */ 10525 Caching[8] = 0x04; /* density-code : reserved for direct-access */ 10526 /* number of blocks */ 10527 Caching[9] = 0x00; /* unspecified */ 10528 Caching[10] = 0x00; /* unspecified */ 10529 Caching[11] = 0x00; /* unspecified */ 10530 Caching[12] = 0x00; /* unspecified */ 10531 Caching[13] = 0x00; /* unspecified */ 10532 Caching[14] = 0x00; /* unspecified */ 10533 Caching[15] = 0x00; /* unspecified */ 10534 /* reserved */ 10535 Caching[16] = 0x00; /* reserved */ 10536 Caching[17] = 0x00; /* reserved */ 10537 Caching[18] = 0x00; /* reserved */ 10538 Caching[19] = 0x00; /* reserved */ 10539 /* Block size */ 10540 Caching[20] = 0x00; 10541 Caching[21] = 0x00; 10542 Caching[22] = 0x02; /* Block size is always 512 bytes */ 10543 Caching[23] = 0x00; 10544 } 10545 else 10546 { 10547 /* density code */ 10548 Caching[8] = 0x04; /* density-code : reserved for direct-access */ 10549 /* number of blocks */ 10550 Caching[9] = 0x00; /* unspecified */ 10551 Caching[10] = 0x00; /* unspecified */ 10552 Caching[11] = 0x00; /* unspecified */ 10553 /* reserved */ 10554 Caching[12] = 0x00; /* reserved */ 10555 /* Block size */ 10556 Caching[13] = 0x00; 10557 Caching[14] = 0x02; /* Block size is always 512 bytes */ 10558 Caching[15] = 0x00; 10559 } 10560 10561 if (LLBAA) 10562 { 10563 index = 24; 10564 } 10565 else 10566 { 10567 index = 16; 10568 } 10569 /* 10570 * Fill-up Caching mode page, SAT, Table 67 10571 */ 10572 /* length 20 */ 10573 Caching[index+0] = 0x08; /* page code */ 10574 Caching[index+1] = 0x12; /* page length */ 10575 if (pSatDevData->satWriteCacheEnabled == agTRUE) 10576 { 10577 Caching[index+2] = 0x04;/* WCE bit is set */ 10578 } 10579 else 10580 { 10581 Caching[index+2] = 0x00;/* WCE bit is NOT set */ 10582 } 10583 10584 Caching[index+3] = 0x00; 10585 Caching[index+4] = 0x00; 10586 Caching[index+5] = 0x00; 10587 Caching[index+6] = 0x00; 10588 Caching[index+7] = 0x00; 10589 Caching[index+8] = 0x00; 10590 Caching[index+9] = 0x00; 10591 Caching[index+10] = 0x00; 10592 Caching[index+11] = 0x00; 10593 if (pSatDevData->satLookAheadEnabled == agTRUE) 10594 { 10595 Caching[index+12] = 0x00;/* DRA bit is NOT set */ 10596 } 10597 else 10598 { 10599 Caching[index+12] = 0x20;/* DRA bit is set */ 10600 } 10601 Caching[index+13] = 0x00; 10602 Caching[index+14] = 0x00; 10603 Caching[index+15] = 0x00; 10604 Caching[index+16] = 0x00; 10605 Caching[index+17] = 0x00; 10606 Caching[index+18] = 0x00; 10607 Caching[index+19] = 0x00; 10608 sm_memcpy(pModeSense, &Caching, lenRead); 10609 10610 } 10611 else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE) 10612 { 10613 SM_DBG5(("smsatModeSense10: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n")); 10614 InfoExceptionCtrl[0] = 0; 10615 InfoExceptionCtrl[1] = (bit8)(lenRead - 2); 10616 InfoExceptionCtrl[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */ 10617 InfoExceptionCtrl[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */ 10618 if (LLBAA) 10619 { 10620 InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA */ 10621 InfoExceptionCtrl[4] = (bit8)(InfoExceptionCtrl[4] | 0x1); /* LONGLBA is set */ 10622 } 10623 else 10624 { 10625 InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */ 10626 } 10627 InfoExceptionCtrl[5] = 0x00; /* reserved */ 10628 InfoExceptionCtrl[6] = 0x00; /* block descriptot length */ 10629 if (LLBAA) 10630 { 10631 InfoExceptionCtrl[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */ 10632 } 10633 else 10634 { 10635 InfoExceptionCtrl[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */ 10636 } 10637 10638 /* 10639 * Fill-up direct-access device block-descriptor, SAT, Table 19 10640 */ 10641 10642 if (LLBAA) 10643 { 10644 /* density code */ 10645 InfoExceptionCtrl[8] = 0x04; /* density-code : reserved for direct-access */ 10646 /* number of blocks */ 10647 InfoExceptionCtrl[9] = 0x00; /* unspecified */ 10648 InfoExceptionCtrl[10] = 0x00; /* unspecified */ 10649 InfoExceptionCtrl[11] = 0x00; /* unspecified */ 10650 InfoExceptionCtrl[12] = 0x00; /* unspecified */ 10651 InfoExceptionCtrl[13] = 0x00; /* unspecified */ 10652 InfoExceptionCtrl[14] = 0x00; /* unspecified */ 10653 InfoExceptionCtrl[15] = 0x00; /* unspecified */ 10654 /* reserved */ 10655 InfoExceptionCtrl[16] = 0x00; /* reserved */ 10656 InfoExceptionCtrl[17] = 0x00; /* reserved */ 10657 InfoExceptionCtrl[18] = 0x00; /* reserved */ 10658 InfoExceptionCtrl[19] = 0x00; /* reserved */ 10659 /* Block size */ 10660 InfoExceptionCtrl[20] = 0x00; 10661 InfoExceptionCtrl[21] = 0x00; 10662 InfoExceptionCtrl[22] = 0x02; /* Block size is always 512 bytes */ 10663 InfoExceptionCtrl[23] = 0x00; 10664 } 10665 else 10666 { 10667 /* density code */ 10668 InfoExceptionCtrl[8] = 0x04; /* density-code : reserved for direct-access */ 10669 /* number of blocks */ 10670 InfoExceptionCtrl[9] = 0x00; /* unspecified */ 10671 InfoExceptionCtrl[10] = 0x00; /* unspecified */ 10672 InfoExceptionCtrl[11] = 0x00; /* unspecified */ 10673 /* reserved */ 10674 InfoExceptionCtrl[12] = 0x00; /* reserved */ 10675 /* Block size */ 10676 InfoExceptionCtrl[13] = 0x00; 10677 InfoExceptionCtrl[14] = 0x02; /* Block size is always 512 bytes */ 10678 InfoExceptionCtrl[15] = 0x00; 10679 } 10680 10681 if (LLBAA) 10682 { 10683 index = 24; 10684 } 10685 else 10686 { 10687 index = 16; 10688 } 10689 /* 10690 * Fill-up informational-exceptions control mode page, SAT, Table 68 10691 */ 10692 InfoExceptionCtrl[index+0] = 0x1C; /* page code */ 10693 InfoExceptionCtrl[index+1] = 0x0A; /* page length */ 10694 if (pSatDevData->satSMARTEnabled == agTRUE) 10695 { 10696 InfoExceptionCtrl[index+2] = 0x00;/* DEXCPT bit is NOT set */ 10697 } 10698 else 10699 { 10700 InfoExceptionCtrl[index+2] = 0x08;/* DEXCPT bit is set */ 10701 } 10702 InfoExceptionCtrl[index+3] = 0x00; /* We don't support MRIE */ 10703 InfoExceptionCtrl[index+4] = 0x00; /* Interval timer vendor-specific */ 10704 InfoExceptionCtrl[index+5] = 0x00; 10705 InfoExceptionCtrl[index+6] = 0x00; 10706 InfoExceptionCtrl[index+7] = 0x00; 10707 InfoExceptionCtrl[index+8] = 0x00; /* REPORT-COUNT */ 10708 InfoExceptionCtrl[index+9] = 0x00; 10709 InfoExceptionCtrl[index+10] = 0x00; 10710 InfoExceptionCtrl[index+11] = 0x00; 10711 sm_memcpy(pModeSense, &InfoExceptionCtrl, lenRead); 10712 10713 } 10714 else 10715 { 10716 /* Error */ 10717 SM_DBG1(("smsatModeSense10: Error page %d!!!\n", page)); 10718 smsatSetSensePayload( pSense, 10719 SCSI_SNSKEY_ILLEGAL_REQUEST, 10720 0, 10721 SCSI_SNSCODE_INVALID_COMMAND, 10722 satIOContext); 10723 10724 /*smEnqueueIO(smRoot, satIOContext);*/ 10725 10726 tdsmIOCompletedCB( smRoot, 10727 smIORequest, 10728 smIOSuccess, 10729 SCSI_STAT_CHECK_CONDITION, 10730 satIOContext->pSmSenseData, 10731 satIOContext->interruptContext ); 10732 return SM_RC_SUCCESS; 10733 } 10734 10735 if (allocationLen > lenRead) 10736 { 10737 SM_DBG1(("smsatModeSense10: reporting underrun lenRead=0x%x allocationLen=0x%x smIORequest=%p\n", lenRead, allocationLen, smIORequest)); 10738 10739 /*smEnqueueIO(smRoot, satIOContext);*/ 10740 10741 tdsmIOCompletedCB( smRoot, 10742 smIORequest, 10743 smIOUnderRun, 10744 allocationLen - lenRead, 10745 agNULL, 10746 satIOContext->interruptContext ); 10747 10748 10749 } 10750 else 10751 { 10752 /*smEnqueueIO(smRoot, satIOContext);*/ 10753 10754 tdsmIOCompletedCB( smRoot, 10755 smIORequest, 10756 smIOSuccess, 10757 SCSI_STAT_GOOD, 10758 agNULL, 10759 satIOContext->interruptContext); 10760 } 10761 10762 return SM_RC_SUCCESS; 10763 } 10764 10765 osGLOBAL bit32 10766 smsatReadCapacity10( 10767 smRoot_t *smRoot, 10768 smIORequest_t *smIORequest, 10769 smDeviceHandle_t *smDeviceHandle, 10770 smScsiInitiatorRequest_t *smScsiRequest, 10771 smSatIOContext_t *satIOContext 10772 ) 10773 { 10774 smScsiRspSense_t *pSense; 10775 smIniScsiCmnd_t *scsiCmnd; 10776 bit8 dataBuffer[8] = {0}; 10777 bit32 allocationLen; 10778 bit8 *pVirtAddr = agNULL; 10779 smDeviceData_t *pSatDevData; 10780 agsaSATAIdentifyData_t *pSATAIdData; 10781 bit32 lastLba; 10782 bit32 word117_118; 10783 bit32 word117; 10784 bit32 word118; 10785 10786 pSense = satIOContext->pSense; 10787 pVirtAddr = (bit8 *) smScsiRequest->sglVirtualAddr; 10788 scsiCmnd = &smScsiRequest->scsiCmnd; 10789 pSatDevData = satIOContext->pSatDevData; 10790 pSATAIdData = &pSatDevData->satIdentifyData; 10791 allocationLen = scsiCmnd->expDataLength; 10792 10793 SM_DBG5(("smsatReadCapacity10: start\n")); 10794 10795 /* checking CONTROL */ 10796 /* NACA == 1 or LINK == 1*/ 10797 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 10798 { 10799 smsatSetSensePayload( pSense, 10800 SCSI_SNSKEY_ILLEGAL_REQUEST, 10801 0, 10802 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10803 satIOContext); 10804 10805 /*smEnqueueIO(smRoot, satIOContext);*/ 10806 10807 tdsmIOCompletedCB( smRoot, 10808 smIORequest, 10809 smIOSuccess, 10810 SCSI_STAT_CHECK_CONDITION, 10811 satIOContext->pSmSenseData, 10812 satIOContext->interruptContext ); 10813 10814 SM_DBG1(("smsatReadCapacity10: return control!!!\n")); 10815 return SM_RC_SUCCESS; 10816 } 10817 10818 10819 /* 10820 * If Logical block address is not set to zero, return error 10821 */ 10822 if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5])) 10823 { 10824 SM_DBG1(("smsatReadCapacity10: *** ERROR *** logical address non zero, did %d!!!\n", 10825 pSatDevData->id)); 10826 10827 smsatSetSensePayload( pSense, 10828 SCSI_SNSKEY_ILLEGAL_REQUEST, 10829 0, 10830 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10831 satIOContext); 10832 10833 /*smEnqueueIO(smRoot, satIOContext);*/ 10834 10835 tdsmIOCompletedCB( smRoot, 10836 smIORequest, 10837 smIOSuccess, 10838 SCSI_STAT_CHECK_CONDITION, 10839 satIOContext->pSmSenseData, 10840 satIOContext->interruptContext ); 10841 return SM_RC_SUCCESS; 10842 10843 } 10844 10845 /* 10846 * If PMI bit is not zero, return error 10847 */ 10848 if ( ((scsiCmnd->cdb[8]) & SCSI_READ_CAPACITY10_PMI_MASK) != 0 ) 10849 { 10850 SM_DBG1(("smsatReadCapacity10: *** ERROR *** PMI is not zero, did %d\n", 10851 pSatDevData->id)); 10852 10853 smsatSetSensePayload( pSense, 10854 SCSI_SNSKEY_ILLEGAL_REQUEST, 10855 0, 10856 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10857 satIOContext); 10858 10859 /*smEnqueueIO(smRoot, satIOContext);*/ 10860 10861 tdsmIOCompletedCB( smRoot, 10862 smIORequest, 10863 smIOSuccess, 10864 SCSI_STAT_CHECK_CONDITION, 10865 satIOContext->pSmSenseData, 10866 satIOContext->interruptContext ); 10867 return SM_RC_SUCCESS; 10868 10869 } 10870 10871 /* 10872 filling in Read Capacity parameter data 10873 saved identify device has been already flipped 10874 See ATA spec p125 and p136 and SBC spec p54 10875 */ 10876 /* 10877 * If 48-bit addressing is supported, set capacity information from Identify 10878 * Device Word 100-103. 10879 */ 10880 if (pSatDevData->sat48BitSupport == agTRUE) 10881 { 10882 /* 10883 * Setting RETURNED LOGICAL BLOCK ADDRESS in READ CAPACITY(10) response data: 10884 * SBC-2 specifies that if the capacity exceeded the 4-byte RETURNED LOGICAL 10885 * BLOCK ADDRESS in READ CAPACITY(10) parameter data, the RETURNED LOGICAL 10886 * BLOCK ADDRESS should be set to 0xFFFFFFFF so the application client would 10887 * then issue a READ CAPACITY(16) command. 10888 */ 10889 /* ATA Identify Device information word 100 - 103 */ 10890 if ( (pSATAIdData->maxLBA32_47 != 0 ) || (pSATAIdData->maxLBA48_63 != 0)) 10891 { 10892 dataBuffer[0] = 0xFF; /* MSB number of block */ 10893 dataBuffer[1] = 0xFF; 10894 dataBuffer[2] = 0xFF; 10895 dataBuffer[3] = 0xFF; /* LSB number of block */ 10896 SM_DBG1(("smsatReadCapacity10: returns 0xFFFFFFFF!!!\n")); 10897 } 10898 else /* Fit the Readcapacity10 4-bytes response length */ 10899 { 10900 lastLba = (((pSATAIdData->maxLBA16_31) << 16) ) | 10901 (pSATAIdData->maxLBA0_15); 10902 lastLba = lastLba - 1; /* LBA starts from zero */ 10903 10904 /* 10905 for testing 10906 lastLba = lastLba - (512*10) - 1; 10907 */ 10908 10909 10910 dataBuffer[0] = (bit8)((lastLba >> 24) & 0xFF); /* MSB */ 10911 dataBuffer[1] = (bit8)((lastLba >> 16) & 0xFF); 10912 dataBuffer[2] = (bit8)((lastLba >> 8) & 0xFF); 10913 dataBuffer[3] = (bit8)((lastLba ) & 0xFF); /* LSB */ 10914 10915 SM_DBG3(("smsatReadCapacity10: lastLba is 0x%x %d\n", lastLba, lastLba)); 10916 SM_DBG3(("smsatReadCapacity10: LBA 0 is 0x%x %d\n", dataBuffer[0], dataBuffer[0])); 10917 SM_DBG3(("smsatReadCapacity10: LBA 1 is 0x%x %d\n", dataBuffer[1], dataBuffer[1])); 10918 SM_DBG3(("smsatReadCapacity10: LBA 2 is 0x%x %d\n", dataBuffer[2], dataBuffer[2])); 10919 SM_DBG3(("smsatReadCapacity10: LBA 3 is 0x%x %d\n", dataBuffer[3], dataBuffer[3])); 10920 10921 } 10922 } 10923 10924 /* 10925 * For 28-bit addressing, set capacity information from Identify 10926 * Device Word 60-61. 10927 */ 10928 else 10929 { 10930 /* ATA Identify Device information word 60 - 61 */ 10931 lastLba = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) | 10932 (pSATAIdData->numOfUserAddressableSectorsLo); 10933 lastLba = lastLba - 1; /* LBA starts from zero */ 10934 10935 dataBuffer[0] = (bit8)((lastLba >> 24) & 0xFF); /* MSB */ 10936 dataBuffer[1] = (bit8)((lastLba >> 16) & 0xFF); 10937 dataBuffer[2] = (bit8)((lastLba >> 8) & 0xFF); 10938 dataBuffer[3] = (bit8)((lastLba ) & 0xFF); /* LSB */ 10939 } 10940 /* SAT Rev 8d */ 10941 if (((pSATAIdData->word104_107[2]) & 0x1000) == 0) 10942 { 10943 SM_DBG5(("smsatReadCapacity10: Default Block Length is 512\n")); 10944 /* 10945 * Set the block size, fixed at 512 bytes. 10946 */ 10947 dataBuffer[4] = 0x00; /* MSB block size in bytes */ 10948 dataBuffer[5] = 0x00; 10949 dataBuffer[6] = 0x02; 10950 dataBuffer[7] = 0x00; /* LSB block size in bytes */ 10951 } 10952 else 10953 { 10954 word118 = pSATAIdData->word112_126[6]; 10955 word117 = pSATAIdData->word112_126[5]; 10956 10957 word117_118 = (word118 << 16) + word117; 10958 word117_118 = word117_118 * 2; 10959 dataBuffer[4] = (bit8)((word117_118 >> 24) & 0xFF); /* MSB block size in bytes */ 10960 dataBuffer[5] = (bit8)((word117_118 >> 16) & 0xFF); 10961 dataBuffer[6] = (bit8)((word117_118 >> 8) & 0xFF); 10962 dataBuffer[7] = (bit8)(word117_118 & 0xFF); /* LSB block size in bytes */ 10963 10964 SM_DBG1(("smsatReadCapacity10: Nondefault word118 %d 0x%x !!!\n", word118, word118)); 10965 SM_DBG1(("smsatReadCapacity10: Nondefault word117 %d 0x%x !!!\n", word117, word117)); 10966 SM_DBG1(("smsatReadCapacity10: Nondefault Block Length is %d 0x%x !!!\n",word117_118, word117_118)); 10967 10968 } 10969 10970 /* fill in MAX LBA, which is used in satSendDiagnostic_1() */ 10971 pSatDevData->satMaxLBA[0] = 0; /* MSB */ 10972 pSatDevData->satMaxLBA[1] = 0; 10973 pSatDevData->satMaxLBA[2] = 0; 10974 pSatDevData->satMaxLBA[3] = 0; 10975 pSatDevData->satMaxLBA[4] = dataBuffer[0]; 10976 pSatDevData->satMaxLBA[5] = dataBuffer[1]; 10977 pSatDevData->satMaxLBA[6] = dataBuffer[2]; 10978 pSatDevData->satMaxLBA[7] = dataBuffer[3]; /* LSB */ 10979 10980 10981 SM_DBG4(("smsatReadCapacity10: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , did %d\n", 10982 dataBuffer[0], dataBuffer[1], dataBuffer[2], dataBuffer[3], 10983 dataBuffer[4], dataBuffer[5], dataBuffer[6], dataBuffer[7], 10984 pSatDevData->id)); 10985 10986 sm_memcpy(pVirtAddr, dataBuffer, MIN(allocationLen, 8)); 10987 10988 /* 10989 * Send the completion response now. 10990 */ 10991 /*smEnqueueIO(smRoot, satIOContext);*/ 10992 10993 tdsmIOCompletedCB( smRoot, 10994 smIORequest, 10995 smIOSuccess, 10996 SCSI_STAT_GOOD, 10997 agNULL, 10998 satIOContext->interruptContext); 10999 return SM_RC_SUCCESS; 11000 } 11001 11002 osGLOBAL bit32 11003 smsatReadCapacity16( 11004 smRoot_t *smRoot, 11005 smIORequest_t *smIORequest, 11006 smDeviceHandle_t *smDeviceHandle, 11007 smScsiInitiatorRequest_t *smScsiRequest, 11008 smSatIOContext_t *satIOContext 11009 ) 11010 { 11011 smScsiRspSense_t *pSense; 11012 smIniScsiCmnd_t *scsiCmnd; 11013 bit8 dataBuffer[32] = {0}; 11014 bit8 *pVirtAddr = agNULL; 11015 smDeviceData_t *pSatDevData; 11016 agsaSATAIdentifyData_t *pSATAIdData; 11017 bit32 lastLbaLo; 11018 bit32 allocationLen; 11019 bit32 readCapacityLen = 32; 11020 bit32 i = 0; 11021 11022 pSense = satIOContext->pSense; 11023 pVirtAddr = (bit8 *) smScsiRequest->sglVirtualAddr; 11024 scsiCmnd = &smScsiRequest->scsiCmnd; 11025 pSatDevData = satIOContext->pSatDevData; 11026 pSATAIdData = &pSatDevData->satIdentifyData; 11027 11028 SM_DBG5(("smsatReadCapacity16: start\n")); 11029 11030 /* Find the buffer size allocated by Initiator */ 11031 allocationLen = (((bit32)scsiCmnd->cdb[10]) << 24) | 11032 (((bit32)scsiCmnd->cdb[11]) << 16) | 11033 (((bit32)scsiCmnd->cdb[12]) << 8 ) | 11034 (((bit32)scsiCmnd->cdb[13]) ); 11035 allocationLen = MIN(allocationLen, scsiCmnd->expDataLength); 11036 11037 #ifdef REMOVED 11038 if (allocationLen < readCapacityLen) 11039 { 11040 SM_DBG1(("smsatReadCapacity16: *** ERROR *** insufficient len=0x%x readCapacityLen=0x%x!!!\n", allocationLen, readCapacityLen)); 11041 11042 smsatSetSensePayload( pSense, 11043 SCSI_SNSKEY_ILLEGAL_REQUEST, 11044 0, 11045 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11046 satIOContext); 11047 11048 /*smEnqueueIO(smRoot, satIOContext);*/ 11049 11050 tdsmIOCompletedCB( smRoot, 11051 smIORequest, 11052 smIOSuccess, 11053 SCSI_STAT_CHECK_CONDITION, 11054 satIOContext->pSmSenseData, 11055 satIOContext->interruptContext ); 11056 return SM_RC_SUCCESS; 11057 11058 } 11059 #endif 11060 11061 /* checking CONTROL */ 11062 /* NACA == 1 or LINK == 1*/ 11063 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 11064 { 11065 smsatSetSensePayload( pSense, 11066 SCSI_SNSKEY_ILLEGAL_REQUEST, 11067 0, 11068 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11069 satIOContext); 11070 11071 /*smEnqueueIO(smRoot, satIOContext);*/ 11072 11073 tdsmIOCompletedCB( smRoot, 11074 smIORequest, 11075 smIOSuccess, 11076 SCSI_STAT_CHECK_CONDITION, 11077 satIOContext->pSmSenseData, 11078 satIOContext->interruptContext ); 11079 11080 SM_DBG1(("smsatReadCapacity16: return control!!!\n")); 11081 return SM_RC_SUCCESS; 11082 } 11083 11084 /* 11085 * If Logical blcok address is not set to zero, return error 11086 */ 11087 if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]) || 11088 (scsiCmnd->cdb[6] || scsiCmnd->cdb[7] || scsiCmnd->cdb[8] || scsiCmnd->cdb[9]) ) 11089 { 11090 SM_DBG1(("smsatReadCapacity16: *** ERROR *** logical address non zero, did %d\n", 11091 pSatDevData->id)); 11092 11093 smsatSetSensePayload( pSense, 11094 SCSI_SNSKEY_ILLEGAL_REQUEST, 11095 0, 11096 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11097 satIOContext); 11098 11099 /*smEnqueueIO(smRoot, satIOContext);*/ 11100 11101 tdsmIOCompletedCB( smRoot, 11102 smIORequest, 11103 smIOSuccess, 11104 SCSI_STAT_CHECK_CONDITION, 11105 satIOContext->pSmSenseData, 11106 satIOContext->interruptContext ); 11107 return SM_RC_SUCCESS; 11108 11109 } 11110 11111 /* 11112 * If PMI bit is not zero, return error 11113 */ 11114 if ( ((scsiCmnd->cdb[14]) & SCSI_READ_CAPACITY16_PMI_MASK) != 0 ) 11115 { 11116 SM_DBG1(("smsatReadCapacity16: *** ERROR *** PMI is not zero, did %d\n", 11117 pSatDevData->id)); 11118 11119 smsatSetSensePayload( pSense, 11120 SCSI_SNSKEY_ILLEGAL_REQUEST, 11121 0, 11122 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11123 satIOContext); 11124 11125 /*smEnqueueIO(smRoot, satIOContext);*/ 11126 11127 tdsmIOCompletedCB( smRoot, 11128 smIORequest, 11129 smIOSuccess, 11130 SCSI_STAT_CHECK_CONDITION, 11131 satIOContext->pSmSenseData, 11132 satIOContext->interruptContext ); 11133 return SM_RC_SUCCESS; 11134 11135 } 11136 11137 /* 11138 filling in Read Capacity parameter data 11139 */ 11140 11141 /* 11142 * If 48-bit addressing is supported, set capacity information from Identify 11143 * Device Word 100-103. 11144 */ 11145 if (pSatDevData->sat48BitSupport == agTRUE) 11146 { 11147 dataBuffer[0] = (bit8)(((pSATAIdData->maxLBA48_63) >> 8) & 0xff); /* MSB */ 11148 dataBuffer[1] = (bit8)((pSATAIdData->maxLBA48_63) & 0xff); 11149 dataBuffer[2] = (bit8)(((pSATAIdData->maxLBA32_47) >> 8) & 0xff); 11150 dataBuffer[3] = (bit8)((pSATAIdData->maxLBA32_47) & 0xff); 11151 11152 lastLbaLo = (((pSATAIdData->maxLBA16_31) << 16) ) | (pSATAIdData->maxLBA0_15); 11153 lastLbaLo = lastLbaLo - 1; /* LBA starts from zero */ 11154 11155 dataBuffer[4] = (bit8)((lastLbaLo >> 24) & 0xFF); 11156 dataBuffer[5] = (bit8)((lastLbaLo >> 16) & 0xFF); 11157 dataBuffer[6] = (bit8)((lastLbaLo >> 8) & 0xFF); 11158 dataBuffer[7] = (bit8)((lastLbaLo ) & 0xFF); /* LSB */ 11159 11160 } 11161 11162 /* 11163 * For 28-bit addressing, set capacity information from Identify 11164 * Device Word 60-61. 11165 */ 11166 else 11167 { 11168 dataBuffer[0] = 0; /* MSB */ 11169 dataBuffer[1] = 0; 11170 dataBuffer[2] = 0; 11171 dataBuffer[3] = 0; 11172 11173 lastLbaLo = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) | 11174 (pSATAIdData->numOfUserAddressableSectorsLo); 11175 lastLbaLo = lastLbaLo - 1; /* LBA starts from zero */ 11176 11177 dataBuffer[4] = (bit8)((lastLbaLo >> 24) & 0xFF); 11178 dataBuffer[5] = (bit8)((lastLbaLo >> 16) & 0xFF); 11179 dataBuffer[6] = (bit8)((lastLbaLo >> 8) & 0xFF); 11180 dataBuffer[7] = (bit8)((lastLbaLo ) & 0xFF); /* LSB */ 11181 11182 } 11183 11184 /* 11185 * Set the block size, fixed at 512 bytes. 11186 */ 11187 dataBuffer[8] = 0x00; /* MSB block size in bytes */ 11188 dataBuffer[9] = 0x00; 11189 dataBuffer[10] = 0x02; 11190 dataBuffer[11] = 0x00; /* LSB block size in bytes */ 11191 11192 11193 /* fill in MAX LBA, which is used in satSendDiagnostic_1() */ 11194 pSatDevData->satMaxLBA[0] = dataBuffer[0]; /* MSB */ 11195 pSatDevData->satMaxLBA[1] = dataBuffer[1]; 11196 pSatDevData->satMaxLBA[2] = dataBuffer[2]; 11197 pSatDevData->satMaxLBA[3] = dataBuffer[3]; 11198 pSatDevData->satMaxLBA[4] = dataBuffer[4]; 11199 pSatDevData->satMaxLBA[5] = dataBuffer[5]; 11200 pSatDevData->satMaxLBA[6] = dataBuffer[6]; 11201 pSatDevData->satMaxLBA[7] = dataBuffer[7]; /* LSB */ 11202 11203 SM_DBG5(("smsatReadCapacity16: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , did %d\n", 11204 dataBuffer[0], dataBuffer[1], dataBuffer[2], dataBuffer[3], 11205 dataBuffer[4], dataBuffer[5], dataBuffer[6], dataBuffer[7], 11206 dataBuffer[8], dataBuffer[9], dataBuffer[10], dataBuffer[11], 11207 pSatDevData->id)); 11208 11209 if (allocationLen > 0xC) /* 0xc = 12 */ 11210 { 11211 for(i=12;i<=31;i++) 11212 { 11213 dataBuffer[i] = 0x00; 11214 } 11215 } 11216 11217 sm_memcpy(pVirtAddr, dataBuffer, MIN(allocationLen, readCapacityLen)); 11218 /* 11219 * Send the completion response now. 11220 */ 11221 if (allocationLen > readCapacityLen) 11222 { 11223 /* underrun */ 11224 SM_DBG1(("smsatReadCapacity16: reporting underrun readCapacityLen=0x%x allocationLen=0x%x !!!\n", readCapacityLen, allocationLen)); 11225 11226 /*smEnqueueIO(smRoot, satIOContext);*/ 11227 11228 tdsmIOCompletedCB( smRoot, 11229 smIORequest, 11230 smIOUnderRun, 11231 allocationLen - readCapacityLen, 11232 agNULL, 11233 satIOContext->interruptContext ); 11234 11235 11236 } 11237 else 11238 { 11239 /*smEnqueueIO(smRoot, satIOContext);*/ 11240 11241 tdsmIOCompletedCB( smRoot, 11242 smIORequest, 11243 smIOSuccess, 11244 SCSI_STAT_GOOD, 11245 agNULL, 11246 satIOContext->interruptContext); 11247 } 11248 return SM_RC_SUCCESS; 11249 } 11250 11251 osGLOBAL bit32 11252 smsatReportLun( 11253 smRoot_t *smRoot, 11254 smIORequest_t *smIORequest, 11255 smDeviceHandle_t *smDeviceHandle, 11256 smScsiInitiatorRequest_t *smScsiRequest, 11257 smSatIOContext_t *satIOContext 11258 ) 11259 { 11260 smScsiRspSense_t *pSense; 11261 bit8 dataBuffer[16] = {0}; 11262 bit32 allocationLen; 11263 bit32 reportLunLen; 11264 smScsiReportLun_t *pReportLun; 11265 smIniScsiCmnd_t *scsiCmnd; 11266 #ifdef TD_DEBUG_ENABLE 11267 smDeviceData_t *pSatDevData; 11268 #endif 11269 11270 pSense = satIOContext->pSense; 11271 pReportLun = (smScsiReportLun_t *) dataBuffer; 11272 scsiCmnd = &smScsiRequest->scsiCmnd; 11273 #ifdef TD_DEBUG_ENABLE 11274 pSatDevData = satIOContext->pSatDevData; 11275 #endif 11276 SM_DBG5(("smsatReportLun: start\n")); 11277 // smhexdump("smsatReportLun: cdb", (bit8 *)scsiCmnd, 16); 11278 /* Find the buffer size allocated by Initiator */ 11279 allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) | 11280 (((bit32)scsiCmnd->cdb[7]) << 16) | 11281 (((bit32)scsiCmnd->cdb[8]) << 8 ) | 11282 (((bit32)scsiCmnd->cdb[9]) ); 11283 allocationLen = MIN(allocationLen, scsiCmnd->expDataLength); 11284 reportLunLen = 16; /* 8 byte header and 8 bytes of LUN0 */ 11285 if (allocationLen < reportLunLen) 11286 { 11287 SM_DBG1(("smsatReportLun: *** ERROR *** insufficient len=0x%x did %d\n", 11288 reportLunLen, pSatDevData->id)); 11289 smsatSetSensePayload( pSense, 11290 SCSI_SNSKEY_ILLEGAL_REQUEST, 11291 0, 11292 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11293 satIOContext); 11294 /*smEnqueueIO(smRoot, satIOContext);*/ 11295 tdsmIOCompletedCB( smRoot, 11296 smIORequest, 11297 smIOSuccess, 11298 SCSI_STAT_CHECK_CONDITION, 11299 satIOContext->pSmSenseData, 11300 satIOContext->interruptContext ); 11301 return SM_RC_SUCCESS; 11302 } 11303 /* Set length to one entry */ 11304 pReportLun->len[0] = 0; 11305 pReportLun->len[1] = 0; 11306 pReportLun->len[2] = 0; 11307 pReportLun->len[3] = sizeof (tiLUN_t); 11308 pReportLun->reserved = 0; 11309 /* Set to LUN 0: 11310 * - address method to 0x00: Peripheral device addressing method, 11311 * - bus identifier to 0 11312 */ 11313 pReportLun->lunList[0].lun[0] = 0; 11314 pReportLun->lunList[0].lun[1] = 0; 11315 pReportLun->lunList[0].lun[2] = 0; 11316 pReportLun->lunList[0].lun[3] = 0; 11317 pReportLun->lunList[0].lun[4] = 0; 11318 pReportLun->lunList[0].lun[5] = 0; 11319 pReportLun->lunList[0].lun[6] = 0; 11320 pReportLun->lunList[0].lun[7] = 0; 11321 11322 sm_memcpy(smScsiRequest->sglVirtualAddr, dataBuffer, MIN(allocationLen, reportLunLen)); 11323 if (allocationLen > reportLunLen) 11324 { 11325 /* underrun */ 11326 SM_DBG1(("smsatReportLun: reporting underrun reportLunLen=0x%x allocationLen=0x%x !!!\n", reportLunLen, allocationLen)); 11327 11328 /*smEnqueueIO(smRoot, satIOContext);*/ 11329 11330 tdsmIOCompletedCB( smRoot, 11331 smIORequest, 11332 smIOUnderRun, 11333 allocationLen - reportLunLen, 11334 agNULL, 11335 satIOContext->interruptContext ); 11336 11337 11338 } 11339 else 11340 { 11341 /*smEnqueueIO(smRoot, satIOContext);*/ 11342 11343 tdsmIOCompletedCB( smRoot, 11344 smIORequest, 11345 smIOSuccess, 11346 SCSI_STAT_GOOD, 11347 agNULL, 11348 satIOContext->interruptContext); 11349 } 11350 return SM_RC_SUCCESS; 11351 } 11352 11353 osGLOBAL bit32 11354 smsatFormatUnit( 11355 smRoot_t *smRoot, 11356 smIORequest_t *smIORequest, 11357 smDeviceHandle_t *smDeviceHandle, 11358 smScsiInitiatorRequest_t *smScsiRequest, 11359 smSatIOContext_t *satIOContext 11360 ) 11361 { 11362 /* 11363 note: we don't support media certification in this version and IP bit 11364 satDevData->satFormatState will be agFalse since SAT does not actually sends 11365 any ATA command 11366 */ 11367 11368 smScsiRspSense_t *pSense; 11369 smIniScsiCmnd_t *scsiCmnd; 11370 bit32 index = 0; 11371 11372 pSense = satIOContext->pSense; 11373 scsiCmnd = &smScsiRequest->scsiCmnd; 11374 SM_DBG5(("smsatFormatUnit: start\n")); 11375 /* 11376 checking opcode 11377 1. FMTDATA bit == 0(no defect list header) 11378 2. FMTDATA bit == 1 and DCRT bit == 1(defect list header is provided 11379 with DCRT bit set) 11380 */ 11381 if ( ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) == 0) || 11382 ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) && 11383 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK)) 11384 ) 11385 { 11386 /*smEnqueueIO(smRoot, satIOContext);*/ 11387 11388 tdsmIOCompletedCB( smRoot, 11389 smIORequest, 11390 smIOSuccess, 11391 SCSI_STAT_GOOD, 11392 agNULL, 11393 satIOContext->interruptContext); 11394 11395 SM_DBG1(("smsatFormatUnit: return opcode!!!\n")); 11396 return SM_RC_SUCCESS; 11397 } 11398 11399 /* 11400 checking DEFECT LIST FORMAT and defect list length 11401 */ 11402 if ( (((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x00) || 11403 ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x06)) ) 11404 { 11405 /* short parameter header */ 11406 if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x00) 11407 { 11408 index = 8; 11409 } 11410 /* long parameter header */ 11411 if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x01) 11412 { 11413 index = 10; 11414 } 11415 /* defect list length */ 11416 if ((scsiCmnd->cdb[index] != 0) || (scsiCmnd->cdb[index+1] != 0)) 11417 { 11418 smsatSetSensePayload( pSense, 11419 SCSI_SNSKEY_ILLEGAL_REQUEST, 11420 0, 11421 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11422 satIOContext); 11423 11424 /*smEnqueueIO(smRoot, satIOContext);*/ 11425 11426 tdsmIOCompletedCB( smRoot, 11427 smIORequest, 11428 smIOSuccess, 11429 SCSI_STAT_CHECK_CONDITION, 11430 satIOContext->pSmSenseData, 11431 satIOContext->interruptContext ); 11432 11433 SM_DBG1(("smsatFormatUnit: return defect list format!!!\n")); 11434 return SM_RC_SUCCESS; 11435 } 11436 } 11437 11438 if ( (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) && 11439 (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_CMPLIST_MASK) ) 11440 { 11441 smsatSetSensePayload( pSense, 11442 SCSI_SNSKEY_ILLEGAL_REQUEST, 11443 0, 11444 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11445 satIOContext); 11446 11447 /*smEnqueueIO(smRoot, satIOContext);*/ 11448 11449 tdsmIOCompletedCB( smRoot, 11450 smIORequest, 11451 smIOSuccess, 11452 SCSI_STAT_CHECK_CONDITION, 11453 satIOContext->pSmSenseData, 11454 satIOContext->interruptContext ); 11455 11456 SM_DBG1(("smsatFormatUnit: return cmplist!!!\n")); 11457 return SM_RC_SUCCESS; 11458 11459 } 11460 11461 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 11462 { 11463 smsatSetSensePayload( pSense, 11464 SCSI_SNSKEY_ILLEGAL_REQUEST, 11465 0, 11466 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11467 satIOContext); 11468 11469 /*smEnqueueIO(smRoot, satIOContext);*/ 11470 11471 tdsmIOCompletedCB( smRoot, 11472 smIORequest, 11473 smIOSuccess, 11474 SCSI_STAT_CHECK_CONDITION, 11475 satIOContext->pSmSenseData, 11476 satIOContext->interruptContext ); 11477 11478 SM_DBG1(("smsatFormatUnit: return control!!!\n")); 11479 return SM_RC_SUCCESS; 11480 } 11481 11482 /* defect list header filed, if exists, SAT rev8, Table 37, p48 */ 11483 if (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) 11484 { 11485 /* case 1,2,3 */ 11486 /* IMMED 1; FOV 0; FOV 1, DCRT 1, IP 0 */ 11487 if ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) || 11488 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK)) || 11489 ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) && 11490 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) && 11491 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK)) 11492 ) 11493 { 11494 /*smEnqueueIO(smRoot, satIOContext);*/ 11495 11496 tdsmIOCompletedCB( smRoot, 11497 smIORequest, 11498 smIOSuccess, 11499 SCSI_STAT_GOOD, 11500 agNULL, 11501 satIOContext->interruptContext); 11502 11503 SM_DBG5(("smsatFormatUnit: return defect list case 1\n")); 11504 return SM_RC_SUCCESS; 11505 } 11506 /* case 4,5,6 */ 11507 /* 11508 1. IMMED 0, FOV 1, DCRT 0, IP 0 11509 2. IMMED 0, FOV 1, DCRT 0, IP 1 11510 3. IMMED 0, FOV 1, DCRT 1, IP 1 11511 */ 11512 11513 if ( ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) && 11514 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) && 11515 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) && 11516 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) ) 11517 || 11518 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) && 11519 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) && 11520 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) && 11521 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) ) 11522 || 11523 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) && 11524 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) && 11525 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) && 11526 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) ) 11527 ) 11528 { 11529 11530 smsatSetSensePayload( pSense, 11531 SCSI_SNSKEY_ILLEGAL_REQUEST, 11532 0, 11533 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 11534 satIOContext); 11535 11536 /*smEnqueueIO(smRoot, satIOContext);*/ 11537 11538 tdsmIOCompletedCB( smRoot, 11539 smIORequest, 11540 smIOSuccess, 11541 SCSI_STAT_CHECK_CONDITION, 11542 satIOContext->pSmSenseData, 11543 satIOContext->interruptContext ); 11544 11545 SM_DBG5(("smsatFormatUnit: return defect list case 2\n")); 11546 return SM_RC_SUCCESS; 11547 11548 } 11549 } 11550 11551 11552 /* 11553 * Send the completion response now. 11554 */ 11555 /*smEnqueueIO(smRoot, satIOContext);*/ 11556 11557 tdsmIOCompletedCB( smRoot, 11558 smIORequest, 11559 smIOSuccess, 11560 SCSI_STAT_GOOD, 11561 agNULL, 11562 satIOContext->interruptContext); 11563 11564 SM_DBG5(("smsatFormatUnit: return last\n")); 11565 return SM_RC_SUCCESS; 11566 } 11567 11568 osGLOBAL bit32 11569 smsatSendDiagnostic( 11570 smRoot_t *smRoot, 11571 smIORequest_t *smIORequest, 11572 smDeviceHandle_t *smDeviceHandle, 11573 smScsiInitiatorRequest_t *smScsiRequest, 11574 smSatIOContext_t *satIOContext 11575 ) 11576 { 11577 bit32 status; 11578 bit32 agRequestType; 11579 smDeviceData_t *pSatDevData; 11580 smScsiRspSense_t *pSense; 11581 smIniScsiCmnd_t *scsiCmnd; 11582 agsaFisRegHostToDevice_t *fis; 11583 bit32 parmLen; 11584 11585 pSense = satIOContext->pSense; 11586 pSatDevData = satIOContext->pSatDevData; 11587 scsiCmnd = &smScsiRequest->scsiCmnd; 11588 fis = satIOContext->pFis; 11589 11590 SM_DBG5(("smsatSendDiagnostic: start\n")); 11591 11592 /* reset satVerifyState */ 11593 pSatDevData->satVerifyState = 0; 11594 /* no pending diagnostic in background */ 11595 pSatDevData->satBGPendingDiag = agFALSE; 11596 11597 /* table 27, 8.10 p39 SAT Rev8 */ 11598 /* 11599 1. checking PF == 1 11600 2. checking DEVOFFL == 1 11601 3. checking UNITOFFL == 1 11602 4. checking PARAMETER LIST LENGTH != 0 11603 11604 */ 11605 if ( (scsiCmnd->cdb[1] & SCSI_PF_MASK) || 11606 (scsiCmnd->cdb[1] & SCSI_DEVOFFL_MASK) || 11607 (scsiCmnd->cdb[1] & SCSI_UNITOFFL_MASK) || 11608 ( (scsiCmnd->cdb[3] != 0) || (scsiCmnd->cdb[4] != 0) ) 11609 ) 11610 { 11611 smsatSetSensePayload( pSense, 11612 SCSI_SNSKEY_ILLEGAL_REQUEST, 11613 0, 11614 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11615 satIOContext); 11616 11617 /*smEnqueueIO(smRoot, satIOContext);*/ 11618 11619 tdsmIOCompletedCB( smRoot, 11620 smIORequest, 11621 smIOSuccess, 11622 SCSI_STAT_CHECK_CONDITION, 11623 satIOContext->pSmSenseData, 11624 satIOContext->interruptContext ); 11625 11626 SM_DBG1(("smsatSendDiagnostic: return PF, DEVOFFL, UNITOFFL, PARAM LIST!!!\n")); 11627 return SM_RC_SUCCESS; 11628 } 11629 11630 /* checking CONTROL */ 11631 /* NACA == 1 or LINK == 1*/ 11632 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 11633 { 11634 smsatSetSensePayload( pSense, 11635 SCSI_SNSKEY_ILLEGAL_REQUEST, 11636 0, 11637 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11638 satIOContext); 11639 11640 /*smEnqueueIO(smRoot, satIOContext);*/ 11641 11642 tdsmIOCompletedCB( smRoot, 11643 smIORequest, 11644 smIOSuccess, 11645 SCSI_STAT_CHECK_CONDITION, 11646 satIOContext->pSmSenseData, 11647 satIOContext->interruptContext ); 11648 11649 SM_DBG1(("smsatSendDiagnostic: return control!!!\n")); 11650 return SM_RC_SUCCESS; 11651 } 11652 11653 parmLen = (scsiCmnd->cdb[3] << 8) + scsiCmnd->cdb[4]; 11654 11655 /* checking SELFTEST bit*/ 11656 /* table 29, 8.10.3, p41 SAT Rev8 */ 11657 /* case 1 */ 11658 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 11659 (pSatDevData->satSMARTSelfTest == agFALSE) 11660 ) 11661 { 11662 smsatSetSensePayload( pSense, 11663 SCSI_SNSKEY_ILLEGAL_REQUEST, 11664 0, 11665 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11666 satIOContext); 11667 11668 /*smEnqueueIO(smRoot, satIOContext);*/ 11669 11670 tdsmIOCompletedCB( smRoot, 11671 smIORequest, 11672 smIOSuccess, 11673 SCSI_STAT_CHECK_CONDITION, 11674 satIOContext->pSmSenseData, 11675 satIOContext->interruptContext ); 11676 11677 SM_DBG1(("smsatSendDiagnostic: return Table 29 case 1!!!\n")); 11678 return SM_RC_SUCCESS; 11679 } 11680 11681 /* case 2 */ 11682 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 11683 (pSatDevData->satSMARTSelfTest == agTRUE) && 11684 (pSatDevData->satSMARTEnabled == agFALSE) 11685 ) 11686 { 11687 smsatSetSensePayload( pSense, 11688 SCSI_SNSKEY_ABORTED_COMMAND, 11689 0, 11690 SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED, 11691 satIOContext); 11692 11693 /*smEnqueueIO(smRoot, satIOContext);*/ 11694 11695 tdsmIOCompletedCB( smRoot, 11696 smIORequest, 11697 smIOSuccess, 11698 SCSI_STAT_CHECK_CONDITION, 11699 satIOContext->pSmSenseData, 11700 satIOContext->interruptContext ); 11701 11702 SM_DBG5(("smsatSendDiagnostic: return Table 29 case 2\n")); 11703 return SM_RC_SUCCESS; 11704 } 11705 /* 11706 case 3 11707 see SELF TEST CODE later 11708 */ 11709 11710 11711 11712 /* case 4 */ 11713 11714 /* 11715 sends three ATA verify commands 11716 11717 */ 11718 if ( ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 11719 (pSatDevData->satSMARTSelfTest == agFALSE)) 11720 || 11721 ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 11722 (pSatDevData->satSMARTSelfTest == agTRUE) && 11723 (pSatDevData->satSMARTEnabled == agFALSE)) 11724 ) 11725 { 11726 /* 11727 sector count 1, LBA 0 11728 sector count 1, LBA MAX 11729 sector count 1, LBA random 11730 */ 11731 if (pSatDevData->sat48BitSupport == agTRUE) 11732 { 11733 /* sends READ VERIFY SECTOR(S) EXT*/ 11734 fis->h.fisType = 0x27; /* Reg host to device */ 11735 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11736 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 11737 fis->h.features = 0; /* FIS reserve */ 11738 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 11739 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 11740 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 11741 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 11742 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 11743 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 11744 fis->d.featuresExp = 0; /* FIS reserve */ 11745 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 11746 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 11747 fis->d.reserved4 = 0; 11748 fis->d.device = 0x40; /* 01000000 */ 11749 fis->d.control = 0; /* FIS HOB bit clear */ 11750 fis->d.reserved5 = 0; 11751 11752 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 11753 } 11754 else 11755 { 11756 /* READ VERIFY SECTOR(S)*/ 11757 fis->h.fisType = 0x27; /* Reg host to device */ 11758 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11759 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 11760 fis->h.features = 0; /* FIS features NA */ 11761 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 11762 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 11763 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 11764 fis->d.lbaLowExp = 0; 11765 fis->d.lbaMidExp = 0; 11766 fis->d.lbaHighExp = 0; 11767 fis->d.featuresExp = 0; 11768 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 11769 fis->d.sectorCountExp = 0; 11770 fis->d.reserved4 = 0; 11771 fis->d.device = 0x40; /* 01000000 */ 11772 fis->d.control = 0; /* FIS HOB bit clear */ 11773 fis->d.reserved5 = 0; 11774 11775 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 11776 } 11777 11778 /* Initialize CB for SATA completion. 11779 */ 11780 satIOContext->satCompleteCB = &smsatSendDiagnosticCB; 11781 11782 /* 11783 * Prepare SGL and send FIS to LL layer. 11784 */ 11785 satIOContext->reqType = agRequestType; /* Save it */ 11786 11787 status = smsataLLIOStart( smRoot, 11788 smIORequest, 11789 smDeviceHandle, 11790 smScsiRequest, 11791 satIOContext); 11792 11793 11794 SM_DBG5(("smsatSendDiagnostic: return Table 29 case 4\n")); 11795 return (status); 11796 } 11797 /* case 5 */ 11798 if ( (scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 11799 (pSatDevData->satSMARTSelfTest == agTRUE) && 11800 (pSatDevData->satSMARTEnabled == agTRUE) 11801 ) 11802 { 11803 /* sends SMART EXECUTE OFF-LINE IMMEDIATE */ 11804 fis->h.fisType = 0x27; /* Reg host to device */ 11805 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11806 fis->h.command = SAT_SMART; /* 0xB0 */ 11807 fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA */ 11808 fis->d.lbaLow = 0x81; /* FIS LBA (7 :0 ) */ 11809 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 11810 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 11811 fis->d.lbaLowExp = 0; 11812 fis->d.lbaMidExp = 0; 11813 fis->d.lbaHighExp = 0; 11814 fis->d.featuresExp = 0; 11815 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 11816 fis->d.sectorCountExp = 0; 11817 fis->d.reserved4 = 0; 11818 fis->d.device = 0; /* FIS DEV is discared in SATA */ 11819 fis->d.control = 0; /* FIS HOB bit clear */ 11820 fis->d.reserved5 = 0; 11821 11822 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 11823 11824 /* Initialize CB for SATA completion. 11825 */ 11826 satIOContext->satCompleteCB = &smsatSendDiagnosticCB; 11827 11828 /* 11829 * Prepare SGL and send FIS to LL layer. 11830 */ 11831 satIOContext->reqType = agRequestType; /* Save it */ 11832 11833 status = smsataLLIOStart( smRoot, 11834 smIORequest, 11835 smDeviceHandle, 11836 smScsiRequest, 11837 satIOContext); 11838 11839 11840 SM_DBG5(("smsatSendDiagnostic: return Table 29 case 5\n")); 11841 return (status); 11842 } 11843 11844 11845 11846 11847 /* SAT rev8 Table29 p41 case 3*/ 11848 /* checking SELF TEST CODE*/ 11849 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 11850 (pSatDevData->satSMARTSelfTest == agTRUE) && 11851 (pSatDevData->satSMARTEnabled == agTRUE) 11852 ) 11853 { 11854 /* SAT rev8 Table28 p40 */ 11855 /* finding self-test code */ 11856 switch ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_TEST_CODE_MASK) >> 5) 11857 { 11858 case 1: 11859 pSatDevData->satBGPendingDiag = agTRUE; 11860 11861 tdsmIOCompletedCB( smRoot, 11862 smIORequest, 11863 smIOSuccess, 11864 SCSI_STAT_GOOD, 11865 agNULL, 11866 satIOContext->interruptContext ); 11867 /* sends SMART EXECUTE OFF-LINE IMMEDIATE */ 11868 fis->h.fisType = 0x27; /* Reg host to device */ 11869 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11870 fis->h.command = SAT_SMART; /* 0x40 */ 11871 fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA */ 11872 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */ 11873 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 11874 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 11875 11876 fis->d.lbaLowExp = 0; 11877 fis->d.lbaMidExp = 0; 11878 fis->d.lbaHighExp = 0; 11879 fis->d.featuresExp = 0; 11880 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 11881 fis->d.sectorCountExp = 0; 11882 fis->d.reserved4 = 0; 11883 fis->d.device = 0; /* FIS DEV is discared in SATA */ 11884 fis->d.control = 0; /* FIS HOB bit clear */ 11885 fis->d.reserved5 = 0; 11886 11887 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 11888 11889 /* Initialize CB for SATA completion. 11890 */ 11891 satIOContext->satCompleteCB = &smsatSendDiagnosticCB; 11892 11893 /* 11894 * Prepare SGL and send FIS to LL layer. 11895 */ 11896 satIOContext->reqType = agRequestType; /* Save it */ 11897 11898 status = smsataLLIOStart( smRoot, 11899 smIORequest, 11900 smDeviceHandle, 11901 smScsiRequest, 11902 satIOContext); 11903 11904 11905 SM_DBG5(("smsatSendDiagnostic: return Table 28 case 1\n")); 11906 return (status); 11907 case 2: 11908 pSatDevData->satBGPendingDiag = agTRUE; 11909 11910 tdsmIOCompletedCB( smRoot, 11911 smIORequest, 11912 smIOSuccess, 11913 SCSI_STAT_GOOD, 11914 agNULL, 11915 satIOContext->interruptContext ); 11916 11917 11918 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */ 11919 fis->h.fisType = 0x27; /* Reg host to device */ 11920 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11921 fis->h.command = SAT_SMART; /* 0x40 */ 11922 fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA */ 11923 fis->d.lbaLow = 0x02; /* FIS LBA (7 :0 ) */ 11924 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 11925 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 11926 fis->d.lbaLowExp = 0; 11927 fis->d.lbaMidExp = 0; 11928 fis->d.lbaHighExp = 0; 11929 fis->d.featuresExp = 0; 11930 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 11931 fis->d.sectorCountExp = 0; 11932 fis->d.reserved4 = 0; 11933 fis->d.device = 0; /* FIS DEV is discared in SATA */ 11934 fis->d.control = 0; /* FIS HOB bit clear */ 11935 fis->d.reserved5 = 0; 11936 11937 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 11938 11939 /* Initialize CB for SATA completion. 11940 */ 11941 satIOContext->satCompleteCB = &smsatSendDiagnosticCB; 11942 11943 /* 11944 * Prepare SGL and send FIS to LL layer. 11945 */ 11946 satIOContext->reqType = agRequestType; /* Save it */ 11947 11948 status = smsataLLIOStart( smRoot, 11949 smIORequest, 11950 smDeviceHandle, 11951 smScsiRequest, 11952 satIOContext); 11953 11954 11955 SM_DBG5(("smsatSendDiagnostic: return Table 28 case 2\n")); 11956 return (status); 11957 case 4: 11958 11959 if (parmLen != 0) 11960 { 11961 /* check condition */ 11962 smsatSetSensePayload( pSense, 11963 SCSI_SNSKEY_ILLEGAL_REQUEST, 11964 0, 11965 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11966 satIOContext); 11967 11968 /*smEnqueueIO(smRoot, satIOContext);*/ 11969 11970 tdsmIOCompletedCB( smRoot, 11971 smIORequest, 11972 smIOSuccess, 11973 SCSI_STAT_CHECK_CONDITION, 11974 satIOContext->pSmSenseData, 11975 satIOContext->interruptContext ); 11976 11977 SM_DBG1(("smsatSendDiagnostic: case 4, non zero ParmLen %d!!!\n", parmLen)); 11978 return SM_RC_SUCCESS; 11979 } 11980 if (pSatDevData->satBGPendingDiag == agTRUE) 11981 { 11982 /* sends SMART EXECUTE OFF-LINE IMMEDIATE abort */ 11983 fis->h.fisType = 0x27; /* Reg host to device */ 11984 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11985 fis->h.command = SAT_SMART; /* 0x40 */ 11986 fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA */ 11987 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */ 11988 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 11989 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 11990 11991 fis->d.lbaLowExp = 0; 11992 fis->d.lbaMidExp = 0; 11993 fis->d.lbaHighExp = 0; 11994 fis->d.featuresExp = 0; 11995 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 11996 fis->d.sectorCountExp = 0; 11997 fis->d.reserved4 = 0; 11998 fis->d.device = 0; /* FIS DEV is discared in SATA */ 11999 fis->d.control = 0; /* FIS HOB bit clear */ 12000 fis->d.reserved5 = 0; 12001 12002 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12003 12004 /* Initialize CB for SATA completion. 12005 */ 12006 satIOContext->satCompleteCB = &smsatSendDiagnosticCB; 12007 12008 /* 12009 * Prepare SGL and send FIS to LL layer. 12010 */ 12011 satIOContext->reqType = agRequestType; /* Save it */ 12012 12013 status = smsataLLIOStart( smRoot, 12014 smIORequest, 12015 smDeviceHandle, 12016 smScsiRequest, 12017 satIOContext); 12018 12019 12020 SM_DBG5(("smsatSendDiagnostic: send SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE case 3\n")); 12021 SM_DBG5(("smsatSendDiagnostic: Table 28 case 4\n")); 12022 return (status); 12023 } 12024 else 12025 { 12026 /* check condition */ 12027 smsatSetSensePayload( pSense, 12028 SCSI_SNSKEY_ILLEGAL_REQUEST, 12029 0, 12030 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12031 satIOContext); 12032 12033 /*smEnqueueIO(smRoot, satIOContext);*/ 12034 12035 tdsmIOCompletedCB( smRoot, 12036 smIORequest, 12037 smIOSuccess, 12038 SCSI_STAT_CHECK_CONDITION, 12039 satIOContext->pSmSenseData, 12040 satIOContext->interruptContext ); 12041 12042 SM_DBG1(("smsatSendDiagnostic: case 4, no pending diagnostic in background!!!\n")); 12043 SM_DBG5(("smsatSendDiagnostic: Table 28 case 4\n")); 12044 return SM_RC_SUCCESS; 12045 } 12046 break; 12047 case 5: 12048 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */ 12049 fis->h.fisType = 0x27; /* Reg host to device */ 12050 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12051 fis->h.command = SAT_SMART; /* 0x40 */ 12052 fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA */ 12053 fis->d.lbaLow = 0x81; /* FIS LBA (7 :0 ) */ 12054 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 12055 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 12056 fis->d.lbaLowExp = 0; 12057 fis->d.lbaMidExp = 0; 12058 fis->d.lbaHighExp = 0; 12059 fis->d.featuresExp = 0; 12060 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 12061 fis->d.sectorCountExp = 0; 12062 fis->d.reserved4 = 0; 12063 fis->d.device = 0; /* FIS DEV is discared in SATA */ 12064 fis->d.control = 0; /* FIS HOB bit clear */ 12065 fis->d.reserved5 = 0; 12066 12067 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12068 12069 /* Initialize CB for SATA completion. 12070 */ 12071 satIOContext->satCompleteCB = &smsatSendDiagnosticCB; 12072 12073 /* 12074 * Prepare SGL and send FIS to LL layer. 12075 */ 12076 satIOContext->reqType = agRequestType; /* Save it */ 12077 12078 status = smsataLLIOStart( smRoot, 12079 smIORequest, 12080 smDeviceHandle, 12081 smScsiRequest, 12082 satIOContext); 12083 12084 12085 SM_DBG5(("smsatSendDiagnostic: return Table 28 case 5\n")); 12086 return (status); 12087 case 6: 12088 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */ 12089 fis->h.fisType = 0x27; /* Reg host to device */ 12090 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12091 fis->h.command = SAT_SMART; /* 0x40 */ 12092 fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA */ 12093 fis->d.lbaLow = 0x82; /* FIS LBA (7 :0 ) */ 12094 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 12095 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 12096 fis->d.lbaLowExp = 0; 12097 fis->d.lbaMidExp = 0; 12098 fis->d.lbaHighExp = 0; 12099 fis->d.featuresExp = 0; 12100 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 12101 fis->d.sectorCountExp = 0; 12102 fis->d.reserved4 = 0; 12103 fis->d.device = 0; /* FIS DEV is discared in SATA */ 12104 fis->d.control = 0; /* FIS HOB bit clear */ 12105 fis->d.reserved5 = 0; 12106 12107 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12108 12109 /* Initialize CB for SATA completion. 12110 */ 12111 satIOContext->satCompleteCB = &smsatSendDiagnosticCB; 12112 12113 /* 12114 * Prepare SGL and send FIS to LL layer. 12115 */ 12116 satIOContext->reqType = agRequestType; /* Save it */ 12117 12118 status = smsataLLIOStart( smRoot, 12119 smIORequest, 12120 smDeviceHandle, 12121 smScsiRequest, 12122 satIOContext); 12123 12124 12125 SM_DBG5(("smsatSendDiagnostic: return Table 28 case 6\n")); 12126 return (status); 12127 case 0: 12128 case 3: /* fall through */ 12129 case 7: /* fall through */ 12130 default: 12131 break; 12132 }/* switch */ 12133 12134 /* returns the results of default self-testing, which is good */ 12135 /*smEnqueueIO(smRoot, satIOContext);*/ 12136 12137 tdsmIOCompletedCB( smRoot, 12138 smIORequest, 12139 smIOSuccess, 12140 SCSI_STAT_GOOD, 12141 agNULL, 12142 satIOContext->interruptContext ); 12143 12144 SM_DBG5(("smsatSendDiagnostic: return Table 28 case 0,3,7 and default\n")); 12145 return SM_RC_SUCCESS; 12146 } 12147 12148 12149 /*smEnqueueIO(smRoot, satIOContext);*/ 12150 12151 tdsmIOCompletedCB( smRoot, 12152 smIORequest, 12153 smIOSuccess, 12154 SCSI_STAT_GOOD, 12155 agNULL, 12156 satIOContext->interruptContext ); 12157 12158 12159 SM_DBG5(("smsatSendDiagnostic: return last\n")); 12160 return SM_RC_SUCCESS; 12161 12162 } 12163 12164 osGLOBAL bit32 12165 smsatStartStopUnit( 12166 smRoot_t *smRoot, 12167 smIORequest_t *smIORequest, 12168 smDeviceHandle_t *smDeviceHandle, 12169 smScsiInitiatorRequest_t *smScsiRequest, 12170 smSatIOContext_t *satIOContext 12171 ) 12172 { 12173 bit32 status; 12174 bit32 agRequestType; 12175 smDeviceData_t *pSatDevData; 12176 smScsiRspSense_t *pSense; 12177 smIniScsiCmnd_t *scsiCmnd; 12178 agsaFisRegHostToDevice_t *fis; 12179 12180 pSense = satIOContext->pSense; 12181 pSatDevData = satIOContext->pSatDevData; 12182 scsiCmnd = &smScsiRequest->scsiCmnd; 12183 fis = satIOContext->pFis; 12184 12185 SM_DBG5(("smsatStartStopUnit: start\n")); 12186 12187 /* checking CONTROL */ 12188 /* NACA == 1 or LINK == 1*/ 12189 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 12190 { 12191 smsatSetSensePayload( pSense, 12192 SCSI_SNSKEY_ILLEGAL_REQUEST, 12193 0, 12194 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12195 satIOContext); 12196 12197 /*smEnqueueIO(smRoot, satIOContext);*/ 12198 12199 tdsmIOCompletedCB( smRoot, 12200 smIORequest, 12201 smIOSuccess, 12202 SCSI_STAT_CHECK_CONDITION, 12203 satIOContext->pSmSenseData, 12204 satIOContext->interruptContext ); 12205 12206 SM_DBG1(("smsatStartStopUnit: return control!!!\n")); 12207 return SM_RC_SUCCESS; 12208 } 12209 12210 /* Spec p55, Table 48 checking START and LOEJ bit */ 12211 /* case 1 */ 12212 if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) 12213 { 12214 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) ) 12215 { 12216 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/ 12217 /*smEnqueueIO(smRoot, satIOContext);*/ 12218 12219 tdsmIOCompletedCB( smRoot, 12220 smIORequest, 12221 smIOSuccess, 12222 SCSI_STAT_GOOD, 12223 agNULL, 12224 satIOContext->interruptContext ); 12225 SM_DBG5(("smsatStartStopUnit: return table48 case 1-1\n")); 12226 return SM_RC_SUCCESS; 12227 } 12228 /* sends FLUSH CACHE or FLUSH CACHE EXT */ 12229 if (pSatDevData->sat48BitSupport == agTRUE) 12230 { 12231 /* FLUSH CACHE EXT */ 12232 fis->h.fisType = 0x27; /* Reg host to device */ 12233 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12234 12235 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */ 12236 fis->h.features = 0; /* FIS reserve */ 12237 fis->d.featuresExp = 0; /* FIS reserve */ 12238 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 12239 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 12240 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 12241 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 12242 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 12243 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 12244 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 12245 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 12246 fis->d.device = 0; /* FIS DEV is discared in SATA */ 12247 fis->d.control = 0; /* FIS HOB bit clear */ 12248 fis->d.reserved4 = 0; 12249 fis->d.reserved5 = 0; 12250 12251 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12252 } 12253 else 12254 { 12255 /* FLUSH CACHE */ 12256 fis->h.fisType = 0x27; /* Reg host to device */ 12257 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12258 12259 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */ 12260 fis->h.features = 0; /* FIS features NA */ 12261 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 12262 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 12263 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 12264 fis->d.lbaLowExp = 0; 12265 fis->d.lbaMidExp = 0; 12266 fis->d.lbaHighExp = 0; 12267 fis->d.featuresExp = 0; 12268 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 12269 fis->d.sectorCountExp = 0; 12270 fis->d.device = 0; /* FIS DEV is discared in SATA */ 12271 fis->d.control = 0; /* FIS HOB bit clear */ 12272 fis->d.reserved4 = 0; 12273 fis->d.reserved5 = 0; 12274 12275 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12276 } 12277 12278 /* Initialize CB for SATA completion. 12279 */ 12280 satIOContext->satCompleteCB = &smsatStartStopUnitCB; 12281 12282 /* 12283 * Prepare SGL and send FIS to LL layer. 12284 */ 12285 satIOContext->reqType = agRequestType; /* Save it */ 12286 12287 status = smsataLLIOStart( smRoot, 12288 smIORequest, 12289 smDeviceHandle, 12290 smScsiRequest, 12291 satIOContext); 12292 12293 12294 SM_DBG5(("smsatStartStopUnit: return table48 case 1\n")); 12295 return (status); 12296 } 12297 /* case 2 */ 12298 else if ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) 12299 { 12300 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/ 12301 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) ) 12302 { 12303 /*smEnqueueIO(smRoot, satIOContext);*/ 12304 12305 tdsmIOCompletedCB( smRoot, 12306 smIORequest, 12307 smIOSuccess, 12308 SCSI_STAT_GOOD, 12309 agNULL, 12310 satIOContext->interruptContext ); 12311 12312 SM_DBG5(("smsatStartStopUnit: return table48 case 2 1\n")); 12313 return SM_RC_SUCCESS; 12314 } 12315 /* 12316 sends READ_VERIFY_SECTORS(_EXT) 12317 sector count 1, any LBA between zero to Maximum 12318 */ 12319 if (pSatDevData->sat48BitSupport == agTRUE) 12320 { 12321 /* READ VERIFY SECTOR(S) EXT*/ 12322 fis->h.fisType = 0x27; /* Reg host to device */ 12323 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12324 12325 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 12326 fis->h.features = 0; /* FIS reserve */ 12327 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */ 12328 fis->d.lbaMid = 0x00; /* FIS LBA (15:8 ) */ 12329 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */ 12330 fis->d.lbaLowExp = 0x00; /* FIS LBA (31:24) */ 12331 fis->d.lbaMidExp = 0x00; /* FIS LBA (39:32) */ 12332 fis->d.lbaHighExp = 0x00; /* FIS LBA (47:40) */ 12333 fis->d.featuresExp = 0; /* FIS reserve */ 12334 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 12335 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 12336 fis->d.reserved4 = 0; 12337 fis->d.device = 0x40; /* 01000000 */ 12338 fis->d.control = 0; /* FIS HOB bit clear */ 12339 fis->d.reserved5 = 0; 12340 12341 } 12342 else 12343 { 12344 /* READ VERIFY SECTOR(S)*/ 12345 fis->h.fisType = 0x27; /* Reg host to device */ 12346 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12347 12348 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 12349 fis->h.features = 0; /* FIS features NA */ 12350 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */ 12351 fis->d.lbaMid = 0x00; /* FIS LBA (15:8 ) */ 12352 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */ 12353 fis->d.lbaLowExp = 0; 12354 fis->d.lbaMidExp = 0; 12355 fis->d.lbaHighExp = 0; 12356 fis->d.featuresExp = 0; 12357 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 12358 fis->d.sectorCountExp = 0; 12359 fis->d.reserved4 = 0; 12360 fis->d.device = 0x40; /* 01000000 */ 12361 fis->d.control = 0; /* FIS HOB bit clear */ 12362 fis->d.reserved5 = 0; 12363 12364 } 12365 12366 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12367 12368 /* Initialize CB for SATA completion. 12369 */ 12370 satIOContext->satCompleteCB = &smsatStartStopUnitCB; 12371 12372 /* 12373 * Prepare SGL and send FIS to LL layer. 12374 */ 12375 satIOContext->reqType = agRequestType; /* Save it */ 12376 12377 status = smsataLLIOStart( smRoot, 12378 smIORequest, 12379 smDeviceHandle, 12380 smScsiRequest, 12381 satIOContext); 12382 12383 SM_DBG5(("smsatStartStopUnit: return table48 case 2 2\n")); 12384 return status; 12385 } 12386 /* case 3 */ 12387 else if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) 12388 { 12389 if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled) 12390 { 12391 /* support for removal media */ 12392 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/ 12393 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) ) 12394 { 12395 /*smEnqueueIO(smRoot, satIOContext);*/ 12396 12397 tdsmIOCompletedCB( smRoot, 12398 smIORequest, 12399 smIOSuccess, 12400 SCSI_STAT_GOOD, 12401 agNULL, 12402 satIOContext->interruptContext ); 12403 12404 SM_DBG5(("smsatStartStopUnit: return table48 case 3 1\n")); 12405 return SM_RC_SUCCESS; 12406 } 12407 /* 12408 sends MEDIA EJECT 12409 */ 12410 /* Media Eject fis */ 12411 fis->h.fisType = 0x27; /* Reg host to device */ 12412 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12413 12414 fis->h.command = SAT_MEDIA_EJECT; /* 0xED */ 12415 fis->h.features = 0; /* FIS features NA */ 12416 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 12417 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 12418 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 12419 fis->d.lbaLowExp = 0; 12420 fis->d.lbaMidExp = 0; 12421 fis->d.lbaHighExp = 0; 12422 fis->d.featuresExp = 0; 12423 /* sector count zero */ 12424 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 12425 fis->d.sectorCountExp = 0; 12426 fis->d.device = 0; /* FIS DEV is discared in SATA */ 12427 fis->d.control = 0; /* FIS HOB bit clear */ 12428 fis->d.reserved4 = 0; 12429 fis->d.reserved5 = 0; 12430 12431 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12432 12433 /* Initialize CB for SATA completion. 12434 */ 12435 satIOContext->satCompleteCB = &smsatStartStopUnitCB; 12436 12437 /* 12438 * Prepare SGL and send FIS to LL layer. 12439 */ 12440 satIOContext->reqType = agRequestType; /* Save it */ 12441 12442 status = smsataLLIOStart( smRoot, 12443 smIORequest, 12444 smDeviceHandle, 12445 smScsiRequest, 12446 satIOContext); 12447 12448 return status; 12449 } 12450 else 12451 { 12452 /* no support for removal media */ 12453 smsatSetSensePayload( pSense, 12454 SCSI_SNSKEY_ILLEGAL_REQUEST, 12455 0, 12456 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12457 satIOContext); 12458 12459 /*smEnqueueIO(smRoot, satIOContext);*/ 12460 12461 tdsmIOCompletedCB( smRoot, 12462 smIORequest, 12463 smIOSuccess, 12464 SCSI_STAT_CHECK_CONDITION, 12465 satIOContext->pSmSenseData, 12466 satIOContext->interruptContext ); 12467 12468 SM_DBG5(("smsatStartStopUnit: return Table 29 case 3 2\n")); 12469 return SM_RC_SUCCESS; 12470 } 12471 12472 } 12473 /* case 4 */ 12474 else /* ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) */ 12475 { 12476 smsatSetSensePayload( pSense, 12477 SCSI_SNSKEY_ILLEGAL_REQUEST, 12478 0, 12479 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12480 satIOContext); 12481 12482 /*smEnqueueIO(smRoot, satIOContext);*/ 12483 12484 tdsmIOCompletedCB( smRoot, 12485 smIORequest, 12486 smIOSuccess, 12487 SCSI_STAT_CHECK_CONDITION, 12488 satIOContext->pSmSenseData, 12489 satIOContext->interruptContext ); 12490 12491 SM_DBG5(("smsatStartStopUnit: return Table 29 case 4\n")); 12492 return SM_RC_SUCCESS; 12493 } 12494 } 12495 12496 osGLOBAL bit32 12497 smsatWriteSame10( 12498 smRoot_t *smRoot, 12499 smIORequest_t *smIORequest, 12500 smDeviceHandle_t *smDeviceHandle, 12501 smScsiInitiatorRequest_t *smScsiRequest, 12502 smSatIOContext_t *satIOContext 12503 ) 12504 { 12505 12506 bit32 status; 12507 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 12508 smDeviceData_t *pSatDevData; 12509 smScsiRspSense_t *pSense; 12510 smIniScsiCmnd_t *scsiCmnd; 12511 agsaFisRegHostToDevice_t *fis; 12512 bit32 lba = 0; 12513 bit32 tl = 0; 12514 12515 pSense = satIOContext->pSense; 12516 pSatDevData = satIOContext->pSatDevData; 12517 scsiCmnd = &smScsiRequest->scsiCmnd; 12518 fis = satIOContext->pFis; 12519 12520 SM_DBG5(("smsatWriteSame10: start\n")); 12521 12522 /* checking CONTROL */ 12523 /* NACA == 1 or LINK == 1*/ 12524 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 12525 { 12526 smsatSetSensePayload( pSense, 12527 SCSI_SNSKEY_ILLEGAL_REQUEST, 12528 0, 12529 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12530 satIOContext); 12531 12532 /*smEnqueueIO(smRoot, satIOContext);*/ 12533 12534 tdsmIOCompletedCB( smRoot, 12535 smIORequest, 12536 smIOSuccess, 12537 SCSI_STAT_CHECK_CONDITION, 12538 satIOContext->pSmSenseData, 12539 satIOContext->interruptContext ); 12540 12541 SM_DBG1(("smsatWriteSame10: return control!!!\n")); 12542 return SM_RC_SUCCESS; 12543 } 12544 12545 12546 /* checking LBDATA and PBDATA */ 12547 /* case 1 */ 12548 if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) && 12549 !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) 12550 { 12551 SM_DBG5(("smsatWriteSame10: case 1\n")); 12552 /* spec 9.26.2, Table 62, p64, case 1*/ 12553 /* 12554 normal case 12555 just like write in 9.17.1 12556 */ 12557 12558 if ( pSatDevData->sat48BitSupport != agTRUE ) 12559 { 12560 /* 12561 writeSame10 but no support for 48 bit addressing 12562 -> problem in transfer length. Therefore, return check condition 12563 */ 12564 smsatSetSensePayload( pSense, 12565 SCSI_SNSKEY_ILLEGAL_REQUEST, 12566 0, 12567 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12568 satIOContext); 12569 12570 /*smEnqueueIO(smRoot, satIOContext);*/ 12571 12572 tdsmIOCompletedCB( smRoot, 12573 smIORequest, 12574 smIOSuccess, 12575 SCSI_STAT_CHECK_CONDITION, 12576 satIOContext->pSmSenseData, 12577 satIOContext->interruptContext ); 12578 12579 SM_DBG1(("smsatWriteSame10: return internal checking!!!\n")); 12580 return SM_RC_SUCCESS; 12581 } 12582 12583 /* cdb10; computing LBA and transfer length */ 12584 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 12585 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 12586 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 12587 12588 12589 /* Table 34, 9.1, p 46 */ 12590 /* 12591 note: As of 2/10/2006, no support for DMA QUEUED 12592 */ 12593 12594 /* 12595 Table 34, 9.1, p 46, b (footnote) 12596 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 12597 return check condition 12598 */ 12599 if (pSatDevData->satNCQ != agTRUE && 12600 pSatDevData->sat48BitSupport != agTRUE 12601 ) 12602 { 12603 if (lba > SAT_TR_LBA_LIMIT - 1) /* SAT_TR_LBA_LIMIT is 2^28, 0x10000000 */ 12604 { 12605 smsatSetSensePayload( pSense, 12606 SCSI_SNSKEY_ILLEGAL_REQUEST, 12607 0, 12608 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 12609 satIOContext); 12610 12611 /*smEnqueueIO(smRoot, satIOContext);*/ 12612 12613 tdsmIOCompletedCB( smRoot, 12614 smIORequest, 12615 smIOSuccess, 12616 SCSI_STAT_CHECK_CONDITION, 12617 satIOContext->pSmSenseData, 12618 satIOContext->interruptContext ); 12619 12620 SM_DBG1(("smsatWriteSame10: return LBA out of range!!!\n")); 12621 return SM_RC_SUCCESS; 12622 } 12623 } 12624 12625 12626 if (lba + tl <= SAT_TR_LBA_LIMIT) 12627 { 12628 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 12629 { 12630 /* case 2 */ 12631 /* WRITE DMA */ 12632 /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */ 12633 SM_DBG1(("smsatWriteSame10: case 1-2 !!! error due to writesame10!!!\n")); 12634 smsatSetSensePayload( pSense, 12635 SCSI_SNSKEY_ILLEGAL_REQUEST, 12636 0, 12637 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12638 satIOContext); 12639 12640 /*smEnqueueIO(smRoot, satIOContext);*/ 12641 12642 tdsmIOCompletedCB( smRoot, 12643 smIORequest, 12644 smIOSuccess, 12645 SCSI_STAT_CHECK_CONDITION, 12646 satIOContext->pSmSenseData, 12647 satIOContext->interruptContext ); 12648 return SM_RC_SUCCESS; 12649 } 12650 else 12651 { 12652 /* case 1 */ 12653 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 12654 /* WRITE SECTORS is chosen for easier implemetation */ 12655 /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */ 12656 SM_DBG1(("smsatWriteSame10: case 1-1 !!! error due to writesame10!!!\n")); 12657 smsatSetSensePayload( pSense, 12658 SCSI_SNSKEY_ILLEGAL_REQUEST, 12659 0, 12660 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12661 satIOContext); 12662 12663 /*smEnqueueIO(smRoot, satIOContext);*/ 12664 12665 tdsmIOCompletedCB( smRoot, 12666 smIORequest, 12667 smIOSuccess, 12668 SCSI_STAT_CHECK_CONDITION, 12669 satIOContext->pSmSenseData, 12670 satIOContext->interruptContext ); 12671 return SM_RC_SUCCESS; 12672 } 12673 } /* end of case 1 and 2 */ 12674 12675 /* case 3 and 4 */ 12676 if (pSatDevData->sat48BitSupport == agTRUE) 12677 { 12678 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 12679 { 12680 /* case 3 */ 12681 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 12682 /* WRITE DMA EXT is chosen since WRITE SAME does not have FUA bit */ 12683 SM_DBG5(("smsatWriteSame10: case 1-3\n")); 12684 fis->h.fisType = 0x27; /* Reg host to device */ 12685 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12686 12687 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 12688 12689 fis->h.features = 0; /* FIS reserve */ 12690 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 12691 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 12692 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 12693 fis->d.device = 0x40; /* FIS LBA mode set */ 12694 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 12695 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 12696 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 12697 fis->d.featuresExp = 0; /* FIS reserve */ 12698 if (tl == 0) 12699 { 12700 /* error check 12701 ATA spec, p125, 6.17.29 12702 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF 12703 and allowed value is 0x0FFFFFFF - 1 12704 */ 12705 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF) 12706 { 12707 SM_DBG1(("smsatWriteSame10: case 3 !!! warning can't fit sectors!!!\n")); 12708 smsatSetSensePayload( pSense, 12709 SCSI_SNSKEY_ILLEGAL_REQUEST, 12710 0, 12711 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12712 satIOContext); 12713 12714 /*smEnqueueIO(smRoot, satIOContext);*/ 12715 12716 tdsmIOCompletedCB( smRoot, 12717 smIORequest, 12718 smIOSuccess, 12719 SCSI_STAT_CHECK_CONDITION, 12720 satIOContext->pSmSenseData, 12721 satIOContext->interruptContext ); 12722 return SM_RC_SUCCESS; 12723 } 12724 } 12725 /* one sector at a time */ 12726 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 12727 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 12728 fis->d.reserved4 = 0; 12729 fis->d.control = 0; /* FIS HOB bit clear */ 12730 fis->d.reserved5 = 0; 12731 12732 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 12733 } 12734 else 12735 { 12736 /* case 4 */ 12737 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 12738 /* WRITE SECTORS EXT is chosen for easier implemetation */ 12739 SM_DBG5(("smsatWriteSame10: case 1-4\n")); 12740 fis->h.fisType = 0x27; /* Reg host to device */ 12741 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12742 12743 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 12744 fis->h.features = 0; /* FIS reserve */ 12745 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 12746 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 12747 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 12748 fis->d.device = 0x40; /* FIS LBA mode set */ 12749 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 12750 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 12751 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 12752 fis->d.featuresExp = 0; /* FIS reserve */ 12753 if (tl == 0) 12754 { 12755 /* error check 12756 ATA spec, p125, 6.17.29 12757 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF 12758 and allowed value is 0x0FFFFFFF - 1 12759 */ 12760 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF) 12761 { 12762 SM_DBG1(("smsatWriteSame10: case 4 !!! warning can't fit sectors!!!\n")); 12763 smsatSetSensePayload( pSense, 12764 SCSI_SNSKEY_ILLEGAL_REQUEST, 12765 0, 12766 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12767 satIOContext); 12768 12769 /*smEnqueueIO(smRoot, satIOContext);*/ 12770 12771 tdsmIOCompletedCB( smRoot, 12772 smIORequest, 12773 smIOSuccess, 12774 SCSI_STAT_CHECK_CONDITION, 12775 satIOContext->pSmSenseData, 12776 satIOContext->interruptContext ); 12777 return SM_RC_SUCCESS; 12778 } 12779 } 12780 /* one sector at a time */ 12781 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 12782 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 12783 fis->d.reserved4 = 0; 12784 fis->d.control = 0; /* FIS HOB bit clear */ 12785 fis->d.reserved5 = 0; 12786 12787 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 12788 } 12789 } 12790 12791 /* case 5 */ 12792 if (pSatDevData->satNCQ == agTRUE) 12793 { 12794 /* WRITE FPDMA QUEUED */ 12795 if (pSatDevData->sat48BitSupport != agTRUE) 12796 { 12797 SM_DBG1(("smsatWriteSame10: case 1-5 !!! error NCQ but 28 bit address support!!!\n")); 12798 smsatSetSensePayload( pSense, 12799 SCSI_SNSKEY_ILLEGAL_REQUEST, 12800 0, 12801 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12802 satIOContext); 12803 12804 /*smEnqueueIO(smRoot, satIOContext);*/ 12805 12806 tdsmIOCompletedCB( smRoot, 12807 smIORequest, 12808 smIOSuccess, 12809 SCSI_STAT_CHECK_CONDITION, 12810 satIOContext->pSmSenseData, 12811 satIOContext->interruptContext ); 12812 return SM_RC_SUCCESS; 12813 } 12814 SM_DBG5(("smsatWriteSame10: case 1-5\n")); 12815 12816 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 12817 12818 fis->h.fisType = 0x27; /* Reg host to device */ 12819 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12820 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 12821 12822 if (tl == 0) 12823 { 12824 /* error check 12825 ATA spec, p125, 6.17.29 12826 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF 12827 and allowed value is 0x0FFFFFFF - 1 12828 */ 12829 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF) 12830 { 12831 SM_DBG1(("smsatWriteSame10: case 4 !!! warning can't fit sectors!!!\n")); 12832 smsatSetSensePayload( pSense, 12833 SCSI_SNSKEY_ILLEGAL_REQUEST, 12834 0, 12835 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12836 satIOContext); 12837 12838 /*smEnqueueIO(smRoot, satIOContext);*/ 12839 12840 tdsmIOCompletedCB( smRoot, 12841 smIORequest, 12842 smIOSuccess, 12843 SCSI_STAT_CHECK_CONDITION, 12844 satIOContext->pSmSenseData, 12845 satIOContext->interruptContext ); 12846 return SM_RC_SUCCESS; 12847 } 12848 } 12849 /* one sector at a time */ 12850 fis->h.features = 1; /* FIS sector count (7:0) */ 12851 fis->d.featuresExp = 0; /* FIS sector count (15:8) */ 12852 12853 12854 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 12855 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 12856 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 12857 12858 /* NO FUA bit in the WRITE SAME 10 */ 12859 fis->d.device = 0x40; /* FIS FUA clear */ 12860 12861 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 12862 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 12863 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 12864 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 12865 fis->d.sectorCountExp = 0; 12866 fis->d.reserved4 = 0; 12867 fis->d.control = 0; /* FIS HOB bit clear */ 12868 fis->d.reserved5 = 0; 12869 12870 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 12871 } 12872 /* Initialize CB for SATA completion. 12873 */ 12874 satIOContext->satCompleteCB = &smsatWriteSame10CB; 12875 12876 /* 12877 * Prepare SGL and send FIS to LL layer. 12878 */ 12879 satIOContext->reqType = agRequestType; /* Save it */ 12880 12881 status = smsataLLIOStart( smRoot, 12882 smIORequest, 12883 smDeviceHandle, 12884 smScsiRequest, 12885 satIOContext); 12886 return (status); 12887 12888 12889 } /* end of case 1 */ 12890 else if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) && 12891 (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) 12892 { 12893 /* spec 9.26.2, Table 62, p64, case 2*/ 12894 smsatSetSensePayload( pSense, 12895 SCSI_SNSKEY_ILLEGAL_REQUEST, 12896 0, 12897 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12898 satIOContext); 12899 12900 /*smEnqueueIO(smRoot, satIOContext);*/ 12901 12902 tdsmIOCompletedCB( smRoot, 12903 smIORequest, 12904 smIOSuccess, 12905 SCSI_STAT_CHECK_CONDITION, 12906 satIOContext->pSmSenseData, 12907 satIOContext->interruptContext ); 12908 12909 SM_DBG5(("smsatWriteSame10: return Table 62 case 2\n")); 12910 return SM_RC_SUCCESS; 12911 } 12912 else if ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) && 12913 !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) 12914 { 12915 SM_DBG5(("smsatWriteSame10: Table 62 case 3\n")); 12916 12917 } 12918 else /* ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) && 12919 (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) */ 12920 { 12921 12922 /* spec 9.26.2, Table 62, p64, case 4*/ 12923 smsatSetSensePayload( pSense, 12924 SCSI_SNSKEY_ILLEGAL_REQUEST, 12925 0, 12926 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12927 satIOContext); 12928 12929 /*smEnqueueIO(smRoot, satIOContext);*/ 12930 12931 tdsmIOCompletedCB( smRoot, 12932 smIORequest, 12933 smIOSuccess, 12934 SCSI_STAT_CHECK_CONDITION, 12935 satIOContext->pSmSenseData, 12936 satIOContext->interruptContext ); 12937 12938 SM_DBG5(("smsatWriteSame10: return Table 62 case 4\n")); 12939 return SM_RC_SUCCESS; 12940 } 12941 12942 12943 return SM_RC_SUCCESS; 12944 } 12945 12946 osGLOBAL bit32 12947 smsatWriteSame16( 12948 smRoot_t *smRoot, 12949 smIORequest_t *smIORequest, 12950 smDeviceHandle_t *smDeviceHandle, 12951 smScsiInitiatorRequest_t *smScsiRequest, 12952 smSatIOContext_t *satIOContext 12953 ) 12954 { 12955 smScsiRspSense_t *pSense; 12956 12957 pSense = satIOContext->pSense; 12958 12959 SM_DBG5(("smsatWriteSame16: start\n")); 12960 12961 12962 smsatSetSensePayload( pSense, 12963 SCSI_SNSKEY_NO_SENSE, 12964 0, 12965 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 12966 satIOContext); 12967 12968 /*smEnqueueIO(smRoot, satIOContext);*/ 12969 12970 tdsmIOCompletedCB( smRoot, 12971 smIORequest, /* == &satIntIo->satOrgSmIORequest */ 12972 smIOSuccess, 12973 SCSI_STAT_CHECK_CONDITION, 12974 satIOContext->pSmSenseData, 12975 satIOContext->interruptContext ); 12976 SM_DBG1(("smsatWriteSame16: return internal checking!!!\n")); 12977 return SM_RC_SUCCESS; 12978 } 12979 12980 osGLOBAL bit32 12981 smsatLogSense( 12982 smRoot_t *smRoot, 12983 smIORequest_t *smIORequest, 12984 smDeviceHandle_t *smDeviceHandle, 12985 smScsiInitiatorRequest_t *smScsiRequest, 12986 smSatIOContext_t *satIOContext 12987 ) 12988 { 12989 bit32 status; 12990 bit32 agRequestType; 12991 smDeviceData_t *pSatDevData; 12992 smScsiRspSense_t *pSense; 12993 smIniScsiCmnd_t *scsiCmnd; 12994 agsaFisRegHostToDevice_t *fis; 12995 bit8 *pLogPage; /* Log Page data buffer */ 12996 bit32 flag = 0; 12997 bit16 AllocLen = 0; /* allocation length */ 12998 bit8 AllLogPages[8]; 12999 bit16 lenRead = 0; 13000 13001 pSense = satIOContext->pSense; 13002 pSatDevData = satIOContext->pSatDevData; 13003 scsiCmnd = &smScsiRequest->scsiCmnd; 13004 fis = satIOContext->pFis; 13005 pLogPage = (bit8 *) smScsiRequest->sglVirtualAddr; 13006 13007 SM_DBG5(("smsatLogSense: start\n")); 13008 13009 sm_memset(&AllLogPages, 0, 8); 13010 /* checking CONTROL */ 13011 /* NACA == 1 or LINK == 1*/ 13012 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 13013 { 13014 smsatSetSensePayload( pSense, 13015 SCSI_SNSKEY_ILLEGAL_REQUEST, 13016 0, 13017 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13018 satIOContext); 13019 13020 /*smEnqueueIO(smRoot, satIOContext);*/ 13021 13022 tdsmIOCompletedCB( smRoot, 13023 smIORequest, 13024 smIOSuccess, 13025 SCSI_STAT_CHECK_CONDITION, 13026 satIOContext->pSmSenseData, 13027 satIOContext->interruptContext ); 13028 13029 SM_DBG1(("smsatLogSense: return control!!!\n")); 13030 return SM_RC_SUCCESS; 13031 } 13032 13033 13034 AllocLen = ((scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]); 13035 AllocLen = MIN(AllocLen, scsiCmnd->expDataLength); 13036 13037 /* checking PC (Page Control) */ 13038 /* nothing */ 13039 13040 /* special cases */ 13041 if (AllocLen == 4) 13042 { 13043 SM_DBG1(("smsatLogSense: AllocLen is 4!!!\n")); 13044 switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK) 13045 { 13046 case LOGSENSE_SUPPORTED_LOG_PAGES: 13047 SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n")); 13048 13049 if (pSatDevData->satSMARTFeatureSet == agTRUE) 13050 { 13051 /* add informational exception log */ 13052 flag = 1; 13053 if (pSatDevData->satSMARTSelfTest == agTRUE) 13054 { 13055 /* add Self-Test results log page */ 13056 flag = 2; 13057 } 13058 } 13059 else 13060 { 13061 /* only supported, no informational exception log, no Self-Test results log page */ 13062 flag = 0; 13063 } 13064 lenRead = 4; 13065 AllLogPages[0] = LOGSENSE_SUPPORTED_LOG_PAGES; /* page code */ 13066 AllLogPages[1] = 0; /* reserved */ 13067 switch (flag) 13068 { 13069 case 0: 13070 /* only supported */ 13071 AllLogPages[2] = 0; /* page length */ 13072 AllLogPages[3] = 1; /* page length */ 13073 break; 13074 case 1: 13075 /* supported and informational exception log */ 13076 AllLogPages[2] = 0; /* page length */ 13077 AllLogPages[3] = 2; /* page length */ 13078 break; 13079 case 2: 13080 /* supported and informational exception log */ 13081 AllLogPages[2] = 0; /* page length */ 13082 AllLogPages[3] = 3; /* page length */ 13083 break; 13084 default: 13085 SM_DBG1(("smsatLogSense: error unallowed flag value %d!!!\n", flag)); 13086 break; 13087 } 13088 sm_memcpy(pLogPage, &AllLogPages, lenRead); 13089 break; 13090 case LOGSENSE_SELFTEST_RESULTS_PAGE: 13091 SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n")); 13092 lenRead = 4; 13093 AllLogPages[0] = LOGSENSE_SELFTEST_RESULTS_PAGE; /* page code */ 13094 AllLogPages[1] = 0; /* reserved */ 13095 /* page length = SELFTEST_RESULTS_LOG_PAGE_LENGTH - 1 - 3 = 400 = 0x190 */ 13096 AllLogPages[2] = 0x01; 13097 AllLogPages[3] = 0x90; /* page length */ 13098 sm_memcpy(pLogPage, &AllLogPages, lenRead); 13099 13100 break; 13101 case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE: 13102 SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n")); 13103 lenRead = 4; 13104 AllLogPages[0] = LOGSENSE_INFORMATION_EXCEPTIONS_PAGE; /* page code */ 13105 AllLogPages[1] = 0; /* reserved */ 13106 AllLogPages[2] = 0; /* page length */ 13107 AllLogPages[3] = INFORMATION_EXCEPTIONS_LOG_PAGE_LENGTH - 1 - 3; /* page length */ 13108 sm_memcpy(pLogPage, &AllLogPages, lenRead); 13109 break; 13110 default: 13111 SM_DBG1(("smsatLogSense: default Page Code 0x%x!!!\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)); 13112 smsatSetSensePayload( pSense, 13113 SCSI_SNSKEY_ILLEGAL_REQUEST, 13114 0, 13115 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13116 satIOContext); 13117 13118 /*smEnqueueIO(smRoot, satIOContext);*/ 13119 13120 tdsmIOCompletedCB( smRoot, 13121 smIORequest, 13122 smIOSuccess, 13123 SCSI_STAT_CHECK_CONDITION, 13124 satIOContext->pSmSenseData, 13125 satIOContext->interruptContext ); 13126 return SM_RC_SUCCESS; 13127 } 13128 /*smEnqueueIO(smRoot, satIOContext);*/ 13129 13130 tdsmIOCompletedCB( smRoot, 13131 smIORequest, 13132 smIOSuccess, 13133 SCSI_STAT_GOOD, 13134 agNULL, 13135 satIOContext->interruptContext); 13136 return SM_RC_SUCCESS; 13137 13138 } /* if */ 13139 13140 /* SAT rev8 Table 11 p30*/ 13141 /* checking Page Code */ 13142 switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK) 13143 { 13144 case LOGSENSE_SUPPORTED_LOG_PAGES: 13145 SM_DBG5(("smsatLogSense: case 1\n")); 13146 13147 if (pSatDevData->satSMARTFeatureSet == agTRUE) 13148 { 13149 /* add informational exception log */ 13150 flag = 1; 13151 if (pSatDevData->satSMARTSelfTest == agTRUE) 13152 { 13153 /* add Self-Test results log page */ 13154 flag = 2; 13155 } 13156 } 13157 else 13158 { 13159 /* only supported, no informational exception log, no Self-Test results log page */ 13160 flag = 0; 13161 } 13162 AllLogPages[0] = 0; /* page code */ 13163 AllLogPages[1] = 0; /* reserved */ 13164 switch (flag) 13165 { 13166 case 0: 13167 /* only supported */ 13168 AllLogPages[2] = 0; /* page length */ 13169 AllLogPages[3] = 1; /* page length */ 13170 AllLogPages[4] = 0x00; /* supported page list */ 13171 lenRead = (bit8)(MIN(AllocLen, 5)); 13172 break; 13173 case 1: 13174 /* supported and informational exception log */ 13175 AllLogPages[2] = 0; /* page length */ 13176 AllLogPages[3] = 2; /* page length */ 13177 AllLogPages[4] = 0x00; /* supported page list */ 13178 AllLogPages[5] = 0x10; /* supported page list */ 13179 lenRead = (bit8)(MIN(AllocLen, 6)); 13180 break; 13181 case 2: 13182 /* supported and informational exception log */ 13183 AllLogPages[2] = 0; /* page length */ 13184 AllLogPages[3] = 3; /* page length */ 13185 AllLogPages[4] = 0x00; /* supported page list */ 13186 AllLogPages[5] = 0x10; /* supported page list */ 13187 AllLogPages[6] = 0x2F; /* supported page list */ 13188 lenRead = (bit8)(MIN(AllocLen, 7)); 13189 break; 13190 default: 13191 SM_DBG1(("smsatLogSense: error unallowed flag value %d!!!\n", flag)); 13192 break; 13193 } 13194 13195 sm_memcpy(pLogPage, &AllLogPages, lenRead); 13196 /* comparing allocation length to Log Page byte size */ 13197 /* SPC-4, 4.3.4.6, p28 */ 13198 if (AllocLen > lenRead ) 13199 { 13200 SM_DBG1(("smsatLogSense: reporting underrun lenRead=0x%x AllocLen=0x%x!!!\n", lenRead, AllocLen)); 13201 /*smEnqueueIO(smRoot, satIOContext);*/ 13202 13203 tdsmIOCompletedCB( smRoot, 13204 smIORequest, 13205 smIOUnderRun, 13206 AllocLen - lenRead, 13207 agNULL, 13208 satIOContext->interruptContext ); 13209 } 13210 else 13211 { 13212 /*smEnqueueIO(smRoot, satIOContext);*/ 13213 tdsmIOCompletedCB( smRoot, 13214 smIORequest, 13215 smIOSuccess, 13216 SCSI_STAT_GOOD, 13217 agNULL, 13218 satIOContext->interruptContext); 13219 } 13220 break; 13221 case LOGSENSE_SELFTEST_RESULTS_PAGE: 13222 SM_DBG5(("smsatLogSense: case 2\n")); 13223 /* checking SMART self-test */ 13224 if (pSatDevData->satSMARTSelfTest == agFALSE) 13225 { 13226 SM_DBG5(("smsatLogSense: case 2 no SMART Self Test\n")); 13227 smsatSetSensePayload( pSense, 13228 SCSI_SNSKEY_ILLEGAL_REQUEST, 13229 0, 13230 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13231 satIOContext); 13232 13233 /*smEnqueueIO(smRoot, satIOContext);*/ 13234 13235 tdsmIOCompletedCB( smRoot, 13236 smIORequest, 13237 smIOSuccess, 13238 SCSI_STAT_CHECK_CONDITION, 13239 satIOContext->pSmSenseData, 13240 satIOContext->interruptContext ); 13241 } 13242 else 13243 { 13244 /* if satSMARTEnabled is false, send SMART_ENABLE_OPERATIONS */ 13245 if (pSatDevData->satSMARTEnabled == agFALSE) 13246 { 13247 SM_DBG5(("smsatLogSense: case 2 calling satSMARTEnable\n")); 13248 status = smsatLogSenseAllocate(smRoot, 13249 smIORequest, 13250 smDeviceHandle, 13251 smScsiRequest, 13252 satIOContext, 13253 0, 13254 LOG_SENSE_0 13255 ); 13256 13257 return status; 13258 13259 } 13260 else 13261 { 13262 /* SAT Rev 8, 10.2.4 p74 */ 13263 if ( pSatDevData->sat48BitSupport == agTRUE ) 13264 { 13265 SM_DBG5(("smsatLogSense: case 2-1 sends READ LOG EXT\n")); 13266 status = smsatLogSenseAllocate(smRoot, 13267 smIORequest, 13268 smDeviceHandle, 13269 smScsiRequest, 13270 satIOContext, 13271 512, 13272 LOG_SENSE_1 13273 ); 13274 13275 return status; 13276 } 13277 else 13278 { 13279 SM_DBG5(("smsatLogSense: case 2-2 sends SMART READ LOG\n")); 13280 status = smsatLogSenseAllocate(smRoot, 13281 smIORequest, 13282 smDeviceHandle, 13283 smScsiRequest, 13284 satIOContext, 13285 512, 13286 LOG_SENSE_2 13287 ); 13288 13289 return status; 13290 } 13291 } 13292 } 13293 break; 13294 case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE: 13295 SM_DBG5(("smsatLogSense: case 3\n")); 13296 /* checking SMART feature set */ 13297 if (pSatDevData->satSMARTFeatureSet == agFALSE) 13298 { 13299 smsatSetSensePayload( pSense, 13300 SCSI_SNSKEY_ILLEGAL_REQUEST, 13301 0, 13302 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13303 satIOContext); 13304 13305 /*smEnqueueIO(smRoot, satIOContext);*/ 13306 13307 tdsmIOCompletedCB( smRoot, 13308 smIORequest, 13309 smIOSuccess, 13310 SCSI_STAT_CHECK_CONDITION, 13311 satIOContext->pSmSenseData, 13312 satIOContext->interruptContext ); 13313 } 13314 else 13315 { 13316 /* checking SMART feature enabled */ 13317 if (pSatDevData->satSMARTEnabled == agFALSE) 13318 { 13319 smsatSetSensePayload( pSense, 13320 SCSI_SNSKEY_ABORTED_COMMAND, 13321 0, 13322 SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED, 13323 satIOContext); 13324 13325 /*smEnqueueIO(smRoot, satIOContext);*/ 13326 13327 tdsmIOCompletedCB( smRoot, 13328 smIORequest, 13329 smIOSuccess, 13330 SCSI_STAT_CHECK_CONDITION, 13331 satIOContext->pSmSenseData, 13332 satIOContext->interruptContext ); 13333 } 13334 else 13335 { 13336 /* SAT Rev 8, 10.2.3 p72 */ 13337 SM_DBG5(("smsatLogSense: case 3 sends SMART RETURN STATUS\n")); 13338 13339 /* sends SMART RETURN STATUS */ 13340 fis->h.fisType = 0x27; /* Reg host to device */ 13341 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13342 13343 fis->h.command = SAT_SMART; /* 0xB0 */ 13344 fis->h.features = SAT_SMART_RETURN_STATUS;/* FIS features */ 13345 fis->d.featuresExp = 0; /* FIS reserve */ 13346 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 13347 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 13348 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 13349 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 13350 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 13351 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 13352 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 13353 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 13354 fis->d.device = 0; /* FIS DEV is discared in SATA */ 13355 fis->d.control = 0; /* FIS HOB bit clear */ 13356 fis->d.reserved4 = 0; 13357 fis->d.reserved5 = 0; 13358 13359 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 13360 /* Initialize CB for SATA completion. 13361 */ 13362 satIOContext->satCompleteCB = &smsatLogSenseCB; 13363 13364 /* 13365 * Prepare SGL and send FIS to LL layer. 13366 */ 13367 satIOContext->reqType = agRequestType; /* Save it */ 13368 13369 status = smsataLLIOStart( smRoot, 13370 smIORequest, 13371 smDeviceHandle, 13372 smScsiRequest, 13373 satIOContext); 13374 13375 13376 return status; 13377 } 13378 } 13379 break; 13380 default: 13381 SM_DBG1(("smsatLogSense: default Page Code 0x%x!!!\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)); 13382 smsatSetSensePayload( pSense, 13383 SCSI_SNSKEY_ILLEGAL_REQUEST, 13384 0, 13385 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13386 satIOContext); 13387 13388 /*smEnqueueIO(smRoot, satIOContext);*/ 13389 13390 tdsmIOCompletedCB( smRoot, 13391 smIORequest, 13392 smIOSuccess, 13393 SCSI_STAT_CHECK_CONDITION, 13394 satIOContext->pSmSenseData, 13395 satIOContext->interruptContext ); 13396 13397 break; 13398 } /* end switch */ 13399 13400 return SM_RC_SUCCESS; 13401 } 13402 13403 osGLOBAL bit32 13404 smsatLogSenseAllocate( 13405 smRoot_t *smRoot, 13406 smIORequest_t *smIORequest, 13407 smDeviceHandle_t *smDeviceHandle, 13408 smScsiInitiatorRequest_t *smSCSIRequest, 13409 smSatIOContext_t *satIOContext, 13410 bit32 payloadSize, 13411 bit32 flag 13412 ) 13413 { 13414 smDeviceData_t *pSatDevData; 13415 smIORequestBody_t *smIORequestBody; 13416 smSatInternalIo_t *satIntIo = agNULL; 13417 smSatIOContext_t *satIOContext2; 13418 bit32 status; 13419 13420 SM_DBG5(("smsatLogSenseAllocate: start\n")); 13421 13422 pSatDevData = satIOContext->pSatDevData; 13423 13424 /* create internal satIOContext */ 13425 satIntIo = smsatAllocIntIoResource( smRoot, 13426 smIORequest, /* original request */ 13427 pSatDevData, 13428 payloadSize, 13429 satIntIo); 13430 13431 if (satIntIo == agNULL) 13432 { 13433 /*smEnqueueIO(smRoot, satIOContext);*/ 13434 13435 tdsmIOCompletedCB( smRoot, 13436 smIORequest, 13437 smIOFailed, 13438 smDetailOtherError, 13439 agNULL, 13440 satIOContext->interruptContext ); 13441 13442 SM_DBG1(("smsatLogSenseAllocate: fail in allocation!!!\n")); 13443 return SM_RC_SUCCESS; 13444 } /* end of memory allocation failure */ 13445 13446 satIntIo->satOrgSmIORequest = smIORequest; 13447 smIORequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody; 13448 satIOContext2 = &(smIORequestBody->transport.SATA.satIOContext); 13449 13450 satIOContext2->pSatDevData = pSatDevData; 13451 satIOContext2->pFis = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 13452 satIOContext2->pScsiCmnd = &(satIntIo->satIntSmScsiXchg.scsiCmnd); 13453 satIOContext2->pSense = &(smIORequestBody->transport.SATA.sensePayload); 13454 satIOContext2->pSmSenseData = &(smIORequestBody->transport.SATA.smSenseData); 13455 satIOContext2->pSmSenseData->senseData = satIOContext2->pSense; 13456 satIOContext2->smRequestBody = satIntIo->satIntRequestBody; 13457 satIOContext2->interruptContext = satIOContext->interruptContext; 13458 satIOContext2->satIntIoContext = satIntIo; 13459 satIOContext2->psmDeviceHandle = smDeviceHandle; 13460 satIOContext2->satOrgIOContext = satIOContext; 13461 13462 if (flag == LOG_SENSE_0) 13463 { 13464 /* SAT_SMART_ENABLE_OPERATIONS */ 13465 status = smsatSMARTEnable( smRoot, 13466 &(satIntIo->satIntSmIORequest), 13467 smDeviceHandle, 13468 &(satIntIo->satIntSmScsiXchg), 13469 satIOContext2); 13470 } 13471 else if (flag == LOG_SENSE_1) 13472 { 13473 /* SAT_READ_LOG_EXT */ 13474 status = smsatLogSense_2( smRoot, 13475 &(satIntIo->satIntSmIORequest), 13476 smDeviceHandle, 13477 &(satIntIo->satIntSmScsiXchg), 13478 satIOContext2); 13479 } 13480 else 13481 { 13482 /* SAT_SMART_READ_LOG */ 13483 /* SAT_READ_LOG_EXT */ 13484 status = smsatLogSense_3( smRoot, 13485 &(satIntIo->satIntSmIORequest), 13486 smDeviceHandle, 13487 &(satIntIo->satIntSmScsiXchg), 13488 satIOContext2); 13489 13490 } 13491 if (status != SM_RC_SUCCESS) 13492 { 13493 smsatFreeIntIoResource( smRoot, 13494 pSatDevData, 13495 satIntIo); 13496 13497 /*smEnqueueIO(smRoot, satIOContext);*/ 13498 13499 tdsmIOCompletedCB( smRoot, 13500 smIORequest, 13501 smIOFailed, 13502 smDetailOtherError, 13503 agNULL, 13504 satIOContext->interruptContext ); 13505 return SM_RC_SUCCESS; 13506 } 13507 13508 13509 return SM_RC_SUCCESS; 13510 } 13511 13512 osGLOBAL bit32 13513 smsatSMARTEnable( 13514 smRoot_t *smRoot, 13515 smIORequest_t *smIORequest, 13516 smDeviceHandle_t *smDeviceHandle, 13517 smScsiInitiatorRequest_t *smScsiRequest, 13518 smSatIOContext_t *satIOContext 13519 ) 13520 { 13521 bit32 status; 13522 bit32 agRequestType; 13523 agsaFisRegHostToDevice_t *fis; 13524 13525 fis = satIOContext->pFis; 13526 SM_DBG5(("smsatSMARTEnable: start\n")); 13527 /* 13528 * Send the SAT_SMART_ENABLE_OPERATIONS command. 13529 */ 13530 fis->h.fisType = 0x27; /* Reg host to device */ 13531 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13532 fis->h.command = SAT_SMART; /* 0xB0 */ 13533 fis->h.features = SAT_SMART_ENABLE_OPERATIONS; 13534 fis->d.lbaLow = 0; 13535 fis->d.lbaMid = 0x4F; 13536 fis->d.lbaHigh = 0xC2; 13537 fis->d.device = 0; 13538 fis->d.lbaLowExp = 0; 13539 fis->d.lbaMidExp = 0; 13540 fis->d.lbaHighExp = 0; 13541 fis->d.featuresExp = 0; 13542 fis->d.sectorCount = 0; 13543 fis->d.sectorCountExp = 0; 13544 fis->d.reserved4 = 0; 13545 fis->d.control = 0; /* FIS HOB bit clear */ 13546 fis->d.reserved5 = 0; 13547 13548 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 13549 13550 /* Initialize CB for SATA completion. 13551 */ 13552 satIOContext->satCompleteCB = &smsatSMARTEnableCB; 13553 13554 /* 13555 * Prepare SGL and send FIS to LL layer. 13556 */ 13557 satIOContext->reqType = agRequestType; /* Save it */ 13558 13559 status = smsataLLIOStart( smRoot, 13560 smIORequest, 13561 smDeviceHandle, 13562 smScsiRequest, 13563 satIOContext); 13564 13565 13566 return status; 13567 } 13568 13569 osGLOBAL bit32 13570 smsatLogSense_2( 13571 smRoot_t *smRoot, 13572 smIORequest_t *smIORequest, 13573 smDeviceHandle_t *smDeviceHandle, 13574 smScsiInitiatorRequest_t *smScsiRequest, 13575 smSatIOContext_t *satIOContext 13576 ) 13577 { 13578 bit32 status; 13579 bit32 agRequestType; 13580 agsaFisRegHostToDevice_t *fis; 13581 13582 fis = satIOContext->pFis; 13583 SM_DBG5(("smsatLogSense_2: start\n")); 13584 13585 /* sends READ LOG EXT */ 13586 fis->h.fisType = 0x27; /* Reg host to device */ 13587 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13588 13589 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */ 13590 fis->h.features = 0; /* FIS reserve */ 13591 fis->d.lbaLow = 0x07; /* 0x07 */ 13592 fis->d.lbaMid = 0; /* */ 13593 fis->d.lbaHigh = 0; /* */ 13594 fis->d.device = 0; /* */ 13595 fis->d.lbaLowExp = 0; /* */ 13596 fis->d.lbaMidExp = 0; /* */ 13597 fis->d.lbaHighExp = 0; /* */ 13598 fis->d.featuresExp = 0; /* FIS reserve */ 13599 fis->d.sectorCount = 0x01; /* 1 sector counts */ 13600 fis->d.sectorCountExp = 0x00; /* 1 sector counts */ 13601 fis->d.reserved4 = 0; 13602 fis->d.control = 0; /* FIS HOB bit clear */ 13603 fis->d.reserved5 = 0; 13604 13605 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 13606 13607 /* Initialize CB for SATA completion. 13608 */ 13609 satIOContext->satCompleteCB = &smsatLogSenseCB; 13610 13611 /* 13612 * Prepare SGL and send FIS to LL layer. 13613 */ 13614 satIOContext->reqType = agRequestType; /* Save it */ 13615 13616 status = smsataLLIOStart( smRoot, 13617 smIORequest, 13618 smDeviceHandle, 13619 smScsiRequest, 13620 satIOContext); 13621 return status; 13622 } 13623 13624 osGLOBAL bit32 13625 smsatLogSense_3( 13626 smRoot_t *smRoot, 13627 smIORequest_t *smIORequest, 13628 smDeviceHandle_t *smDeviceHandle, 13629 smScsiInitiatorRequest_t *smScsiRequest, 13630 smSatIOContext_t *satIOContext 13631 ) 13632 { 13633 bit32 status; 13634 bit32 agRequestType; 13635 agsaFisRegHostToDevice_t *fis; 13636 13637 fis = satIOContext->pFis; 13638 SM_DBG5(("smsatLogSense_3: start\n")); 13639 /* sends READ LOG EXT */ 13640 fis->h.fisType = 0x27; /* Reg host to device */ 13641 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13642 fis->h.command = SAT_SMART; /* 0x2F */ 13643 fis->h.features = SAT_SMART_READ_LOG; /* 0xd5 */ 13644 fis->d.lbaLow = 0x06; /* 0x06 */ 13645 fis->d.lbaMid = 0x4F; /* 0x4f */ 13646 fis->d.lbaHigh = 0xC2; /* 0xc2 */ 13647 fis->d.device = 0; /* */ 13648 fis->d.lbaLowExp = 0; /* */ 13649 fis->d.lbaMidExp = 0; /* */ 13650 fis->d.lbaHighExp = 0; /* */ 13651 fis->d.featuresExp = 0; /* FIS reserve */ 13652 fis->d.sectorCount = 0x01; /* 1 sector counts */ 13653 fis->d.sectorCountExp = 0x00; /* 1 sector counts */ 13654 fis->d.reserved4 = 0; 13655 fis->d.control = 0; /* FIS HOB bit clear */ 13656 fis->d.reserved5 = 0; 13657 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 13658 /* Initialize CB for SATA completion. 13659 */ 13660 satIOContext->satCompleteCB = &smsatLogSenseCB; 13661 /* 13662 * Prepare SGL and send FIS to LL layer. 13663 */ 13664 satIOContext->reqType = agRequestType; /* Save it */ 13665 status = smsataLLIOStart( smRoot, 13666 smIORequest, 13667 smDeviceHandle, 13668 smScsiRequest, 13669 satIOContext); 13670 return status; 13671 } 13672 13673 13674 osGLOBAL bit32 13675 smsatModeSelect6( 13676 smRoot_t *smRoot, 13677 smIORequest_t *smIORequest, 13678 smDeviceHandle_t *smDeviceHandle, 13679 smScsiInitiatorRequest_t *smScsiRequest, 13680 smSatIOContext_t *satIOContext 13681 ) 13682 { 13683 bit32 status; 13684 bit32 agRequestType; 13685 smDeviceData_t *pSatDevData; 13686 smScsiRspSense_t *pSense; 13687 smIniScsiCmnd_t *scsiCmnd; 13688 agsaFisRegHostToDevice_t *fis; 13689 bit8 *pLogPage; /* Log Page data buffer */ 13690 bit32 StartingIndex = 0; 13691 bit8 PageCode = 0; 13692 bit32 chkCnd = agFALSE; 13693 bit32 parameterListLen = 0; 13694 13695 pSense = satIOContext->pSense; 13696 pSatDevData = satIOContext->pSatDevData; 13697 scsiCmnd = &smScsiRequest->scsiCmnd; 13698 fis = satIOContext->pFis; 13699 pLogPage = (bit8 *) smScsiRequest->sglVirtualAddr; 13700 13701 SM_DBG5(("smsatModeSelect6: start\n")); 13702 13703 /* checking CONTROL */ 13704 /* NACA == 1 or LINK == 1*/ 13705 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 13706 { 13707 smsatSetSensePayload( pSense, 13708 SCSI_SNSKEY_ILLEGAL_REQUEST, 13709 0, 13710 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13711 satIOContext); 13712 13713 /*smEnqueueIO(smRoot, satIOContext);*/ 13714 13715 tdsmIOCompletedCB( smRoot, 13716 smIORequest, 13717 smIOSuccess, 13718 SCSI_STAT_CHECK_CONDITION, 13719 satIOContext->pSmSenseData, 13720 satIOContext->interruptContext ); 13721 13722 SM_DBG1(("smsatModeSelect6: return control!!!\n")); 13723 return SM_RC_SUCCESS; 13724 } 13725 13726 /* checking PF bit */ 13727 if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT6_PF_MASK)) 13728 { 13729 smsatSetSensePayload( pSense, 13730 SCSI_SNSKEY_ILLEGAL_REQUEST, 13731 0, 13732 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13733 satIOContext); 13734 13735 /*smEnqueueIO(smRoot, satIOContext);*/ 13736 13737 tdsmIOCompletedCB( smRoot, 13738 smIORequest, 13739 smIOSuccess, 13740 SCSI_STAT_CHECK_CONDITION, 13741 satIOContext->pSmSenseData, 13742 satIOContext->interruptContext ); 13743 13744 SM_DBG1(("smsatModeSelect6: PF bit check!!!\n")); 13745 return SM_RC_SUCCESS; 13746 } 13747 13748 parameterListLen = scsiCmnd->cdb[4]; 13749 parameterListLen = MIN(parameterListLen, scsiCmnd->expDataLength); 13750 if ((0 == parameterListLen) || (agNULL == pLogPage)) 13751 { 13752 tdsmIOCompletedCB( smRoot, 13753 smIORequest, 13754 smIOSuccess, 13755 SCSI_STAT_GOOD, 13756 agNULL, 13757 satIOContext->interruptContext); 13758 return SM_RC_SUCCESS; 13759 } 13760 13761 /* checking Block Descriptor Length on Mode parameter header(6)*/ 13762 if (pLogPage[3] == 8) 13763 { 13764 /* mode parameter block descriptor exists */ 13765 PageCode = (bit8)(pLogPage[12] & 0x3F); /* page code and index is 4 + 8 */ 13766 StartingIndex = 12; 13767 } 13768 else if (pLogPage[3] == 0) 13769 { 13770 /* mode parameter block descriptor does not exist */ 13771 PageCode = (bit8)(pLogPage[4] & 0x3F); /* page code and index is 4 + 0 */ 13772 StartingIndex = 4; 13773 /*smEnqueueIO(smRoot, satIOContext);*/ 13774 13775 tdsmIOCompletedCB( smRoot, 13776 smIORequest, 13777 smIOSuccess, 13778 SCSI_STAT_GOOD, 13779 agNULL, 13780 satIOContext->interruptContext); 13781 return SM_RC_SUCCESS; 13782 } 13783 else 13784 { 13785 SM_DBG1(("smsatModeSelect6: return mode parameter block descriptor 0x%x!!!\n", pLogPage[3])); 13786 13787 smsatSetSensePayload( pSense, 13788 SCSI_SNSKEY_NO_SENSE, 13789 0, 13790 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 13791 satIOContext); 13792 13793 /*smEnqueueIO(smRoot, satIOContext);*/ 13794 13795 tdsmIOCompletedCB( smRoot, 13796 smIORequest, 13797 smIOSuccess, 13798 SCSI_STAT_CHECK_CONDITION, 13799 satIOContext->pSmSenseData, 13800 satIOContext->interruptContext ); 13801 return SM_RC_SUCCESS; 13802 } 13803 13804 13805 13806 switch (PageCode) /* page code */ 13807 { 13808 case MODESELECT_CONTROL_PAGE: 13809 SM_DBG1(("smsatModeSelect6: Control mode page!!!\n")); 13810 13811 if ( pLogPage[StartingIndex+1] != 0x0A || 13812 pLogPage[StartingIndex+2] != 0x02 || 13813 (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) || 13814 (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) || 13815 (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */ 13816 (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */ 13817 (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */ 13818 13819 (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */ 13820 (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */ 13821 (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */ 13822 (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */ 13823 13824 pLogPage[StartingIndex+8] != 0xFF || 13825 pLogPage[StartingIndex+9] != 0xFF || 13826 pLogPage[StartingIndex+10] != 0x00 || 13827 pLogPage[StartingIndex+11] != 0x00 13828 ) 13829 { 13830 chkCnd = agTRUE; 13831 } 13832 if (chkCnd == agTRUE) 13833 { 13834 smsatSetSensePayload( pSense, 13835 SCSI_SNSKEY_ILLEGAL_REQUEST, 13836 0, 13837 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13838 satIOContext); 13839 13840 /*smEnqueueIO(smRoot, satIOContext);*/ 13841 13842 tdsmIOCompletedCB( smRoot, 13843 smIORequest, 13844 smIOSuccess, 13845 SCSI_STAT_CHECK_CONDITION, 13846 satIOContext->pSmSenseData, 13847 satIOContext->interruptContext ); 13848 13849 SM_DBG1(("smsatModeSelect6: unexpected values!!!\n")); 13850 } 13851 else 13852 { 13853 /*smEnqueueIO(smRoot, satIOContext);*/ 13854 13855 tdsmIOCompletedCB( smRoot, 13856 smIORequest, 13857 smIOSuccess, 13858 SCSI_STAT_GOOD, 13859 agNULL, 13860 satIOContext->interruptContext); 13861 } 13862 return SM_RC_SUCCESS; 13863 break; 13864 case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE: 13865 SM_DBG1(("smsatModeSelect6: Read-Write Error Recovery mode page!!!\n")); 13866 13867 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_AWRE_MASK) || 13868 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_RC_MASK) || 13869 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_EER_MASK) || 13870 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PER_MASK) || 13871 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DTE_MASK) || 13872 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DCR_MASK) || 13873 (pLogPage[StartingIndex + 10]) || 13874 (pLogPage[StartingIndex + 11]) 13875 ) 13876 { 13877 SM_DBG5(("smsatModeSelect6: return check condition\n")); 13878 13879 smsatSetSensePayload( pSense, 13880 SCSI_SNSKEY_ILLEGAL_REQUEST, 13881 0, 13882 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 13883 satIOContext); 13884 13885 /*smEnqueueIO(smRoot, satIOContext);*/ 13886 13887 tdsmIOCompletedCB( smRoot, 13888 smIORequest, 13889 smIOSuccess, 13890 SCSI_STAT_CHECK_CONDITION, 13891 satIOContext->pSmSenseData, 13892 satIOContext->interruptContext ); 13893 return SM_RC_SUCCESS; 13894 } 13895 else 13896 { 13897 SM_DBG5(("smsatModeSelect6: return GOOD \n")); 13898 /*smEnqueueIO(smRoot, satIOContext);*/ 13899 13900 tdsmIOCompletedCB( smRoot, 13901 smIORequest, 13902 smIOSuccess, 13903 SCSI_STAT_GOOD, 13904 agNULL, 13905 satIOContext->interruptContext); 13906 return SM_RC_SUCCESS; 13907 } 13908 13909 break; 13910 case MODESELECT_CACHING: 13911 /* SAT rev8 Table67, p69*/ 13912 SM_DBG5(("smsatModeSelect6: Caching mode page\n")); 13913 if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */ 13914 (pLogPage[StartingIndex + 3]) || 13915 (pLogPage[StartingIndex + 4]) || 13916 (pLogPage[StartingIndex + 5]) || 13917 (pLogPage[StartingIndex + 6]) || 13918 (pLogPage[StartingIndex + 7]) || 13919 (pLogPage[StartingIndex + 8]) || 13920 (pLogPage[StartingIndex + 9]) || 13921 (pLogPage[StartingIndex + 10]) || 13922 (pLogPage[StartingIndex + 11]) || 13923 13924 (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */ 13925 (pLogPage[StartingIndex + 13]) || 13926 (pLogPage[StartingIndex + 14]) || 13927 (pLogPage[StartingIndex + 15]) 13928 ) 13929 { 13930 SM_DBG1(("smsatModeSelect6: return check condition!!!\n")); 13931 13932 smsatSetSensePayload( pSense, 13933 SCSI_SNSKEY_ILLEGAL_REQUEST, 13934 0, 13935 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 13936 satIOContext); 13937 13938 /*smEnqueueIO(smRoot, satIOContext);*/ 13939 13940 tdsmIOCompletedCB( smRoot, 13941 smIORequest, 13942 smIOSuccess, 13943 SCSI_STAT_CHECK_CONDITION, 13944 satIOContext->pSmSenseData, 13945 satIOContext->interruptContext ); 13946 return SM_RC_SUCCESS; 13947 13948 } 13949 else 13950 { 13951 /* sends ATA SET FEATURES based on WCE bit */ 13952 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_WCE_MASK) ) 13953 { 13954 SM_DBG5(("smsatModeSelect6: disable write cache\n")); 13955 /* sends SET FEATURES */ 13956 fis->h.fisType = 0x27; /* Reg host to device */ 13957 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13958 13959 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 13960 fis->h.features = 0x82; /* disable write cache */ 13961 fis->d.lbaLow = 0; /* */ 13962 fis->d.lbaMid = 0; /* */ 13963 fis->d.lbaHigh = 0; /* */ 13964 fis->d.device = 0; /* */ 13965 fis->d.lbaLowExp = 0; /* */ 13966 fis->d.lbaMidExp = 0; /* */ 13967 fis->d.lbaHighExp = 0; /* */ 13968 fis->d.featuresExp = 0; /* */ 13969 fis->d.sectorCount = 0; /* */ 13970 fis->d.sectorCountExp = 0; /* */ 13971 fis->d.reserved4 = 0; 13972 fis->d.control = 0; /* FIS HOB bit clear */ 13973 fis->d.reserved5 = 0; 13974 13975 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 13976 13977 /* Initialize CB for SATA completion. 13978 */ 13979 satIOContext->satCompleteCB = &smsatModeSelect6n10CB; 13980 13981 /* 13982 * Prepare SGL and send FIS to LL layer. 13983 */ 13984 satIOContext->reqType = agRequestType; /* Save it */ 13985 13986 status = smsataLLIOStart( smRoot, 13987 smIORequest, 13988 smDeviceHandle, 13989 smScsiRequest, 13990 satIOContext); 13991 return status; 13992 } 13993 else 13994 { 13995 SM_DBG5(("smsatModeSelect6: enable write cache\n")); 13996 /* sends SET FEATURES */ 13997 fis->h.fisType = 0x27; /* Reg host to device */ 13998 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13999 14000 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 14001 fis->h.features = 0x02; /* enable write cache */ 14002 fis->d.lbaLow = 0; /* */ 14003 fis->d.lbaMid = 0; /* */ 14004 fis->d.lbaHigh = 0; /* */ 14005 fis->d.device = 0; /* */ 14006 fis->d.lbaLowExp = 0; /* */ 14007 fis->d.lbaMidExp = 0; /* */ 14008 fis->d.lbaHighExp = 0; /* */ 14009 fis->d.featuresExp = 0; /* */ 14010 fis->d.sectorCount = 0; /* */ 14011 fis->d.sectorCountExp = 0; /* */ 14012 fis->d.reserved4 = 0; 14013 fis->d.control = 0; /* FIS HOB bit clear */ 14014 fis->d.reserved5 = 0; 14015 14016 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14017 14018 /* Initialize CB for SATA completion. 14019 */ 14020 satIOContext->satCompleteCB = &smsatModeSelect6n10CB; 14021 14022 /* 14023 * Prepare SGL and send FIS to LL layer. 14024 */ 14025 satIOContext->reqType = agRequestType; /* Save it */ 14026 14027 status = smsataLLIOStart( smRoot, 14028 smIORequest, 14029 smDeviceHandle, 14030 smScsiRequest, 14031 satIOContext); 14032 return status; 14033 14034 } 14035 } 14036 break; 14037 case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE: 14038 SM_DBG5(("smsatModeSelect6: Informational Exception Control mode page\n")); 14039 14040 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PERF_MASK) || 14041 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_TEST_MASK) 14042 ) 14043 { 14044 SM_DBG1(("smsatModeSelect6: return check condition!!! \n")); 14045 14046 smsatSetSensePayload( pSense, 14047 SCSI_SNSKEY_ILLEGAL_REQUEST, 14048 0, 14049 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 14050 satIOContext); 14051 14052 /*smEnqueueIO(smRoot, satIOContext);*/ 14053 14054 tdsmIOCompletedCB( smRoot, 14055 smIORequest, 14056 smIOSuccess, 14057 SCSI_STAT_CHECK_CONDITION, 14058 satIOContext->pSmSenseData, 14059 satIOContext->interruptContext ); 14060 return SM_RC_SUCCESS; 14061 } 14062 else 14063 { 14064 /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */ 14065 if ( !(pLogPage[StartingIndex + 2] & 0x08) ) 14066 { 14067 SM_DBG5(("smsatModeSelect6: enable information exceptions reporting\n")); 14068 /* sends SMART ENABLE OPERATIONS */ 14069 fis->h.fisType = 0x27; /* Reg host to device */ 14070 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14071 14072 fis->h.command = SAT_SMART; /* 0xB0 */ 14073 fis->h.features = SAT_SMART_ENABLE_OPERATIONS; /* enable */ 14074 fis->d.lbaLow = 0; /* */ 14075 fis->d.lbaMid = 0x4F; /* 0x4F */ 14076 fis->d.lbaHigh = 0xC2; /* 0xC2 */ 14077 fis->d.device = 0; /* */ 14078 fis->d.lbaLowExp = 0; /* */ 14079 fis->d.lbaMidExp = 0; /* */ 14080 fis->d.lbaHighExp = 0; /* */ 14081 fis->d.featuresExp = 0; /* */ 14082 fis->d.sectorCount = 0; /* */ 14083 fis->d.sectorCountExp = 0; /* */ 14084 fis->d.reserved4 = 0; 14085 fis->d.control = 0; /* FIS HOB bit clear */ 14086 fis->d.reserved5 = 0; 14087 14088 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14089 14090 /* Initialize CB for SATA completion. 14091 */ 14092 satIOContext->satCompleteCB = &smsatModeSelect6n10CB; 14093 14094 /* 14095 * Prepare SGL and send FIS to LL layer. 14096 */ 14097 satIOContext->reqType = agRequestType; /* Save it */ 14098 14099 status = smsataLLIOStart( smRoot, 14100 smIORequest, 14101 smDeviceHandle, 14102 smScsiRequest, 14103 satIOContext); 14104 return status; 14105 } 14106 else 14107 { 14108 SM_DBG5(("smsatModeSelect6: disable information exceptions reporting\n")); 14109 /* sends SMART DISABLE OPERATIONS */ 14110 fis->h.fisType = 0x27; /* Reg host to device */ 14111 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14112 14113 fis->h.command = SAT_SMART; /* 0xB0 */ 14114 fis->h.features = SAT_SMART_DISABLE_OPERATIONS; /* disable */ 14115 fis->d.lbaLow = 0; /* */ 14116 fis->d.lbaMid = 0x4F; /* 0x4F */ 14117 fis->d.lbaHigh = 0xC2; /* 0xC2 */ 14118 fis->d.device = 0; /* */ 14119 fis->d.lbaLowExp = 0; /* */ 14120 fis->d.lbaMidExp = 0; /* */ 14121 fis->d.lbaHighExp = 0; /* */ 14122 fis->d.featuresExp = 0; /* */ 14123 fis->d.sectorCount = 0; /* */ 14124 fis->d.sectorCountExp = 0; /* */ 14125 fis->d.reserved4 = 0; 14126 fis->d.control = 0; /* FIS HOB bit clear */ 14127 fis->d.reserved5 = 0; 14128 14129 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14130 14131 /* Initialize CB for SATA completion. 14132 */ 14133 satIOContext->satCompleteCB = &smsatModeSelect6n10CB; 14134 14135 /* 14136 * Prepare SGL and send FIS to LL layer. 14137 */ 14138 satIOContext->reqType = agRequestType; /* Save it */ 14139 14140 status = smsataLLIOStart( smRoot, 14141 smIORequest, 14142 smDeviceHandle, 14143 smScsiRequest, 14144 satIOContext); 14145 return status; 14146 14147 } 14148 } 14149 break; 14150 default: 14151 SM_DBG1(("smsatModeSelect6: Error unknown page code 0x%x!!!\n", pLogPage[12])); 14152 smsatSetSensePayload( pSense, 14153 SCSI_SNSKEY_NO_SENSE, 14154 0, 14155 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 14156 satIOContext); 14157 14158 /*smEnqueueIO(smRoot, satIOContext);*/ 14159 14160 tdsmIOCompletedCB( smRoot, 14161 smIORequest, 14162 smIOSuccess, 14163 SCSI_STAT_CHECK_CONDITION, 14164 satIOContext->pSmSenseData, 14165 satIOContext->interruptContext ); 14166 return SM_RC_SUCCESS; 14167 } 14168 } 14169 14170 14171 osGLOBAL bit32 14172 smsatModeSelect10( 14173 smRoot_t *smRoot, 14174 smIORequest_t *smIORequest, 14175 smDeviceHandle_t *smDeviceHandle, 14176 smScsiInitiatorRequest_t *smScsiRequest, 14177 smSatIOContext_t *satIOContext 14178 ) 14179 { 14180 bit32 status; 14181 bit32 agRequestType; 14182 smDeviceData_t *pSatDevData; 14183 smScsiRspSense_t *pSense; 14184 smIniScsiCmnd_t *scsiCmnd; 14185 agsaFisRegHostToDevice_t *fis; 14186 bit8 *pLogPage; /* Log Page data buffer */ 14187 bit16 BlkDescLen = 0; /* Block Descriptor Length */ 14188 bit32 StartingIndex = 0; 14189 bit8 PageCode = 0; 14190 bit32 chkCnd = agFALSE; 14191 bit32 parameterListLen = 0; 14192 14193 pSense = satIOContext->pSense; 14194 pSatDevData = satIOContext->pSatDevData; 14195 scsiCmnd = &smScsiRequest->scsiCmnd; 14196 fis = satIOContext->pFis; 14197 pLogPage = (bit8 *) smScsiRequest->sglVirtualAddr; 14198 14199 SM_DBG5(("smsatModeSelect10: start\n")); 14200 14201 /* checking CONTROL */ 14202 /* NACA == 1 or LINK == 1*/ 14203 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 14204 { 14205 smsatSetSensePayload( pSense, 14206 SCSI_SNSKEY_ILLEGAL_REQUEST, 14207 0, 14208 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 14209 satIOContext); 14210 14211 /*smEnqueueIO(smRoot, satIOContext);*/ 14212 14213 tdsmIOCompletedCB( smRoot, 14214 smIORequest, 14215 smIOSuccess, 14216 SCSI_STAT_CHECK_CONDITION, 14217 satIOContext->pSmSenseData, 14218 satIOContext->interruptContext ); 14219 14220 SM_DBG1(("smsatModeSelect10: return control!!!\n")); 14221 return SM_RC_SUCCESS; 14222 } 14223 14224 /* checking PF bit */ 14225 if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT10_PF_MASK)) 14226 { 14227 smsatSetSensePayload( pSense, 14228 SCSI_SNSKEY_ILLEGAL_REQUEST, 14229 0, 14230 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 14231 satIOContext); 14232 14233 /*smEnqueueIO(smRoot, satIOContext);*/ 14234 14235 tdsmIOCompletedCB( smRoot, 14236 smIORequest, 14237 smIOSuccess, 14238 SCSI_STAT_CHECK_CONDITION, 14239 satIOContext->pSmSenseData, 14240 satIOContext->interruptContext ); 14241 14242 SM_DBG1(("smsatModeSelect10: PF bit check!!!\n")); 14243 return SM_RC_SUCCESS; 14244 } 14245 14246 parameterListLen = ((scsiCmnd->cdb[7]) << 8) + scsiCmnd->cdb[8]; 14247 parameterListLen = MIN(parameterListLen, scsiCmnd->expDataLength); 14248 if ((0 == parameterListLen) || (agNULL == pLogPage)) 14249 { 14250 tdsmIOCompletedCB( smRoot, 14251 smIORequest, 14252 smIOSuccess, 14253 SCSI_STAT_GOOD, 14254 agNULL, 14255 satIOContext->interruptContext); 14256 return SM_RC_SUCCESS; 14257 } 14258 14259 BlkDescLen = (bit8)((pLogPage[6] << 8) + pLogPage[7]); 14260 14261 /* checking Block Descriptor Length on Mode parameter header(10) and LONGLBA bit*/ 14262 if ( (BlkDescLen == 8) && !(pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) ) 14263 { 14264 /* mode parameter block descriptor exists and length is 8 byte */ 14265 PageCode = (bit8)(pLogPage[16] & 0x3F); /* page code and index is 8 + 8 */ 14266 StartingIndex = 16; 14267 } 14268 else if ( (BlkDescLen == 16) && (pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) ) 14269 { 14270 /* mode parameter block descriptor exists and length is 16 byte */ 14271 PageCode = (bit8)(pLogPage[24] & 0x3F); /* page code and index is 8 + 16 */ 14272 StartingIndex = 24; 14273 } 14274 else if (BlkDescLen == 0) 14275 { 14276 PageCode = (bit8)(pLogPage[8] & 0x3F); /* page code and index is 8 + 0 */ 14277 StartingIndex = 8; 14278 /*smEnqueueIO(smRoot, satIOContext);*/ 14279 14280 tdsmIOCompletedCB( smRoot, 14281 smIORequest, 14282 smIOSuccess, 14283 SCSI_STAT_GOOD, 14284 agNULL, 14285 satIOContext->interruptContext); 14286 return SM_RC_SUCCESS; 14287 } 14288 else 14289 { 14290 SM_DBG1(("smsatModeSelect10: return mode parameter block descriptor 0x%x!!!\n", BlkDescLen)); 14291 /* no more than one mode parameter block descriptor shall be supported */ 14292 smsatSetSensePayload( pSense, 14293 SCSI_SNSKEY_NO_SENSE, 14294 0, 14295 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 14296 satIOContext); 14297 14298 /*smEnqueueIO(smRoot, satIOContext);*/ 14299 14300 tdsmIOCompletedCB( smRoot, 14301 smIORequest, 14302 smIOSuccess, 14303 SCSI_STAT_CHECK_CONDITION, 14304 satIOContext->pSmSenseData, 14305 satIOContext->interruptContext ); 14306 return SM_RC_SUCCESS; 14307 } 14308 /* 14309 for debugging only 14310 */ 14311 if (StartingIndex == 8) 14312 { 14313 smhexdump("startingindex 8", (bit8 *)pLogPage, 8); 14314 } 14315 else if(StartingIndex == 16) 14316 { 14317 if (PageCode == MODESELECT_CACHING) 14318 { 14319 smhexdump("startingindex 16", (bit8 *)pLogPage, 16+20); 14320 } 14321 else 14322 { 14323 smhexdump("startingindex 16", (bit8 *)pLogPage, 16+12); 14324 } 14325 } 14326 else 14327 { 14328 if (PageCode == MODESELECT_CACHING) 14329 { 14330 smhexdump("startingindex 24", (bit8 *)pLogPage, 24+20); 14331 } 14332 else 14333 { 14334 smhexdump("startingindex 24", (bit8 *)pLogPage, 24+12); 14335 } 14336 } 14337 switch (PageCode) /* page code */ 14338 { 14339 case MODESELECT_CONTROL_PAGE: 14340 SM_DBG5(("smsatModeSelect10: Control mode page\n")); 14341 /* 14342 compare pLogPage to expected value (SAT Table 65, p67) 14343 If not match, return check condition 14344 */ 14345 if ( pLogPage[StartingIndex+1] != 0x0A || 14346 pLogPage[StartingIndex+2] != 0x02 || 14347 (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) || 14348 (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) || 14349 (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */ 14350 (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */ 14351 (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */ 14352 14353 (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */ 14354 (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */ 14355 (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */ 14356 (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */ 14357 14358 pLogPage[StartingIndex+8] != 0xFF || 14359 pLogPage[StartingIndex+9] != 0xFF || 14360 pLogPage[StartingIndex+10] != 0x00 || 14361 pLogPage[StartingIndex+11] != 0x00 14362 ) 14363 { 14364 chkCnd = agTRUE; 14365 } 14366 if (chkCnd == agTRUE) 14367 { 14368 smsatSetSensePayload( pSense, 14369 SCSI_SNSKEY_ILLEGAL_REQUEST, 14370 0, 14371 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 14372 satIOContext); 14373 14374 /*smEnqueueIO(smRoot, satIOContext);*/ 14375 14376 tdsmIOCompletedCB( smRoot, 14377 smIORequest, 14378 smIOSuccess, 14379 SCSI_STAT_CHECK_CONDITION, 14380 satIOContext->pSmSenseData, 14381 satIOContext->interruptContext ); 14382 14383 SM_DBG1(("smsatModeSelect10: unexpected values!!!\n")); 14384 } 14385 else 14386 { 14387 /*smEnqueueIO(smRoot, satIOContext);*/ 14388 14389 tdsmIOCompletedCB( smRoot, 14390 smIORequest, 14391 smIOSuccess, 14392 SCSI_STAT_GOOD, 14393 agNULL, 14394 satIOContext->interruptContext); 14395 } 14396 return SM_RC_SUCCESS; 14397 break; 14398 case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE: 14399 SM_DBG5(("smsatModeSelect10: Read-Write Error Recovery mode page\n")); 14400 14401 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_AWRE_MASK) || 14402 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_RC_MASK) || 14403 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_EER_MASK) || 14404 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PER_MASK) || 14405 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DTE_MASK) || 14406 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DCR_MASK) || 14407 (pLogPage[StartingIndex + 10]) || 14408 (pLogPage[StartingIndex + 11]) 14409 ) 14410 { 14411 SM_DBG1(("smsatModeSelect10: return check condition!!!\n")); 14412 14413 smsatSetSensePayload( pSense, 14414 SCSI_SNSKEY_ILLEGAL_REQUEST, 14415 0, 14416 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 14417 satIOContext); 14418 14419 /*smEnqueueIO(smRoot, satIOContext);*/ 14420 14421 tdsmIOCompletedCB( smRoot, 14422 smIORequest, 14423 smIOSuccess, 14424 SCSI_STAT_CHECK_CONDITION, 14425 satIOContext->pSmSenseData, 14426 satIOContext->interruptContext ); 14427 return SM_RC_SUCCESS; 14428 } 14429 else 14430 { 14431 SM_DBG2(("smsatModeSelect10: return GOOD \n")); 14432 /*smEnqueueIO(smRoot, satIOContext);*/ 14433 14434 tdsmIOCompletedCB( smRoot, 14435 smIORequest, 14436 smIOSuccess, 14437 SCSI_STAT_GOOD, 14438 agNULL, 14439 satIOContext->interruptContext); 14440 return SM_RC_SUCCESS; 14441 } 14442 14443 break; 14444 case MODESELECT_CACHING: 14445 /* SAT rev8 Table67, p69*/ 14446 SM_DBG5(("smsatModeSelect10: Caching mode page\n")); 14447 if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */ 14448 (pLogPage[StartingIndex + 3]) || 14449 (pLogPage[StartingIndex + 4]) || 14450 (pLogPage[StartingIndex + 5]) || 14451 (pLogPage[StartingIndex + 6]) || 14452 (pLogPage[StartingIndex + 7]) || 14453 (pLogPage[StartingIndex + 8]) || 14454 (pLogPage[StartingIndex + 9]) || 14455 (pLogPage[StartingIndex + 10]) || 14456 (pLogPage[StartingIndex + 11]) || 14457 14458 (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */ 14459 (pLogPage[StartingIndex + 13]) || 14460 (pLogPage[StartingIndex + 14]) || 14461 (pLogPage[StartingIndex + 15]) 14462 ) 14463 { 14464 SM_DBG1(("smsatModeSelect10: return check condition!!!\n")); 14465 14466 smsatSetSensePayload( pSense, 14467 SCSI_SNSKEY_ILLEGAL_REQUEST, 14468 0, 14469 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 14470 satIOContext); 14471 14472 /*smEnqueueIO(smRoot, satIOContext);*/ 14473 14474 tdsmIOCompletedCB( smRoot, 14475 smIORequest, 14476 smIOSuccess, 14477 SCSI_STAT_CHECK_CONDITION, 14478 satIOContext->pSmSenseData, 14479 satIOContext->interruptContext ); 14480 return SM_RC_SUCCESS; 14481 14482 } 14483 else 14484 { 14485 /* sends ATA SET FEATURES based on WCE bit */ 14486 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_WCE_MASK) ) 14487 { 14488 SM_DBG5(("smsatModeSelect10: disable write cache\n")); 14489 /* sends SET FEATURES */ 14490 fis->h.fisType = 0x27; /* Reg host to device */ 14491 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14492 14493 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 14494 fis->h.features = 0x82; /* disable write cache */ 14495 fis->d.lbaLow = 0; /* */ 14496 fis->d.lbaMid = 0; /* */ 14497 fis->d.lbaHigh = 0; /* */ 14498 fis->d.device = 0; /* */ 14499 fis->d.lbaLowExp = 0; /* */ 14500 fis->d.lbaMidExp = 0; /* */ 14501 fis->d.lbaHighExp = 0; /* */ 14502 fis->d.featuresExp = 0; /* */ 14503 fis->d.sectorCount = 0; /* */ 14504 fis->d.sectorCountExp = 0; /* */ 14505 fis->d.reserved4 = 0; 14506 fis->d.control = 0; /* FIS HOB bit clear */ 14507 fis->d.reserved5 = 0; 14508 14509 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14510 14511 /* Initialize CB for SATA completion. 14512 */ 14513 satIOContext->satCompleteCB = &smsatModeSelect6n10CB; 14514 14515 /* 14516 * Prepare SGL and send FIS to LL layer. 14517 */ 14518 satIOContext->reqType = agRequestType; /* Save it */ 14519 14520 status = smsataLLIOStart( smRoot, 14521 smIORequest, 14522 smDeviceHandle, 14523 smScsiRequest, 14524 satIOContext); 14525 return status; 14526 } 14527 else 14528 { 14529 SM_DBG5(("smsatModeSelect10: enable write cache\n")); 14530 /* sends SET FEATURES */ 14531 fis->h.fisType = 0x27; /* Reg host to device */ 14532 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14533 14534 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 14535 fis->h.features = 0x02; /* enable write cache */ 14536 fis->d.lbaLow = 0; /* */ 14537 fis->d.lbaMid = 0; /* */ 14538 fis->d.lbaHigh = 0; /* */ 14539 fis->d.device = 0; /* */ 14540 fis->d.lbaLowExp = 0; /* */ 14541 fis->d.lbaMidExp = 0; /* */ 14542 fis->d.lbaHighExp = 0; /* */ 14543 fis->d.featuresExp = 0; /* */ 14544 fis->d.sectorCount = 0; /* */ 14545 fis->d.sectorCountExp = 0; /* */ 14546 fis->d.reserved4 = 0; 14547 fis->d.control = 0; /* FIS HOB bit clear */ 14548 fis->d.reserved5 = 0; 14549 14550 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14551 14552 /* Initialize CB for SATA completion. 14553 */ 14554 satIOContext->satCompleteCB = &smsatModeSelect6n10CB; 14555 14556 /* 14557 * Prepare SGL and send FIS to LL layer. 14558 */ 14559 satIOContext->reqType = agRequestType; /* Save it */ 14560 14561 status = smsataLLIOStart( smRoot, 14562 smIORequest, 14563 smDeviceHandle, 14564 smScsiRequest, 14565 satIOContext); 14566 return status; 14567 14568 } 14569 } 14570 break; 14571 case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE: 14572 SM_DBG5(("smsatModeSelect10: Informational Exception Control mode page\n")); 14573 14574 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PERF_MASK) || 14575 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_TEST_MASK) 14576 ) 14577 { 14578 SM_DBG1(("smsatModeSelect10: return check condition!!!\n")); 14579 14580 smsatSetSensePayload( pSense, 14581 SCSI_SNSKEY_ILLEGAL_REQUEST, 14582 0, 14583 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 14584 satIOContext); 14585 14586 /*smEnqueueIO(smRoot, satIOContext);*/ 14587 14588 tdsmIOCompletedCB( smRoot, 14589 smIORequest, 14590 smIOSuccess, 14591 SCSI_STAT_CHECK_CONDITION, 14592 satIOContext->pSmSenseData, 14593 satIOContext->interruptContext ); 14594 return SM_RC_SUCCESS; 14595 } 14596 else 14597 { 14598 /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */ 14599 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DEXCPT_MASK) ) 14600 { 14601 SM_DBG5(("smsatModeSelect10: enable information exceptions reporting\n")); 14602 /* sends SMART ENABLE OPERATIONS */ 14603 fis->h.fisType = 0x27; /* Reg host to device */ 14604 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14605 14606 fis->h.command = SAT_SMART; /* 0xB0 */ 14607 fis->h.features = SAT_SMART_ENABLE_OPERATIONS; /* enable */ 14608 fis->d.lbaLow = 0; /* */ 14609 fis->d.lbaMid = 0x4F; /* 0x4F */ 14610 fis->d.lbaHigh = 0xC2; /* 0xC2 */ 14611 fis->d.device = 0; /* */ 14612 fis->d.lbaLowExp = 0; /* */ 14613 fis->d.lbaMidExp = 0; /* */ 14614 fis->d.lbaHighExp = 0; /* */ 14615 fis->d.featuresExp = 0; /* */ 14616 fis->d.sectorCount = 0; /* */ 14617 fis->d.sectorCountExp = 0; /* */ 14618 fis->d.reserved4 = 0; 14619 fis->d.control = 0; /* FIS HOB bit clear */ 14620 fis->d.reserved5 = 0; 14621 14622 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14623 14624 /* Initialize CB for SATA completion. 14625 */ 14626 satIOContext->satCompleteCB = &smsatModeSelect6n10CB; 14627 14628 /* 14629 * Prepare SGL and send FIS to LL layer. 14630 */ 14631 satIOContext->reqType = agRequestType; /* Save it */ 14632 14633 status = smsataLLIOStart( smRoot, 14634 smIORequest, 14635 smDeviceHandle, 14636 smScsiRequest, 14637 satIOContext); 14638 return status; 14639 } 14640 else 14641 { 14642 SM_DBG5(("smsatModeSelect10: disable information exceptions reporting\n")); 14643 /* sends SMART DISABLE OPERATIONS */ 14644 fis->h.fisType = 0x27; /* Reg host to device */ 14645 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14646 14647 fis->h.command = SAT_SMART; /* 0xB0 */ 14648 fis->h.features = SAT_SMART_DISABLE_OPERATIONS; /* disable */ 14649 fis->d.lbaLow = 0; /* */ 14650 fis->d.lbaMid = 0x4F; /* 0x4F */ 14651 fis->d.lbaHigh = 0xC2; /* 0xC2 */ 14652 fis->d.device = 0; /* */ 14653 fis->d.lbaLowExp = 0; /* */ 14654 fis->d.lbaMidExp = 0; /* */ 14655 fis->d.lbaHighExp = 0; /* */ 14656 fis->d.featuresExp = 0; /* */ 14657 fis->d.sectorCount = 0; /* */ 14658 fis->d.sectorCountExp = 0; /* */ 14659 fis->d.reserved4 = 0; 14660 fis->d.control = 0; /* FIS HOB bit clear */ 14661 fis->d.reserved5 = 0; 14662 14663 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14664 14665 /* Initialize CB for SATA completion. 14666 */ 14667 satIOContext->satCompleteCB = &smsatModeSelect6n10CB; 14668 14669 /* 14670 * Prepare SGL and send FIS to LL layer. 14671 */ 14672 satIOContext->reqType = agRequestType; /* Save it */ 14673 14674 status = smsataLLIOStart( smRoot, 14675 smIORequest, 14676 smDeviceHandle, 14677 smScsiRequest, 14678 satIOContext); 14679 return status; 14680 14681 } 14682 } 14683 break; 14684 default: 14685 SM_DBG1(("smsatModeSelect10: Error unknown page code 0x%x!!!\n", pLogPage[12])); 14686 smsatSetSensePayload( pSense, 14687 SCSI_SNSKEY_NO_SENSE, 14688 0, 14689 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 14690 satIOContext); 14691 14692 /*smEnqueueIO(smRoot, satIOContext);*/ 14693 14694 tdsmIOCompletedCB( smRoot, 14695 smIORequest, 14696 smIOSuccess, 14697 SCSI_STAT_CHECK_CONDITION, 14698 satIOContext->pSmSenseData, 14699 satIOContext->interruptContext ); 14700 return SM_RC_SUCCESS; 14701 } 14702 } 14703 14704 osGLOBAL bit32 14705 smsatSynchronizeCache10( 14706 smRoot_t *smRoot, 14707 smIORequest_t *smIORequest, 14708 smDeviceHandle_t *smDeviceHandle, 14709 smScsiInitiatorRequest_t *smScsiRequest, 14710 smSatIOContext_t *satIOContext 14711 ) 14712 { 14713 bit32 status; 14714 bit32 agRequestType; 14715 smDeviceData_t *pSatDevData; 14716 smScsiRspSense_t *pSense; 14717 smIniScsiCmnd_t *scsiCmnd; 14718 agsaFisRegHostToDevice_t *fis; 14719 14720 pSense = satIOContext->pSense; 14721 pSatDevData = satIOContext->pSatDevData; 14722 scsiCmnd = &smScsiRequest->scsiCmnd; 14723 fis = satIOContext->pFis; 14724 14725 SM_DBG5(("smsatSynchronizeCache10: start\n")); 14726 14727 /* checking CONTROL */ 14728 /* NACA == 1 or LINK == 1*/ 14729 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 14730 { 14731 smsatSetSensePayload( pSense, 14732 SCSI_SNSKEY_ILLEGAL_REQUEST, 14733 0, 14734 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 14735 satIOContext); 14736 14737 /*smEnqueueIO(smRoot, satIOContext);*/ 14738 14739 tdsmIOCompletedCB( smRoot, 14740 smIORequest, 14741 smIOSuccess, 14742 SCSI_STAT_CHECK_CONDITION, 14743 satIOContext->pSmSenseData, 14744 satIOContext->interruptContext ); 14745 14746 SM_DBG1(("smsatSynchronizeCache10: return control!!!\n")); 14747 return SM_RC_SUCCESS; 14748 } 14749 14750 /* checking IMMED bit */ 14751 if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK) 14752 { 14753 SM_DBG1(("smsatSynchronizeCache10: GOOD status due to IMMED bit!!!\n")); 14754 14755 /* return GOOD status first here */ 14756 tdsmIOCompletedCB( smRoot, 14757 smIORequest, 14758 smIOSuccess, 14759 SCSI_STAT_GOOD, 14760 agNULL, 14761 satIOContext->interruptContext); 14762 } 14763 14764 /* sends FLUSH CACHE or FLUSH CACHE EXT */ 14765 if (pSatDevData->sat48BitSupport == agTRUE) 14766 { 14767 SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE EXT\n")); 14768 /* FLUSH CACHE EXT */ 14769 fis->h.fisType = 0x27; /* Reg host to device */ 14770 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14771 14772 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */ 14773 fis->h.features = 0; /* FIS reserve */ 14774 fis->d.featuresExp = 0; /* FIS reserve */ 14775 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 14776 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 14777 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 14778 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 14779 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 14780 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14781 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 14782 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14783 fis->d.device = 0; /* FIS DEV is discared in SATA */ 14784 fis->d.control = 0; /* FIS HOB bit clear */ 14785 fis->d.reserved4 = 0; 14786 fis->d.reserved5 = 0; 14787 14788 } 14789 else 14790 { 14791 SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE\n")); 14792 /* FLUSH CACHE */ 14793 fis->h.fisType = 0x27; /* Reg host to device */ 14794 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14795 14796 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */ 14797 fis->h.features = 0; /* FIS features NA */ 14798 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 14799 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 14800 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 14801 fis->d.lbaLowExp = 0; 14802 fis->d.lbaMidExp = 0; 14803 fis->d.lbaHighExp = 0; 14804 fis->d.featuresExp = 0; 14805 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 14806 fis->d.sectorCountExp = 0; 14807 fis->d.device = 0; /* FIS DEV is discared in SATA */ 14808 fis->d.control = 0; /* FIS HOB bit clear */ 14809 fis->d.reserved4 = 0; 14810 fis->d.reserved5 = 0; 14811 14812 } 14813 14814 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14815 14816 /* Initialize CB for SATA completion. 14817 */ 14818 satIOContext->satCompleteCB = &smsatSynchronizeCache10n16CB; 14819 14820 /* 14821 * Prepare SGL and send FIS to LL layer. 14822 */ 14823 satIOContext->reqType = agRequestType; /* Save it */ 14824 14825 status = smsataLLIOStart( smRoot, 14826 smIORequest, 14827 smDeviceHandle, 14828 smScsiRequest, 14829 satIOContext); 14830 14831 14832 return (status); 14833 } 14834 14835 osGLOBAL bit32 14836 smsatSynchronizeCache16( 14837 smRoot_t *smRoot, 14838 smIORequest_t *smIORequest, 14839 smDeviceHandle_t *smDeviceHandle, 14840 smScsiInitiatorRequest_t *smScsiRequest, 14841 smSatIOContext_t *satIOContext 14842 ) 14843 { 14844 bit32 status; 14845 bit32 agRequestType; 14846 smDeviceData_t *pSatDevData; 14847 smScsiRspSense_t *pSense; 14848 smIniScsiCmnd_t *scsiCmnd; 14849 agsaFisRegHostToDevice_t *fis; 14850 14851 pSense = satIOContext->pSense; 14852 pSatDevData = satIOContext->pSatDevData; 14853 scsiCmnd = &smScsiRequest->scsiCmnd; 14854 fis = satIOContext->pFis; 14855 14856 SM_DBG5(("smsatSynchronizeCache10: start\n")); 14857 14858 /* checking CONTROL */ 14859 /* NACA == 1 or LINK == 1*/ 14860 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 14861 { 14862 smsatSetSensePayload( pSense, 14863 SCSI_SNSKEY_ILLEGAL_REQUEST, 14864 0, 14865 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 14866 satIOContext); 14867 14868 /*smEnqueueIO(smRoot, satIOContext);*/ 14869 14870 tdsmIOCompletedCB( smRoot, 14871 smIORequest, 14872 smIOSuccess, 14873 SCSI_STAT_CHECK_CONDITION, 14874 satIOContext->pSmSenseData, 14875 satIOContext->interruptContext ); 14876 14877 SM_DBG1(("smsatSynchronizeCache10: return control!!!\n")); 14878 return SM_RC_SUCCESS; 14879 } 14880 14881 14882 /* checking IMMED bit */ 14883 if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK) 14884 { 14885 SM_DBG1(("smsatSynchronizeCache10: GOOD status due to IMMED bit!!!\n")); 14886 14887 /* return GOOD status first here */ 14888 tdsmIOCompletedCB( smRoot, 14889 smIORequest, 14890 smIOSuccess, 14891 SCSI_STAT_GOOD, 14892 agNULL, 14893 satIOContext->interruptContext); 14894 } 14895 14896 /* sends FLUSH CACHE or FLUSH CACHE EXT */ 14897 if (pSatDevData->sat48BitSupport == agTRUE) 14898 { 14899 SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE EXT\n")); 14900 /* FLUSH CACHE EXT */ 14901 fis->h.fisType = 0x27; /* Reg host to device */ 14902 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14903 14904 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */ 14905 fis->h.features = 0; /* FIS reserve */ 14906 fis->d.featuresExp = 0; /* FIS reserve */ 14907 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 14908 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 14909 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 14910 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 14911 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 14912 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14913 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 14914 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14915 fis->d.device = 0; /* FIS DEV is discared in SATA */ 14916 fis->d.control = 0; /* FIS HOB bit clear */ 14917 fis->d.reserved4 = 0; 14918 fis->d.reserved5 = 0; 14919 14920 } 14921 else 14922 { 14923 SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE\n")); 14924 /* FLUSH CACHE */ 14925 fis->h.fisType = 0x27; /* Reg host to device */ 14926 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14927 14928 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */ 14929 fis->h.features = 0; /* FIS features NA */ 14930 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 14931 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 14932 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 14933 fis->d.lbaLowExp = 0; 14934 fis->d.lbaMidExp = 0; 14935 fis->d.lbaHighExp = 0; 14936 fis->d.featuresExp = 0; 14937 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 14938 fis->d.sectorCountExp = 0; 14939 fis->d.device = 0; /* FIS DEV is discared in SATA */ 14940 fis->d.control = 0; /* FIS HOB bit clear */ 14941 fis->d.reserved4 = 0; 14942 fis->d.reserved5 = 0; 14943 14944 } 14945 14946 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14947 14948 /* Initialize CB for SATA completion. 14949 */ 14950 satIOContext->satCompleteCB = &smsatSynchronizeCache10n16CB; 14951 14952 /* 14953 * Prepare SGL and send FIS to LL layer. 14954 */ 14955 satIOContext->reqType = agRequestType; /* Save it */ 14956 14957 status = smsataLLIOStart( smRoot, 14958 smIORequest, 14959 smDeviceHandle, 14960 smScsiRequest, 14961 satIOContext); 14962 14963 14964 return (status); 14965 } 14966 14967 osGLOBAL bit32 14968 smsatWriteAndVerify10( 14969 smRoot_t *smRoot, 14970 smIORequest_t *smIORequest, 14971 smDeviceHandle_t *smDeviceHandle, 14972 smScsiInitiatorRequest_t *smScsiRequest, 14973 smSatIOContext_t *satIOContext 14974 ) 14975 { 14976 /* 14977 combination of write10 and verify10 14978 */ 14979 14980 bit32 status; 14981 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14982 smDeviceData_t *pSatDevData; 14983 smScsiRspSense_t *pSense; 14984 smIniScsiCmnd_t *scsiCmnd; 14985 agsaFisRegHostToDevice_t *fis; 14986 bit32 lba = 0; 14987 bit32 tl = 0; 14988 bit32 LoopNum = 1; 14989 bit8 LBA[8]; 14990 bit8 TL[8]; 14991 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 14992 14993 pSense = satIOContext->pSense; 14994 pSatDevData = satIOContext->pSatDevData; 14995 scsiCmnd = &smScsiRequest->scsiCmnd; 14996 fis = satIOContext->pFis; 14997 14998 SM_DBG5(("smsatWriteAndVerify10: start\n")); 14999 15000 /* checking BYTCHK bit */ 15001 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK) 15002 { 15003 smsatSetSensePayload( pSense, 15004 SCSI_SNSKEY_ILLEGAL_REQUEST, 15005 0, 15006 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15007 satIOContext); 15008 15009 /*smEnqueueIO(smRoot, satIOContext);*/ 15010 15011 tdsmIOCompletedCB( smRoot, 15012 smIORequest, 15013 smIOSuccess, 15014 SCSI_STAT_CHECK_CONDITION, 15015 satIOContext->pSmSenseData, 15016 satIOContext->interruptContext ); 15017 15018 SM_DBG1(("smsatWriteAndVerify10: BYTCHK bit checking!!!\n")); 15019 return SM_RC_SUCCESS; 15020 } 15021 15022 15023 /* checking CONTROL */ 15024 /* NACA == 1 or LINK == 1*/ 15025 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 15026 { 15027 smsatSetSensePayload( pSense, 15028 SCSI_SNSKEY_ILLEGAL_REQUEST, 15029 0, 15030 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15031 satIOContext); 15032 15033 /*smEnqueueIO(smRoot, satIOContext);*/ 15034 15035 tdsmIOCompletedCB( smRoot, 15036 smIORequest, 15037 smIOSuccess, 15038 SCSI_STAT_CHECK_CONDITION, 15039 satIOContext->pSmSenseData, 15040 satIOContext->interruptContext ); 15041 15042 SM_DBG1(("smsatWriteAndVerify10: return control!!!\n")); 15043 return SM_RC_SUCCESS; 15044 } 15045 15046 sm_memset(LBA, 0, sizeof(LBA)); 15047 sm_memset(TL, 0, sizeof(TL)); 15048 15049 /* do not use memcpy due to indexing in LBA and TL */ 15050 LBA[0] = 0; /* MSB */ 15051 LBA[1] = 0; 15052 LBA[2] = 0; 15053 LBA[3] = 0; 15054 LBA[4] = scsiCmnd->cdb[2]; 15055 LBA[5] = scsiCmnd->cdb[3]; 15056 LBA[6] = scsiCmnd->cdb[4]; 15057 LBA[7] = scsiCmnd->cdb[5]; /* LSB */ 15058 15059 TL[0] = 0; 15060 TL[1] = 0; 15061 TL[2] = 0; 15062 TL[3] = 0; 15063 TL[4] = 0; 15064 TL[5] = 0; 15065 TL[6] = scsiCmnd->cdb[7]; 15066 TL[7] = scsiCmnd->cdb[8]; /* LSB */ 15067 15068 15069 /* cbd10; computing LBA and transfer length */ 15070 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 15071 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 15072 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 15073 15074 15075 /* Table 34, 9.1, p 46 */ 15076 /* 15077 note: As of 2/10/2006, no support for DMA QUEUED 15078 */ 15079 15080 /* 15081 Table 34, 9.1, p 46, b 15082 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 15083 return check condition 15084 */ 15085 if (pSatDevData->satNCQ != agTRUE && 15086 pSatDevData->sat48BitSupport != agTRUE 15087 ) 15088 { 15089 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 15090 if (AllChk) 15091 { 15092 SM_DBG1(("smsatWriteAndVerify10: return LBA out of range!!!\n")); 15093 smsatSetSensePayload( pSense, 15094 SCSI_SNSKEY_ILLEGAL_REQUEST, 15095 0, 15096 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 15097 satIOContext); 15098 15099 /*smEnqueueIO(smRoot, satIOContext);*/ 15100 15101 tdsmIOCompletedCB( smRoot, 15102 smIORequest, 15103 smIOSuccess, 15104 SCSI_STAT_CHECK_CONDITION, 15105 satIOContext->pSmSenseData, 15106 satIOContext->interruptContext ); 15107 15108 return SM_RC_SUCCESS; 15109 } 15110 } 15111 else 15112 { 15113 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 15114 if (AllChk) 15115 { 15116 SM_DBG1(("smsatWriteAndVerify10: return LBA out of range, EXT!!!\n")); 15117 smsatSetSensePayload( pSense, 15118 SCSI_SNSKEY_ILLEGAL_REQUEST, 15119 0, 15120 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 15121 satIOContext); 15122 15123 /*smEnqueueIO(smRoot, satIOContext);*/ 15124 15125 tdsmIOCompletedCB( smRoot, 15126 smIORequest, 15127 smIOSuccess, 15128 SCSI_STAT_CHECK_CONDITION, 15129 satIOContext->pSmSenseData, 15130 satIOContext->interruptContext ); 15131 15132 return SM_RC_SUCCESS; 15133 } 15134 } 15135 15136 15137 /* case 1 and 2 */ 15138 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 15139 { 15140 /* case 2 */ 15141 /* WRITE DMA*/ 15142 /* can't fit the transfer length */ 15143 SM_DBG5(("smsatWriteAndVerify10: case 2\n")); 15144 fis->h.fisType = 0x27; /* Reg host to device */ 15145 fis->h.c_pmPort = 0x80; /* C bit is set */ 15146 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 15147 fis->h.features = 0; /* FIS reserve */ 15148 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15149 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15150 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15151 15152 /* FIS LBA mode set LBA (27:24) */ 15153 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 15154 15155 fis->d.lbaLowExp = 0; 15156 fis->d.lbaMidExp = 0; 15157 fis->d.lbaHighExp = 0; 15158 fis->d.featuresExp = 0; 15159 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 15160 fis->d.sectorCountExp = 0; 15161 fis->d.reserved4 = 0; 15162 fis->d.control = 0; /* FIS HOB bit clear */ 15163 fis->d.reserved5 = 0; 15164 15165 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 15166 satIOContext->ATACmd = SAT_WRITE_DMA; 15167 } 15168 else 15169 { 15170 /* case 1 */ 15171 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 15172 /* WRITE SECTORS for easier implemetation */ 15173 /* can't fit the transfer length */ 15174 SM_DBG5(("smsatWriteAndVerify10: case 1\n")); 15175 fis->h.fisType = 0x27; /* Reg host to device */ 15176 fis->h.c_pmPort = 0x80; /* C bit is set */ 15177 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 15178 fis->h.features = 0; /* FIS reserve */ 15179 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15180 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15181 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15182 15183 /* FIS LBA mode set LBA (27:24) */ 15184 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 15185 15186 fis->d.lbaLowExp = 0; 15187 fis->d.lbaMidExp = 0; 15188 fis->d.lbaHighExp = 0; 15189 fis->d.featuresExp = 0; 15190 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 15191 fis->d.sectorCountExp = 0; 15192 fis->d.reserved4 = 0; 15193 fis->d.control = 0; /* FIS HOB bit clear */ 15194 fis->d.reserved5 = 0; 15195 15196 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 15197 satIOContext->ATACmd = SAT_WRITE_SECTORS; 15198 15199 } 15200 15201 /* case 3 and 4 */ 15202 if (pSatDevData->sat48BitSupport == agTRUE) 15203 { 15204 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 15205 { 15206 /* case 3 */ 15207 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 15208 SM_DBG5(("smsatWriteAndVerify10: case 3\n")); 15209 fis->h.fisType = 0x27; /* Reg host to device */ 15210 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15211 15212 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 15213 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 15214 15215 fis->h.features = 0; /* FIS reserve */ 15216 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15217 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15218 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15219 fis->d.device = 0x40; /* FIS LBA mode set */ 15220 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 15221 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 15222 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 15223 fis->d.featuresExp = 0; /* FIS reserve */ 15224 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 15225 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 15226 fis->d.reserved4 = 0; 15227 fis->d.control = 0; /* FIS HOB bit clear */ 15228 fis->d.reserved5 = 0; 15229 15230 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 15231 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 15232 } 15233 else 15234 { 15235 /* case 4 */ 15236 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 15237 /* WRITE SECTORS EXT for easier implemetation */ 15238 SM_DBG5(("smsatWriteAndVerify10: case 4\n")); 15239 fis->h.fisType = 0x27; /* Reg host to device */ 15240 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15241 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 15242 15243 fis->h.features = 0; /* FIS reserve */ 15244 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15245 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15246 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15247 fis->d.device = 0x40; /* FIS LBA mode set */ 15248 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 15249 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 15250 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 15251 fis->d.featuresExp = 0; /* FIS reserve */ 15252 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 15253 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 15254 fis->d.reserved4 = 0; 15255 fis->d.control = 0; /* FIS HOB bit clear */ 15256 fis->d.reserved5 = 0; 15257 15258 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 15259 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 15260 } 15261 } 15262 /* case 5 */ 15263 if (pSatDevData->satNCQ == agTRUE) 15264 { 15265 /* WRITE FPDMA QUEUED */ 15266 if (pSatDevData->sat48BitSupport != agTRUE) 15267 { 15268 SM_DBG1(("smsatWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support!!!\n")); 15269 smsatSetSensePayload( pSense, 15270 SCSI_SNSKEY_ILLEGAL_REQUEST, 15271 0, 15272 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15273 satIOContext); 15274 15275 /*smEnqueueIO(smRoot, satIOContext);*/ 15276 15277 tdsmIOCompletedCB( smRoot, 15278 smIORequest, 15279 smIOSuccess, 15280 SCSI_STAT_CHECK_CONDITION, 15281 satIOContext->pSmSenseData, 15282 satIOContext->interruptContext ); 15283 return SM_RC_SUCCESS; 15284 } 15285 SM_DBG5(("smsatWriteAndVerify10: case 5\n")); 15286 15287 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 15288 15289 fis->h.fisType = 0x27; /* Reg host to device */ 15290 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15291 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 15292 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 15293 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15294 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15295 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15296 15297 /* Check FUA bit */ 15298 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK) 15299 fis->d.device = 0xC0; /* FIS FUA set */ 15300 else 15301 fis->d.device = 0x40; /* FIS FUA clear */ 15302 15303 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 15304 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 15305 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 15306 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 15307 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 15308 fis->d.sectorCountExp = 0; 15309 fis->d.reserved4 = 0; 15310 fis->d.control = 0; /* FIS HOB bit clear */ 15311 fis->d.reserved5 = 0; 15312 15313 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 15314 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 15315 } 15316 15317 satIOContext->currentLBA = lba; 15318 satIOContext->OrgTL = tl; 15319 15320 /* 15321 computing number of loop and remainder for tl 15322 0xFF in case not ext 15323 0xFFFF in case EXT 15324 */ 15325 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 15326 { 15327 LoopNum = smsatComputeLoopNum(tl, 0xFF); 15328 } 15329 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 15330 fis->h.command == SAT_WRITE_DMA_EXT || 15331 fis->h.command == SAT_WRITE_DMA_FUA_EXT 15332 ) 15333 { 15334 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 15335 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 15336 } 15337 else 15338 { 15339 /* SAT_WRITE_FPDMA_QUEUED */ 15340 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 15341 } 15342 15343 satIOContext->LoopNum = LoopNum; 15344 15345 15346 if (LoopNum == 1) 15347 { 15348 SM_DBG5(("smsatWriteAndVerify10: NON CHAINED data\n")); 15349 /* Initialize CB for SATA completion. 15350 */ 15351 satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB; 15352 } 15353 else 15354 { 15355 SM_DBG1(("smsatWriteAndVerify10: CHAINED data!!!\n")); 15356 /* re-setting tl */ 15357 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 15358 { 15359 fis->d.sectorCount = 0xFF; 15360 } 15361 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 15362 fis->h.command == SAT_WRITE_DMA_EXT || 15363 fis->h.command == SAT_WRITE_DMA_FUA_EXT 15364 ) 15365 { 15366 fis->d.sectorCount = 0xFF; 15367 fis->d.sectorCountExp = 0xFF; 15368 } 15369 else 15370 { 15371 /* SAT_WRITE_FPDMA_QUEUED */ 15372 fis->h.features = 0xFF; 15373 fis->d.featuresExp = 0xFF; 15374 } 15375 15376 /* Initialize CB for SATA completion. 15377 */ 15378 satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB; 15379 } 15380 15381 15382 /* 15383 * Prepare SGL and send FIS to LL layer. 15384 */ 15385 satIOContext->reqType = agRequestType; /* Save it */ 15386 15387 status = smsataLLIOStart( smRoot, 15388 smIORequest, 15389 smDeviceHandle, 15390 smScsiRequest, 15391 satIOContext); 15392 return (status); 15393 15394 } 15395 15396 osGLOBAL bit32 15397 smsatWriteAndVerify12( 15398 smRoot_t *smRoot, 15399 smIORequest_t *smIORequest, 15400 smDeviceHandle_t *smDeviceHandle, 15401 smScsiInitiatorRequest_t *smScsiRequest, 15402 smSatIOContext_t *satIOContext 15403 ) 15404 { 15405 /* 15406 combination of write12 and verify12 15407 temp: since write12 is not support (due to internal checking), no support 15408 */ 15409 bit32 status; 15410 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 15411 smDeviceData_t *pSatDevData; 15412 smScsiRspSense_t *pSense; 15413 smIniScsiCmnd_t *scsiCmnd; 15414 agsaFisRegHostToDevice_t *fis; 15415 bit32 lba = 0; 15416 bit32 tl = 0; 15417 bit32 LoopNum = 1; 15418 bit8 LBA[8]; 15419 bit8 TL[8]; 15420 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 15421 15422 pSense = satIOContext->pSense; 15423 pSatDevData = satIOContext->pSatDevData; 15424 scsiCmnd = &smScsiRequest->scsiCmnd; 15425 fis = satIOContext->pFis; 15426 15427 SM_DBG5(("smsatWriteAndVerify12: start\n")); 15428 15429 /* checking BYTCHK bit */ 15430 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK) 15431 { 15432 smsatSetSensePayload( pSense, 15433 SCSI_SNSKEY_ILLEGAL_REQUEST, 15434 0, 15435 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15436 satIOContext); 15437 15438 /*smEnqueueIO(smRoot, satIOContext);*/ 15439 15440 tdsmIOCompletedCB( smRoot, 15441 smIORequest, 15442 smIOSuccess, 15443 SCSI_STAT_CHECK_CONDITION, 15444 satIOContext->pSmSenseData, 15445 satIOContext->interruptContext ); 15446 15447 SM_DBG1(("smsatWriteAndVerify12: BYTCHK bit checking!!!\n")); 15448 return SM_RC_SUCCESS; 15449 } 15450 15451 /* checking CONTROL */ 15452 /* NACA == 1 or LINK == 1*/ 15453 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) ) 15454 { 15455 smsatSetSensePayload( pSense, 15456 SCSI_SNSKEY_ILLEGAL_REQUEST, 15457 0, 15458 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15459 satIOContext); 15460 15461 /*smEnqueueIO(smRoot, satIOContext);*/ 15462 15463 tdsmIOCompletedCB( smRoot, 15464 smIORequest, 15465 smIOSuccess, 15466 SCSI_STAT_CHECK_CONDITION, 15467 satIOContext->pSmSenseData, 15468 satIOContext->interruptContext ); 15469 15470 SM_DBG1(("smsatWriteAndVerify12: return control!!!\n")); 15471 return SM_RC_SUCCESS; 15472 } 15473 15474 sm_memset(LBA, 0, sizeof(LBA)); 15475 sm_memset(TL, 0, sizeof(TL)); 15476 15477 /* do not use memcpy due to indexing in LBA and TL */ 15478 LBA[0] = 0; /* MSB */ 15479 LBA[1] = 0; 15480 LBA[2] = 0; 15481 LBA[3] = 0; 15482 LBA[4] = scsiCmnd->cdb[2]; 15483 LBA[5] = scsiCmnd->cdb[3]; 15484 LBA[6] = scsiCmnd->cdb[4]; 15485 LBA[7] = scsiCmnd->cdb[5]; /* LSB */ 15486 15487 TL[0] = 0; /* MSB */ 15488 TL[1] = 0; 15489 TL[2] = 0; 15490 TL[3] = 0; 15491 TL[4] = scsiCmnd->cdb[6]; 15492 TL[5] = scsiCmnd->cdb[7]; 15493 TL[6] = scsiCmnd->cdb[8]; 15494 TL[7] = scsiCmnd->cdb[9]; /* LSB */ 15495 15496 15497 lba = smsatComputeCDB12LBA(satIOContext); 15498 tl = smsatComputeCDB12TL(satIOContext); 15499 15500 15501 /* Table 34, 9.1, p 46 */ 15502 /* 15503 note: As of 2/10/2006, no support for DMA QUEUED 15504 */ 15505 15506 /* 15507 Table 34, 9.1, p 46, b 15508 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 15509 return check condition 15510 */ 15511 if (pSatDevData->satNCQ != agTRUE && 15512 pSatDevData->sat48BitSupport != agTRUE 15513 ) 15514 { 15515 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 15516 if (AllChk) 15517 { 15518 15519 /*smEnqueueIO(smRoot, satIOContext);*/ 15520 15521 15522 SM_DBG1(("smsatWriteAndVerify12: return LBA out of range, not EXT!!!\n")); 15523 15524 smsatSetSensePayload( pSense, 15525 SCSI_SNSKEY_ILLEGAL_REQUEST, 15526 0, 15527 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 15528 satIOContext); 15529 15530 /*smEnqueueIO(smRoot, satIOContext);*/ 15531 15532 tdsmIOCompletedCB( smRoot, 15533 smIORequest, 15534 smIOSuccess, 15535 SCSI_STAT_CHECK_CONDITION, 15536 satIOContext->pSmSenseData, 15537 satIOContext->interruptContext ); 15538 15539 return SM_RC_SUCCESS; 15540 } 15541 } 15542 else 15543 { 15544 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 15545 if (AllChk) 15546 { 15547 SM_DBG1(("smsatWriteAndVerify12: return LBA out of range, EXT!!!\n")); 15548 smsatSetSensePayload( pSense, 15549 SCSI_SNSKEY_ILLEGAL_REQUEST, 15550 0, 15551 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 15552 satIOContext); 15553 tdsmIOCompletedCB( smRoot, 15554 smIORequest, 15555 smIOSuccess, 15556 SCSI_STAT_CHECK_CONDITION, 15557 satIOContext->pSmSenseData, 15558 satIOContext->interruptContext ); 15559 return SM_RC_SUCCESS; 15560 } 15561 } 15562 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 15563 { 15564 /* case 2 */ 15565 /* WRITE DMA*/ 15566 /* In case that we can't fit the transfer length, we loop */ 15567 SM_DBG5(("smsatWriteAndVerify12: case 2\n")); 15568 fis->h.fisType = 0x27; /* Reg host to device */ 15569 fis->h.c_pmPort = 0x80; /* C bit is set */ 15570 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 15571 fis->h.features = 0; /* FIS reserve */ 15572 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15573 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15574 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15575 15576 /* FIS LBA mode set LBA (27:24) */ 15577 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 15578 15579 fis->d.lbaLowExp = 0; 15580 fis->d.lbaMidExp = 0; 15581 fis->d.lbaHighExp = 0; 15582 fis->d.featuresExp = 0; 15583 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 15584 fis->d.sectorCountExp = 0; 15585 fis->d.reserved4 = 0; 15586 fis->d.control = 0; /* FIS HOB bit clear */ 15587 fis->d.reserved5 = 0; 15588 15589 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 15590 satIOContext->ATACmd = SAT_WRITE_DMA; 15591 } 15592 else 15593 { 15594 /* case 1 */ 15595 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 15596 /* WRITE SECTORS for easier implemetation */ 15597 /* In case that we can't fit the transfer length, we loop */ 15598 SM_DBG5(("smsatWriteAndVerify12: case 1\n")); 15599 fis->h.fisType = 0x27; /* Reg host to device */ 15600 fis->h.c_pmPort = 0x80; /* C bit is set */ 15601 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 15602 fis->h.features = 0; /* FIS reserve */ 15603 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15604 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15605 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15606 15607 /* FIS LBA mode set LBA (27:24) */ 15608 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 15609 15610 fis->d.lbaLowExp = 0; 15611 fis->d.lbaMidExp = 0; 15612 fis->d.lbaHighExp = 0; 15613 fis->d.featuresExp = 0; 15614 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 15615 fis->d.sectorCountExp = 0; 15616 fis->d.reserved4 = 0; 15617 fis->d.control = 0; /* FIS HOB bit clear */ 15618 fis->d.reserved5 = 0; 15619 15620 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 15621 satIOContext->ATACmd = SAT_WRITE_SECTORS; 15622 } 15623 15624 /* case 3 and 4 */ 15625 if (pSatDevData->sat48BitSupport == agTRUE) 15626 { 15627 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 15628 { 15629 /* case 3 */ 15630 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 15631 SM_DBG5(("smsatWriteAndVerify12: case 3\n")); 15632 fis->h.fisType = 0x27; /* Reg host to device */ 15633 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15634 15635 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 15636 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 15637 15638 fis->h.features = 0; /* FIS reserve */ 15639 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15640 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15641 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15642 fis->d.device = 0x40; /* FIS LBA mode set */ 15643 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 15644 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 15645 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 15646 fis->d.featuresExp = 0; /* FIS reserve */ 15647 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 15648 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 15649 fis->d.reserved4 = 0; 15650 fis->d.control = 0; /* FIS HOB bit clear */ 15651 fis->d.reserved5 = 0; 15652 15653 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 15654 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 15655 } 15656 else 15657 { 15658 /* case 4 */ 15659 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 15660 /* WRITE SECTORS EXT for easier implemetation */ 15661 SM_DBG5(("smsatWriteAndVerify12: case 4\n")); 15662 fis->h.fisType = 0x27; /* Reg host to device */ 15663 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15664 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 15665 15666 fis->h.features = 0; /* FIS reserve */ 15667 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15668 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15669 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15670 fis->d.device = 0x40; /* FIS LBA mode set */ 15671 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 15672 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 15673 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 15674 fis->d.featuresExp = 0; /* FIS reserve */ 15675 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 15676 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 15677 fis->d.reserved4 = 0; 15678 fis->d.control = 0; /* FIS HOB bit clear */ 15679 fis->d.reserved5 = 0; 15680 15681 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 15682 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 15683 } 15684 } 15685 15686 /* case 5 */ 15687 if (pSatDevData->satNCQ == agTRUE) 15688 { 15689 /* WRITE FPDMA QUEUED */ 15690 if (pSatDevData->sat48BitSupport != agTRUE) 15691 { 15692 SM_DBG1(("smsatWriteAndVerify12: case 5 !!! error NCQ but 28 bit address support!!!\n")); 15693 smsatSetSensePayload( pSense, 15694 SCSI_SNSKEY_ILLEGAL_REQUEST, 15695 0, 15696 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15697 satIOContext); 15698 15699 /*smEnqueueIO(smRoot, satIOContext);*/ 15700 15701 tdsmIOCompletedCB( smRoot, 15702 smIORequest, 15703 smIOSuccess, 15704 SCSI_STAT_CHECK_CONDITION, 15705 satIOContext->pSmSenseData, 15706 satIOContext->interruptContext ); 15707 return SM_RC_SUCCESS; 15708 } 15709 SM_DBG6(("smsatWriteAndVerify12: case 5\n")); 15710 15711 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 15712 15713 fis->h.fisType = 0x27; /* Reg host to device */ 15714 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15715 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 15716 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 15717 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15718 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15719 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15720 15721 /* Check FUA bit */ 15722 if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK) 15723 fis->d.device = 0xC0; /* FIS FUA set */ 15724 else 15725 fis->d.device = 0x40; /* FIS FUA clear */ 15726 15727 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 15728 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 15729 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 15730 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 15731 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 15732 fis->d.sectorCountExp = 0; 15733 fis->d.reserved4 = 0; 15734 fis->d.control = 0; /* FIS HOB bit clear */ 15735 fis->d.reserved5 = 0; 15736 15737 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 15738 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 15739 } 15740 15741 satIOContext->currentLBA = lba; 15742 // satIOContext->OrgLBA = lba; 15743 satIOContext->OrgTL = tl; 15744 15745 /* 15746 computing number of loop and remainder for tl 15747 0xFF in case not ext 15748 0xFFFF in case EXT 15749 */ 15750 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 15751 { 15752 LoopNum = smsatComputeLoopNum(tl, 0xFF); 15753 } 15754 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 15755 fis->h.command == SAT_WRITE_DMA_EXT || 15756 fis->h.command == SAT_WRITE_DMA_FUA_EXT 15757 ) 15758 { 15759 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 15760 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 15761 } 15762 else 15763 { 15764 /* SAT_WRITE_FPDMA_QUEUEDK */ 15765 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 15766 } 15767 15768 satIOContext->LoopNum = LoopNum; 15769 satIOContext->LoopNum2 = LoopNum; 15770 15771 15772 if (LoopNum == 1) 15773 { 15774 SM_DBG5(("smsatWriteAndVerify12: NON CHAINED data\n")); 15775 /* Initialize CB for SATA completion. 15776 */ 15777 satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB; 15778 } 15779 else 15780 { 15781 SM_DBG1(("smsatWriteAndVerify12: CHAINED data!!!\n")); 15782 /* re-setting tl */ 15783 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 15784 { 15785 fis->d.sectorCount = 0xFF; 15786 } 15787 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 15788 fis->h.command == SAT_WRITE_DMA_EXT || 15789 fis->h.command == SAT_WRITE_DMA_FUA_EXT 15790 ) 15791 { 15792 fis->d.sectorCount = 0xFF; 15793 fis->d.sectorCountExp = 0xFF; 15794 } 15795 else 15796 { 15797 /* SAT_WRITE_FPDMA_QUEUED */ 15798 fis->h.features = 0xFF; 15799 fis->d.featuresExp = 0xFF; 15800 } 15801 15802 /* Initialize CB for SATA completion. 15803 */ 15804 satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB; 15805 } 15806 15807 15808 /* 15809 * Prepare SGL and send FIS to LL layer. 15810 */ 15811 satIOContext->reqType = agRequestType; /* Save it */ 15812 15813 status = smsataLLIOStart( smRoot, 15814 smIORequest, 15815 smDeviceHandle, 15816 smScsiRequest, 15817 satIOContext); 15818 return (status); 15819 } 15820 15821 osGLOBAL bit32 15822 smsatWriteAndVerify16( 15823 smRoot_t *smRoot, 15824 smIORequest_t *smIORequest, 15825 smDeviceHandle_t *smDeviceHandle, 15826 smScsiInitiatorRequest_t *smScsiRequest, 15827 smSatIOContext_t *satIOContext 15828 ) 15829 { 15830 /* 15831 combination of write16 and verify16 15832 since write16 has 8 bytes LBA -> problem ATA LBA(upto 6 bytes), no support 15833 */ 15834 bit32 status; 15835 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 15836 smDeviceData_t *pSatDevData; 15837 smScsiRspSense_t *pSense; 15838 smIniScsiCmnd_t *scsiCmnd; 15839 agsaFisRegHostToDevice_t *fis; 15840 bit32 lba = 0; 15841 bit32 tl = 0; 15842 bit32 LoopNum = 1; 15843 bit8 LBA[8]; 15844 bit8 TL[8]; 15845 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 15846 15847 pSense = satIOContext->pSense; 15848 pSatDevData = satIOContext->pSatDevData; 15849 scsiCmnd = &smScsiRequest->scsiCmnd; 15850 fis = satIOContext->pFis; 15851 15852 SM_DBG5(("smsatWriteAndVerify16: start\n")); 15853 15854 /* checking BYTCHK bit */ 15855 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK) 15856 { 15857 smsatSetSensePayload( pSense, 15858 SCSI_SNSKEY_ILLEGAL_REQUEST, 15859 0, 15860 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15861 satIOContext); 15862 15863 /*smEnqueueIO(smRoot, satIOContext);*/ 15864 15865 tdsmIOCompletedCB( smRoot, 15866 smIORequest, 15867 smIOSuccess, 15868 SCSI_STAT_CHECK_CONDITION, 15869 satIOContext->pSmSenseData, 15870 satIOContext->interruptContext ); 15871 15872 SM_DBG1(("smsatWriteAndVerify16: BYTCHK bit checking!!!\n")); 15873 return SM_RC_SUCCESS; 15874 } 15875 15876 15877 /* checking CONTROL */ 15878 /* NACA == 1 or LINK == 1*/ 15879 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 15880 { 15881 smsatSetSensePayload( pSense, 15882 SCSI_SNSKEY_ILLEGAL_REQUEST, 15883 0, 15884 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15885 satIOContext); 15886 15887 /*smEnqueueIO(smRoot, satIOContext);*/ 15888 15889 tdsmIOCompletedCB( smRoot, 15890 smIORequest, 15891 smIOSuccess, 15892 SCSI_STAT_CHECK_CONDITION, 15893 satIOContext->pSmSenseData, 15894 satIOContext->interruptContext ); 15895 15896 SM_DBG1(("smsatWriteAndVerify16: return control!!!\n")); 15897 return SM_RC_SUCCESS; 15898 } 15899 15900 sm_memset(LBA, 0, sizeof(LBA)); 15901 sm_memset(TL, 0, sizeof(TL)); 15902 15903 15904 /* do not use memcpy due to indexing in LBA and TL */ 15905 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 15906 LBA[1] = scsiCmnd->cdb[3]; 15907 LBA[2] = scsiCmnd->cdb[4]; 15908 LBA[3] = scsiCmnd->cdb[5]; 15909 LBA[4] = scsiCmnd->cdb[6]; 15910 LBA[5] = scsiCmnd->cdb[7]; 15911 LBA[6] = scsiCmnd->cdb[8]; 15912 LBA[7] = scsiCmnd->cdb[9]; /* LSB */ 15913 15914 TL[0] = 0; 15915 TL[1] = 0; 15916 TL[2] = 0; 15917 TL[3] = 0; 15918 TL[4] = scsiCmnd->cdb[10]; /* MSB */ 15919 TL[5] = scsiCmnd->cdb[11]; 15920 TL[6] = scsiCmnd->cdb[12]; 15921 TL[7] = scsiCmnd->cdb[13]; /* LSB */ 15922 15923 15924 15925 lba = smsatComputeCDB16LBA(satIOContext); 15926 tl = smsatComputeCDB16TL(satIOContext); 15927 15928 15929 /* Table 34, 9.1, p 46 */ 15930 /* 15931 note: As of 2/10/2006, no support for DMA QUEUED 15932 */ 15933 15934 /* 15935 Table 34, 9.1, p 46, b 15936 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 15937 return check condition 15938 */ 15939 if (pSatDevData->satNCQ != agTRUE && 15940 pSatDevData->sat48BitSupport != agTRUE 15941 ) 15942 { 15943 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 15944 if (AllChk) 15945 { 15946 SM_DBG1(("smsatWriteAndVerify16: return LBA out of range, not EXT!!!\n")); 15947 smsatSetSensePayload( pSense, 15948 SCSI_SNSKEY_ILLEGAL_REQUEST, 15949 0, 15950 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 15951 satIOContext); 15952 15953 /*smEnqueueIO(smRoot, satIOContext);*/ 15954 15955 tdsmIOCompletedCB( smRoot, 15956 smIORequest, 15957 smIOSuccess, 15958 SCSI_STAT_CHECK_CONDITION, 15959 satIOContext->pSmSenseData, 15960 satIOContext->interruptContext ); 15961 15962 return SM_RC_SUCCESS; 15963 } 15964 } 15965 else 15966 { 15967 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 15968 if (AllChk) 15969 { 15970 SM_DBG1(("smsatWriteAndVerify16: return LBA out of range, EXT!!!\n")); 15971 smsatSetSensePayload( pSense, 15972 SCSI_SNSKEY_ILLEGAL_REQUEST, 15973 0, 15974 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 15975 satIOContext); 15976 15977 /*smEnqueueIO(smRoot, satIOContext);*/ 15978 15979 tdsmIOCompletedCB( smRoot, 15980 smIORequest, 15981 smIOSuccess, 15982 SCSI_STAT_CHECK_CONDITION, 15983 satIOContext->pSmSenseData, 15984 satIOContext->interruptContext ); 15985 15986 return SM_RC_SUCCESS; 15987 } 15988 } 15989 15990 15991 /* case 1 and 2 */ 15992 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 15993 { 15994 /* case 2 */ 15995 /* WRITE DMA*/ 15996 /* In case that we can't fit the transfer length, we loop */ 15997 SM_DBG5(("smsatWriteAndVerify16: case 2\n")); 15998 fis->h.fisType = 0x27; /* Reg host to device */ 15999 fis->h.c_pmPort = 0x80; /* C bit is set */ 16000 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 16001 fis->h.features = 0; /* FIS reserve */ 16002 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 16003 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 16004 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 16005 16006 /* FIS LBA mode set LBA (27:24) */ 16007 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); 16008 16009 fis->d.lbaLowExp = 0; 16010 fis->d.lbaMidExp = 0; 16011 fis->d.lbaHighExp = 0; 16012 fis->d.featuresExp = 0; 16013 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 16014 fis->d.sectorCountExp = 0; 16015 fis->d.reserved4 = 0; 16016 fis->d.control = 0; /* FIS HOB bit clear */ 16017 fis->d.reserved5 = 0; 16018 16019 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 16020 satIOContext->ATACmd = SAT_WRITE_DMA; 16021 } 16022 else 16023 { 16024 /* case 1 */ 16025 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 16026 /* WRITE SECTORS for easier implemetation */ 16027 /* In case that we can't fit the transfer length, we loop */ 16028 SM_DBG5(("smsatWriteAndVerify16: case 1\n")); 16029 fis->h.fisType = 0x27; /* Reg host to device */ 16030 fis->h.c_pmPort = 0x80; /* C bit is set */ 16031 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 16032 fis->h.features = 0; /* FIS reserve */ 16033 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 16034 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 16035 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 16036 16037 /* FIS LBA mode set LBA (27:24) */ 16038 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); 16039 16040 fis->d.lbaLowExp = 0; 16041 fis->d.lbaMidExp = 0; 16042 fis->d.lbaHighExp = 0; 16043 fis->d.featuresExp = 0; 16044 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 16045 fis->d.sectorCountExp = 0; 16046 fis->d.reserved4 = 0; 16047 fis->d.control = 0; /* FIS HOB bit clear */ 16048 fis->d.reserved5 = 0; 16049 16050 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 16051 satIOContext->ATACmd = SAT_WRITE_SECTORS; 16052 } 16053 16054 /* case 3 and 4 */ 16055 if (pSatDevData->sat48BitSupport == agTRUE) 16056 { 16057 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 16058 { 16059 /* case 3 */ 16060 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 16061 SM_DBG5(("smsatWriteAndVerify16: case 3\n")); 16062 fis->h.fisType = 0x27; /* Reg host to device */ 16063 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16064 16065 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 16066 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 16067 16068 fis->h.features = 0; /* FIS reserve */ 16069 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 16070 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 16071 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 16072 fis->d.device = 0x40; /* FIS LBA mode set */ 16073 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 16074 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 16075 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 16076 fis->d.featuresExp = 0; /* FIS reserve */ 16077 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 16078 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 16079 fis->d.reserved4 = 0; 16080 fis->d.control = 0; /* FIS HOB bit clear */ 16081 fis->d.reserved5 = 0; 16082 16083 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 16084 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 16085 } 16086 else 16087 { 16088 /* case 4 */ 16089 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 16090 /* WRITE SECTORS EXT for easier implemetation */ 16091 SM_DBG5(("smsatWriteAndVerify16: case 4\n")); 16092 fis->h.fisType = 0x27; /* Reg host to device */ 16093 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16094 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 16095 16096 fis->h.features = 0; /* FIS reserve */ 16097 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 16098 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 16099 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 16100 fis->d.device = 0x40; /* FIS LBA mode set */ 16101 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 16102 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 16103 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 16104 fis->d.featuresExp = 0; /* FIS reserve */ 16105 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 16106 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 16107 fis->d.reserved4 = 0; 16108 fis->d.control = 0; /* FIS HOB bit clear */ 16109 fis->d.reserved5 = 0; 16110 16111 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 16112 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 16113 } 16114 } 16115 16116 /* case 5 */ 16117 if (pSatDevData->satNCQ == agTRUE) 16118 { 16119 /* WRITE FPDMA QUEUED */ 16120 if (pSatDevData->sat48BitSupport != agTRUE) 16121 { 16122 SM_DBG1(("smsatWriteAndVerify16: case 5 !!! error NCQ but 28 bit address support!!!\n")); 16123 smsatSetSensePayload( pSense, 16124 SCSI_SNSKEY_ILLEGAL_REQUEST, 16125 0, 16126 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16127 satIOContext); 16128 16129 /*smEnqueueIO(smRoot, satIOContext);*/ 16130 16131 tdsmIOCompletedCB( smRoot, 16132 smIORequest, 16133 smIOSuccess, 16134 SCSI_STAT_CHECK_CONDITION, 16135 satIOContext->pSmSenseData, 16136 satIOContext->interruptContext ); 16137 return SM_RC_SUCCESS; 16138 } 16139 SM_DBG6(("smsatWriteAndVerify16: case 5\n")); 16140 16141 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 16142 16143 fis->h.fisType = 0x27; /* Reg host to device */ 16144 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16145 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 16146 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 16147 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 16148 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 16149 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 16150 16151 /* Check FUA bit */ 16152 if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK) 16153 fis->d.device = 0xC0; /* FIS FUA set */ 16154 else 16155 fis->d.device = 0x40; /* FIS FUA clear */ 16156 16157 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 16158 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 16159 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 16160 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 16161 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 16162 fis->d.sectorCountExp = 0; 16163 fis->d.reserved4 = 0; 16164 fis->d.control = 0; /* FIS HOB bit clear */ 16165 fis->d.reserved5 = 0; 16166 16167 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 16168 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 16169 } 16170 16171 satIOContext->currentLBA = lba; 16172 satIOContext->OrgTL = tl; 16173 16174 /* 16175 computing number of loop and remainder for tl 16176 0xFF in case not ext 16177 0xFFFF in case EXT 16178 */ 16179 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 16180 { 16181 LoopNum = smsatComputeLoopNum(tl, 0xFF); 16182 } 16183 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 16184 fis->h.command == SAT_WRITE_DMA_EXT || 16185 fis->h.command == SAT_WRITE_DMA_FUA_EXT 16186 ) 16187 { 16188 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 16189 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 16190 } 16191 else 16192 { 16193 /* SAT_WRITE_FPDMA_QUEUEDK */ 16194 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 16195 } 16196 16197 satIOContext->LoopNum = LoopNum; 16198 16199 16200 if (LoopNum == 1) 16201 { 16202 SM_DBG5(("smsatWriteAndVerify16: NON CHAINED data\n")); 16203 /* Initialize CB for SATA completion. 16204 */ 16205 satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB; 16206 } 16207 else 16208 { 16209 SM_DBG1(("smsatWriteAndVerify16: CHAINED data!!!\n")); 16210 /* re-setting tl */ 16211 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 16212 { 16213 fis->d.sectorCount = 0xFF; 16214 } 16215 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 16216 fis->h.command == SAT_WRITE_DMA_EXT || 16217 fis->h.command == SAT_WRITE_DMA_FUA_EXT 16218 ) 16219 { 16220 fis->d.sectorCount = 0xFF; 16221 fis->d.sectorCountExp = 0xFF; 16222 } 16223 else 16224 { 16225 /* SAT_WRITE_FPDMA_QUEUED */ 16226 fis->h.features = 0xFF; 16227 fis->d.featuresExp = 0xFF; 16228 } 16229 16230 /* Initialize CB for SATA completion. 16231 */ 16232 satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB; 16233 } 16234 16235 16236 /* 16237 * Prepare SGL and send FIS to LL layer. 16238 */ 16239 satIOContext->reqType = agRequestType; /* Save it */ 16240 16241 status = smsataLLIOStart( smRoot, 16242 smIORequest, 16243 smDeviceHandle, 16244 smScsiRequest, 16245 satIOContext); 16246 return (status); 16247 } 16248 16249 osGLOBAL bit32 16250 smsatReadMediaSerialNumber( 16251 smRoot_t *smRoot, 16252 smIORequest_t *smIORequest, 16253 smDeviceHandle_t *smDeviceHandle, 16254 smScsiInitiatorRequest_t *smScsiRequest, 16255 smSatIOContext_t *satIOContext 16256 ) 16257 { 16258 bit32 status; 16259 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 16260 smDeviceData_t *pSatDevData; 16261 smScsiRspSense_t *pSense; 16262 smIniScsiCmnd_t *scsiCmnd; 16263 agsaFisRegHostToDevice_t *fis; 16264 agsaSATAIdentifyData_t *pSATAIdData; 16265 bit8 *pSerialNumber; 16266 bit8 MediaSerialNumber[64] = {0}; 16267 bit32 allocationLen = 0; 16268 16269 pSense = satIOContext->pSense; 16270 pSatDevData = satIOContext->pSatDevData; 16271 scsiCmnd = &smScsiRequest->scsiCmnd; 16272 fis = satIOContext->pFis; 16273 pSATAIdData = &(pSatDevData->satIdentifyData); 16274 pSerialNumber = (bit8 *) smScsiRequest->sglVirtualAddr; 16275 16276 SM_DBG5(("smsatReadMediaSerialNumber: start\n")); 16277 16278 /* checking CONTROL */ 16279 /* NACA == 1 or LINK == 1*/ 16280 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) ) 16281 { 16282 smsatSetSensePayload( pSense, 16283 SCSI_SNSKEY_ILLEGAL_REQUEST, 16284 0, 16285 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16286 satIOContext); 16287 16288 /*smEnqueueIO(smRoot, satIOContext);*/ 16289 16290 tdsmIOCompletedCB( smRoot, 16291 smIORequest, 16292 smIOSuccess, 16293 SCSI_STAT_CHECK_CONDITION, 16294 satIOContext->pSmSenseData, 16295 satIOContext->interruptContext ); 16296 16297 SM_DBG1(("smsatReadMediaSerialNumber: return control!!!\n")); 16298 return SM_RC_SUCCESS; 16299 } 16300 16301 allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) | 16302 (((bit32)scsiCmnd->cdb[7]) << 16) | 16303 (((bit32)scsiCmnd->cdb[8]) << 8 ) | 16304 (((bit32)scsiCmnd->cdb[9])); 16305 allocationLen = MIN(allocationLen, scsiCmnd->expDataLength); 16306 if (allocationLen == 4) 16307 { 16308 if (pSATAIdData->commandSetFeatureDefault & 0x4) 16309 { 16310 SM_DBG1(("smsatReadMediaSerialNumber: Media serial number returning only length!!!\n")); 16311 /* SPC-3 6.16 p192; filling in length */ 16312 MediaSerialNumber[0] = 0; 16313 MediaSerialNumber[1] = 0; 16314 MediaSerialNumber[2] = 0; 16315 MediaSerialNumber[3] = 0x3C; 16316 } 16317 else 16318 { 16319 /* 1 sector - 4 = 512 - 4 to avoid underflow; 0x1fc*/ 16320 MediaSerialNumber[0] = 0; 16321 MediaSerialNumber[1] = 0; 16322 MediaSerialNumber[2] = 0x1; 16323 MediaSerialNumber[3] = 0xfc; 16324 } 16325 16326 sm_memcpy(pSerialNumber, MediaSerialNumber, 4); 16327 /*smEnqueueIO(smRoot, satIOContext);*/ 16328 16329 tdsmIOCompletedCB( smRoot, 16330 smIORequest, 16331 smIOSuccess, 16332 SCSI_STAT_GOOD, 16333 agNULL, 16334 satIOContext->interruptContext); 16335 16336 return SM_RC_SUCCESS; 16337 } 16338 16339 if ( pSatDevData->IDDeviceValid == agTRUE) 16340 { 16341 if (pSATAIdData->commandSetFeatureDefault & 0x4) 16342 { 16343 /* word87 bit2 Media serial number is valid */ 16344 /* read word 176 to 205; length is 2*30 = 60 = 0x3C*/ 16345 #ifdef LOG_ENABLE 16346 smhexdump("ID smsatReadMediaSerialNumber", (bit8*)pSATAIdData->currentMediaSerialNumber, 2*30); 16347 #endif 16348 /* SPC-3 6.16 p192; filling in length */ 16349 MediaSerialNumber[0] = 0; 16350 MediaSerialNumber[1] = 0; 16351 MediaSerialNumber[2] = 0; 16352 MediaSerialNumber[3] = 0x3C; 16353 sm_memcpy(&MediaSerialNumber[4], (void *)pSATAIdData->currentMediaSerialNumber, 60); 16354 #ifdef LOG_ENABLE 16355 smhexdump("smsatReadMediaSerialNumber", (bit8*)MediaSerialNumber, 2*30 + 4); 16356 #endif 16357 sm_memcpy(pSerialNumber, MediaSerialNumber, MIN(allocationLen, 64)); 16358 /*smEnqueueIO(smRoot, satIOContext);*/ 16359 16360 tdsmIOCompletedCB( smRoot, 16361 smIORequest, 16362 smIOSuccess, 16363 SCSI_STAT_GOOD, 16364 agNULL, 16365 satIOContext->interruptContext); 16366 return SM_RC_SUCCESS; 16367 16368 16369 } 16370 else 16371 { 16372 /* word87 bit2 Media serial number is NOT valid */ 16373 SM_DBG1(("smsatReadMediaSerialNumber: Media serial number is NOT valid!!!\n")); 16374 16375 if (pSatDevData->sat48BitSupport == agTRUE) 16376 { 16377 /* READ VERIFY SECTORS EXT */ 16378 fis->h.fisType = 0x27; /* Reg host to device */ 16379 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16380 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 16381 16382 fis->h.features = 0; /* FIS reserve */ 16383 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 16384 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 16385 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 16386 fis->d.device = 0x40; /* FIS LBA mode set */ 16387 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 16388 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 16389 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 16390 fis->d.featuresExp = 0; /* FIS reserve */ 16391 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 16392 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 16393 fis->d.reserved4 = 0; 16394 fis->d.control = 0; /* FIS HOB bit clear */ 16395 fis->d.reserved5 = 0; 16396 16397 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 16398 } 16399 else 16400 { 16401 /* READ VERIFY SECTORS */ 16402 fis->h.fisType = 0x27; /* Reg host to device */ 16403 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16404 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 16405 fis->h.features = 0; /* FIS reserve */ 16406 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 16407 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 16408 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 16409 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */ 16410 fis->d.lbaLowExp = 0; 16411 fis->d.lbaMidExp = 0; 16412 fis->d.lbaHighExp = 0; 16413 fis->d.featuresExp = 0; 16414 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 16415 fis->d.sectorCountExp = 0; 16416 fis->d.reserved4 = 0; 16417 fis->d.control = 0; /* FIS HOB bit clear */ 16418 fis->d.reserved5 = 0; 16419 16420 16421 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 16422 } 16423 satIOContext->satCompleteCB = &smsatReadMediaSerialNumberCB; 16424 satIOContext->reqType = agRequestType; /* Save it */ 16425 status = smsataLLIOStart( smRoot, 16426 smIORequest, 16427 smDeviceHandle, 16428 smScsiRequest, 16429 satIOContext); 16430 16431 return status; 16432 } 16433 } 16434 else 16435 { 16436 16437 tdsmIOCompletedCB( smRoot, 16438 smIORequest, 16439 smIOFailed, 16440 smDetailOtherError, 16441 agNULL, 16442 satIOContext->interruptContext); 16443 16444 return SM_RC_SUCCESS; 16445 16446 } 16447 } 16448 16449 osGLOBAL bit32 16450 smsatReadBuffer( 16451 smRoot_t *smRoot, 16452 smIORequest_t *smIORequest, 16453 smDeviceHandle_t *smDeviceHandle, 16454 smScsiInitiatorRequest_t *smScsiRequest, 16455 smSatIOContext_t *satIOContext 16456 ) 16457 { 16458 bit32 status = SM_RC_SUCCESS; 16459 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 16460 smScsiRspSense_t *pSense; 16461 smIniScsiCmnd_t *scsiCmnd; 16462 agsaFisRegHostToDevice_t *fis; 16463 bit32 bufferOffset; 16464 bit32 tl; 16465 bit8 mode; 16466 bit8 bufferID; 16467 bit8 *pBuff; 16468 16469 pSense = satIOContext->pSense; 16470 scsiCmnd = &smScsiRequest->scsiCmnd; 16471 fis = satIOContext->pFis; 16472 pBuff = (bit8 *) smScsiRequest->sglVirtualAddr; 16473 16474 SM_DBG5(("smsatReadBuffer: start\n")); 16475 16476 /* checking CONTROL */ 16477 /* NACA == 1 or LINK == 1*/ 16478 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 16479 { 16480 smsatSetSensePayload( pSense, 16481 SCSI_SNSKEY_ILLEGAL_REQUEST, 16482 0, 16483 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16484 satIOContext); 16485 16486 /*smEnqueueIO(smRoot, satIOContext);*/ 16487 16488 tdsmIOCompletedCB( smRoot, 16489 smIORequest, 16490 smIOSuccess, 16491 SCSI_STAT_CHECK_CONDITION, 16492 satIOContext->pSmSenseData, 16493 satIOContext->interruptContext ); 16494 16495 SM_DBG1(("smsatReadBuffer: return control!!!\n")); 16496 return SM_RC_SUCCESS; 16497 } 16498 16499 bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 16500 tl = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 16501 16502 mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK); 16503 bufferID = scsiCmnd->cdb[2]; 16504 16505 if (mode == READ_BUFFER_DATA_MODE) /* 2 */ 16506 { 16507 if (bufferID == 0 && bufferOffset == 0 && tl == 512) 16508 { 16509 /* send ATA READ BUFFER */ 16510 fis->h.fisType = 0x27; /* Reg host to device */ 16511 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16512 fis->h.command = SAT_READ_BUFFER; /* 0xE4 */ 16513 fis->h.features = 0; /* FIS reserve */ 16514 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 16515 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 16516 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 16517 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */ 16518 fis->d.lbaLowExp = 0; 16519 fis->d.lbaMidExp = 0; 16520 fis->d.lbaHighExp = 0; 16521 fis->d.featuresExp = 0; 16522 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 16523 fis->d.sectorCountExp = 0; 16524 fis->d.reserved4 = 0; 16525 fis->d.control = 0; /* FIS HOB bit clear */ 16526 fis->d.reserved5 = 0; 16527 16528 16529 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 16530 16531 satIOContext->satCompleteCB = &smsatReadBufferCB; 16532 16533 satIOContext->reqType = agRequestType; /* Save it */ 16534 16535 status = smsataLLIOStart( smRoot, 16536 smIORequest, 16537 smDeviceHandle, 16538 smScsiRequest, 16539 satIOContext); 16540 return status; 16541 } 16542 16543 if (bufferID == 0 && bufferOffset == 0 && tl != 512) 16544 { 16545 smsatSetSensePayload( pSense, 16546 SCSI_SNSKEY_ILLEGAL_REQUEST, 16547 0, 16548 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16549 satIOContext); 16550 16551 /*smEnqueueIO(smRoot, satIOContext);*/ 16552 16553 tdsmIOCompletedCB( smRoot, 16554 smIORequest, 16555 smIOSuccess, 16556 SCSI_STAT_CHECK_CONDITION, 16557 satIOContext->pSmSenseData, 16558 satIOContext->interruptContext ); 16559 16560 SM_DBG1(("smsatReadBuffer: allocation length is not 512; it is %d!!!\n", tl)); 16561 return SM_RC_SUCCESS; 16562 } 16563 16564 if (bufferID == 0 && bufferOffset != 0) 16565 { 16566 smsatSetSensePayload( pSense, 16567 SCSI_SNSKEY_ILLEGAL_REQUEST, 16568 0, 16569 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16570 satIOContext); 16571 16572 /*smEnqueueIO(smRoot, satIOContext);*/ 16573 16574 tdsmIOCompletedCB( smRoot, 16575 smIORequest, 16576 smIOSuccess, 16577 SCSI_STAT_CHECK_CONDITION, 16578 satIOContext->pSmSenseData, 16579 satIOContext->interruptContext ); 16580 16581 SM_DBG1(("smsatReadBuffer: buffer offset is not 0; it is %d!!!\n", bufferOffset)); 16582 return SM_RC_SUCCESS; 16583 } 16584 /* all other cases unsupported */ 16585 SM_DBG1(("smsatReadBuffer: unsupported case 1!!!\n")); 16586 smsatSetSensePayload( pSense, 16587 SCSI_SNSKEY_ILLEGAL_REQUEST, 16588 0, 16589 SCSI_SNSCODE_INVALID_COMMAND, 16590 satIOContext); 16591 16592 /*smEnqueueIO(smRoot, satIOContext);*/ 16593 16594 tdsmIOCompletedCB( smRoot, 16595 smIORequest, 16596 smIOSuccess, 16597 SCSI_STAT_CHECK_CONDITION, 16598 satIOContext->pSmSenseData, 16599 satIOContext->interruptContext ); 16600 16601 return SM_RC_SUCCESS; 16602 16603 } 16604 else if (mode == READ_BUFFER_DESCRIPTOR_MODE) /* 3 */ 16605 { 16606 if (tl < READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN) /* 4 */ 16607 { 16608 smsatSetSensePayload( pSense, 16609 SCSI_SNSKEY_ILLEGAL_REQUEST, 16610 0, 16611 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16612 satIOContext); 16613 16614 /*smEnqueueIO(smRoot, satIOContext);*/ 16615 16616 tdsmIOCompletedCB( smRoot, 16617 smIORequest, 16618 smIOSuccess, 16619 SCSI_STAT_CHECK_CONDITION, 16620 satIOContext->pSmSenseData, 16621 satIOContext->interruptContext ); 16622 16623 SM_DBG1(("smsatReadBuffer: tl < 4; tl is %d!!!\n", tl)); 16624 return SM_RC_SUCCESS; 16625 } 16626 if (bufferID == 0) 16627 { 16628 /* SPC-4, 6.15.5, p189; SAT-2 Rev00, 8.7.2.3, p41*/ 16629 pBuff[0] = 0xFF; 16630 pBuff[1] = 0x00; 16631 pBuff[2] = 0x02; 16632 pBuff[3] = 0x00; 16633 if (READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN < tl) 16634 { 16635 /* underrrun */ 16636 SM_DBG1(("smsatReadBuffer: underrun tl %d data %d!!!\n", tl, READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN)); 16637 /*smEnqueueIO(smRoot, satIOContext);*/ 16638 16639 tdsmIOCompletedCB( smRoot, 16640 smIORequest, 16641 smIOUnderRun, 16642 tl - READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN, 16643 agNULL, 16644 satIOContext->interruptContext ); 16645 16646 return SM_RC_SUCCESS; 16647 } 16648 else 16649 { 16650 /*smEnqueueIO(smRoot, satIOContext);*/ 16651 16652 tdsmIOCompletedCB( smRoot, 16653 smIORequest, 16654 smIOSuccess, 16655 SCSI_STAT_GOOD, 16656 agNULL, 16657 satIOContext->interruptContext); 16658 return SM_RC_SUCCESS; 16659 } 16660 } 16661 else 16662 { 16663 /* We don't support other than bufferID 0 */ 16664 smsatSetSensePayload( pSense, 16665 SCSI_SNSKEY_ILLEGAL_REQUEST, 16666 0, 16667 SCSI_SNSCODE_INVALID_COMMAND, 16668 satIOContext); 16669 16670 /*smEnqueueIO(smRoot, satIOContext);*/ 16671 16672 tdsmIOCompletedCB( smRoot, 16673 smIORequest, 16674 smIOSuccess, 16675 SCSI_STAT_CHECK_CONDITION, 16676 satIOContext->pSmSenseData, 16677 satIOContext->interruptContext ); 16678 16679 return SM_RC_SUCCESS; 16680 } 16681 } 16682 else 16683 { 16684 /* We don't support any other mode */ 16685 SM_DBG1(("smsatReadBuffer: unsupported mode %d!!!\n", mode)); 16686 smsatSetSensePayload( pSense, 16687 SCSI_SNSKEY_ILLEGAL_REQUEST, 16688 0, 16689 SCSI_SNSCODE_INVALID_COMMAND, 16690 satIOContext); 16691 16692 /*smEnqueueIO(smRoot, satIOContext);*/ 16693 16694 tdsmIOCompletedCB( smRoot, 16695 smIORequest, 16696 smIOSuccess, 16697 SCSI_STAT_CHECK_CONDITION, 16698 satIOContext->pSmSenseData, 16699 satIOContext->interruptContext ); 16700 16701 return SM_RC_SUCCESS; 16702 } 16703 } 16704 16705 osGLOBAL bit32 16706 smsatWriteBuffer( 16707 smRoot_t *smRoot, 16708 smIORequest_t *smIORequest, 16709 smDeviceHandle_t *smDeviceHandle, 16710 smScsiInitiatorRequest_t *smScsiRequest, 16711 smSatIOContext_t *satIOContext 16712 ) 16713 { 16714 #ifdef NOT_YET 16715 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 16716 #endif 16717 smScsiRspSense_t *pSense; 16718 smIniScsiCmnd_t *scsiCmnd; 16719 #ifdef NOT_YET 16720 agsaFisRegHostToDevice_t *fis; 16721 #endif 16722 bit32 bufferOffset; 16723 bit32 parmLen; 16724 bit8 mode; 16725 bit8 bufferID; 16726 bit8 *pBuff; 16727 16728 pSense = satIOContext->pSense; 16729 scsiCmnd = &smScsiRequest->scsiCmnd; 16730 #ifdef NOT_YET 16731 fis = satIOContext->pFis; 16732 #endif 16733 pBuff = (bit8 *) smScsiRequest->sglVirtualAddr; 16734 16735 SM_DBG5(("smsatWriteBuffer: start\n")); 16736 16737 /* checking CONTROL */ 16738 /* NACA == 1 or LINK == 1*/ 16739 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 16740 { 16741 smsatSetSensePayload( pSense, 16742 SCSI_SNSKEY_ILLEGAL_REQUEST, 16743 0, 16744 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16745 satIOContext); 16746 16747 /*smEnqueueIO(smRoot, satIOContext);*/ 16748 16749 tdsmIOCompletedCB( smRoot, 16750 smIORequest, 16751 smIOSuccess, 16752 SCSI_STAT_CHECK_CONDITION, 16753 satIOContext->pSmSenseData, 16754 satIOContext->interruptContext ); 16755 16756 SM_DBG1(("smsatWriteBuffer: return control!!!\n")); 16757 return SM_RC_SUCCESS; 16758 } 16759 16760 bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 16761 parmLen = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 16762 16763 mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK); 16764 bufferID = scsiCmnd->cdb[2]; 16765 16766 /* for debugging only */ 16767 smhexdump("smsatWriteBuffer pBuff", (bit8 *)pBuff, 24); 16768 16769 if (mode == WRITE_BUFFER_DATA_MODE) /* 2 */ 16770 { 16771 if (bufferID == 0 && bufferOffset == 0 && parmLen == 512) 16772 { 16773 SM_DBG1(("smsatWriteBuffer: sending ATA WRITE BUFFER!!!\n")); 16774 /* send ATA WRITE BUFFER */ 16775 #ifdef NOT_YET 16776 fis->h.fisType = 0x27; /* Reg host to device */ 16777 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16778 fis->h.command = SAT_WRITE_BUFFER; /* 0xE8 */ 16779 fis->h.features = 0; /* FIS reserve */ 16780 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 16781 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 16782 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 16783 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */ 16784 fis->d.lbaLowExp = 0; 16785 fis->d.lbaMidExp = 0; 16786 fis->d.lbaHighExp = 0; 16787 fis->d.featuresExp = 0; 16788 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 16789 fis->d.sectorCountExp = 0; 16790 fis->d.reserved4 = 0; 16791 fis->d.control = 0; /* FIS HOB bit clear */ 16792 fis->d.reserved5 = 0; 16793 16794 16795 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 16796 16797 satIOContext->satCompleteCB = &smsatWriteBufferCB; 16798 16799 satIOContext->reqType = agRequestType; /* Save it */ 16800 16801 status = smsataLLIOStart( smRoot, 16802 smIORequest, 16803 smDeviceHandle, 16804 smScsiRequest, 16805 satIOContext); 16806 return status; 16807 #endif 16808 /* temp */ 16809 /*smEnqueueIO(smRoot, satIOContext);*/ 16810 16811 tdsmIOCompletedCB( smRoot, 16812 smIORequest, 16813 smIOSuccess, 16814 SCSI_STAT_GOOD, 16815 agNULL, 16816 satIOContext->interruptContext); 16817 return SM_RC_SUCCESS; 16818 } 16819 if ( (bufferID == 0 && bufferOffset != 0) || 16820 (bufferID == 0 && parmLen != 512) 16821 ) 16822 { 16823 smsatSetSensePayload( pSense, 16824 SCSI_SNSKEY_ILLEGAL_REQUEST, 16825 0, 16826 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16827 satIOContext); 16828 16829 /*smEnqueueIO(smRoot, satIOContext);*/ 16830 16831 tdsmIOCompletedCB( smRoot, 16832 smIORequest, 16833 smIOSuccess, 16834 SCSI_STAT_CHECK_CONDITION, 16835 satIOContext->pSmSenseData, 16836 satIOContext->interruptContext ); 16837 16838 SM_DBG1(("smsatWriteBuffer: wrong buffer offset %d or parameter length parmLen %d!!!\n", bufferOffset, parmLen)); 16839 return SM_RC_SUCCESS; 16840 } 16841 16842 /* all other cases unsupported */ 16843 SM_DBG1(("smsatWriteBuffer: unsupported case 1!!!\n")); 16844 smsatSetSensePayload( pSense, 16845 SCSI_SNSKEY_ILLEGAL_REQUEST, 16846 0, 16847 SCSI_SNSCODE_INVALID_COMMAND, 16848 satIOContext); 16849 16850 /*smEnqueueIO(smRoot, satIOContext);*/ 16851 16852 tdsmIOCompletedCB( smRoot, 16853 smIORequest, 16854 smIOSuccess, 16855 SCSI_STAT_CHECK_CONDITION, 16856 satIOContext->pSmSenseData, 16857 satIOContext->interruptContext ); 16858 16859 return SM_RC_SUCCESS; 16860 16861 } 16862 else if (mode == WRITE_BUFFER_DL_MICROCODE_SAVE_MODE) /* 5 */ 16863 { 16864 /* temporary */ 16865 SM_DBG1(("smsatWriteBuffer: not yet supported mode %d!!!\n", mode)); 16866 smsatSetSensePayload( pSense, 16867 SCSI_SNSKEY_ILLEGAL_REQUEST, 16868 0, 16869 SCSI_SNSCODE_INVALID_COMMAND, 16870 satIOContext); 16871 16872 16873 tdsmIOCompletedCB( smRoot, 16874 smIORequest, 16875 smIOSuccess, 16876 SCSI_STAT_CHECK_CONDITION, 16877 satIOContext->pSmSenseData, 16878 satIOContext->interruptContext ); 16879 16880 return SM_RC_SUCCESS; 16881 } 16882 else 16883 { 16884 /* We don't support any other mode */ 16885 SM_DBG1(("smsatWriteBuffer: unsupported mode %d!!!\n", mode)); 16886 smsatSetSensePayload( pSense, 16887 SCSI_SNSKEY_ILLEGAL_REQUEST, 16888 0, 16889 SCSI_SNSCODE_INVALID_COMMAND, 16890 satIOContext); 16891 16892 /*smEnqueueIO(smRoot, satIOContext);*/ 16893 16894 tdsmIOCompletedCB( smRoot, 16895 smIORequest, 16896 smIOSuccess, 16897 SCSI_STAT_CHECK_CONDITION, 16898 satIOContext->pSmSenseData, 16899 satIOContext->interruptContext ); 16900 16901 return SM_RC_SUCCESS; 16902 } 16903 16904 } 16905 16906 osGLOBAL bit32 16907 smsatReassignBlocks( 16908 smRoot_t *smRoot, 16909 smIORequest_t *smIORequest, 16910 smDeviceHandle_t *smDeviceHandle, 16911 smScsiInitiatorRequest_t *smScsiRequest, 16912 smSatIOContext_t *satIOContext 16913 ) 16914 { 16915 /* 16916 assumes all LBA fits in ATA command; no boundary condition is checked here yet 16917 */ 16918 bit32 status; 16919 bit32 agRequestType; 16920 smDeviceData_t *pSatDevData; 16921 smScsiRspSense_t *pSense; 16922 smIniScsiCmnd_t *scsiCmnd; 16923 agsaFisRegHostToDevice_t *fis; 16924 bit8 *pParmList; /* Log Page data buffer */ 16925 bit8 LongLBA; 16926 bit8 LongList; 16927 bit32 defectListLen; 16928 bit8 LBA[8]; 16929 bit32 startingIndex; 16930 16931 pSense = satIOContext->pSense; 16932 pSatDevData = satIOContext->pSatDevData; 16933 scsiCmnd = &smScsiRequest->scsiCmnd; 16934 fis = satIOContext->pFis; 16935 pParmList = (bit8 *) smScsiRequest->sglVirtualAddr; 16936 16937 SM_DBG5(("smsatReassignBlocks: start\n")); 16938 16939 /* checking CONTROL */ 16940 /* NACA == 1 or LINK == 1*/ 16941 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 16942 { 16943 smsatSetSensePayload( pSense, 16944 SCSI_SNSKEY_ILLEGAL_REQUEST, 16945 0, 16946 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16947 satIOContext); 16948 16949 /*smEnqueueIO(smRoot, satIOContext);*/ 16950 16951 tdsmIOCompletedCB( smRoot, 16952 smIORequest, 16953 smIOSuccess, 16954 SCSI_STAT_CHECK_CONDITION, 16955 satIOContext->pSmSenseData, 16956 satIOContext->interruptContext ); 16957 16958 SM_DBG1(("smsatReassignBlocks: return control!!!\n")); 16959 return SM_RC_SUCCESS; 16960 } 16961 16962 sm_memset(satIOContext->LBA, 0, 8); 16963 satIOContext->ParmIndex = 0; 16964 satIOContext->ParmLen = 0; 16965 16966 LongList = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLIST_MASK); 16967 LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK); 16968 sm_memset(LBA, 0, sizeof(LBA)); 16969 16970 if (LongList == 0) 16971 { 16972 defectListLen = (pParmList[2] << 8) + pParmList[3]; 16973 } 16974 else 16975 { 16976 defectListLen = (pParmList[0] << (8*3)) + (pParmList[1] << (8*2)) 16977 + (pParmList[2] << 8) + pParmList[3]; 16978 } 16979 /* SBC 5.16.2, p61*/ 16980 satIOContext->ParmLen = defectListLen + 4 /* header size */; 16981 16982 startingIndex = 4; 16983 16984 if (LongLBA == 0) 16985 { 16986 LBA[4] = pParmList[startingIndex]; /* MSB */ 16987 LBA[5] = pParmList[startingIndex+1]; 16988 LBA[6] = pParmList[startingIndex+2]; 16989 LBA[7] = pParmList[startingIndex+3]; /* LSB */ 16990 startingIndex = startingIndex + 4; 16991 } 16992 else 16993 { 16994 LBA[0] = pParmList[startingIndex]; /* MSB */ 16995 LBA[1] = pParmList[startingIndex+1]; 16996 LBA[2] = pParmList[startingIndex+2]; 16997 LBA[3] = pParmList[startingIndex+3]; 16998 LBA[4] = pParmList[startingIndex+4]; 16999 LBA[5] = pParmList[startingIndex+5]; 17000 LBA[6] = pParmList[startingIndex+6]; 17001 LBA[7] = pParmList[startingIndex+7]; /* LSB */ 17002 startingIndex = startingIndex + 8; 17003 } 17004 17005 smhexdump("smsatReassignBlocks Parameter list", (bit8 *)pParmList, 4 + defectListLen); 17006 17007 if (pSatDevData->sat48BitSupport == agTRUE) 17008 { 17009 /* sends READ VERIFY SECTOR(S) EXT*/ 17010 fis->h.fisType = 0x27; /* Reg host to device */ 17011 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17012 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 17013 fis->h.features = 0; /* FIS reserve */ 17014 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 17015 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 17016 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 17017 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */ 17018 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */ 17019 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */ 17020 fis->d.featuresExp = 0; /* FIS reserve */ 17021 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 17022 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 17023 fis->d.reserved4 = 0; 17024 fis->d.device = 0x40; /* 01000000 */ 17025 fis->d.control = 0; /* FIS HOB bit clear */ 17026 fis->d.reserved5 = 0; 17027 } 17028 else 17029 { 17030 /* READ VERIFY SECTOR(S)*/ 17031 fis->h.fisType = 0x27; /* Reg host to device */ 17032 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17033 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 17034 fis->h.features = 0; /* FIS features NA */ 17035 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 17036 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 17037 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 17038 fis->d.lbaLowExp = 0; 17039 fis->d.lbaMidExp = 0; 17040 fis->d.lbaHighExp = 0; 17041 fis->d.featuresExp = 0; 17042 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 17043 fis->d.sectorCountExp = 0; 17044 fis->d.reserved4 = 0; 17045 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF)); 17046 /* DEV and LBA 27:24 */ 17047 fis->d.control = 0; /* FIS HOB bit clear */ 17048 fis->d.reserved5 = 0; 17049 } 17050 17051 sm_memcpy(satIOContext->LBA, LBA, 8); 17052 satIOContext->ParmIndex = startingIndex; 17053 17054 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 17055 17056 /* Initialize CB for SATA completion. 17057 */ 17058 satIOContext->satCompleteCB = &smsatReassignBlocksCB; 17059 17060 /* 17061 * Prepare SGL and send FIS to LL layer. 17062 */ 17063 satIOContext->reqType = agRequestType; /* Save it */ 17064 17065 status = smsataLLIOStart( smRoot, 17066 smIORequest, 17067 smDeviceHandle, 17068 smScsiRequest, 17069 satIOContext); 17070 17071 return status; 17072 } 17073 17074 osGLOBAL bit32 17075 smsatRead_1( 17076 smRoot_t *smRoot, 17077 smIORequest_t *smIORequest, 17078 smDeviceHandle_t *smDeviceHandle, 17079 smScsiInitiatorRequest_t *smScsiRequest, 17080 smSatIOContext_t *satIOContext 17081 ) 17082 { 17083 /* 17084 Assumption: error check on lba and tl has been done in satRead*() 17085 lba = lba + tl; 17086 */ 17087 bit32 status; 17088 smSatIOContext_t *satOrgIOContext = agNULL; 17089 smIniScsiCmnd_t *scsiCmnd; 17090 agsaFisRegHostToDevice_t *fis; 17091 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 17092 bit32 lba = 0; 17093 bit32 DenomTL = 0xFF; 17094 bit32 Remainder = 0; 17095 bit8 LBA[4]; /* 0 MSB, 3 LSB */ 17096 17097 SM_DBG2(("smsatRead_1: start\n")); 17098 17099 fis = satIOContext->pFis; 17100 satOrgIOContext = satIOContext->satOrgIOContext; 17101 scsiCmnd = satOrgIOContext->pScsiCmnd; 17102 17103 sm_memset(LBA,0, sizeof(LBA)); 17104 17105 switch (satOrgIOContext->ATACmd) 17106 { 17107 case SAT_READ_DMA: 17108 DenomTL = 0x100; 17109 break; 17110 case SAT_READ_SECTORS: 17111 DenomTL = 0x100; 17112 break; 17113 case SAT_READ_DMA_EXT: 17114 DenomTL = 0xFFFF; 17115 break; 17116 case SAT_READ_SECTORS_EXT: 17117 DenomTL = 0xFFFF; 17118 break; 17119 case SAT_READ_FPDMA_QUEUED: 17120 DenomTL = 0xFFFF; 17121 break; 17122 default: 17123 SM_DBG1(("smsatRead_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd)); 17124 return SM_RC_FAILURE; 17125 break; 17126 } 17127 17128 Remainder = satOrgIOContext->OrgTL % DenomTL; 17129 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL; 17130 lba = satOrgIOContext->currentLBA; 17131 17132 LBA[0] = (bit8)((lba & 0xFF000000) >> (8 * 3)); 17133 LBA[1] = (bit8)((lba & 0xFF0000) >> (8 * 2)); 17134 LBA[2] = (bit8)((lba & 0xFF00) >> 8); 17135 LBA[3] = (bit8)(lba & 0xFF); 17136 17137 switch (satOrgIOContext->ATACmd) 17138 { 17139 case SAT_READ_DMA: 17140 fis->h.fisType = 0x27; /* Reg host to device */ 17141 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17142 fis->h.command = SAT_READ_DMA; /* 0xC8 */ 17143 fis->h.features = 0; /* FIS reserve */ 17144 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 17145 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 17146 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 17147 fis->d.device = 17148 (bit8)((0x4 << 4) | (LBA[0] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 17149 fis->d.lbaLowExp = 0; 17150 fis->d.lbaMidExp = 0; 17151 fis->d.lbaHighExp = 0; 17152 fis->d.featuresExp = 0; 17153 17154 if (satOrgIOContext->LoopNum == 1) 17155 { 17156 /* last loop */ 17157 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 17158 } 17159 else 17160 { 17161 fis->d.sectorCount = 0x0; /* FIS sector count (7:0) */ 17162 } 17163 17164 fis->d.sectorCountExp = 0; 17165 fis->d.reserved4 = 0; 17166 fis->d.control = 0; /* FIS HOB bit clear */ 17167 fis->d.reserved5 = 0; 17168 17169 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 17170 17171 break; 17172 case SAT_READ_SECTORS: 17173 fis->h.fisType = 0x27; /* Reg host to device */ 17174 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17175 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 17176 fis->h.features = 0; /* FIS reserve */ 17177 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 17178 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 17179 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 17180 fis->d.device = 17181 (bit8)((0x4 << 4) | (LBA[0] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 17182 fis->d.lbaLowExp = 0; 17183 fis->d.lbaMidExp = 0; 17184 fis->d.lbaHighExp = 0; 17185 fis->d.featuresExp = 0; 17186 if (satOrgIOContext->LoopNum == 1) 17187 { 17188 /* last loop */ 17189 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 17190 } 17191 else 17192 { 17193 fis->d.sectorCount = 0x0; /* FIS sector count (7:0) */ 17194 } 17195 fis->d.sectorCountExp = 0; 17196 fis->d.reserved4 = 0; 17197 fis->d.control = 0; /* FIS HOB bit clear */ 17198 fis->d.reserved5 = 0; 17199 17200 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 17201 17202 break; 17203 case SAT_READ_DMA_EXT: 17204 fis->h.fisType = 0x27; /* Reg host to device */ 17205 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17206 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */ 17207 fis->h.features = 0; /* FIS reserve */ 17208 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 17209 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 17210 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 17211 fis->d.device = 0x40; /* FIS LBA mode set */ 17212 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 17213 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 17214 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 17215 fis->d.featuresExp = 0; /* FIS reserve */ 17216 if (satOrgIOContext->LoopNum == 1) 17217 { 17218 /* last loop */ 17219 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 17220 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 17221 17222 } 17223 else 17224 { 17225 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 17226 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 17227 } 17228 fis->d.reserved4 = 0; 17229 fis->d.control = 0; /* FIS HOB bit clear */ 17230 fis->d.reserved5 = 0; 17231 17232 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 17233 17234 break; 17235 case SAT_READ_SECTORS_EXT: 17236 fis->h.fisType = 0x27; /* Reg host to device */ 17237 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17238 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 17239 fis->h.features = 0; /* FIS reserve */ 17240 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 17241 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 17242 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 17243 fis->d.device = 0x40; /* FIS LBA mode set */ 17244 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 17245 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 17246 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 17247 fis->d.featuresExp = 0; /* FIS reserve */ 17248 if (satOrgIOContext->LoopNum == 1) 17249 { 17250 /* last loop */ 17251 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 17252 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 17253 } 17254 else 17255 { 17256 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 17257 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 17258 } 17259 fis->d.reserved4 = 0; 17260 fis->d.control = 0; /* FIS HOB bit clear */ 17261 fis->d.reserved5 = 0; 17262 17263 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 17264 break; 17265 case SAT_READ_FPDMA_QUEUED: 17266 fis->h.fisType = 0x27; /* Reg host to device */ 17267 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17268 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */ 17269 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 17270 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 17271 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 17272 17273 /* Check FUA bit */ 17274 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK) 17275 fis->d.device = 0xC0; /* FIS FUA set */ 17276 else 17277 fis->d.device = 0x40; /* FIS FUA clear */ 17278 17279 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 17280 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 17281 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 17282 if (satOrgIOContext->LoopNum == 1) 17283 { 17284 /* last loop */ 17285 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 17286 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 17287 } 17288 else 17289 { 17290 fis->h.features = 0xFF; /* FIS sector count (7:0) */ 17291 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */ 17292 } 17293 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 17294 fis->d.sectorCountExp = 0; 17295 fis->d.reserved4 = 0; 17296 fis->d.control = 0; /* FIS HOB bit clear */ 17297 fis->d.reserved5 = 0; 17298 17299 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ; 17300 break; 17301 default: 17302 SM_DBG1(("smsatRead_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd)); 17303 return SM_RC_FAILURE; 17304 break; 17305 } 17306 17307 /* Initialize CB for SATA completion. 17308 */ 17309 /* chained data */ 17310 satIOContext->satCompleteCB = &smsatChainedDataIOCB; 17311 17312 if (satOrgIOContext->ATACmd == SAT_READ_DMA || satOrgIOContext->ATACmd == SAT_READ_SECTORS) 17313 { 17314 smsatSplitSGL(smRoot, 17315 smIORequest, 17316 smDeviceHandle, 17317 (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg, 17318 satOrgIOContext, 17319 NON_BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0x100 * 0x200*/ 17320 (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE, 17321 agFALSE); 17322 } 17323 else 17324 { 17325 smsatSplitSGL(smRoot, 17326 smIORequest, 17327 smDeviceHandle, 17328 (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg, 17329 satOrgIOContext, 17330 BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0xFFFF * 0x200*/ 17331 (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE, 17332 agFALSE); 17333 } 17334 17335 /* 17336 * Prepare SGL and send FIS to LL layer. 17337 */ 17338 satIOContext->reqType = agRequestType; /* Save it */ 17339 17340 status = smsataLLIOStart( smRoot, 17341 smIORequest, 17342 smDeviceHandle, 17343 (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg, //smScsiRequest, 17344 satIOContext); 17345 17346 SM_DBG5(("smsatRead_1: return\n")); 17347 return (status); 17348 } 17349 17350 osGLOBAL bit32 17351 smsatWrite_1( 17352 smRoot_t *smRoot, 17353 smIORequest_t *smIORequest, 17354 smDeviceHandle_t *smDeviceHandle, 17355 smScsiInitiatorRequest_t *smScsiRequest, 17356 smSatIOContext_t *satIOContext 17357 ) 17358 { 17359 /* 17360 Assumption: error check on lba and tl has been done in satWrite*() 17361 lba = lba + tl; 17362 */ 17363 bit32 status; 17364 smSatIOContext_t *satOrgIOContext = agNULL; 17365 smIniScsiCmnd_t *scsiCmnd; 17366 agsaFisRegHostToDevice_t *fis; 17367 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 17368 bit32 lba = 0; 17369 bit32 DenomTL = 0xFF; 17370 bit32 Remainder = 0; 17371 bit8 LBA[4]; /* 0 MSB, 3 LSB */ 17372 17373 SM_DBG2(("smsatWrite_1: start\n")); 17374 17375 fis = satIOContext->pFis; 17376 satOrgIOContext = satIOContext->satOrgIOContext; 17377 scsiCmnd = satOrgIOContext->pScsiCmnd; 17378 17379 sm_memset(LBA,0, sizeof(LBA)); 17380 17381 switch (satOrgIOContext->ATACmd) 17382 { 17383 case SAT_WRITE_DMA: 17384 DenomTL = 0x100; 17385 break; 17386 case SAT_WRITE_SECTORS: 17387 DenomTL = 0x100; 17388 break; 17389 case SAT_WRITE_DMA_EXT: 17390 DenomTL = 0xFFFF; 17391 break; 17392 case SAT_WRITE_DMA_FUA_EXT: 17393 DenomTL = 0xFFFF; 17394 break; 17395 case SAT_WRITE_SECTORS_EXT: 17396 DenomTL = 0xFFFF; 17397 break; 17398 case SAT_WRITE_FPDMA_QUEUED: 17399 DenomTL = 0xFFFF; 17400 break; 17401 default: 17402 SM_DBG1(("smsatWrite_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd)); 17403 return SM_RC_FAILURE; 17404 break; 17405 } 17406 17407 Remainder = satOrgIOContext->OrgTL % DenomTL; 17408 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL; 17409 lba = satOrgIOContext->currentLBA; 17410 17411 17412 LBA[0] = (bit8)((lba & 0xFF000000) >> (8 * 3)); 17413 LBA[1] = (bit8)((lba & 0xFF0000) >> (8 * 2)); 17414 LBA[2] = (bit8)((lba & 0xFF00) >> 8); 17415 LBA[3] = (bit8)(lba & 0xFF); 17416 17417 switch (satOrgIOContext->ATACmd) 17418 { 17419 case SAT_WRITE_DMA: 17420 fis->h.fisType = 0x27; /* Reg host to device */ 17421 fis->h.c_pmPort = 0x80; /* C bit is set */ 17422 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 17423 fis->h.features = 0; /* FIS reserve */ 17424 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 17425 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 17426 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 17427 17428 /* FIS LBA mode set LBA (27:24) */ 17429 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 17430 17431 fis->d.lbaLowExp = 0; 17432 fis->d.lbaMidExp = 0; 17433 fis->d.lbaHighExp = 0; 17434 fis->d.featuresExp = 0; 17435 if (satOrgIOContext->LoopNum == 1) 17436 { 17437 /* last loop */ 17438 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 17439 } 17440 else 17441 { 17442 fis->d.sectorCount = 0x0; /* FIS sector count (7:0) */ 17443 } 17444 fis->d.sectorCountExp = 0; 17445 fis->d.reserved4 = 0; 17446 fis->d.control = 0; /* FIS HOB bit clear */ 17447 fis->d.reserved5 = 0; 17448 17449 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 17450 17451 break; 17452 case SAT_WRITE_SECTORS: 17453 fis->h.fisType = 0x27; /* Reg host to device */ 17454 fis->h.c_pmPort = 0x80; /* C bit is set */ 17455 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 17456 fis->h.features = 0; /* FIS reserve */ 17457 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 17458 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 17459 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 17460 17461 /* FIS LBA mode set LBA (27:24) */ 17462 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 17463 17464 fis->d.lbaLowExp = 0; 17465 fis->d.lbaMidExp = 0; 17466 fis->d.lbaHighExp = 0; 17467 fis->d.featuresExp = 0; 17468 if (satOrgIOContext->LoopNum == 1) 17469 { 17470 /* last loop */ 17471 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 17472 } 17473 else 17474 { 17475 fis->d.sectorCount = 0x0; /* FIS sector count (7:0) */ 17476 } 17477 fis->d.sectorCountExp = 0; 17478 fis->d.reserved4 = 0; 17479 fis->d.control = 0; /* FIS HOB bit clear */ 17480 fis->d.reserved5 = 0; 17481 17482 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 17483 17484 break; 17485 case SAT_WRITE_DMA_EXT: 17486 fis->h.fisType = 0x27; /* Reg host to device */ 17487 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17488 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x3D */ 17489 fis->h.features = 0; /* FIS reserve */ 17490 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 17491 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 17492 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 17493 fis->d.device = 0x40; /* FIS LBA mode set */ 17494 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 17495 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 17496 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 17497 fis->d.featuresExp = 0; /* FIS reserve */ 17498 if (satOrgIOContext->LoopNum == 1) 17499 { 17500 /* last loop */ 17501 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 17502 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 17503 } 17504 else 17505 { 17506 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 17507 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 17508 } 17509 fis->d.reserved4 = 0; 17510 fis->d.control = 0; /* FIS HOB bit clear */ 17511 fis->d.reserved5 = 0; 17512 17513 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 17514 17515 break; 17516 case SAT_WRITE_SECTORS_EXT: 17517 fis->h.fisType = 0x27; /* Reg host to device */ 17518 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17519 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 17520 17521 fis->h.features = 0; /* FIS reserve */ 17522 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 17523 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 17524 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 17525 fis->d.device = 0x40; /* FIS LBA mode set */ 17526 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 17527 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 17528 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 17529 fis->d.featuresExp = 0; /* FIS reserve */ 17530 if (satOrgIOContext->LoopNum == 1) 17531 { 17532 /* last loop */ 17533 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 17534 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 17535 } 17536 else 17537 { 17538 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 17539 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 17540 } 17541 fis->d.reserved4 = 0; 17542 fis->d.control = 0; /* FIS HOB bit clear */ 17543 fis->d.reserved5 = 0; 17544 17545 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 17546 17547 break; 17548 case SAT_WRITE_FPDMA_QUEUED: 17549 fis->h.fisType = 0x27; /* Reg host to device */ 17550 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17551 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 17552 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 17553 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 17554 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 17555 17556 /* Check FUA bit */ 17557 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK) 17558 fis->d.device = 0xC0; /* FIS FUA set */ 17559 else 17560 fis->d.device = 0x40; /* FIS FUA clear */ 17561 17562 fis->d.lbaLowExp = LBA[0];; /* FIS LBA (31:24) */ 17563 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 17564 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 17565 if (satOrgIOContext->LoopNum == 1) 17566 { 17567 /* last loop */ 17568 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 17569 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 17570 } 17571 else 17572 { 17573 fis->h.features = 0xFF; /* FIS sector count (7:0) */ 17574 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */ 17575 } 17576 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 17577 fis->d.sectorCountExp = 0; 17578 fis->d.reserved4 = 0; 17579 fis->d.control = 0; /* FIS HOB bit clear */ 17580 fis->d.reserved5 = 0; 17581 17582 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 17583 break; 17584 17585 default: 17586 SM_DBG1(("smsatWrite_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd)); 17587 return SM_RC_FAILURE; 17588 break; 17589 } 17590 17591 /* Initialize CB for SATA completion. 17592 */ 17593 /* chained data */ 17594 satIOContext->satCompleteCB = &smsatChainedDataIOCB; 17595 17596 if (satOrgIOContext->ATACmd == SAT_WRITE_DMA || satOrgIOContext->ATACmd == SAT_WRITE_SECTORS) 17597 { 17598 smsatSplitSGL(smRoot, 17599 smIORequest, 17600 smDeviceHandle, 17601 (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg, 17602 satOrgIOContext, 17603 NON_BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0x100 * 0x200*/ 17604 (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE, 17605 agFALSE); 17606 } 17607 else 17608 { 17609 smsatSplitSGL(smRoot, 17610 smIORequest, 17611 smDeviceHandle, 17612 (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg, 17613 satOrgIOContext, 17614 BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0xFFFF * 0x200*/ 17615 (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE, 17616 agFALSE); 17617 } 17618 17619 /* 17620 * Prepare SGL and send FIS to LL layer. 17621 */ 17622 satIOContext->reqType = agRequestType; /* Save it */ 17623 17624 status = smsataLLIOStart( smRoot, 17625 smIORequest, 17626 smDeviceHandle, 17627 (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg, //smScsiRequest, 17628 satIOContext); 17629 17630 SM_DBG5(("smsatWrite_1: return\n")); 17631 return (status); 17632 } 17633 17634 osGLOBAL bit32 17635 smsatPassthrough( 17636 smRoot_t *smRoot, 17637 smIORequest_t *smIORequest, 17638 smDeviceHandle_t *smDeviceHandle, 17639 smScsiInitiatorRequest_t *smScsiRequest, 17640 smSatIOContext_t *satIOContext 17641 ) 17642 { 17643 smScsiRspSense_t *pSense; 17644 smIniScsiCmnd_t *scsiCmnd; 17645 smDeviceData_t *pSatDevData; 17646 agsaFisRegHostToDevice_t *fis; 17647 bit32 status; 17648 bit32 agRequestType; 17649 smAtaPassThroughHdr_t ataPassThroughHdr; 17650 17651 17652 pSense = satIOContext->pSense; 17653 scsiCmnd = &smScsiRequest->scsiCmnd; 17654 pSatDevData = satIOContext->pSatDevData; 17655 fis = satIOContext->pFis; 17656 17657 SM_DBG1(("smsatPassthrough: START!!!\n")); 17658 17659 osti_memset(&ataPassThroughHdr, 0 , sizeof(smAtaPassThroughHdr_t)); 17660 17661 ataPassThroughHdr.opc = scsiCmnd->cdb[0]; 17662 ataPassThroughHdr.mulCount = scsiCmnd->cdb[1] >> 5; 17663 ataPassThroughHdr.proto = (scsiCmnd->cdb[1] >> 1) & 0x0F; 17664 ataPassThroughHdr.extend = scsiCmnd->cdb[1] & 1; 17665 ataPassThroughHdr.offline = scsiCmnd->cdb[2] >> 6; 17666 ataPassThroughHdr.ckCond = (scsiCmnd->cdb[2] >> 5) & 1; 17667 ataPassThroughHdr.tType = (scsiCmnd->cdb[2] >> 4) & 1; 17668 ataPassThroughHdr.tDir = (scsiCmnd->cdb[2] >> 3) & 1; 17669 ataPassThroughHdr.byteBlock = (scsiCmnd->cdb[2] >> 2) & 1; 17670 ataPassThroughHdr.tlength = scsiCmnd->cdb[2] & 0x3; 17671 17672 switch(ataPassThroughHdr.proto) 17673 { 17674 case 0: 17675 case 9: 17676 agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET; //Device Reset 17677 break; 17678 case 1: 17679 agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT; //Software reset 17680 break; 17681 case 3: 17682 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; //Non Data mode 17683 break; 17684 case 4: 17685 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; //IO_Data_In mode 17686 break; 17687 case 5: 17688 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; //PIO_Data_out 17689 break; 17690 case 6: 17691 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; //DMA READ and WRITE 17692 break; 17693 case 8: 17694 agRequestType = AGSA_SATA_ATAP_EXECDEVDIAG; //device diagnostic 17695 break; 17696 case 12: 17697 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; //FPDMA Read and Write 17698 break; 17699 default: 17700 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; //Default Non Data Mode 17701 break; 17702 } 17703 17704 17705 if((ataPassThroughHdr.tlength == 0) && (agRequestType != AGSA_SATA_PROTOCOL_NON_DATA)) 17706 { 17707 SM_DBG1(("smsatPassthrough SCSI_SNSCODE_INVALID_FIELD_IN_CDB\n")); 17708 17709 smsatSetSensePayload( pSense, 17710 SCSI_SNSKEY_ILLEGAL_REQUEST, 17711 0, 17712 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 17713 satIOContext); 17714 17715 tdsmIOCompletedCB( smRoot, 17716 smIORequest, 17717 smIOSuccess, 17718 SCSI_STAT_CHECK_CONDITION, 17719 satIOContext->pSmSenseData, 17720 satIOContext->interruptContext ); 17721 17722 return SM_RC_SUCCESS; 17723 } 17724 17725 if(scsiCmnd->cdb[0] == 0xA1) 17726 { 17727 SM_DBG1(("smsatPassthrough A1h: COMMAND: %x FEATURE: %x \n",scsiCmnd->cdb[9],scsiCmnd->cdb[3])); 17728 17729 fis->h.fisType = 0x27; /* Reg host to device */ 17730 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17731 fis->h.features = scsiCmnd->cdb[3]; 17732 fis->d.sectorCount = scsiCmnd->cdb[4]; /* 0x01 FIS sector count (7:0) */ 17733 fis->d.lbaLow = scsiCmnd->cdb[5]; /* Reading LBA FIS LBA (7 :0 ) */ 17734 fis->d.lbaMid = scsiCmnd->cdb[6]; 17735 fis->d.lbaHigh = scsiCmnd->cdb[7]; 17736 fis->d.device = scsiCmnd->cdb[8]; 17737 fis->h.command = scsiCmnd->cdb[9]; 17738 fis->d.featuresExp = 0; 17739 fis->d.sectorCountExp = 0; 17740 fis->d.lbaLowExp = 0; 17741 fis->d.lbaMidExp = 0; 17742 fis->d.lbaHighExp = 0; 17743 fis->d.reserved4 = 0; 17744 fis->d.control = 0; /* FIS HOB bit clear */ 17745 fis->d.reserved5 = 0; 17746 17747 /* Initialize CB for SATA completion*/ 17748 satIOContext->satCompleteCB = &smsatPassthroughCB; 17749 17750 /* 17751 * Prepare SGL and send FIS to LL layer. 17752 */ 17753 17754 satIOContext->reqType = agRequestType; 17755 status = smsataLLIOStart( smRoot, 17756 smIORequest, 17757 smDeviceHandle, 17758 smScsiRequest, 17759 satIOContext); 17760 return status; 17761 17762 } 17763 else if(scsiCmnd->cdb[0] == 0x85) 17764 { 17765 SM_DBG1(("smsatPassthrough 85h: COMMAND: %x FEATURE: %x \n",scsiCmnd->cdb[14],scsiCmnd->cdb[4])); 17766 17767 fis->h.fisType = 0x27; /* Reg host to device */ 17768 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17769 17770 if(1 == ataPassThroughHdr.extend) 17771 { 17772 fis->d.featuresExp = scsiCmnd->cdb[3]; 17773 fis->d.sectorCountExp = scsiCmnd->cdb[5]; 17774 fis->d.lbaMidExp = scsiCmnd->cdb[9]; 17775 fis->d.lbaHighExp = scsiCmnd->cdb[11]; 17776 fis->d.lbaLowExp = scsiCmnd->cdb[7]; 17777 } 17778 fis->h.features = scsiCmnd->cdb[4]; 17779 fis->d.sectorCount = scsiCmnd->cdb[6]; 17780 fis->d.lbaLow = scsiCmnd->cdb[8]; 17781 fis->d.lbaMid = scsiCmnd->cdb[10]; 17782 fis->d.lbaHigh = scsiCmnd->cdb[12]; 17783 fis->d.device = scsiCmnd->cdb[13]; 17784 fis->h.command = scsiCmnd->cdb[14]; 17785 fis->d.reserved4 = 0; 17786 fis->d.control = 0; 17787 fis->d.reserved5 = 0; 17788 17789 17790 /* Initialize CB for SATA completion. 17791 */ 17792 17793 satIOContext->satCompleteCB = &smsatPassthroughCB; 17794 17795 /* 17796 * Prepare SGL and send FIS to LL layer. 17797 */ 17798 satIOContext->reqType = agRequestType; 17799 status = smsataLLIOStart( smRoot, 17800 smIORequest, 17801 smDeviceHandle, 17802 smScsiRequest, 17803 satIOContext); 17804 return status; 17805 17806 } 17807 else 17808 { 17809 SM_DBG1(("smsatPassthrough : INVALD PASSTHROUGH!!!\n")); 17810 smsatSetSensePayload( pSense, 17811 SCSI_SNSKEY_ILLEGAL_REQUEST, 17812 0, 17813 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 17814 satIOContext); 17815 tdsmIOCompletedCB( smRoot, 17816 smIORequest, 17817 smIOSuccess, 17818 SCSI_STAT_CHECK_CONDITION, 17819 satIOContext->pSmSenseData, 17820 satIOContext->interruptContext ); 17821 17822 SM_DBG1(("smsatPassthrough : return control!!!\n")); 17823 17824 return SM_RC_SUCCESS; 17825 } 17826 } 17827 17828 osGLOBAL bit32 17829 smsatNonChainedWriteNVerify_Verify( 17830 smRoot_t *smRoot, 17831 smIORequest_t *smIORequest, 17832 smDeviceHandle_t *smDeviceHandle, 17833 smScsiInitiatorRequest_t *smScsiRequest, 17834 smSatIOContext_t *satIOContext 17835 ) 17836 { 17837 bit32 status; 17838 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 17839 smDeviceData_t *pSatDevData; 17840 smIniScsiCmnd_t *scsiCmnd; 17841 agsaFisRegHostToDevice_t *fis; 17842 17843 pSatDevData = satIOContext->pSatDevData; 17844 scsiCmnd = &smScsiRequest->scsiCmnd; 17845 fis = satIOContext->pFis; 17846 SM_DBG5(("smsatNonChainedWriteNVerify_Verify: start\n")); 17847 if (pSatDevData->sat48BitSupport == agTRUE) 17848 { 17849 fis->h.fisType = 0x27; /* Reg host to device */ 17850 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17851 17852 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 17853 fis->h.features = 0; /* FIS reserve */ 17854 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 17855 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 17856 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 17857 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 17858 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 17859 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 17860 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 17861 fis->d.featuresExp = 0; /* FIS reserve */ 17862 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 17863 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 17864 17865 fis->d.reserved4 = 0; 17866 fis->d.control = 0; /* FIS HOB bit clear */ 17867 fis->d.reserved5 = 0; 17868 17869 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 17870 17871 /* Initialize CB for SATA completion. 17872 */ 17873 satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB; 17874 17875 /* 17876 * Prepare SGL and send FIS to LL layer. 17877 */ 17878 satIOContext->reqType = agRequestType; /* Save it */ 17879 17880 status = smsataLLIOStart( smRoot, 17881 smIORequest, 17882 smDeviceHandle, 17883 smScsiRequest, 17884 satIOContext); 17885 17886 17887 SM_DBG1(("smsatNonChainedWriteNVerify_Verify: return status %d!!!\n", status)); 17888 return (status); 17889 } 17890 else 17891 { 17892 /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */ 17893 SM_DBG1(("smsatNonChainedWriteNVerify_Verify: can't fit in SAT_READ_VERIFY_SECTORS!!!\n")); 17894 return SM_RC_FAILURE; 17895 } 17896 } 17897 17898 osGLOBAL bit32 17899 smsatChainedWriteNVerify_Start_Verify( 17900 smRoot_t *smRoot, 17901 smIORequest_t *smIORequest, 17902 smDeviceHandle_t *smDeviceHandle, 17903 smScsiInitiatorRequest_t *smScsiRequest, 17904 smSatIOContext_t *satIOContext 17905 ) 17906 { 17907 /* 17908 deal with transfer length; others have been handled previously at this point; 17909 no LBA check; no range check; 17910 */ 17911 bit32 status; 17912 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 17913 smDeviceData_t *pSatDevData; 17914 smIniScsiCmnd_t *scsiCmnd; 17915 agsaFisRegHostToDevice_t *fis; 17916 bit32 lba = 0; 17917 bit32 tl = 0; 17918 bit32 LoopNum = 1; 17919 bit8 LBA[4]; 17920 bit8 TL[4]; 17921 17922 pSatDevData = satIOContext->pSatDevData; 17923 scsiCmnd = &smScsiRequest->scsiCmnd; 17924 fis = satIOContext->pFis; 17925 17926 SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: start\n")); 17927 sm_memset(LBA, 0, sizeof(LBA)); 17928 sm_memset(TL, 0, sizeof(TL)); 17929 /* do not use memcpy due to indexing in LBA and TL */ 17930 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 17931 LBA[1] = scsiCmnd->cdb[3]; 17932 LBA[2] = scsiCmnd->cdb[4]; 17933 LBA[3] = scsiCmnd->cdb[5]; /* LSB */ 17934 TL[0] = scsiCmnd->cdb[6]; /* MSB */ 17935 TL[1] = scsiCmnd->cdb[7]; 17936 TL[2] = scsiCmnd->cdb[7]; 17937 TL[3] = scsiCmnd->cdb[8]; /* LSB */ 17938 lba = smsatComputeCDB12LBA(satIOContext); 17939 tl = smsatComputeCDB12TL(satIOContext); 17940 if (pSatDevData->sat48BitSupport == agTRUE) 17941 { 17942 SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS_EXT\n")); 17943 fis->h.fisType = 0x27; /* Reg host to device */ 17944 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17945 17946 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 17947 fis->h.features = 0; /* FIS reserve */ 17948 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 17949 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 17950 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 17951 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 17952 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 17953 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 17954 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 17955 fis->d.featuresExp = 0; /* FIS reserve */ 17956 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 17957 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 17958 17959 fis->d.reserved4 = 0; 17960 fis->d.control = 0; /* FIS HOB bit clear */ 17961 fis->d.reserved5 = 0; 17962 17963 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 17964 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT; 17965 } 17966 else 17967 { 17968 SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS\n")); 17969 fis->h.fisType = 0x27; /* Reg host to device */ 17970 fis->h.c_pmPort = 0x80; /* C bit is set */ 17971 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 17972 fis->h.features = 0; /* FIS reserve */ 17973 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 17974 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 17975 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 17976 /* FIS LBA mode set LBA (27:24) */ 17977 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 17978 fis->d.lbaLowExp = 0; 17979 fis->d.lbaMidExp = 0; 17980 fis->d.lbaHighExp = 0; 17981 fis->d.featuresExp = 0; 17982 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 17983 fis->d.sectorCountExp = 0; 17984 fis->d.reserved4 = 0; 17985 fis->d.control = 0; /* FIS HOB bit clear */ 17986 fis->d.reserved5 = 0; 17987 17988 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 17989 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS; 17990 17991 } 17992 17993 satIOContext->currentLBA = lba; 17994 satIOContext->OrgTL = tl; 17995 17996 /* 17997 computing number of loop and remainder for tl 17998 0xFF in case not ext 17999 0xFFFF in case EXT 18000 */ 18001 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 18002 { 18003 LoopNum = smsatComputeLoopNum(tl, 0xFF); 18004 } 18005 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 18006 { 18007 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 18008 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 18009 } 18010 else 18011 { 18012 SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: error case 1!!!\n")); 18013 LoopNum = 1; 18014 } 18015 18016 satIOContext->LoopNum = LoopNum; 18017 18018 if (LoopNum == 1) 18019 { 18020 SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: NON CHAINED data\n")); 18021 /* Initialize CB for SATA completion. 18022 */ 18023 satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB; 18024 } 18025 else 18026 { 18027 SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: CHAINED data!!!\n")); 18028 /* re-setting tl */ 18029 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 18030 { 18031 fis->d.sectorCount = 0xFF; 18032 } 18033 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 18034 { 18035 fis->d.sectorCount = 0xFF; 18036 fis->d.sectorCountExp = 0xFF; 18037 } 18038 else 18039 { 18040 SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: error case 2!!!\n")); 18041 } 18042 18043 /* Initialize CB for SATA completion. 18044 */ 18045 satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB; 18046 } 18047 18048 18049 /* 18050 * Prepare SGL and send FIS to LL layer. 18051 */ 18052 satIOContext->reqType = agRequestType; /* Save it */ 18053 18054 status = smsataLLIOStart( smRoot, 18055 smIORequest, 18056 smDeviceHandle, 18057 smScsiRequest, 18058 satIOContext); 18059 return (status); 18060 18061 18062 } 18063 18064 osGLOBAL bit32 18065 smsatChainedWriteNVerify_Write( 18066 smRoot_t *smRoot, 18067 smIORequest_t *smIORequest, 18068 smDeviceHandle_t *smDeviceHandle, 18069 smScsiInitiatorRequest_t *smScsiRequest, 18070 smSatIOContext_t *satIOContext 18071 ) 18072 { 18073 /* 18074 Assumption: error check on lba and tl has been done in satWrite*() 18075 lba = lba + tl; 18076 */ 18077 bit32 status; 18078 smSatIOContext_t *satOrgIOContext = agNULL; 18079 smIniScsiCmnd_t *scsiCmnd; 18080 agsaFisRegHostToDevice_t *fis; 18081 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 18082 bit32 lba = 0; 18083 bit32 DenomTL = 0xFF; 18084 bit32 Remainder = 0; 18085 bit8 LBA[4]; /* 0 MSB, 3 LSB */ 18086 18087 SM_DBG1(("smsatChainedWriteNVerify_Write: start\n")); 18088 18089 fis = satIOContext->pFis; 18090 satOrgIOContext = satIOContext->satOrgIOContext; 18091 scsiCmnd = satOrgIOContext->pScsiCmnd; 18092 18093 18094 sm_memset(LBA,0, sizeof(LBA)); 18095 18096 switch (satOrgIOContext->ATACmd) 18097 { 18098 case SAT_WRITE_DMA: 18099 DenomTL = 0xFF; 18100 break; 18101 case SAT_WRITE_SECTORS: 18102 DenomTL = 0xFF; 18103 break; 18104 case SAT_WRITE_DMA_EXT: 18105 DenomTL = 0xFFFF; 18106 break; 18107 case SAT_WRITE_DMA_FUA_EXT: 18108 DenomTL = 0xFFFF; 18109 break; 18110 case SAT_WRITE_SECTORS_EXT: 18111 DenomTL = 0xFFFF; 18112 break; 18113 case SAT_WRITE_FPDMA_QUEUED: 18114 DenomTL = 0xFFFF; 18115 break; 18116 default: 18117 SM_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd)); 18118 return SM_RC_FAILURE; 18119 break; 18120 } 18121 18122 Remainder = satOrgIOContext->OrgTL % DenomTL; 18123 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL; 18124 lba = satOrgIOContext->currentLBA; 18125 18126 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */ 18127 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2)); 18128 LBA[2] = (bit8)((lba & 0xF0) >> 8); 18129 LBA[3] = (bit8)(lba & 0xF); /* LSB */ 18130 18131 switch (satOrgIOContext->ATACmd) 18132 { 18133 case SAT_WRITE_DMA: 18134 fis->h.fisType = 0x27; /* Reg host to device */ 18135 fis->h.c_pmPort = 0x80; /* C bit is set */ 18136 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 18137 fis->h.features = 0; /* FIS reserve */ 18138 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 18139 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 18140 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 18141 18142 /* FIS LBA mode set LBA (27:24) */ 18143 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 18144 18145 fis->d.lbaLowExp = 0; 18146 fis->d.lbaMidExp = 0; 18147 fis->d.lbaHighExp = 0; 18148 fis->d.featuresExp = 0; 18149 if (satOrgIOContext->LoopNum == 1) 18150 { 18151 /* last loop */ 18152 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 18153 } 18154 else 18155 { 18156 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 18157 } 18158 fis->d.sectorCountExp = 0; 18159 fis->d.reserved4 = 0; 18160 fis->d.control = 0; /* FIS HOB bit clear */ 18161 fis->d.reserved5 = 0; 18162 18163 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 18164 18165 break; 18166 case SAT_WRITE_SECTORS: 18167 fis->h.fisType = 0x27; /* Reg host to device */ 18168 fis->h.c_pmPort = 0x80; /* C bit is set */ 18169 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 18170 fis->h.features = 0; /* FIS reserve */ 18171 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 18172 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 18173 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 18174 18175 /* FIS LBA mode set LBA (27:24) */ 18176 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 18177 18178 fis->d.lbaLowExp = 0; 18179 fis->d.lbaMidExp = 0; 18180 fis->d.lbaHighExp = 0; 18181 fis->d.featuresExp = 0; 18182 if (satOrgIOContext->LoopNum == 1) 18183 { 18184 /* last loop */ 18185 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 18186 } 18187 else 18188 { 18189 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 18190 } 18191 fis->d.sectorCountExp = 0; 18192 fis->d.reserved4 = 0; 18193 fis->d.control = 0; /* FIS HOB bit clear */ 18194 fis->d.reserved5 = 0; 18195 18196 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 18197 18198 break; 18199 case SAT_WRITE_DMA_EXT: 18200 fis->h.fisType = 0x27; /* Reg host to device */ 18201 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18202 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x3D */ 18203 fis->h.features = 0; /* FIS reserve */ 18204 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 18205 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 18206 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 18207 fis->d.device = 0x40; /* FIS LBA mode set */ 18208 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 18209 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 18210 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 18211 fis->d.featuresExp = 0; /* FIS reserve */ 18212 if (satOrgIOContext->LoopNum == 1) 18213 { 18214 /* last loop */ 18215 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 18216 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 18217 } 18218 else 18219 { 18220 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 18221 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 18222 } 18223 fis->d.reserved4 = 0; 18224 fis->d.control = 0; /* FIS HOB bit clear */ 18225 fis->d.reserved5 = 0; 18226 18227 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 18228 18229 break; 18230 case SAT_WRITE_SECTORS_EXT: 18231 fis->h.fisType = 0x27; /* Reg host to device */ 18232 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18233 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 18234 18235 fis->h.features = 0; /* FIS reserve */ 18236 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 18237 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 18238 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 18239 fis->d.device = 0x40; /* FIS LBA mode set */ 18240 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 18241 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 18242 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 18243 fis->d.featuresExp = 0; /* FIS reserve */ 18244 if (satOrgIOContext->LoopNum == 1) 18245 { 18246 /* last loop */ 18247 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 18248 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 18249 } 18250 else 18251 { 18252 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 18253 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 18254 } 18255 fis->d.reserved4 = 0; 18256 fis->d.control = 0; /* FIS HOB bit clear */ 18257 fis->d.reserved5 = 0; 18258 18259 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 18260 18261 break; 18262 case SAT_WRITE_FPDMA_QUEUED: 18263 fis->h.fisType = 0x27; /* Reg host to device */ 18264 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18265 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 18266 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 18267 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 18268 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 18269 18270 /* Check FUA bit */ 18271 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK) 18272 fis->d.device = 0xC0; /* FIS FUA set */ 18273 else 18274 fis->d.device = 0x40; /* FIS FUA clear */ 18275 18276 fis->d.lbaLowExp = LBA[0];; /* FIS LBA (31:24) */ 18277 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 18278 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 18279 if (satOrgIOContext->LoopNum == 1) 18280 { 18281 /* last loop */ 18282 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 18283 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 18284 } 18285 else 18286 { 18287 fis->h.features = 0xFF; /* FIS sector count (7:0) */ 18288 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */ 18289 } 18290 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 18291 fis->d.sectorCountExp = 0; 18292 fis->d.reserved4 = 0; 18293 fis->d.control = 0; /* FIS HOB bit clear */ 18294 fis->d.reserved5 = 0; 18295 18296 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 18297 break; 18298 18299 default: 18300 SM_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd)); 18301 return SM_RC_FAILURE; 18302 break; 18303 } 18304 18305 /* Initialize CB for SATA completion. 18306 */ 18307 /* chained data */ 18308 satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB; 18309 18310 18311 /* 18312 * Prepare SGL and send FIS to LL layer. 18313 */ 18314 satIOContext->reqType = agRequestType; /* Save it */ 18315 18316 status = smsataLLIOStart( smRoot, 18317 smIORequest, 18318 smDeviceHandle, 18319 smScsiRequest, 18320 satIOContext); 18321 18322 SM_DBG5(("satChainedWriteNVerify_Write: return\n")); 18323 return (status); 18324 } 18325 18326 osGLOBAL bit32 18327 smsatChainedWriteNVerify_Verify( 18328 smRoot_t *smRoot, 18329 smIORequest_t *smIORequest, 18330 smDeviceHandle_t *smDeviceHandle, 18331 smScsiInitiatorRequest_t *smScsiRequest, 18332 smSatIOContext_t *satIOContext 18333 ) 18334 { 18335 bit32 status; 18336 smSatIOContext_t *satOrgIOContext = agNULL; 18337 agsaFisRegHostToDevice_t *fis; 18338 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 18339 bit32 lba = 0; 18340 bit32 DenomTL = 0xFF; 18341 bit32 Remainder = 0; 18342 bit8 LBA[4]; /* 0 MSB, 3 LSB */ 18343 18344 SM_DBG2(("smsatChainedWriteNVerify_Verify: start\n")); 18345 fis = satIOContext->pFis; 18346 satOrgIOContext = satIOContext->satOrgIOContext; 18347 sm_memset(LBA,0, sizeof(LBA)); 18348 switch (satOrgIOContext->ATACmd) 18349 { 18350 case SAT_READ_VERIFY_SECTORS: 18351 DenomTL = 0xFF; 18352 break; 18353 case SAT_READ_VERIFY_SECTORS_EXT: 18354 DenomTL = 0xFFFF; 18355 break; 18356 default: 18357 SM_DBG1(("smsatChainedWriteNVerify_Verify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd)); 18358 return SM_RC_FAILURE; 18359 break; 18360 } 18361 18362 Remainder = satOrgIOContext->OrgTL % DenomTL; 18363 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL; 18364 lba = satOrgIOContext->currentLBA; 18365 18366 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */ 18367 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2)); 18368 LBA[2] = (bit8)((lba & 0xF0) >> 8); 18369 LBA[3] = (bit8)(lba & 0xF); /* LSB */ 18370 18371 switch (satOrgIOContext->ATACmd) 18372 { 18373 case SAT_READ_VERIFY_SECTORS: 18374 fis->h.fisType = 0x27; /* Reg host to device */ 18375 fis->h.c_pmPort = 0x80; /* C bit is set */ 18376 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 18377 fis->h.features = 0; /* FIS reserve */ 18378 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 18379 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 18380 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 18381 18382 /* FIS LBA mode set LBA (27:24) */ 18383 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 18384 18385 fis->d.lbaLowExp = 0; 18386 fis->d.lbaMidExp = 0; 18387 fis->d.lbaHighExp = 0; 18388 fis->d.featuresExp = 0; 18389 if (satOrgIOContext->LoopNum == 1) 18390 { 18391 /* last loop */ 18392 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 18393 } 18394 else 18395 { 18396 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 18397 } 18398 fis->d.sectorCountExp = 0; 18399 fis->d.reserved4 = 0; 18400 fis->d.control = 0; /* FIS HOB bit clear */ 18401 fis->d.reserved5 = 0; 18402 18403 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 18404 18405 break; 18406 case SAT_READ_VERIFY_SECTORS_EXT: 18407 fis->h.fisType = 0x27; /* Reg host to device */ 18408 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18409 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT; /* 0x42 */ 18410 fis->h.features = 0; /* FIS reserve */ 18411 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 18412 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 18413 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 18414 fis->d.device = 0x40; /* FIS LBA mode set */ 18415 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 18416 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 18417 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 18418 fis->d.featuresExp = 0; /* FIS reserve */ 18419 if (satOrgIOContext->LoopNum == 1) 18420 { 18421 /* last loop */ 18422 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 18423 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 18424 } 18425 else 18426 { 18427 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 18428 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 18429 } 18430 fis->d.reserved4 = 0; 18431 fis->d.control = 0; /* FIS HOB bit clear */ 18432 fis->d.reserved5 = 0; 18433 18434 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 18435 18436 break; 18437 18438 default: 18439 SM_DBG1(("smsatChainedWriteNVerify_Verify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd)); 18440 return SM_RC_FAILURE; 18441 break; 18442 } 18443 18444 /* Initialize CB for SATA completion. 18445 */ 18446 /* chained data */ 18447 satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB; 18448 18449 18450 /* 18451 * Prepare SGL and send FIS to LL layer. 18452 */ 18453 satIOContext->reqType = agRequestType; /* Save it */ 18454 18455 status = smsataLLIOStart( smRoot, 18456 smIORequest, 18457 smDeviceHandle, 18458 smScsiRequest, 18459 satIOContext); 18460 18461 SM_DBG5(("smsatChainedWriteNVerify_Verify: return\n")); 18462 return (status); 18463 } 18464 18465 osGLOBAL bit32 18466 smsatChainedVerify( 18467 smRoot_t *smRoot, 18468 smIORequest_t *smIORequest, 18469 smDeviceHandle_t *smDeviceHandle, 18470 smScsiInitiatorRequest_t *smScsiRequest, 18471 smSatIOContext_t *satIOContext 18472 ) 18473 { 18474 bit32 status; 18475 smSatIOContext_t *satOrgIOContext = agNULL; 18476 agsaFisRegHostToDevice_t *fis; 18477 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 18478 bit32 lba = 0; 18479 bit32 DenomTL = 0xFF; 18480 bit32 Remainder = 0; 18481 bit8 LBA[4]; /* 0 MSB, 3 LSB */ 18482 18483 SM_DBG2(("smsatChainedVerify: start\n")); 18484 fis = satIOContext->pFis; 18485 satOrgIOContext = satIOContext->satOrgIOContext; 18486 sm_memset(LBA,0, sizeof(LBA)); 18487 switch (satOrgIOContext->ATACmd) 18488 { 18489 case SAT_READ_VERIFY_SECTORS: 18490 DenomTL = 0xFF; 18491 break; 18492 case SAT_READ_VERIFY_SECTORS_EXT: 18493 DenomTL = 0xFFFF; 18494 break; 18495 default: 18496 SM_DBG1(("satChainedVerify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd)); 18497 return tiError; 18498 break; 18499 } 18500 18501 Remainder = satOrgIOContext->OrgTL % DenomTL; 18502 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL; 18503 lba = satOrgIOContext->currentLBA; 18504 18505 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */ 18506 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2)); 18507 LBA[2] = (bit8)((lba & 0xF0) >> 8); 18508 LBA[3] = (bit8)(lba & 0xF); /* LSB */ 18509 18510 switch (satOrgIOContext->ATACmd) 18511 { 18512 case SAT_READ_VERIFY_SECTORS: 18513 fis->h.fisType = 0x27; /* Reg host to device */ 18514 fis->h.c_pmPort = 0x80; /* C bit is set */ 18515 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 18516 fis->h.features = 0; /* FIS reserve */ 18517 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 18518 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 18519 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 18520 18521 /* FIS LBA mode set LBA (27:24) */ 18522 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 18523 18524 fis->d.lbaLowExp = 0; 18525 fis->d.lbaMidExp = 0; 18526 fis->d.lbaHighExp = 0; 18527 fis->d.featuresExp = 0; 18528 if (satOrgIOContext->LoopNum == 1) 18529 { 18530 /* last loop */ 18531 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 18532 } 18533 else 18534 { 18535 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 18536 } 18537 fis->d.sectorCountExp = 0; 18538 fis->d.reserved4 = 0; 18539 fis->d.control = 0; /* FIS HOB bit clear */ 18540 fis->d.reserved5 = 0; 18541 18542 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 18543 18544 break; 18545 case SAT_READ_VERIFY_SECTORS_EXT: 18546 fis->h.fisType = 0x27; /* Reg host to device */ 18547 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18548 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT; /* 0x42 */ 18549 fis->h.features = 0; /* FIS reserve */ 18550 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 18551 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 18552 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 18553 fis->d.device = 0x40; /* FIS LBA mode set */ 18554 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 18555 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 18556 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 18557 fis->d.featuresExp = 0; /* FIS reserve */ 18558 if (satOrgIOContext->LoopNum == 1) 18559 { 18560 /* last loop */ 18561 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 18562 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 18563 } 18564 else 18565 { 18566 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 18567 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 18568 } 18569 fis->d.reserved4 = 0; 18570 fis->d.control = 0; /* FIS HOB bit clear */ 18571 fis->d.reserved5 = 0; 18572 18573 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 18574 18575 break; 18576 18577 default: 18578 SM_DBG1(("satChainedVerify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd)); 18579 return tiError; 18580 break; 18581 } 18582 18583 /* Initialize CB for SATA completion. 18584 */ 18585 /* chained data */ 18586 satIOContext->satCompleteCB = &smsatChainedVerifyCB; 18587 18588 18589 /* 18590 * Prepare SGL and send FIS to LL layer. 18591 */ 18592 satIOContext->reqType = agRequestType; /* Save it */ 18593 18594 status = smsataLLIOStart( smRoot, 18595 smIORequest, 18596 smDeviceHandle, 18597 smScsiRequest, 18598 satIOContext); 18599 18600 SM_DBG5(("satChainedVerify: return\n")); 18601 return (status); 18602 } 18603 18604 osGLOBAL bit32 18605 smsatWriteSame10_1( 18606 smRoot_t *smRoot, 18607 smIORequest_t *smIORequest, 18608 smDeviceHandle_t *smDeviceHandle, 18609 smScsiInitiatorRequest_t *smScsiRequest, 18610 smSatIOContext_t *satIOContext, 18611 bit32 lba 18612 ) 18613 { 18614 /* 18615 sends SAT_WRITE_DMA_EXT 18616 */ 18617 18618 bit32 status; 18619 bit32 agRequestType; 18620 agsaFisRegHostToDevice_t *fis; 18621 bit8 lba1, lba2 ,lba3, lba4; 18622 18623 SM_DBG5(("smsatWriteSame10_1: start\n")); 18624 fis = satIOContext->pFis; 18625 /* MSB */ 18626 lba1 = (bit8)((lba & 0xFF000000) >> (8*3)); 18627 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2)); 18628 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1)); 18629 /* LSB */ 18630 lba4 = (bit8)(lba & 0x000000FF); 18631 /* SAT_WRITE_DMA_EXT */ 18632 fis->h.fisType = 0x27; /* Reg host to device */ 18633 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18634 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 18635 fis->h.features = 0; /* FIS reserve */ 18636 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */ 18637 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */ 18638 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */ 18639 fis->d.device = 0x40; /* FIS LBA mode set */ 18640 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */ 18641 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 18642 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 18643 fis->d.featuresExp = 0; /* FIS reserve */ 18644 /* one sector at a time */ 18645 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 18646 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 18647 fis->d.reserved4 = 0; 18648 fis->d.control = 0; /* FIS HOB bit clear */ 18649 fis->d.reserved5 = 0; 18650 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 18651 /* Initialize CB for SATA completion. 18652 */ 18653 satIOContext->satCompleteCB = &smsatWriteSame10CB; 18654 /* 18655 * Prepare SGL and send FIS to LL layer. 18656 */ 18657 satIOContext->reqType = agRequestType; /* Save it */ 18658 status = smsataLLIOStart( smRoot, 18659 smIORequest, 18660 smDeviceHandle, 18661 smScsiRequest, 18662 satIOContext); 18663 SM_DBG5(("smsatWriteSame10_1 return status %d\n", status)); 18664 return status; 18665 } 18666 18667 18668 osGLOBAL bit32 18669 smsatWriteSame10_2( 18670 smRoot_t *smRoot, 18671 smIORequest_t *smIORequest, 18672 smDeviceHandle_t *smDeviceHandle, 18673 smScsiInitiatorRequest_t *smScsiRequest, 18674 smSatIOContext_t *satIOContext, 18675 bit32 lba 18676 ) 18677 { 18678 /* 18679 sends SAT_WRITE_SECTORS_EXT 18680 */ 18681 18682 bit32 status; 18683 bit32 agRequestType; 18684 agsaFisRegHostToDevice_t *fis; 18685 bit8 lba1, lba2 ,lba3, lba4; 18686 18687 SM_DBG5(("smsatWriteSame10_2: start\n")); 18688 fis = satIOContext->pFis; 18689 /* MSB */ 18690 lba1 = (bit8)((lba & 0xFF000000) >> (8*3)); 18691 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2)); 18692 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1)); 18693 /* LSB */ 18694 lba4 = (bit8)(lba & 0x000000FF); 18695 /* SAT_WRITE_SECTORS_EXT */ 18696 fis->h.fisType = 0x27; /* Reg host to device */ 18697 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18698 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 18699 fis->h.features = 0; /* FIS reserve */ 18700 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */ 18701 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */ 18702 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */ 18703 fis->d.device = 0x40; /* FIS LBA mode set */ 18704 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */ 18705 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 18706 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 18707 fis->d.featuresExp = 0; /* FIS reserve */ 18708 /* one sector at a time */ 18709 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 18710 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 18711 fis->d.reserved4 = 0; 18712 fis->d.control = 0; /* FIS HOB bit clear */ 18713 fis->d.reserved5 = 0; 18714 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 18715 /* Initialize CB for SATA completion. 18716 */ 18717 satIOContext->satCompleteCB = &smsatWriteSame10CB; 18718 /* 18719 * Prepare SGL and send FIS to LL layer. 18720 */ 18721 satIOContext->reqType = agRequestType; /* Save it */ 18722 status = smsataLLIOStart( smRoot, 18723 smIORequest, 18724 smDeviceHandle, 18725 smScsiRequest, 18726 satIOContext); 18727 SM_DBG5(("smsatWriteSame10_2 return status %d\n", status)); 18728 return status; 18729 } 18730 18731 18732 osGLOBAL bit32 18733 smsatWriteSame10_3( 18734 smRoot_t *smRoot, 18735 smIORequest_t *smIORequest, 18736 smDeviceHandle_t *smDeviceHandle, 18737 smScsiInitiatorRequest_t *smScsiRequest, 18738 smSatIOContext_t *satIOContext, 18739 bit32 lba 18740 ) 18741 { 18742 /* 18743 sends SAT_WRITE_FPDMA_QUEUED 18744 */ 18745 18746 bit32 status; 18747 bit32 agRequestType; 18748 agsaFisRegHostToDevice_t *fis; 18749 bit8 lba1, lba2 ,lba3, lba4; 18750 18751 SM_DBG5(("smsatWriteSame10_3: start\n")); 18752 fis = satIOContext->pFis; 18753 /* MSB */ 18754 lba1 = (bit8)((lba & 0xFF000000) >> (8*3)); 18755 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2)); 18756 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1)); 18757 /* LSB */ 18758 lba4 = (bit8)(lba & 0x000000FF); 18759 18760 /* SAT_WRITE_FPDMA_QUEUED */ 18761 fis->h.fisType = 0x27; /* Reg host to device */ 18762 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18763 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 18764 18765 18766 /* one sector at a time */ 18767 fis->h.features = 1; /* FIS sector count (7:0) */ 18768 fis->d.featuresExp = 0; /* FIS sector count (15:8) */ 18769 18770 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */ 18771 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */ 18772 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */ 18773 /* NO FUA bit in the WRITE SAME 10 */ 18774 fis->d.device = 0x40; /* FIS FUA clear */ 18775 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */ 18776 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 18777 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 18778 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 18779 fis->d.sectorCountExp = 0; 18780 fis->d.reserved4 = 0; 18781 fis->d.control = 0; /* FIS HOB bit clear */ 18782 fis->d.reserved5 = 0; 18783 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 18784 18785 /* Initialize CB for SATA completion. 18786 */ 18787 satIOContext->satCompleteCB = &smsatWriteSame10CB; 18788 /* 18789 * Prepare SGL and send FIS to LL layer. 18790 */ 18791 satIOContext->reqType = agRequestType; /* Save it */ 18792 status = smsataLLIOStart( smRoot, 18793 smIORequest, 18794 smDeviceHandle, 18795 smScsiRequest, 18796 satIOContext); 18797 18798 SM_DBG5(("smsatWriteSame10_3 return status %d\n", status)); 18799 return status; 18800 } 18801 18802 osGLOBAL bit32 18803 smsatStartStopUnit_1( 18804 smRoot_t *smRoot, 18805 smIORequest_t *smIORequest, 18806 smDeviceHandle_t *smDeviceHandle, 18807 smScsiInitiatorRequest_t *smScsiRequest, 18808 smSatIOContext_t *satIOContext 18809 ) 18810 { 18811 /* 18812 SAT Rev 8, Table 48, 9.11.3 p55 18813 sends STANDBY 18814 */ 18815 bit32 status; 18816 bit32 agRequestType; 18817 agsaFisRegHostToDevice_t *fis; 18818 18819 SM_DBG5(("smsatStartStopUnit_1: start\n")); 18820 fis = satIOContext->pFis; 18821 /* STANDBY */ 18822 fis->h.fisType = 0x27; /* Reg host to device */ 18823 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18824 fis->h.command = SAT_STANDBY; /* 0xE2 */ 18825 fis->h.features = 0; /* FIS features NA */ 18826 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 18827 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 18828 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 18829 fis->d.lbaLowExp = 0; 18830 fis->d.lbaMidExp = 0; 18831 fis->d.lbaHighExp = 0; 18832 fis->d.featuresExp = 0; 18833 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 18834 fis->d.sectorCountExp = 0; 18835 fis->d.reserved4 = 0; 18836 fis->d.device = 0; /* 0 */ 18837 fis->d.control = 0; /* FIS HOB bit clear */ 18838 fis->d.reserved5 = 0; 18839 18840 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 18841 18842 /* Initialize CB for SATA completion. 18843 */ 18844 satIOContext->satCompleteCB = &smsatStartStopUnitCB; 18845 18846 /* 18847 * Prepare SGL and send FIS to LL layer. 18848 */ 18849 satIOContext->reqType = agRequestType; /* Save it */ 18850 18851 status = smsataLLIOStart( smRoot, 18852 smIORequest, 18853 smDeviceHandle, 18854 smScsiRequest, 18855 satIOContext); 18856 18857 SM_DBG5(("smsatStartStopUnit_1 return status %d\n", status)); 18858 return status; 18859 } 18860 18861 osGLOBAL bit32 18862 smsatSendDiagnostic_1( 18863 smRoot_t *smRoot, 18864 smIORequest_t *smIORequest, 18865 smDeviceHandle_t *smDeviceHandle, 18866 smScsiInitiatorRequest_t *smScsiRequest, 18867 smSatIOContext_t *satIOContext 18868 ) 18869 { 18870 /* 18871 SAT Rev9, Table29, p41 18872 send 2nd SAT_READ_VERIFY_SECTORS(_EXT) 18873 */ 18874 bit32 status; 18875 bit32 agRequestType; 18876 smDeviceData_t *pSatDevData; 18877 agsaFisRegHostToDevice_t *fis; 18878 18879 SM_DBG5(("smsatSendDiagnostic_1: start\n")); 18880 pSatDevData = satIOContext->pSatDevData; 18881 fis = satIOContext->pFis; 18882 /* 18883 sector count 1, LBA MAX 18884 */ 18885 if (pSatDevData->sat48BitSupport == agTRUE) 18886 { 18887 /* sends READ VERIFY SECTOR(S) EXT*/ 18888 fis->h.fisType = 0x27; /* Reg host to device */ 18889 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18890 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 18891 fis->h.features = 0; /* FIS reserve */ 18892 fis->d.lbaLow = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */ 18893 fis->d.lbaMid = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */ 18894 fis->d.lbaHigh = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */ 18895 fis->d.lbaLowExp = pSatDevData->satMaxLBA[4]; /* FIS LBA (31:24) */ 18896 fis->d.lbaMidExp = pSatDevData->satMaxLBA[3]; /* FIS LBA (39:32) */ 18897 fis->d.lbaHighExp = pSatDevData->satMaxLBA[2]; /* FIS LBA (47:40) */ 18898 fis->d.featuresExp = 0; /* FIS reserve */ 18899 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 18900 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 18901 fis->d.reserved4 = 0; 18902 fis->d.device = 0x40; /* 01000000 */ 18903 fis->d.control = 0; /* FIS HOB bit clear */ 18904 fis->d.reserved5 = 0; 18905 18906 } 18907 else 18908 { 18909 /* READ VERIFY SECTOR(S)*/ 18910 fis->h.fisType = 0x27; /* Reg host to device */ 18911 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18912 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 18913 fis->h.features = 0; /* FIS features NA */ 18914 fis->d.lbaLow = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */ 18915 fis->d.lbaMid = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */ 18916 fis->d.lbaHigh = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */ 18917 fis->d.lbaLowExp = 0; 18918 fis->d.lbaMidExp = 0; 18919 fis->d.lbaHighExp = 0; 18920 fis->d.featuresExp = 0; 18921 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 18922 fis->d.sectorCountExp = 0; 18923 fis->d.reserved4 = 0; 18924 fis->d.device = (bit8)((0x4 << 4) | (pSatDevData->satMaxLBA[4] & 0xF)); 18925 /* DEV and LBA 27:24 */ 18926 fis->d.control = 0; /* FIS HOB bit clear */ 18927 fis->d.reserved5 = 0; 18928 18929 } 18930 18931 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 18932 18933 /* Initialize CB for SATA completion. 18934 */ 18935 satIOContext->satCompleteCB = &smsatSendDiagnosticCB; 18936 18937 /* 18938 * Prepare SGL and send FIS to LL layer. 18939 */ 18940 satIOContext->reqType = agRequestType; /* Save it */ 18941 18942 status = smsataLLIOStart( smRoot, 18943 smIORequest, 18944 smDeviceHandle, 18945 smScsiRequest, 18946 satIOContext); 18947 18948 18949 return status; 18950 } 18951 18952 osGLOBAL bit32 18953 smsatSendDiagnostic_2( 18954 smRoot_t *smRoot, 18955 smIORequest_t *smIORequest, 18956 smDeviceHandle_t *smDeviceHandle, 18957 smScsiInitiatorRequest_t *smScsiRequest, 18958 smSatIOContext_t *satIOContext 18959 ) 18960 { 18961 /* 18962 SAT Rev9, Table29, p41 18963 send 3rd SAT_READ_VERIFY_SECTORS(_EXT) 18964 */ 18965 bit32 status; 18966 bit32 agRequestType; 18967 smDeviceData_t *pSatDevData; 18968 agsaFisRegHostToDevice_t *fis; 18969 18970 SM_DBG5(("smsatSendDiagnostic_2: start\n")); 18971 18972 pSatDevData = satIOContext->pSatDevData; 18973 fis = satIOContext->pFis; 18974 /* 18975 sector count 1, LBA Random 18976 */ 18977 if (pSatDevData->sat48BitSupport == agTRUE) 18978 { 18979 /* sends READ VERIFY SECTOR(S) EXT*/ 18980 fis->h.fisType = 0x27; /* Reg host to device */ 18981 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18982 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 18983 fis->h.features = 0; /* FIS reserve */ 18984 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */ 18985 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 18986 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 18987 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 18988 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 18989 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 18990 fis->d.featuresExp = 0; /* FIS reserve */ 18991 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 18992 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 18993 fis->d.reserved4 = 0; 18994 fis->d.device = 0x40; /* 01000000 */ 18995 fis->d.control = 0; /* FIS HOB bit clear */ 18996 fis->d.reserved5 = 0; 18997 18998 } 18999 else 19000 { 19001 /* READ VERIFY SECTOR(S)*/ 19002 fis->h.fisType = 0x27; /* Reg host to device */ 19003 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19004 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 19005 fis->h.features = 0; /* FIS features NA */ 19006 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */ 19007 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 19008 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 19009 fis->d.lbaLowExp = 0; 19010 fis->d.lbaMidExp = 0; 19011 fis->d.lbaHighExp = 0; 19012 fis->d.featuresExp = 0; 19013 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 19014 fis->d.sectorCountExp = 0; 19015 fis->d.reserved4 = 0; 19016 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 19017 fis->d.control = 0; /* FIS HOB bit clear */ 19018 fis->d.reserved5 = 0; 19019 19020 } 19021 19022 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 19023 19024 /* Initialize CB for SATA completion. 19025 */ 19026 satIOContext->satCompleteCB = &smsatSendDiagnosticCB; 19027 19028 /* 19029 * Prepare SGL and send FIS to LL layer. 19030 */ 19031 satIOContext->reqType = agRequestType; /* Save it */ 19032 19033 status = smsataLLIOStart( smRoot, 19034 smIORequest, 19035 smDeviceHandle, 19036 smScsiRequest, 19037 satIOContext); 19038 19039 19040 return status; 19041 } 19042 19043 osGLOBAL bit32 19044 smsatModeSelect6n10_1( 19045 smRoot_t *smRoot, 19046 smIORequest_t *smIORequest, 19047 smDeviceHandle_t *smDeviceHandle, 19048 smScsiInitiatorRequest_t *smScsiRequest, 19049 smSatIOContext_t *satIOContext 19050 ) 19051 { 19052 /* sends either ATA SET FEATURES based on DRA bit */ 19053 bit32 status; 19054 bit32 agRequestType; 19055 agsaFisRegHostToDevice_t *fis; 19056 bit8 *pLogPage; /* Log Page data buffer */ 19057 bit32 StartingIndex = 0; 19058 19059 fis = satIOContext->pFis; 19060 pLogPage = (bit8 *) smScsiRequest->sglVirtualAddr; 19061 SM_DBG5(("smsatModeSelect6n10_1: start\n")); 19062 19063 if (pLogPage[3] == 8) 19064 { 19065 /* mode parameter block descriptor exists */ 19066 StartingIndex = 12; 19067 } 19068 else 19069 { 19070 /* mode parameter block descriptor does not exist */ 19071 StartingIndex = 4; 19072 } 19073 19074 /* sends ATA SET FEATURES based on DRA bit */ 19075 if ( !(pLogPage[StartingIndex + 12] & SCSI_MODE_SELECT6_DRA_MASK) ) 19076 { 19077 SM_DBG5(("smsatModeSelect6n10_1: enable read look-ahead feature\n")); 19078 /* sends SET FEATURES */ 19079 fis->h.fisType = 0x27; /* Reg host to device */ 19080 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19081 19082 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 19083 fis->h.features = 0xAA; /* enable read look-ahead */ 19084 fis->d.lbaLow = 0; /* */ 19085 fis->d.lbaMid = 0; /* */ 19086 fis->d.lbaHigh = 0; /* */ 19087 fis->d.device = 0; /* */ 19088 fis->d.lbaLowExp = 0; /* */ 19089 fis->d.lbaMidExp = 0; /* */ 19090 fis->d.lbaHighExp = 0; /* */ 19091 fis->d.featuresExp = 0; /* */ 19092 fis->d.sectorCount = 0; /* */ 19093 fis->d.sectorCountExp = 0; /* */ 19094 fis->d.reserved4 = 0; 19095 fis->d.control = 0; /* FIS HOB bit clear */ 19096 fis->d.reserved5 = 0; 19097 19098 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 19099 19100 /* Initialize CB for SATA completion. 19101 */ 19102 satIOContext->satCompleteCB = &smsatModeSelect6n10CB; 19103 19104 /* 19105 * Prepare SGL and send FIS to LL layer. 19106 */ 19107 satIOContext->reqType = agRequestType; /* Save it */ 19108 19109 status = smsataLLIOStart( smRoot, 19110 smIORequest, 19111 smDeviceHandle, 19112 smScsiRequest, 19113 satIOContext); 19114 return status; 19115 } 19116 else 19117 { 19118 SM_DBG5(("smsatModeSelect6n10_1: disable read look-ahead feature\n")); 19119 /* sends SET FEATURES */ 19120 fis->h.fisType = 0x27; /* Reg host to device */ 19121 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19122 19123 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 19124 fis->h.features = 0x55; /* disable read look-ahead */ 19125 fis->d.lbaLow = 0; /* */ 19126 fis->d.lbaMid = 0; /* */ 19127 fis->d.lbaHigh = 0; /* */ 19128 fis->d.device = 0; /* */ 19129 fis->d.lbaLowExp = 0; /* */ 19130 fis->d.lbaMidExp = 0; /* */ 19131 fis->d.lbaHighExp = 0; /* */ 19132 fis->d.featuresExp = 0; /* */ 19133 fis->d.sectorCount = 0; /* */ 19134 fis->d.sectorCountExp = 0; /* */ 19135 fis->d.reserved4 = 0; 19136 fis->d.control = 0; /* FIS HOB bit clear */ 19137 fis->d.reserved5 = 0; 19138 19139 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 19140 19141 /* Initialize CB for SATA completion. 19142 */ 19143 satIOContext->satCompleteCB = &smsatModeSelect6n10CB; 19144 19145 /* 19146 * Prepare SGL and send FIS to LL layer. 19147 */ 19148 satIOContext->reqType = agRequestType; /* Save it */ 19149 19150 status = smsataLLIOStart( smRoot, 19151 smIORequest, 19152 smDeviceHandle, 19153 smScsiRequest, 19154 satIOContext); 19155 return status; 19156 } 19157 } 19158 19159 19160 osGLOBAL bit32 19161 smsatLogSense_1( 19162 smRoot_t *smRoot, 19163 smIORequest_t *smIORequest, 19164 smDeviceHandle_t *smDeviceHandle, 19165 smScsiInitiatorRequest_t *smScsiRequest, 19166 smSatIOContext_t *satIOContext 19167 ) 19168 { 19169 bit32 status; 19170 bit32 agRequestType; 19171 smDeviceData_t *pSatDevData; 19172 agsaFisRegHostToDevice_t *fis; 19173 19174 pSatDevData = satIOContext->pSatDevData; 19175 fis = satIOContext->pFis; 19176 19177 SM_DBG5(("smsatLogSense_1: start\n")); 19178 19179 /* SAT Rev 8, 10.2.4 p74 */ 19180 if ( pSatDevData->sat48BitSupport == agTRUE ) 19181 { 19182 SM_DBG5(("smsatLogSense_1: case 2-1 sends READ LOG EXT\n")); 19183 /* sends READ LOG EXT */ 19184 fis->h.fisType = 0x27; /* Reg host to device */ 19185 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19186 19187 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */ 19188 fis->h.features = 0; /* FIS reserve */ 19189 fis->d.lbaLow = 0x07; /* 0x07 */ 19190 fis->d.lbaMid = 0; /* */ 19191 fis->d.lbaHigh = 0; /* */ 19192 fis->d.device = 0; /* */ 19193 fis->d.lbaLowExp = 0; /* */ 19194 fis->d.lbaMidExp = 0; /* */ 19195 fis->d.lbaHighExp = 0; /* */ 19196 fis->d.featuresExp = 0; /* FIS reserve */ 19197 fis->d.sectorCount = 0x01; /* 1 sector counts */ 19198 fis->d.sectorCountExp = 0x00; /* 1 sector counts */ 19199 fis->d.reserved4 = 0; 19200 fis->d.control = 0; /* FIS HOB bit clear */ 19201 fis->d.reserved5 = 0; 19202 19203 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 19204 19205 /* Initialize CB for SATA completion. 19206 */ 19207 satIOContext->satCompleteCB = &smsatLogSenseCB; 19208 19209 /* 19210 * Prepare SGL and send FIS to LL layer. 19211 */ 19212 satIOContext->reqType = agRequestType; /* Save it */ 19213 19214 status = smsataLLIOStart( smRoot, 19215 smIORequest, 19216 smDeviceHandle, 19217 smScsiRequest, 19218 satIOContext); 19219 return status; 19220 19221 } 19222 else 19223 { 19224 SM_DBG5(("smsatLogSense_1: case 2-2 sends SMART READ LOG\n")); 19225 /* sends SMART READ LOG */ 19226 fis->h.fisType = 0x27; /* Reg host to device */ 19227 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19228 19229 fis->h.command = SAT_SMART; /* 0x2F */ 19230 fis->h.features = SAT_SMART_READ_LOG; /* 0xd5 */ 19231 fis->d.lbaLow = 0x06; /* 0x06 */ 19232 fis->d.lbaMid = 0x00; /* 0x4f */ 19233 fis->d.lbaHigh = 0x00; /* 0xc2 */ 19234 fis->d.device = 0; /* */ 19235 fis->d.lbaLowExp = 0; /* */ 19236 fis->d.lbaMidExp = 0; /* */ 19237 fis->d.lbaHighExp = 0; /* */ 19238 fis->d.featuresExp = 0; /* FIS reserve */ 19239 fis->d.sectorCount = 0x01; /* */ 19240 fis->d.sectorCountExp = 0x00; /* */ 19241 fis->d.reserved4 = 0; 19242 fis->d.control = 0; /* FIS HOB bit clear */ 19243 fis->d.reserved5 = 0; 19244 19245 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 19246 19247 /* Initialize CB for SATA completion. 19248 */ 19249 satIOContext->satCompleteCB = &smsatLogSenseCB; 19250 19251 /* 19252 * Prepare SGL and send FIS to LL layer. 19253 */ 19254 satIOContext->reqType = agRequestType; /* Save it */ 19255 19256 status = smsataLLIOStart( smRoot, 19257 smIORequest, 19258 smDeviceHandle, 19259 smScsiRequest, 19260 satIOContext); 19261 return status; 19262 19263 } 19264 } 19265 19266 osGLOBAL bit32 19267 smsatReassignBlocks_2( 19268 smRoot_t *smRoot, 19269 smIORequest_t *smIORequest, 19270 smDeviceHandle_t *smDeviceHandle, 19271 smScsiInitiatorRequest_t *smScsiRequest, 19272 smSatIOContext_t *satIOContext, 19273 bit8 *LBA 19274 ) 19275 { 19276 /* 19277 assumes all LBA fits in ATA command; no boundary condition is checked here yet 19278 tiScsiRequest is TD generated for writing 19279 */ 19280 bit32 status; 19281 bit32 agRequestType; 19282 smDeviceData_t *pSatDevData; 19283 smScsiRspSense_t *pSense; 19284 agsaFisRegHostToDevice_t *fis; 19285 19286 pSense = satIOContext->pSense; 19287 pSatDevData = satIOContext->pSatDevData; 19288 fis = satIOContext->pFis; 19289 SM_DBG5(("smsatReassignBlocks_2: start\n")); 19290 19291 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 19292 { 19293 /* case 2 */ 19294 /* WRITE DMA*/ 19295 /* can't fit the transfer length */ 19296 SM_DBG5(("smsatReassignBlocks_2: case 2\n")); 19297 fis->h.fisType = 0x27; /* Reg host to device */ 19298 fis->h.c_pmPort = 0x80; /* C bit is set */ 19299 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 19300 fis->h.features = 0; /* FIS reserve */ 19301 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 19302 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 19303 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 19304 19305 /* FIS LBA mode set LBA (27:24) */ 19306 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF)); 19307 19308 fis->d.lbaLowExp = 0; 19309 fis->d.lbaMidExp = 0; 19310 fis->d.lbaHighExp = 0; 19311 fis->d.featuresExp = 0; 19312 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 19313 fis->d.sectorCountExp = 0; 19314 fis->d.reserved4 = 0; 19315 fis->d.control = 0; /* FIS HOB bit clear */ 19316 fis->d.reserved5 = 0; 19317 19318 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 19319 satIOContext->ATACmd = SAT_WRITE_DMA; 19320 } 19321 else 19322 { 19323 /* case 1 */ 19324 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 19325 /* WRITE SECTORS for easier implemetation */ 19326 /* can't fit the transfer length */ 19327 SM_DBG5(("smsatReassignBlocks_2: case 1\n")); 19328 fis->h.fisType = 0x27; /* Reg host to device */ 19329 fis->h.c_pmPort = 0x80; /* C bit is set */ 19330 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 19331 fis->h.features = 0; /* FIS reserve */ 19332 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 19333 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 19334 fis->d.lbaHigh = LBA[7]; /* FIS LBA (23:16) */ 19335 19336 /* FIS LBA mode set LBA (27:24) */ 19337 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF)); 19338 19339 fis->d.lbaLowExp = 0; 19340 fis->d.lbaMidExp = 0; 19341 fis->d.lbaHighExp = 0; 19342 fis->d.featuresExp = 0; 19343 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 19344 fis->d.sectorCountExp = 0; 19345 fis->d.reserved4 = 0; 19346 fis->d.control = 0; /* FIS HOB bit clear */ 19347 fis->d.reserved5 = 0; 19348 19349 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 19350 satIOContext->ATACmd = SAT_WRITE_SECTORS; 19351 } 19352 19353 /* case 3 and 4 */ 19354 if (pSatDevData->sat48BitSupport == agTRUE) 19355 { 19356 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 19357 { 19358 /* case 3 */ 19359 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 19360 SM_DBG5(("smsatReassignBlocks_2: case 3\n")); 19361 fis->h.fisType = 0x27; /* Reg host to device */ 19362 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19363 19364 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 19365 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 19366 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 19367 19368 fis->h.features = 0; /* FIS reserve */ 19369 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 19370 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 19371 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 19372 fis->d.device = 0x40; /* FIS LBA mode set */ 19373 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */ 19374 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */ 19375 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */ 19376 fis->d.featuresExp = 0; /* FIS reserve */ 19377 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 19378 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 19379 fis->d.reserved4 = 0; 19380 fis->d.control = 0; /* FIS HOB bit clear */ 19381 fis->d.reserved5 = 0; 19382 19383 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 19384 } 19385 else 19386 { 19387 /* case 4 */ 19388 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 19389 /* WRITE SECTORS EXT for easier implemetation */ 19390 SM_DBG5(("smsatReassignBlocks_2: case 4\n")); 19391 fis->h.fisType = 0x27; /* Reg host to device */ 19392 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19393 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 19394 19395 fis->h.features = 0; /* FIS reserve */ 19396 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 19397 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 19398 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 19399 fis->d.device = 0x40; /* FIS LBA mode set */ 19400 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */ 19401 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */ 19402 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */ 19403 fis->d.featuresExp = 0; /* FIS reserve */ 19404 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 19405 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 19406 fis->d.reserved4 = 0; 19407 fis->d.control = 0; /* FIS HOB bit clear */ 19408 fis->d.reserved5 = 0; 19409 19410 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 19411 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 19412 } 19413 } 19414 /* case 5 */ 19415 if (pSatDevData->satNCQ == agTRUE) 19416 { 19417 /* WRITE FPDMA QUEUED */ 19418 if (pSatDevData->sat48BitSupport != agTRUE) 19419 { 19420 SM_DBG5(("smsatReassignBlocks_2: case 5 !!! error NCQ but 28 bit address support \n")); 19421 smsatSetSensePayload( pSense, 19422 SCSI_SNSKEY_HARDWARE_ERROR, 19423 0, 19424 SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED, 19425 satIOContext); 19426 19427 /*smEnqueueIO(smRoot, satIOContext);*/ 19428 19429 tdsmIOCompletedCB( smRoot, 19430 smIORequest, 19431 smIOSuccess, 19432 SCSI_STAT_CHECK_CONDITION, 19433 satIOContext->pSmSenseData, 19434 satIOContext->interruptContext ); 19435 return SM_RC_SUCCESS; 19436 } 19437 SM_DBG6(("satWrite10: case 5\n")); 19438 19439 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 19440 19441 fis->h.fisType = 0x27; /* Reg host to device */ 19442 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19443 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 19444 fis->h.features = 1; /* FIS sector count (7:0) */ 19445 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 19446 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 19447 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 19448 19449 /* Check FUA bit */ 19450 fis->d.device = 0x40; /* FIS FUA clear */ 19451 19452 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */ 19453 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */ 19454 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */ 19455 fis->d.featuresExp = 0; /* FIS sector count (15:8) */ 19456 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 19457 fis->d.sectorCountExp = 0; 19458 fis->d.reserved4 = 0; 19459 fis->d.control = 0; /* FIS HOB bit clear */ 19460 fis->d.reserved5 = 0; 19461 19462 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 19463 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 19464 } 19465 19466 satIOContext->satCompleteCB = &smsatReassignBlocksCB; 19467 19468 /* 19469 * Prepare SGL and send FIS to LL layer. 19470 */ 19471 satIOContext->reqType = agRequestType; /* Save it */ 19472 19473 status = smsataLLIOStart( smRoot, 19474 smIORequest, 19475 smDeviceHandle, 19476 /* not the original, should be the TD generated one */ 19477 smScsiRequest, 19478 satIOContext); 19479 return (status); 19480 } 19481 19482 osGLOBAL bit32 19483 smsatReassignBlocks_1( 19484 smRoot_t *smRoot, 19485 smIORequest_t *smIORequest, 19486 smDeviceHandle_t *smDeviceHandle, 19487 smScsiInitiatorRequest_t *smScsiRequest, 19488 smSatIOContext_t *satIOContext, 19489 smSatIOContext_t *satOrgIOContext 19490 ) 19491 { 19492 /* 19493 assumes all LBA fits in ATA command; no boundary condition is checked here yet 19494 tiScsiRequest is OS generated; needs for accessing parameter list 19495 */ 19496 bit32 agRequestType; 19497 smDeviceData_t *pSatDevData; 19498 smIniScsiCmnd_t *scsiCmnd; 19499 agsaFisRegHostToDevice_t *fis; 19500 bit8 *pParmList; /* Log Page data buffer */ 19501 bit8 LongLBA; 19502 bit8 LBA[8]; 19503 bit32 startingIndex; 19504 19505 pSatDevData = satIOContext->pSatDevData; 19506 scsiCmnd = &smScsiRequest->scsiCmnd; 19507 fis = satIOContext->pFis; 19508 pParmList = (bit8 *) smScsiRequest->sglVirtualAddr; 19509 SM_DBG5(("smsatReassignBlocks_1: start\n")); 19510 LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK); 19511 sm_memset(LBA, 0, sizeof(LBA)); 19512 startingIndex = satOrgIOContext->ParmIndex; 19513 if (LongLBA == 0) 19514 { 19515 LBA[4] = pParmList[startingIndex]; 19516 LBA[5] = pParmList[startingIndex+1]; 19517 LBA[6] = pParmList[startingIndex+2]; 19518 LBA[7] = pParmList[startingIndex+3]; 19519 startingIndex = startingIndex + 4; 19520 } 19521 else 19522 { 19523 LBA[0] = pParmList[startingIndex]; 19524 LBA[1] = pParmList[startingIndex+1]; 19525 LBA[2] = pParmList[startingIndex+2]; 19526 LBA[3] = pParmList[startingIndex+3]; 19527 LBA[4] = pParmList[startingIndex+4]; 19528 LBA[5] = pParmList[startingIndex+5]; 19529 LBA[6] = pParmList[startingIndex+6]; 19530 LBA[7] = pParmList[startingIndex+7]; 19531 startingIndex = startingIndex + 8; 19532 } 19533 19534 if (pSatDevData->sat48BitSupport == agTRUE) 19535 { 19536 /* sends READ VERIFY SECTOR(S) EXT*/ 19537 fis->h.fisType = 0x27; /* Reg host to device */ 19538 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19539 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 19540 fis->h.features = 0; /* FIS reserve */ 19541 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 19542 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 19543 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 19544 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */ 19545 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */ 19546 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */ 19547 fis->d.featuresExp = 0; /* FIS reserve */ 19548 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 19549 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 19550 fis->d.reserved4 = 0; 19551 fis->d.device = 0x40; /* 01000000 */ 19552 fis->d.control = 0; /* FIS HOB bit clear */ 19553 fis->d.reserved5 = 0; 19554 } 19555 else 19556 { 19557 /* READ VERIFY SECTOR(S)*/ 19558 fis->h.fisType = 0x27; /* Reg host to device */ 19559 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19560 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 19561 fis->h.features = 0; /* FIS features NA */ 19562 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 19563 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 19564 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 19565 fis->d.lbaLowExp = 0; 19566 fis->d.lbaMidExp = 0; 19567 fis->d.lbaHighExp = 0; 19568 fis->d.featuresExp = 0; 19569 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 19570 fis->d.sectorCountExp = 0; 19571 fis->d.reserved4 = 0; 19572 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF)); 19573 /* DEV and LBA 27:24 */ 19574 fis->d.control = 0; /* FIS HOB bit clear */ 19575 fis->d.reserved5 = 0; 19576 } 19577 19578 sm_memcpy(satOrgIOContext->LBA, LBA, 8); 19579 satOrgIOContext->ParmIndex = startingIndex; 19580 19581 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 19582 19583 /* Initialize CB for SATA completion. 19584 */ 19585 satIOContext->satCompleteCB = &smsatReassignBlocksCB; 19586 19587 /* 19588 * Prepare SGL and send FIS to LL layer. 19589 */ 19590 satIOContext->reqType = agRequestType; /* Save it */ 19591 19592 smsataLLIOStart( smRoot, 19593 smIORequest, 19594 smDeviceHandle, 19595 smScsiRequest, 19596 satIOContext); 19597 19598 return SM_RC_SUCCESS; 19599 } 19600 19601 osGLOBAL bit32 19602 smsatSendReadLogExt( 19603 smRoot_t *smRoot, 19604 smIORequest_t *smIORequest, 19605 smDeviceHandle_t *smDeviceHandle, 19606 smScsiInitiatorRequest_t *smScsiRequest, 19607 smSatIOContext_t *satIOContext 19608 ) 19609 { 19610 bit32 status; 19611 bit32 agRequestType; 19612 agsaFisRegHostToDevice_t *fis; 19613 19614 fis = satIOContext->pFis; 19615 SM_DBG1(("smsatSendReadLogExt: start\n")); 19616 fis->h.fisType = 0x27; /* Reg host to device */ 19617 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19618 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */ 19619 fis->h.features = 0; /* FIS reserve */ 19620 fis->d.lbaLow = 0x10; /* Page number */ 19621 fis->d.lbaMid = 0; /* */ 19622 fis->d.lbaHigh = 0; /* */ 19623 fis->d.device = 0; /* DEV is ignored in SATA */ 19624 fis->d.lbaLowExp = 0; /* */ 19625 fis->d.lbaMidExp = 0; /* */ 19626 fis->d.lbaHighExp = 0; /* */ 19627 fis->d.featuresExp = 0; /* FIS reserve */ 19628 fis->d.sectorCount = 0x01; /* 1 sector counts*/ 19629 fis->d.sectorCountExp = 0x00; /* 1 sector counts */ 19630 fis->d.reserved4 = 0; 19631 fis->d.control = 0; /* FIS HOB bit clear */ 19632 fis->d.reserved5 = 0; 19633 19634 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 19635 19636 /* Initialize CB for SATA completion. 19637 */ 19638 satIOContext->satCompleteCB = &smsatReadLogExtCB; 19639 19640 /* 19641 * Prepare SGL and send FIS to LL layer. 19642 */ 19643 satIOContext->reqType = agRequestType; /* Save it */ 19644 19645 status = smsataLLIOStart( smRoot, 19646 smIORequest, 19647 smDeviceHandle, 19648 smScsiRequest, 19649 satIOContext); 19650 19651 SM_DBG1(("smsatSendReadLogExt: end status %d!!!\n", status)); 19652 19653 return (status); 19654 } 19655 19656 osGLOBAL bit32 19657 smsatCheckPowerMode( 19658 smRoot_t *smRoot, 19659 smIORequest_t *smIORequest, 19660 smDeviceHandle_t *smDeviceHandle, 19661 smScsiInitiatorRequest_t *smScsiRequest, 19662 smSatIOContext_t *satIOContext 19663 ) 19664 { 19665 /* 19666 sends SAT_CHECK_POWER_MODE as a part of ABORT TASKMANGEMENT for NCQ commands 19667 internally generated - no directly corresponding scsi 19668 */ 19669 bit32 status; 19670 bit32 agRequestType; 19671 agsaFisRegHostToDevice_t *fis; 19672 19673 fis = satIOContext->pFis; 19674 SM_DBG1(("smsatCheckPowerMode: start\n")); 19675 /* 19676 * Send the ATA CHECK POWER MODE command. 19677 */ 19678 fis->h.fisType = 0x27; /* Reg host to device */ 19679 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19680 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */ 19681 fis->h.features = 0; 19682 fis->d.lbaLow = 0; 19683 fis->d.lbaMid = 0; 19684 fis->d.lbaHigh = 0; 19685 fis->d.device = 0; 19686 fis->d.lbaLowExp = 0; 19687 fis->d.lbaMidExp = 0; 19688 fis->d.lbaHighExp = 0; 19689 fis->d.featuresExp = 0; 19690 fis->d.sectorCount = 0; 19691 fis->d.sectorCountExp = 0; 19692 fis->d.reserved4 = 0; 19693 fis->d.control = 0; /* FIS HOB bit clear */ 19694 fis->d.reserved5 = 0; 19695 19696 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 19697 19698 /* Initialize CB for SATA completion. 19699 */ 19700 satIOContext->satCompleteCB = &smsatCheckPowerModeCB; 19701 19702 /* 19703 * Prepare SGL and send FIS to LL layer. 19704 */ 19705 satIOContext->reqType = agRequestType; /* Save it */ 19706 19707 status = smsataLLIOStart( smRoot, 19708 smIORequest, 19709 smDeviceHandle, 19710 smScsiRequest, 19711 satIOContext); 19712 19713 SM_DBG5(("smsatCheckPowerMode: return\n")); 19714 19715 return status; 19716 } 19717 19718 osGLOBAL bit32 19719 smsatResetDevice( 19720 smRoot_t *smRoot, 19721 smIORequest_t *smIORequest, 19722 smDeviceHandle_t *smDeviceHandle, 19723 smScsiInitiatorRequest_t *smScsiRequest, /* NULL */ 19724 smSatIOContext_t *satIOContext 19725 ) 19726 { 19727 bit32 status; 19728 bit32 agRequestType; 19729 agsaFisRegHostToDevice_t *fis; 19730 #ifdef TD_DEBUG_ENABLE 19731 smIORequestBody_t *smIORequestBody; 19732 smSatInternalIo_t *satIntIoContext; 19733 #endif 19734 19735 fis = satIOContext->pFis; 19736 SM_DBG1(("smsatResetDevice: start\n")); 19737 #ifdef TD_DEBUG_ENABLE 19738 satIntIoContext = satIOContext->satIntIoContext; 19739 smIORequestBody = satIntIoContext->satIntRequestBody; 19740 #endif 19741 SM_DBG5(("smsatResetDevice: satIOContext %p smIORequestBody %p\n", satIOContext, smIORequestBody)); 19742 /* any fis should work */ 19743 fis->h.fisType = 0x27; /* Reg host to device */ 19744 fis->h.c_pmPort = 0; /* C Bit is not set */ 19745 fis->h.command = 0; /* any command */ 19746 fis->h.features = 0; /* FIS reserve */ 19747 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 19748 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 19749 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 19750 fis->d.device = 0; /* FIS LBA mode */ 19751 fis->d.lbaLowExp = 0; 19752 fis->d.lbaMidExp = 0; 19753 fis->d.lbaHighExp = 0; 19754 fis->d.featuresExp = 0; 19755 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 19756 fis->d.sectorCountExp = 0; 19757 fis->d.reserved4 = 0; 19758 fis->d.control = 0x4; /* SRST bit is set */ 19759 fis->d.reserved5 = 0; 19760 19761 agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT; 19762 19763 /* Initialize CB for SATA completion. 19764 */ 19765 satIOContext->satCompleteCB = &smsatResetDeviceCB; 19766 19767 /* 19768 * Prepare SGL and send FIS to LL layer. 19769 */ 19770 satIOContext->reqType = agRequestType; /* Save it */ 19771 19772 #ifdef SM_INTERNAL_DEBUG 19773 smhexdump("smsatResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 19774 #ifdef TD_DEBUG_ENABLE 19775 smhexdump("smsatResetDevice LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t)); 19776 #endif 19777 #endif 19778 19779 status = smsataLLIOStart( smRoot, 19780 smIORequest, 19781 smDeviceHandle, 19782 smScsiRequest, 19783 satIOContext); 19784 19785 SM_DBG6(("smsatResetDevice: end status %d\n", status)); 19786 return status; 19787 } 19788 19789 osGLOBAL bit32 19790 smsatDeResetDevice( 19791 smRoot_t *smRoot, 19792 smIORequest_t *smIORequest, 19793 smDeviceHandle_t *smDeviceHandle, 19794 smScsiInitiatorRequest_t *smScsiRequest, 19795 smSatIOContext_t *satIOContext 19796 ) 19797 { 19798 bit32 status; 19799 bit32 agRequestType; 19800 agsaFisRegHostToDevice_t *fis; 19801 #ifdef TD_DEBUG_ENABLE 19802 smIORequestBody_t *smIORequestBody; 19803 smSatInternalIo_t *satIntIoContext; 19804 #endif 19805 19806 fis = satIOContext->pFis; 19807 SM_DBG1(("smsatDeResetDevice: start\n")); 19808 #ifdef TD_DEBUG_ENABLE 19809 satIntIoContext = satIOContext->satIntIoContext; 19810 smIORequestBody = satIntIoContext->satIntRequestBody; 19811 #endif 19812 SM_DBG5(("smsatDeResetDevice: satIOContext %p smIORequestBody %p\n", satIOContext, smIORequestBody)); 19813 /* any fis should work */ 19814 fis->h.fisType = 0x27; /* Reg host to device */ 19815 fis->h.c_pmPort = 0; /* C Bit is not set */ 19816 fis->h.command = 0; /* any command */ 19817 fis->h.features = 0; /* FIS reserve */ 19818 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 19819 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 19820 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 19821 fis->d.device = 0; /* FIS LBA mode */ 19822 fis->d.lbaLowExp = 0; 19823 fis->d.lbaMidExp = 0; 19824 fis->d.lbaHighExp = 0; 19825 fis->d.featuresExp = 0; 19826 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 19827 fis->d.sectorCountExp = 0; 19828 fis->d.reserved4 = 0; 19829 fis->d.control = 0; /* SRST bit is not set */ 19830 fis->d.reserved5 = 0; 19831 19832 agRequestType = AGSA_SATA_PROTOCOL_SRST_DEASSERT; 19833 19834 /* Initialize CB for SATA completion. 19835 */ 19836 satIOContext->satCompleteCB = &smsatDeResetDeviceCB; 19837 19838 /* 19839 * Prepare SGL and send FIS to LL layer. 19840 */ 19841 satIOContext->reqType = agRequestType; /* Save it */ 19842 19843 #ifdef SM_INTERNAL_DEBUG 19844 smhexdump("smsatDeResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 19845 #ifdef TD_DEBUG_ENABLE 19846 smhexdump("smsatDeResetDevice LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t)); 19847 #endif 19848 #endif 19849 19850 status = smsataLLIOStart( smRoot, 19851 smIORequest, 19852 smDeviceHandle, 19853 smScsiRequest, 19854 satIOContext); 19855 19856 SM_DBG6(("smsatDeResetDevice: end status %d\n", status)); 19857 return status; 19858 } 19859 19860 /* set feature for auto activate */ 19861 osGLOBAL bit32 19862 smsatSetFeaturesAA( 19863 smRoot_t *smRoot, 19864 smIORequest_t *smIORequest, 19865 smDeviceHandle_t *smDeviceHandle, 19866 smScsiInitiatorRequest_t *smScsiRequest, 19867 smSatIOContext_t *satIOContext 19868 ) 19869 { 19870 bit32 status = SM_RC_FAILURE; 19871 bit32 agRequestType; 19872 agsaFisRegHostToDevice_t *fis; 19873 19874 fis = satIOContext->pFis; 19875 SM_DBG2(("smsatSetFeaturesAA: start\n")); 19876 /* 19877 * Send the Set Features command. 19878 * See SATA II 1.0a spec 19879 */ 19880 fis->h.fisType = 0x27; /* Reg host to device */ 19881 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19882 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 19883 fis->h.features = 0x10; /* enable SATA feature */ 19884 fis->d.lbaLow = 0; 19885 fis->d.lbaMid = 0; 19886 fis->d.lbaHigh = 0; 19887 fis->d.device = 0; 19888 fis->d.lbaLowExp = 0; 19889 fis->d.lbaMidExp = 0; 19890 fis->d.lbaHighExp = 0; 19891 fis->d.featuresExp = 0; 19892 fis->d.sectorCount = 0x02; /* DMA Setup FIS Auto-Activate */ 19893 fis->d.sectorCountExp = 0; 19894 fis->d.reserved4 = 0; 19895 fis->d.control = 0; /* FIS HOB bit clear */ 19896 fis->d.reserved5 = 0; 19897 19898 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 19899 19900 /* Initialize CB for SATA completion. 19901 */ 19902 satIOContext->satCompleteCB = &smsatSetFeaturesAACB; 19903 19904 /* 19905 * Prepare SGL and send FIS to LL layer. 19906 */ 19907 satIOContext->reqType = agRequestType; /* Save it */ 19908 19909 status = smsataLLIOStart( smRoot, 19910 smIORequest, 19911 smDeviceHandle, 19912 smScsiRequest, 19913 satIOContext); 19914 19915 /* debugging code */ 19916 if (smIORequest->tdData == smIORequest->smData) 19917 { 19918 SM_DBG1(("smsatSetFeaturesAA: incorrect smIORequest\n")); 19919 } 19920 SM_DBG2(("smsatSetFeatures: return\n")); 19921 return status; 19922 } 19923 19924 19925 /* set feature for DMA transfer mode*/ 19926 osGLOBAL bit32 19927 smsatSetFeaturesDMA( 19928 smRoot_t *smRoot, 19929 smIORequest_t *smIORequest, 19930 smDeviceHandle_t *smDeviceHandle, 19931 smScsiInitiatorRequest_t *smScsiRequest, 19932 smSatIOContext_t *satIOContext 19933 ) 19934 { 19935 bit32 status = SM_RC_FAILURE; 19936 bit32 agRequestType; 19937 smDeviceData_t *pSatDevData; 19938 agsaFisRegHostToDevice_t *fis; 19939 19940 pSatDevData = satIOContext->pSatDevData; 19941 fis = satIOContext->pFis; 19942 SM_DBG2(("smsatSetFeaturesDMA: start\n")); 19943 /* 19944 * Send the Set Features command. 19945 * See SATA II 1.0a spec 19946 */ 19947 fis->h.fisType = 0x27; /* Reg host to device */ 19948 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19949 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 19950 fis->h.features = 0x03; /* enable ATA transfer mode */ 19951 fis->d.lbaLow = 0; 19952 fis->d.lbaMid = 0; 19953 fis->d.lbaHigh = 0; 19954 fis->d.device = 0; 19955 fis->d.lbaLowExp = 0; 19956 fis->d.lbaMidExp = 0; 19957 fis->d.lbaHighExp = 0; 19958 fis->d.featuresExp = 0; 19959 fis->d.sectorCount = 0x40 |(bit8)pSatDevData->satUltraDMAMode; /* enable Ultra DMA mode */ 19960 fis->d.sectorCountExp = 0; 19961 fis->d.reserved4 = 0; 19962 fis->d.control = 0; /* FIS HOB bit clear */ 19963 fis->d.reserved5 = 0; 19964 19965 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 19966 19967 /* Initialize CB for SATA completion. 19968 */ 19969 satIOContext->satCompleteCB = &smsatSetFeaturesDMACB; 19970 19971 /* 19972 * Prepare SGL and send FIS to LL layer. 19973 */ 19974 satIOContext->reqType = agRequestType; /* Save it */ 19975 19976 status = smsataLLIOStart( smRoot, 19977 smIORequest, 19978 smDeviceHandle, 19979 smScsiRequest, 19980 satIOContext); 19981 19982 /* debugging code */ 19983 if (smIORequest->tdData == smIORequest->smData) 19984 { 19985 SM_DBG1(("smsatSetFeaturesDMA: incorrect smIORequest\n")); 19986 } 19987 19988 SM_DBG2(("smsatSetFeaturesDMA: return\n")); 19989 19990 return status; 19991 } 19992 19993 /* set feature for Read Look Ahead*/ 19994 osGLOBAL bit32 19995 smsatSetFeaturesReadLookAhead( 19996 smRoot_t *smRoot, 19997 smIORequest_t *smIORequest, 19998 smDeviceHandle_t *smDeviceHandle, 19999 smScsiInitiatorRequest_t *smScsiRequest, 20000 smSatIOContext_t *satIOContext 20001 ) 20002 { 20003 bit32 status = SM_RC_FAILURE; 20004 bit32 agRequestType; 20005 agsaFisRegHostToDevice_t *fis; 20006 20007 fis = satIOContext->pFis; 20008 SM_DBG2(("smsatSetFeaturesReadLookAhead: start\n")); 20009 /* 20010 * Send the Set Features command. 20011 * See SATA II 1.0a spec 20012 */ 20013 fis->h.fisType = 0x27; /* Reg host to device */ 20014 fis->h.c_pmPort = 0x80; /* C Bit is set */ 20015 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 20016 fis->h.features = 0xAA; /* Enable read look-ahead feature */ 20017 fis->d.lbaLow = 0; 20018 fis->d.lbaMid = 0; 20019 fis->d.lbaHigh = 0; 20020 fis->d.device = 0; 20021 fis->d.lbaLowExp = 0; 20022 fis->d.lbaMidExp = 0; 20023 fis->d.lbaHighExp = 0; 20024 fis->d.featuresExp = 0; 20025 fis->d.sectorCount = 0; 20026 fis->d.sectorCountExp = 0; 20027 fis->d.reserved4 = 0; 20028 fis->d.control = 0; /* FIS HOB bit clear */ 20029 fis->d.reserved5 = 0; 20030 20031 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 20032 20033 /* Initialize CB for SATA completion. 20034 */ 20035 satIOContext->satCompleteCB = &smsatSetFeaturesReadLookAheadCB; 20036 20037 /* 20038 * Prepare SGL and send FIS to LL layer. 20039 */ 20040 satIOContext->reqType = agRequestType; /* Save it */ 20041 20042 status = smsataLLIOStart( smRoot, 20043 smIORequest, 20044 smDeviceHandle, 20045 smScsiRequest, 20046 satIOContext); 20047 20048 /* debugging code */ 20049 if (smIORequest->tdData == smIORequest->smData) 20050 { 20051 SM_DBG1(("smsatSetFeaturesReadLookAhead: incorrect smIORequest\n")); 20052 } 20053 20054 SM_DBG2(("smsatSetFeaturesReadLookAhead: return\n")); 20055 20056 return status; 20057 } 20058 20059 /* set feature for Volatile Write Cache*/ 20060 osGLOBAL bit32 20061 smsatSetFeaturesVolatileWriteCache( 20062 smRoot_t *smRoot, 20063 smIORequest_t *smIORequest, 20064 smDeviceHandle_t *smDeviceHandle, 20065 smScsiInitiatorRequest_t *smScsiRequest, 20066 smSatIOContext_t *satIOContext 20067 ) 20068 { 20069 bit32 status = SM_RC_FAILURE; 20070 bit32 agRequestType; 20071 agsaFisRegHostToDevice_t *fis; 20072 20073 fis = satIOContext->pFis; 20074 SM_DBG2(("smsatSetFeaturesVolatileWriteCache: start\n")); 20075 /* 20076 * Send the Set Features command. 20077 * See SATA II 1.0a spec 20078 */ 20079 fis->h.fisType = 0x27; /* Reg host to device */ 20080 fis->h.c_pmPort = 0x80; /* C Bit is set */ 20081 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 20082 fis->h.features = 0x02; /* Enable Volatile Write Cache feature */ 20083 fis->d.lbaLow = 0; 20084 fis->d.lbaMid = 0; 20085 fis->d.lbaHigh = 0; 20086 fis->d.device = 0; 20087 fis->d.lbaLowExp = 0; 20088 fis->d.lbaMidExp = 0; 20089 fis->d.lbaHighExp = 0; 20090 fis->d.featuresExp = 0; 20091 fis->d.sectorCount = 0; 20092 fis->d.sectorCountExp = 0; 20093 fis->d.reserved4 = 0; 20094 fis->d.control = 0; /* FIS HOB bit clear */ 20095 fis->d.reserved5 = 0; 20096 20097 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 20098 20099 /* Initialize CB for SATA completion. 20100 */ 20101 satIOContext->satCompleteCB = &smsatSetFeaturesVolatileWriteCacheCB; 20102 /* 20103 * Prepare SGL and send FIS to LL layer. 20104 */ 20105 satIOContext->reqType = agRequestType; /* Save it */ 20106 20107 status = smsataLLIOStart( smRoot, 20108 smIORequest, 20109 smDeviceHandle, 20110 smScsiRequest, 20111 satIOContext); 20112 /* debugging code */ 20113 if (smIORequest->tdData == smIORequest->smData) 20114 { 20115 SM_DBG1(("smsatSetFeaturesVolatileWriteCache: incorrect smIORequest\n")); 20116 } 20117 SM_DBG2(("smsatSetFeaturesVolatileWriteCache: return\n")); 20118 20119 return status; 20120 } 20121 20122 20123 20124 /******************************** start of utils ***********************************************************/ 20125 osGLOBAL FORCEINLINE void 20126 smsatBitSet(smRoot_t *smRoot, bit8 *data, bit32 index) 20127 { 20128 data[index>>3] |= (1 << (index&7)); 20129 } 20130 20131 osGLOBAL FORCEINLINE void 20132 smsatBitClear(smRoot_t *smRoot, bit8 *data, bit32 index) 20133 { 20134 data[index>>3] &= ~(1 << (index&7)); 20135 } 20136 20137 osGLOBAL FORCEINLINE BOOLEAN 20138 smsatBitTest(smRoot_t *smRoot, bit8 *data, bit32 index) 20139 { 20140 return ( (BOOLEAN)((data[index>>3] & (1 << (index&7)) ) ? 1: 0)); 20141 } 20142 20143 20144 FORCEINLINE bit32 20145 smsatTagAlloc( 20146 smRoot_t *smRoot, 20147 smDeviceData_t *pSatDevData, 20148 bit8 *pTag 20149 ) 20150 { 20151 bit32 retCode = agFALSE; 20152 bit32 i; 20153 20154 tdsmSingleThreadedEnter(smRoot, SM_NCQ_TAG_LOCK); 20155 20156 #ifdef CCFLAG_OPTIMIZE_SAT_LOCK 20157 20158 if (tdsmBitScanForward(smRoot, &i, ~(pSatDevData->freeSATAFDMATagBitmap))) 20159 { 20160 smsatBitSet(smRoot, (bit8*)&pSatDevData->freeSATAFDMATagBitmap, i); 20161 *pTag = (bit8)i; 20162 retCode = agTRUE; 20163 } 20164 20165 #else 20166 20167 for ( i = 0; i < pSatDevData->satNCQMaxIO; i ++ ) 20168 { 20169 if ( 0 == smsatBitTest(smRoot, (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, i) ) 20170 { 20171 smsatBitSet(smRoot, (bit8*)&pSatDevData->freeSATAFDMATagBitmap, i); 20172 *pTag = (bit8) i; 20173 retCode = agTRUE; 20174 break; 20175 } 20176 } 20177 20178 #endif 20179 20180 tdsmSingleThreadedLeave(smRoot, SM_NCQ_TAG_LOCK); 20181 20182 return retCode; 20183 } 20184 20185 FORCEINLINE bit32 20186 smsatTagRelease( 20187 smRoot_t *smRoot, 20188 smDeviceData_t *pSatDevData, 20189 bit8 tag 20190 ) 20191 { 20192 bit32 retCode = agFALSE; 20193 20194 if ( tag < pSatDevData->satNCQMaxIO ) 20195 { 20196 tdsmSingleThreadedEnter(smRoot, SM_NCQ_TAG_LOCK); 20197 smsatBitClear(smRoot, (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, (bit32)tag); 20198 tdsmSingleThreadedLeave(smRoot, SM_NCQ_TAG_LOCK); 20199 /*tdsmInterlockedAnd(smRoot, (volatile LONG *)(&pSatDevData->freeSATAFDMATagBitmap), ~(1 << (tag&31)));*/ 20200 retCode = agTRUE; 20201 } 20202 else 20203 { 20204 SM_DBG1(("smsatTagRelease: tag %d >= satNCQMaxIO %d!!!!\n", tag, pSatDevData->satNCQMaxIO)); 20205 } 20206 return retCode; 20207 } 20208 20209 20210 20211 osGLOBAL bit32 20212 smsatComputeCDB10LBA(smSatIOContext_t *satIOContext) 20213 { 20214 smIniScsiCmnd_t *scsiCmnd; 20215 smScsiInitiatorRequest_t *smScsiRequest; 20216 bit32 lba = 0; 20217 20218 SM_DBG5(("smsatComputeCDB10LBA: start\n")); 20219 smScsiRequest = satIOContext->smScsiXchg; 20220 scsiCmnd = &(smScsiRequest->scsiCmnd); 20221 20222 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 20223 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 20224 20225 return lba; 20226 } 20227 20228 osGLOBAL bit32 20229 smsatComputeCDB10TL(smSatIOContext_t *satIOContext) 20230 { 20231 20232 smIniScsiCmnd_t *scsiCmnd; 20233 smScsiInitiatorRequest_t *smScsiRequest; 20234 bit32 tl = 0; 20235 20236 SM_DBG5(("smsatComputeCDB10TL: start\n")); 20237 smScsiRequest = satIOContext->smScsiXchg; 20238 scsiCmnd = &(smScsiRequest->scsiCmnd); 20239 20240 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 20241 return tl; 20242 } 20243 20244 osGLOBAL bit32 20245 smsatComputeCDB12LBA(smSatIOContext_t *satIOContext) 20246 { 20247 smIniScsiCmnd_t *scsiCmnd; 20248 smScsiInitiatorRequest_t *smScsiRequest; 20249 bit32 lba = 0; 20250 20251 SM_DBG5(("smsatComputeCDB12LBA: start\n")); 20252 smScsiRequest = satIOContext->smScsiXchg; 20253 scsiCmnd = &(smScsiRequest->scsiCmnd); 20254 20255 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 20256 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 20257 20258 return lba; 20259 } 20260 20261 osGLOBAL bit32 20262 smsatComputeCDB12TL(smSatIOContext_t *satIOContext) 20263 { 20264 20265 smIniScsiCmnd_t *scsiCmnd; 20266 smScsiInitiatorRequest_t *smScsiRequest; 20267 bit32 tl = 0; 20268 20269 SM_DBG5(("smsatComputeCDB12TL: start\n")); 20270 smScsiRequest = satIOContext->smScsiXchg; 20271 scsiCmnd = &(smScsiRequest->scsiCmnd); 20272 20273 tl = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2)) 20274 + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9]; 20275 return tl; 20276 } 20277 20278 /* 20279 CBD16 has bit64 LBA 20280 But it has to be less than (2^28 - 1) 20281 Therefore, use last four bytes to compute LBA is OK 20282 */ 20283 osGLOBAL bit32 20284 smsatComputeCDB16LBA(smSatIOContext_t *satIOContext) 20285 { 20286 smIniScsiCmnd_t *scsiCmnd; 20287 smScsiInitiatorRequest_t *smScsiRequest; 20288 bit32 lba = 0; 20289 20290 SM_DBG5(("smsatComputeCDB16LBA: start\n")); 20291 smScsiRequest = satIOContext->smScsiXchg; 20292 scsiCmnd = &(smScsiRequest->scsiCmnd); 20293 20294 lba = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2)) 20295 + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9]; 20296 20297 return lba; 20298 } 20299 20300 osGLOBAL bit32 20301 smsatComputeCDB16TL(smSatIOContext_t *satIOContext) 20302 { 20303 20304 smIniScsiCmnd_t *scsiCmnd; 20305 smScsiInitiatorRequest_t *smScsiRequest; 20306 bit32 tl = 0; 20307 20308 SM_DBG5(("smsatComputeCDB16TL: start\n")); 20309 smScsiRequest = satIOContext->smScsiXchg; 20310 scsiCmnd = &(smScsiRequest->scsiCmnd); 20311 20312 tl = (scsiCmnd->cdb[10] << (8*3)) + (scsiCmnd->cdb[11] << (8*2)) 20313 + (scsiCmnd->cdb[12] << 8) + scsiCmnd->cdb[13]; 20314 return tl; 20315 } 20316 20317 /* 20318 (tl, denom) 20319 tl can be upto bit32 because CDB16 has bit32 tl 20320 Therefore, fine 20321 either (tl, 0xFF) or (tl, 0xFFFF) 20322 */ 20323 osGLOBAL FORCEINLINE bit32 20324 smsatComputeLoopNum(bit32 a, bit32 b) 20325 { 20326 bit32 LoopNum = 0; 20327 20328 SM_DBG5(("smsatComputeLoopNum: start\n")); 20329 20330 if (a < b || a == 0) 20331 { 20332 LoopNum = 1; 20333 } 20334 else 20335 { 20336 if (a == b || a == 0) 20337 { 20338 LoopNum = a/b; 20339 } 20340 else 20341 { 20342 LoopNum = a/b + 1; 20343 } 20344 } 20345 20346 return LoopNum; 20347 } 20348 20349 /* 20350 Generic new function for checking 20351 LBA itself, LBA+TL < SAT_TR_LBA_LIMIT or SAT_EXT_TR_LBA_LIMIT 20352 and LBA+TL < Read Capacity Limit 20353 flag: false - not 48BitSupport; true - 48BitSupport 20354 returns TRUE when over the limit 20355 20356 */ 20357 osGLOBAL FORCEINLINE bit32 20358 smsatCheckLimit(bit8 *lba, bit8 *tl, int flag, smDeviceData_t *pSatDevData) 20359 { 20360 bit32 lbaCheck = agFALSE; 20361 int i; 20362 bit8 limit[8]; 20363 bit32 rangeCheck = agFALSE; 20364 bit16 ans[8]; // 0 MSB, 8 LSB 20365 bit8 final_ans[9]; // 0 MSB, 9 LSB 20366 bit8 Bit28max[8]; 20367 bit8 Bit48max[8]; 20368 bit32 ReadCapCheck = agFALSE; 20369 bit32 ret; 20370 20371 bit8 final_satMaxLBA[9]; 20372 bit8 oneTL[8]; 20373 bit8 temp_satMaxLBA[8]; // 0 MSB, 8 LSB 20374 /* 20375 check LBA 20376 */ 20377 if (flag == agFALSE) 20378 { 20379 /* limit is 0xF FF FF = 2^28 - 1 */ 20380 limit[0] = 0x0; /* MSB */ 20381 limit[1] = 0x0; 20382 limit[2] = 0x0; 20383 limit[3] = 0x0; 20384 limit[4] = 0xF; 20385 limit[5] = 0xFF; 20386 limit[6] = 0xFF; 20387 limit[7] = 0xFF; /* LSB */ 20388 } 20389 else 20390 { 20391 /* limit is 0xF FF FF = 2^48 - 1 */ 20392 limit[0] = 0x0; /* MSB */ 20393 limit[1] = 0x0; 20394 limit[2] = 0xFF; 20395 limit[3] = 0xFF; 20396 limit[4] = 0xFF; 20397 limit[5] = 0xFF; 20398 limit[6] = 0xFF; 20399 limit[7] = 0xFF; /* LSB */ 20400 } 20401 //compare lba to limit 20402 for(i=0;i<8;i++) 20403 { 20404 if (lba[i] > limit[i]) 20405 { 20406 SM_DBG1(("smsatCheckLimit: LBA check True at %d\n", i)); 20407 lbaCheck = agTRUE; 20408 break; 20409 } 20410 else if (lba[i] < limit[i]) 20411 { 20412 SM_DBG5(("smsatCheckLimit: LBA check False at %d\n", i)); 20413 lbaCheck = agFALSE; 20414 break; 20415 } 20416 else 20417 { 20418 continue; 20419 } 20420 } 20421 20422 if (lbaCheck == agTRUE) 20423 { 20424 SM_DBG1(("smsatCheckLimit: return LBA check True\n")); 20425 return agTRUE; 20426 } 20427 20428 /* 20429 check LBA+TL < SAT_TR_LBA_LIMIT or SAT_EXT_TR_LBA_LIMIT 20430 */ 20431 sm_memset(ans, 0, sizeof(ans)); 20432 sm_memset(final_ans, 0, sizeof(final_ans)); 20433 20434 // adding from LSB to MSB 20435 for(i=7;i>=0;i--) 20436 { 20437 ans[i] = (bit16)(lba[i] + tl[i]); 20438 if (i != 7) 20439 { 20440 ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8)); 20441 } 20442 } 20443 20444 /* 20445 filling in the final answer 20446 */ 20447 final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8)); 20448 20449 for(i=1;i<=8;i++) 20450 { 20451 final_ans[i] = (bit8)(ans[i-1] & 0xFF); 20452 } 20453 20454 20455 if (flag == agFALSE) 20456 { 20457 sm_memset(Bit28max, 0, sizeof(Bit28max)); 20458 Bit28max[4] = 0x10; // max =0x1000 0000 20459 20460 //compare final_ans to max 20461 if (final_ans[0] != 0 || final_ans[1] != 0 || final_ans[2] != 0 20462 || final_ans[3] != 0 || final_ans[4] != 0) 20463 { 20464 SM_DBG1(("smsatCheckLimit: before 28Bit addressing TRUE\n")); 20465 rangeCheck = agTRUE; 20466 } 20467 else 20468 { 20469 for(i=5;i<=8;i++) 20470 { 20471 if (final_ans[i] > Bit28max[i-1]) 20472 { 20473 SM_DBG1(("smsatCheckLimit: 28Bit addressing TRUE at %d\n", i)); 20474 rangeCheck = agTRUE; 20475 break; 20476 } 20477 else if (final_ans[i] < Bit28max[i-1]) 20478 { 20479 SM_DBG5(("smsatCheckLimit: 28Bit addressing FALSE at %d\n", i)); 20480 rangeCheck = agFALSE; 20481 break; 20482 } 20483 else 20484 { 20485 continue; 20486 } 20487 } 20488 } 20489 } 20490 else 20491 { 20492 sm_memset(Bit48max, 0, sizeof(Bit48max)); 20493 Bit48max[1] = 0x1; //max = 0x1 0000 0000 0000 20494 20495 //compare final_ans to max 20496 if (final_ans[0] != 0 || final_ans[1] != 0) 20497 { 20498 SM_DBG1(("smsatCheckLimit: before 48Bit addressing TRUE\n")); 20499 rangeCheck = agTRUE; 20500 } 20501 else 20502 { 20503 for(i=2;i<=8;i++) 20504 { 20505 if (final_ans[i] > Bit48max[i-1]) 20506 { 20507 SM_DBG1(("smsatCheckLimit: 48Bit addressing TRUE at %d\n", i)); 20508 rangeCheck = agTRUE; 20509 break; 20510 } 20511 else if (final_ans[i] < Bit48max[i-1]) 20512 { 20513 SM_DBG5(("smsatCheckLimit: 48Bit addressing FALSE at %d\n", i)); 20514 rangeCheck = agFALSE; 20515 break; 20516 } 20517 else 20518 { 20519 continue; 20520 } 20521 } 20522 } 20523 } 20524 if (rangeCheck == agTRUE) 20525 { 20526 SM_DBG1(("smsatCheckLimit: return rangeCheck True\n")); 20527 return agTRUE; 20528 } 20529 20530 /* 20531 LBA+TL < Read Capacity Limit 20532 */ 20533 sm_memset(temp_satMaxLBA, 0, sizeof(temp_satMaxLBA)); 20534 sm_memset(oneTL, 0, sizeof(oneTL)); 20535 sm_memset(final_satMaxLBA, 0, sizeof(final_satMaxLBA)); 20536 sm_memset(ans, 0, sizeof(ans)); 20537 20538 sm_memcpy(&temp_satMaxLBA, &pSatDevData->satMaxLBA, sizeof(temp_satMaxLBA)); 20539 oneTL[7] = 1; 20540 20541 // adding temp_satMaxLBA to oneTL 20542 for(i=7;i>=0;i--) 20543 { 20544 ans[i] = (bit16)(temp_satMaxLBA[i] + oneTL[i]); 20545 if (i != 7) 20546 { 20547 ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8)); 20548 } 20549 } 20550 20551 /* 20552 filling in the final answer 20553 */ 20554 final_satMaxLBA[0] = (bit8)(((ans[0] & 0xFF00) >> 8)); 20555 20556 for(i=1;i<=8;i++) 20557 { 20558 final_satMaxLBA[i] = (bit8)(ans[i-1] & 0xFF); 20559 } 20560 if ( pSatDevData->ReadCapacity == 10) 20561 { 20562 for (i=0;i<=8;i++) 20563 { 20564 if (final_ans[i] > final_satMaxLBA[i]) 20565 { 20566 SM_DBG1(("smsatCheckLimit: Read Capacity 10 TRUE at %d\n", i)); 20567 ReadCapCheck = agTRUE; 20568 break; 20569 } 20570 else if (final_ans[i] < final_satMaxLBA[i]) 20571 { 20572 SM_DBG5(("smsatCheckLimit: Read Capacity 10 FALSE at %d\n", i)); 20573 ReadCapCheck = agFALSE; 20574 break; 20575 } 20576 else 20577 { 20578 continue; 20579 } 20580 } 20581 if ( ReadCapCheck) 20582 { 20583 SM_DBG1(("smsatCheckLimit: after Read Capacity 10 TRUE\n")); 20584 } 20585 else 20586 { 20587 SM_DBG5(("smsatCheckLimit: after Read Capacity 10 FALSE\n")); 20588 } 20589 } 20590 else if ( pSatDevData->ReadCapacity == 16) 20591 { 20592 for (i=0;i<=8;i++) 20593 { 20594 if (final_ans[i] > final_satMaxLBA[i]) 20595 { 20596 SM_DBG1(("smsatCheckLimit: Read Capacity 16 TRUE at %d\n", i)); 20597 ReadCapCheck = agTRUE; 20598 break; 20599 } 20600 else if (final_ans[i] < final_satMaxLBA[i]) 20601 { 20602 SM_DBG5(("smsatCheckLimit: Read Capacity 16 FALSE at %d\n", i)); 20603 ReadCapCheck = agFALSE; 20604 break; 20605 } 20606 else 20607 { 20608 continue; 20609 } 20610 } 20611 if ( ReadCapCheck) 20612 { 20613 SM_DBG1(("smsatCheckLimit: after Read Capacity 16 TRUE\n")); 20614 } 20615 else 20616 { 20617 SM_DBG5(("smsatCheckLimit: after Read Capacity 16 FALSE\n")); 20618 } 20619 } 20620 else 20621 { 20622 SM_DBG5(("smsatCheckLimit: unknown pSatDevData->ReadCapacity %d\n", pSatDevData->ReadCapacity)); 20623 } 20624 20625 if (ReadCapCheck == agTRUE) 20626 { 20627 SM_DBG1(("smsatCheckLimit: return ReadCapCheck True\n")); 20628 return agTRUE; 20629 } 20630 20631 20632 ret = (lbaCheck | rangeCheck | ReadCapCheck); 20633 if (ret == agTRUE) 20634 { 20635 SM_DBG1(("smsatCheckLimit: final check TRUE\n")); 20636 } 20637 else 20638 { 20639 SM_DBG5(("smsatCheckLimit: final check FALSE\n")); 20640 } 20641 return ret; 20642 } 20643 20644 20645 20646 osGLOBAL void 20647 smsatPrintSgl( 20648 smRoot_t *smRoot, 20649 agsaEsgl_t *agEsgl, 20650 bit32 idx 20651 ) 20652 { 20653 bit32 i=0; 20654 #ifdef TD_DEBUG_ENABLE 20655 agsaSgl_t *agSgl; 20656 #endif 20657 20658 for (i=0;i<idx;i++) 20659 { 20660 #ifdef TD_DEBUG_ENABLE 20661 agSgl = &(agEsgl->descriptor[i]); 20662 #endif 20663 SM_DBG3(("smsatPrintSgl: agSgl %d upperAddr 0x%08x lowerAddr 0x%08x len 0x%08x ext 0x%08x\n", 20664 i, agSgl->sgUpper, agSgl->sgLower, agSgl->len, agSgl->extReserved)); 20665 } 20666 20667 return; 20668 } 20669 20670 20671 osGLOBAL void 20672 smsatSplitSGL( 20673 smRoot_t *smRoot, 20674 smIORequest_t *smIORequest, 20675 smDeviceHandle_t *smDeviceHandle, 20676 smScsiInitiatorRequest_t *smScsiRequest, 20677 smSatIOContext_t *satIOContext, 20678 bit32 split, /*in sector number, depeding on IO value */ 20679 bit32 tl, /* in sector number */ 20680 bit32 flag 20681 ) 20682 { 20683 agsaSgl_t *agSgl; 20684 agsaEsgl_t *agEsgl; 20685 bit32 i=0; 20686 smIniScsiCmnd_t *scsiCmnd; 20687 bit32 totalLen=0; /* in bytes */ 20688 bit32 splitLen=0; /* in bytes */ 20689 bit32 splitDiffByte = 0; /* in bytes */ 20690 bit32 splitDiffExtra = 0; /* in bytes */ 20691 bit32 splitIdx = 0; 20692 bit32 UpperAddr, LowerAddr; 20693 bit32 tmpLowerAddr; 20694 void *sglVirtualAddr; 20695 void *sglSplitVirtualAddr; 20696 20697 scsiCmnd = &smScsiRequest->scsiCmnd; 20698 SM_DBG3(("smsatSplitSGL: start\n")); 20699 20700 if (smScsiRequest->smSgl1.type == 0x80000000) /* esgl */ 20701 { 20702 if (flag == agFALSE) 20703 { 20704 SM_DBG3(("smsatSplitSGL: Not first time\n")); 20705 SM_DBG3(("smsatSplitSGL: UpperAddr 0x%08x LowerAddr 0x%08x\n", satIOContext->UpperAddr, satIOContext->LowerAddr)); 20706 SM_DBG3(("smsatSplitSGL: SplitIdx %d AdjustBytes 0x%08x\n", satIOContext->SplitIdx, satIOContext->AdjustBytes)); 20707 20708 sglVirtualAddr = smScsiRequest->sglVirtualAddr; 20709 20710 agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr; 20711 20712 sglSplitVirtualAddr = &(agEsgl->descriptor[satIOContext->SplitIdx]); 20713 20714 agEsgl = (agsaEsgl_t *)sglSplitVirtualAddr; 20715 20716 if (agEsgl == agNULL) 20717 { 20718 SM_DBG1(("smsatSplitSGL: error!\n")); 20719 return; 20720 } 20721 /* first sgl ajustment */ 20722 agSgl = &(agEsgl->descriptor[0]); 20723 agSgl->sgUpper = satIOContext->UpperAddr; 20724 agSgl->sgLower = satIOContext->LowerAddr; 20725 agSgl->len = satIOContext->AdjustBytes; 20726 sm_memcpy(sglVirtualAddr, sglSplitVirtualAddr, (satIOContext->EsglLen) * sizeof(agsaSgl_t)); 20727 agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr; 20728 smsatPrintSgl(smRoot, (agsaEsgl_t *)sglVirtualAddr, satIOContext->EsglLen); 20729 } 20730 else 20731 { 20732 /* first time */ 20733 SM_DBG3(("smsatSplitSGL: first time\n")); 20734 satIOContext->EsglLen = smScsiRequest->smSgl1.len; 20735 agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr; 20736 if (agEsgl == agNULL) 20737 { 20738 return; 20739 } 20740 smsatPrintSgl(smRoot, agEsgl, satIOContext->EsglLen); 20741 } 20742 20743 if (tl > split) 20744 { 20745 /* split */ 20746 SM_DBG3(("smsatSplitSGL: split case\n")); 20747 i = 0; 20748 while (1) 20749 { 20750 agSgl = &(agEsgl->descriptor[i]); 20751 splitLen = splitLen + agSgl->len; 20752 if (splitLen >= split) 20753 { 20754 splitDiffExtra = splitLen - split; 20755 splitDiffByte = agSgl->len - splitDiffExtra; 20756 splitIdx = i; 20757 break; 20758 } 20759 i++; 20760 } 20761 SM_DBG3(("smsatSplitSGL: splitIdx %d\n", splitIdx)); 20762 SM_DBG3(("smsatSplitSGL: splitDiffByte 0x%8x\n", splitDiffByte)); 20763 SM_DBG3(("smsatSplitSGL: splitDiffExtra 0x%8x \n", splitDiffExtra)); 20764 20765 20766 agSgl = &(agEsgl->descriptor[splitIdx]); 20767 UpperAddr = agSgl->sgUpper; 20768 LowerAddr = agSgl->sgLower; 20769 tmpLowerAddr = LowerAddr + splitDiffByte; 20770 if (tmpLowerAddr < LowerAddr) 20771 { 20772 UpperAddr = UpperAddr + 1; 20773 } 20774 SM_DBG3(("smsatSplitSGL: UpperAddr 0x%08x tmpLowerAddr 0x%08x\n", UpperAddr, tmpLowerAddr)); 20775 agSgl->len = splitDiffByte; 20776 /* Esgl len adjustment */ 20777 smScsiRequest->smSgl1.len = splitIdx; 20778 /* expected data lent adjustment */ 20779 scsiCmnd->expDataLength = 0x20000; 20780 /* remeber for the next round */ 20781 satIOContext->UpperAddr = UpperAddr; 20782 satIOContext->LowerAddr = tmpLowerAddr; 20783 satIOContext->SplitIdx = splitIdx; 20784 satIOContext->AdjustBytes = splitDiffExtra; 20785 satIOContext->EsglLen = satIOContext->EsglLen - smScsiRequest->smSgl1.len; 20786 satIOContext->OrgTL = satIOContext->OrgTL - 0x100; 20787 // smsatPrintSgl(smRoot, agEsgl, satIOContext->EsglLen); 20788 20789 } 20790 else 20791 { 20792 /* no split */ 20793 SM_DBG3(("smsatSplitSGL: no split case\n")); 20794 /* Esgl len adjustment */ 20795 smScsiRequest->smSgl1.len = satIOContext->EsglLen; 20796 for (i=0;i< smScsiRequest->smSgl1.len;i++) 20797 { 20798 agSgl = &(agEsgl->descriptor[i]); 20799 totalLen = totalLen + (agSgl->len); 20800 } 20801 /* expected data lent adjustment */ 20802 scsiCmnd->expDataLength = totalLen; 20803 // smsatPrintSgl(smRoot, agEsgl, satIOContext->EsglLen); 20804 } 20805 } 20806 else 20807 { 20808 SM_DBG1(("not exntened esgl\n")); 20809 20810 } 20811 20812 return; 20813 } 20814 20815 20816 /******************************** end of utils ***********************************************************/ 20817 20818 20819 20820