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 __FBSDID("$FreeBSD$"); 24 #include <dev/pms/config.h> 25 26 #include <dev/pms/freebsd/driver/common/osenv.h> 27 #include <dev/pms/freebsd/driver/common/ostypes.h> 28 #include <dev/pms/freebsd/driver/common/osdebug.h> 29 30 #include <dev/pms/RefTisa/tisa/api/titypes.h> 31 32 #include <dev/pms/RefTisa/sallsdk/api/sa.h> 33 #include <dev/pms/RefTisa/sallsdk/api/saapi.h> 34 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h> 35 36 #include <dev/pms/RefTisa/sat/api/sm.h> 37 #include <dev/pms/RefTisa/sat/api/smapi.h> 38 #include <dev/pms/RefTisa/sat/api/tdsmapi.h> 39 40 #include <dev/pms/RefTisa/sat/src/smdefs.h> 41 #include <dev/pms/RefTisa/sat/src/smproto.h> 42 #include <dev/pms/RefTisa/sat/src/smtypes.h> 43 44 /* start smapi defined APIs */ 45 osGLOBAL bit32 46 smRegisterDevice( 47 smRoot_t *smRoot, 48 agsaDevHandle_t *agDevHandle, 49 smDeviceHandle_t *smDeviceHandle, 50 agsaDevHandle_t *agExpDevHandle, 51 bit32 phyID, 52 bit32 DeviceType 53 ) 54 { 55 smDeviceData_t *oneDeviceData = agNULL; 56 57 SM_DBG2(("smRegisterDevice: start\n")); 58 59 if (smDeviceHandle == agNULL) 60 { 61 SM_DBG1(("smRegisterDevice: smDeviceHandle is NULL!!!\n")); 62 return SM_RC_FAILURE; 63 } 64 65 if (agDevHandle == agNULL) 66 { 67 SM_DBG1(("smRegisterDevice: agDevHandle is NULL!!!\n")); 68 return SM_RC_FAILURE; 69 } 70 71 oneDeviceData = smAddToSharedcontext(smRoot, agDevHandle, smDeviceHandle, agExpDevHandle, phyID); 72 if (oneDeviceData != agNULL) 73 { 74 oneDeviceData->satDeviceType = DeviceType; 75 return SM_RC_SUCCESS; 76 } 77 else 78 { 79 return SM_RC_FAILURE; 80 } 81 82 } 83 84 osGLOBAL bit32 85 smDeregisterDevice( 86 smRoot_t *smRoot, 87 agsaDevHandle_t *agDevHandle, 88 smDeviceHandle_t *smDeviceHandle 89 ) 90 { 91 bit32 status = SM_RC_FAILURE; 92 93 SM_DBG2(("smDeregisterDevice: start\n")); 94 95 if (smDeviceHandle == agNULL) 96 { 97 SM_DBG1(("smDeregisterDevice: smDeviceHandle is NULL!!!\n")); 98 return SM_RC_FAILURE; 99 } 100 101 if (agDevHandle == agNULL) 102 { 103 SM_DBG1(("smDeregisterDevice: agDevHandle is NULL!!!\n")); 104 return SM_RC_FAILURE; 105 } 106 107 status = smRemoveFromSharedcontext(smRoot, agDevHandle, smDeviceHandle); 108 109 return status; 110 } 111 112 osGLOBAL bit32 113 smIOAbort( 114 smRoot_t *smRoot, 115 smIORequest_t *tasktag 116 ) 117 118 { 119 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData; 120 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 121 agsaRoot_t *agRoot; 122 smIORequestBody_t *smIORequestBody = agNULL; 123 smIORequestBody_t *smIONewRequestBody = agNULL; 124 agsaIORequest_t *agIORequest = agNULL; /* IO to be aborted */ 125 bit32 status = SM_RC_FAILURE; 126 agsaIORequest_t *agAbortIORequest; /* abort IO itself */ 127 smIORequestBody_t *smAbortIORequestBody; 128 #if 1 129 bit32 PhysUpper32; 130 bit32 PhysLower32; 131 bit32 memAllocStatus; 132 void *osMemHandle; 133 #endif 134 smSatIOContext_t *satIOContext; 135 smSatInternalIo_t *satIntIo; 136 smSatIOContext_t *satAbortIOContext; 137 138 SM_DBG1(("smIOAbort: start\n")); 139 SM_DBG2(("smIOAbort: tasktag %p\n", tasktag)); 140 /* 141 alloc smIORequestBody for abort itself 142 call saSATAAbort() 143 */ 144 145 agRoot = smAllShared->agRoot; 146 smIORequestBody = (smIORequestBody_t *)tasktag->smData; 147 148 if (smIORequestBody == agNULL) 149 { 150 SM_DBG1(("smIOAbort: smIORequestBody is NULL!!!\n")); 151 return SM_RC_FAILURE; 152 } 153 154 /* needs to distinguish internally generated or externally generated */ 155 satIOContext = &(smIORequestBody->transport.SATA.satIOContext); 156 satIntIo = satIOContext->satIntIoContext; 157 if (satIntIo == agNULL) 158 { 159 SM_DBG2(("smIOAbort: External, OS generated\n")); 160 agIORequest = &(smIORequestBody->agIORequest); 161 } 162 else 163 { 164 SM_DBG2(("smIOAbort: Internal, SM generated\n")); 165 smIONewRequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody; 166 agIORequest = &(smIONewRequestBody->agIORequest); 167 } 168 169 /* 170 allocate smAbortIORequestBody for abort request itself 171 */ 172 173 #if 1 174 /* allocating agIORequest for abort itself */ 175 memAllocStatus = tdsmAllocMemory( 176 smRoot, 177 &osMemHandle, 178 (void **)&smAbortIORequestBody, 179 &PhysUpper32, 180 &PhysLower32, 181 8, 182 sizeof(smIORequestBody_t), 183 agTRUE 184 ); 185 if (memAllocStatus != SM_RC_SUCCESS) 186 { 187 /* let os process IO */ 188 SM_DBG1(("smIOAbort: tdsmAllocMemory failed...!!!\n")); 189 return SM_RC_FAILURE; 190 } 191 192 if (smAbortIORequestBody == agNULL) 193 { 194 /* let os process IO */ 195 SM_DBG1(("smIOAbort: tdsmAllocMemory returned NULL smAbortIORequestBody!!!\n")); 196 return SM_RC_FAILURE; 197 } 198 199 smIOReInit(smRoot, smAbortIORequestBody); 200 201 /* setup task management structure */ 202 smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 203 satAbortIOContext = &(smAbortIORequestBody->transport.SATA.satIOContext); 204 satAbortIOContext->smRequestBody = smAbortIORequestBody; 205 206 smAbortIORequestBody->smDevHandle = smIORequestBody->smDevHandle; 207 208 /* initialize agIORequest */ 209 agAbortIORequest = &(smAbortIORequestBody->agIORequest); 210 agAbortIORequest->osData = (void *) smAbortIORequestBody; 211 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */ 212 213 /* remember IO to be aborted */ 214 smAbortIORequestBody->smIOToBeAbortedRequest = tasktag; 215 216 status = saSATAAbort(agRoot, agAbortIORequest, 0, agNULL, 0, agIORequest, smaSATAAbortCB); 217 218 SM_DBG2(("smIOAbort: return status=0x%x\n", status)); 219 220 #endif /* 1 */ 221 222 223 if (status == AGSA_RC_SUCCESS) 224 { 225 return SM_RC_SUCCESS; 226 } 227 else 228 { 229 SM_DBG1(("smIOAbort: failed to call saSATAAbort, status=%d!!!\n", status)); 230 tdsmFreeMemory(smRoot, 231 smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle, 232 sizeof(smIORequestBody_t) 233 ); 234 return SM_RC_FAILURE; 235 } 236 } 237 238 osGLOBAL bit32 239 smIOAbortAll( 240 smRoot_t *smRoot, 241 smDeviceHandle_t *smDeviceHandle 242 ) 243 { 244 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData; 245 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 246 agsaRoot_t *agRoot; 247 bit32 status = SM_RC_FAILURE; 248 agsaIORequest_t *agAbortIORequest; 249 smIORequestBody_t *smAbortIORequestBody; 250 smSatIOContext_t *satAbortIOContext; 251 smDeviceData_t *oneDeviceData = agNULL; 252 agsaDevHandle_t *agDevHandle; 253 254 bit32 PhysUpper32; 255 bit32 PhysLower32; 256 bit32 memAllocStatus; 257 void *osMemHandle; 258 259 260 SM_DBG2(("smIOAbortAll: start\n")); 261 262 agRoot = smAllShared->agRoot; 263 264 if (smDeviceHandle == agNULL) 265 { 266 SM_DBG1(("smIOAbortAll: smDeviceHandle is NULL!!!\n")); 267 return SM_RC_FAILURE; 268 } 269 270 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData; 271 if (oneDeviceData == agNULL) 272 { 273 SM_DBG1(("smIOAbortAll: oneDeviceData is NULL!!!\n")); 274 return SM_RC_FAILURE; 275 } 276 if (oneDeviceData->valid == agFALSE) 277 { 278 SM_DBG1(("smIOAbortAll: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id)); 279 return SM_RC_FAILURE; 280 } 281 282 agDevHandle = oneDeviceData->agDevHandle; 283 if (agDevHandle == agNULL) 284 { 285 SM_DBG1(("smIOAbortAll: agDevHandle is NULL!!!\n")); 286 return SM_RC_FAILURE; 287 } 288 /* 289 smAbortIORequestBody = smDequeueIO(smRoot); 290 if (smAbortIORequestBody == agNULL) 291 { 292 SM_DBG1(("smIOAbortAll: empty freeIOList!!!\n")); 293 return SM_RC_FAILURE; 294 } 295 */ 296 /* allocating agIORequest for abort itself */ 297 memAllocStatus = tdsmAllocMemory( 298 smRoot, 299 &osMemHandle, 300 (void **)&smAbortIORequestBody, 301 &PhysUpper32, 302 &PhysLower32, 303 8, 304 sizeof(smIORequestBody_t), 305 agTRUE 306 ); 307 if (memAllocStatus != SM_RC_SUCCESS) 308 { 309 /* let os process IO */ 310 SM_DBG1(("smIOAbortAll: tdsmAllocMemory failed...!!!\n")); 311 return SM_RC_FAILURE; 312 } 313 314 if (smAbortIORequestBody == agNULL) 315 { 316 /* let os process IO */ 317 SM_DBG1(("smIOAbortAll: tdsmAllocMemory returned NULL smAbortIORequestBody!!!\n")); 318 return SM_RC_FAILURE; 319 } 320 321 smIOReInit(smRoot, smAbortIORequestBody); 322 323 /* setup task management structure */ 324 smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 325 326 satAbortIOContext = &(smAbortIORequestBody->transport.SATA.satIOContext); 327 satAbortIOContext->smRequestBody = smAbortIORequestBody; 328 smAbortIORequestBody->smDevHandle = smDeviceHandle; 329 330 /* initialize agIORequest */ 331 agAbortIORequest = &(smAbortIORequestBody->agIORequest); 332 agAbortIORequest->osData = (void *) smAbortIORequestBody; 333 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */ 334 335 oneDeviceData->OSAbortAll = agTRUE; 336 /* abort all */ 337 status = saSATAAbort(agRoot, agAbortIORequest, tdsmRotateQnumber(smRoot, smDeviceHandle), agDevHandle, 1, agNULL, smaSATAAbortCB); 338 if (status != AGSA_RC_SUCCESS) 339 { 340 SM_DBG1(("smIOAbortAll: failed to call saSATAAbort, status=%d!!!\n", status)); 341 tdsmFreeMemory(smRoot, 342 smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle, 343 sizeof(smIORequestBody_t) 344 ); 345 } 346 347 return status; 348 } 349 350 osGLOBAL bit32 351 smSuperIOStart( 352 smRoot_t *smRoot, 353 smIORequest_t *smIORequest, 354 smDeviceHandle_t *smDeviceHandle, 355 smSuperScsiInitiatorRequest_t *smSCSIRequest, 356 bit32 AddrHi, 357 bit32 AddrLo, 358 bit32 interruptContext 359 ) 360 { 361 smDeviceData_t *oneDeviceData = agNULL; 362 smIORequestBody_t *smIORequestBody = agNULL; 363 smSatIOContext_t *satIOContext = agNULL; 364 bit32 status = SM_RC_FAILURE; 365 366 SM_DBG2(("smSuperIOStart: start\n")); 367 368 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData; 369 if (oneDeviceData == agNULL) 370 { 371 SM_DBG1(("smSuperIOStart: oneDeviceData is NULL!!!\n")); 372 return SM_RC_FAILURE; 373 } 374 if (oneDeviceData->valid == agFALSE) 375 { 376 SM_DBG1(("smSuperIOStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id)); 377 return SM_RC_FAILURE; 378 } 379 smIORequestBody = (smIORequestBody_t*)smIORequest->smData;//smDequeueIO(smRoot); 380 381 if (smIORequestBody == agNULL) 382 { 383 SM_DBG1(("smSuperIOStart: smIORequestBody is NULL!!!\n")); 384 return SM_RC_FAILURE; 385 } 386 387 smIOReInit(smRoot, smIORequestBody); 388 389 SM_DBG3(("smSuperIOStart: io ID %d!!!\n", smIORequestBody->id )); 390 391 oneDeviceData->sasAddressHi = AddrHi; 392 oneDeviceData->sasAddressLo = AddrLo; 393 394 smIORequestBody->smIORequest = smIORequest; 395 smIORequestBody->smDevHandle = smDeviceHandle; 396 397 satIOContext = &(smIORequestBody->transport.SATA.satIOContext); 398 399 /* 400 * Need to initialize all the fields within satIOContext except 401 * reqType and satCompleteCB which will be set later in SM. 402 */ 403 smIORequestBody->transport.SATA.smSenseData.senseData = agNULL; 404 smIORequestBody->transport.SATA.smSenseData.senseLen = 0; 405 satIOContext->pSatDevData = oneDeviceData; 406 satIOContext->pFis = 407 &smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev; 408 satIOContext->pScsiCmnd = &smSCSIRequest->scsiCmnd; 409 satIOContext->pSense = &smIORequestBody->transport.SATA.sensePayload; 410 satIOContext->pSmSenseData = &smIORequestBody->transport.SATA.smSenseData; 411 satIOContext->pSmSenseData->senseData = satIOContext->pSense; 412 /* satIOContext->pSense = (scsiRspSense_t *)satIOContext->pSmSenseData->senseData; */ 413 satIOContext->smRequestBody = smIORequestBody; 414 satIOContext->interruptContext = interruptContext; 415 satIOContext->psmDeviceHandle = smDeviceHandle; 416 satIOContext->smScsiXchg = smSCSIRequest; 417 satIOContext->superIOFlag = agTRUE; 418 // satIOContext->superIOFlag = agFALSE; 419 420 satIOContext->satIntIoContext = agNULL; 421 satIOContext->satOrgIOContext = agNULL; 422 /* satIOContext->tiIORequest = tiIORequest; */ 423 424 /* save context if we need to abort later */ 425 /*smIORequest->smData = smIORequestBody;*/ 426 427 /* followings are used only for internal IO */ 428 satIOContext->currentLBA = 0; 429 satIOContext->OrgTL = 0; 430 431 status = smsatIOStart(smRoot, smIORequest, smDeviceHandle, (smScsiInitiatorRequest_t *)smSCSIRequest, satIOContext); 432 433 return status; 434 } 435 436 /* 437 osGLOBAL bit32 438 tiINIIOStart( 439 tiRoot_t *tiRoot, 440 tiIORequest_t *tiIORequest, 441 tiDeviceHandle_t *tiDeviceHandle, 442 tiScsiInitiatorRequest_t *tiScsiRequest, 443 void *tiRequestBody, 444 bit32 interruptContext 445 ) 446 447 GLOBAL bit32 satIOStart( 448 tiRoot_t *tiRoot, 449 tiIORequest_t *tiIORequest, 450 tiDeviceHandle_t *tiDeviceHandle, 451 tiScsiInitiatorRequest_t *tiScsiRequest, 452 smSatIOContext_t *satIOContext 453 ) 454 smIOStart( 455 smRoot_t *smRoot, 456 smIORequest_t *smIORequest, 457 smDeviceHandle_t *smDeviceHandle, 458 smScsiInitiatorRequest_t *smSCSIRequest, 459 smIORequestBody_t *smRequestBody, 460 bit32 interruptContext 461 ) 462 463 464 */ 465 FORCEINLINE bit32 466 smIOStart( 467 smRoot_t *smRoot, 468 smIORequest_t *smIORequest, 469 smDeviceHandle_t *smDeviceHandle, 470 smScsiInitiatorRequest_t *smSCSIRequest, 471 bit32 interruptContext 472 ) 473 { 474 smDeviceData_t *oneDeviceData = agNULL; 475 smIORequestBody_t *smIORequestBody = agNULL; 476 smSatIOContext_t *satIOContext = agNULL; 477 bit32 status = SM_RC_FAILURE; 478 479 SM_DBG2(("smIOStart: start\n")); 480 481 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData; 482 if (oneDeviceData == agNULL) 483 { 484 SM_DBG1(("smIOStart: oneDeviceData is NULL!!!\n")); 485 return SM_RC_FAILURE; 486 } 487 if (oneDeviceData->valid == agFALSE) 488 { 489 SM_DBG1(("smIOStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id)); 490 return SM_RC_FAILURE; 491 } 492 smIORequestBody = (smIORequestBody_t*)smIORequest->smData;//smDequeueIO(smRoot); 493 494 if (smIORequestBody == agNULL) 495 { 496 SM_DBG1(("smIOStart: smIORequestBody is NULL!!!\n")); 497 return SM_RC_FAILURE; 498 } 499 500 smIOReInit(smRoot, smIORequestBody); 501 502 SM_DBG3(("smIOStart: io ID %d!!!\n", smIORequestBody->id )); 503 504 smIORequestBody->smIORequest = smIORequest; 505 smIORequestBody->smDevHandle = smDeviceHandle; 506 507 satIOContext = &(smIORequestBody->transport.SATA.satIOContext); 508 509 /* 510 * Need to initialize all the fields within satIOContext except 511 * reqType and satCompleteCB which will be set later in SM. 512 */ 513 smIORequestBody->transport.SATA.smSenseData.senseData = agNULL; 514 smIORequestBody->transport.SATA.smSenseData.senseLen = 0; 515 satIOContext->pSatDevData = oneDeviceData; 516 satIOContext->pFis = 517 &smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev; 518 satIOContext->pScsiCmnd = &smSCSIRequest->scsiCmnd; 519 satIOContext->pSense = &smIORequestBody->transport.SATA.sensePayload; 520 satIOContext->pSmSenseData = &smIORequestBody->transport.SATA.smSenseData; 521 satIOContext->pSmSenseData->senseData = satIOContext->pSense; 522 /* satIOContext->pSense = (scsiRspSense_t *)satIOContext->pSmSenseData->senseData; */ 523 satIOContext->smRequestBody = smIORequestBody; 524 satIOContext->interruptContext = interruptContext; 525 satIOContext->psmDeviceHandle = smDeviceHandle; 526 satIOContext->smScsiXchg = smSCSIRequest; 527 satIOContext->superIOFlag = agFALSE; 528 529 satIOContext->satIntIoContext = agNULL; 530 satIOContext->satOrgIOContext = agNULL; 531 satIOContext->currentLBA = 0; 532 satIOContext->OrgTL = 0; 533 534 status = smsatIOStart(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext); 535 536 return status; 537 538 } 539 540 541 542 osGLOBAL bit32 543 smTaskManagement( 544 smRoot_t *smRoot, 545 smDeviceHandle_t *smDeviceHandle, 546 bit32 task, 547 smLUN_t *lun, 548 smIORequest_t *taskTag, /* io to be aborted */ 549 smIORequest_t *currentTaskTag /* task management */ 550 ) 551 { 552 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData; 553 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 554 agsaRoot_t *agRoot = smAllShared->agRoot; 555 smDeviceData_t *oneDeviceData = agNULL; 556 smIORequestBody_t *smIORequestBody = agNULL; 557 bit32 status; 558 agsaContext_t *agContext = agNULL; 559 smSatIOContext_t *satIOContext; 560 561 SM_DBG1(("smTaskManagement: start\n")); 562 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData; 563 564 if (task == SM_LOGICAL_UNIT_RESET || task == SM_TARGET_WARM_RESET || task == SM_ABORT_TASK) 565 { 566 if (task == AG_LOGICAL_UNIT_RESET) 567 { 568 if ( (lun->lun[0] | lun->lun[1] | lun->lun[2] | lun->lun[3] | 569 lun->lun[4] | lun->lun[5] | lun->lun[6] | lun->lun[7] ) != 0 ) 570 { 571 SM_DBG1(("smTaskManagement: *** REJECT *** LUN not zero, did %d!!!\n", 572 oneDeviceData->id)); 573 return SM_RC_FAILURE; 574 } 575 } 576 577 oneDeviceData->satDriveState = SAT_DEV_STATE_IN_RECOVERY; 578 oneDeviceData->satAbortAfterReset = agFALSE; 579 580 saSetDeviceState(agRoot, 581 agNULL, 582 tdsmRotateQnumber(smRoot, smDeviceHandle), 583 oneDeviceData->agDevHandle, 584 SA_DS_IN_RECOVERY 585 ); 586 587 if (oneDeviceData->directlyAttached == agFALSE) 588 { 589 /* expander attached */ 590 SM_DBG1(("smTaskManagement: LUN reset or device reset expander attached!!!\n")); 591 status = smPhyControlSend(smRoot, 592 oneDeviceData, 593 SMP_PHY_CONTROL_HARD_RESET, 594 currentTaskTag, 595 tdsmRotateQnumber(smRoot, smDeviceHandle) 596 ); 597 return status; 598 } 599 else 600 { 601 SM_DBG1(("smTaskManagement: LUN reset or device reset directly attached\n")); 602 603 smIORequestBody = (smIORequestBody_t*)currentTaskTag->smData;//smDequeueIO(smRoot); 604 605 if (smIORequestBody == agNULL) 606 { 607 SM_DBG1(("smTaskManagement: smIORequestBody is NULL!!!\n")); 608 return SM_RC_FAILURE; 609 } 610 611 smIOReInit(smRoot, smIORequestBody); 612 613 satIOContext = &(smIORequestBody->transport.SATA.satIOContext); 614 satIOContext->smRequestBody = smIORequestBody; 615 smIORequestBody->smDevHandle = smDeviceHandle; 616 617 agContext = &(oneDeviceData->agDeviceResetContext); 618 agContext->osData = currentTaskTag; 619 620 status = saLocalPhyControl(agRoot, 621 agContext, 622 tdsmRotateQnumber(smRoot, smDeviceHandle) &0xFFFF, 623 oneDeviceData->phyID, 624 AGSA_PHY_HARD_RESET, 625 smLocalPhyControlCB 626 ); 627 628 if ( status == AGSA_RC_SUCCESS) 629 { 630 return SM_RC_SUCCESS; 631 } 632 else if (status == AGSA_RC_BUSY) 633 { 634 return SM_RC_BUSY; 635 } 636 else if (status == AGSA_RC_FAILURE) 637 { 638 return SM_RC_FAILURE; 639 } 640 else 641 { 642 SM_DBG1(("smTaskManagement: unknown status %d\n",status)); 643 return SM_RC_FAILURE; 644 } 645 } 646 } 647 else 648 { 649 /* smsatsmTaskManagement() which is satTM() */ 650 smIORequestBody = (smIORequestBody_t*)currentTaskTag->smData;//smDequeueIO(smRoot); 651 652 if (smIORequestBody == agNULL) 653 { 654 SM_DBG1(("smTaskManagement: smIORequestBody is NULL!!!\n")); 655 return SM_RC_FAILURE; 656 } 657 658 smIOReInit(smRoot, smIORequestBody); 659 /*currentTaskTag->smData = smIORequestBody;*/ 660 661 status = smsatTaskManagement(smRoot, 662 smDeviceHandle, 663 task, 664 lun, 665 taskTag, 666 currentTaskTag, 667 smIORequestBody 668 ); 669 670 return status; 671 } 672 return SM_RC_SUCCESS; 673 } 674 675 676 677 /********************************************************* end smapi defined APIS */ 678 /* counterpart is 679 smEnqueueIO(smRoot_t *smRoot, 680 smSatIOContext_t *satIOContext) 681 */ 682 osGLOBAL smIORequestBody_t * 683 smDequeueIO(smRoot_t *smRoot) 684 { 685 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData; 686 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 687 smIORequestBody_t *smIORequestBody = agNULL; 688 smList_t *IOListList; 689 690 SM_DBG2(("smDequeueIO: start\n")); 691 692 tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK); 693 if (SMLIST_EMPTY(&(smAllShared->freeIOList))) 694 { 695 SM_DBG1(("smDequeueIO: empty freeIOList!!!\n")); 696 tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 697 return agNULL; 698 } 699 700 SMLIST_DEQUEUE_FROM_HEAD(&IOListList, &(smAllShared->freeIOList)); 701 smIORequestBody = SMLIST_OBJECT_BASE(smIORequestBody_t, satIoBodyLink, IOListList); 702 SMLIST_DEQUEUE_THIS(&(smIORequestBody->satIoBodyLink)); 703 SMLIST_ENQUEUE_AT_TAIL(&(smIORequestBody->satIoBodyLink), &(smAllShared->mainIOList)); 704 tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 705 706 if (smIORequestBody->InUse == agTRUE) 707 { 708 SM_DBG1(("smDequeueIO: wrong. already in USE ID %d!!!!\n", smIORequestBody->id)); 709 } 710 smIOReInit(smRoot, smIORequestBody); 711 712 713 SM_DBG2(("smDequeueIO: io ID %d!\n", smIORequestBody->id)); 714 715 /* debugging */ 716 if (smIORequestBody->satIoBodyLink.flink == agNULL) 717 { 718 SM_DBG1(("smDequeueIO: io ID %d, flink is NULL!!!\n", smIORequestBody->id)); 719 } 720 if (smIORequestBody->satIoBodyLink.blink == agNULL) 721 { 722 SM_DBG1(("smDequeueIO: io ID %d, blink is NULL!!!\n", smIORequestBody->id)); 723 } 724 725 return smIORequestBody; 726 } 727 728 //start here 729 //compare with ossaSATAAbortCB() 730 //qqq1 731 osGLOBAL void 732 smsatAbort( 733 smRoot_t *smRoot, 734 agsaRoot_t *agRoot, 735 smSatIOContext_t *satIOContext 736 ) 737 { 738 smIORequestBody_t *smIORequestBody = agNULL; /* abort itself */ 739 smIORequestBody_t *smToBeAbortedIORequestBody; /* io to be aborted */ 740 agsaIORequest_t *agToBeAbortedIORequest; /* io to be aborted */ 741 agsaIORequest_t *agAbortIORequest; /* abort io itself */ 742 smSatIOContext_t *satAbortIOContext; 743 bit32 PhysUpper32; 744 bit32 PhysLower32; 745 bit32 memAllocStatus; 746 void *osMemHandle; 747 748 749 SM_DBG2(("smsatAbort: start\n")); 750 751 if (satIOContext == agNULL) 752 { 753 SM_DBG1(("smsatAbort: satIOContext is NULL, wrong!!!\n")); 754 return; 755 } 756 757 smToBeAbortedIORequestBody = (smIORequestBody_t *)satIOContext->smRequestBody; 758 agToBeAbortedIORequest = (agsaIORequest_t *)&(smToBeAbortedIORequestBody->agIORequest); 759 /* 760 smIORequestBody = smDequeueIO(smRoot); 761 762 if (smIORequestBody == agNULL) 763 { 764 SM_DBG1(("smsatAbort: empty freeIOList!!!\n")); 765 return; 766 } 767 */ 768 /* allocating agIORequest for abort itself */ 769 memAllocStatus = tdsmAllocMemory( 770 smRoot, 771 &osMemHandle, 772 (void **)&smIORequestBody, 773 &PhysUpper32, 774 &PhysLower32, 775 8, 776 sizeof(smIORequestBody_t), 777 agTRUE 778 ); 779 if (memAllocStatus != tiSuccess) 780 { 781 /* let os process IO */ 782 SM_DBG1(("smsatAbort: ostiAllocMemory failed...\n")); 783 return; 784 } 785 786 if (smIORequestBody == agNULL) 787 { 788 /* let os process IO */ 789 SM_DBG1(("smsatAbort: ostiAllocMemory returned NULL smIORequestBody\n")); 790 return; 791 } 792 smIOReInit(smRoot, smIORequestBody); 793 794 smIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; 795 smIORequestBody->smDevHandle = smToBeAbortedIORequestBody->smDevHandle; 796 /* initialize agIORequest */ 797 satAbortIOContext = &(smIORequestBody->transport.SATA.satIOContext); 798 satAbortIOContext->smRequestBody = smIORequestBody; 799 800 agAbortIORequest = &(smIORequestBody->agIORequest); 801 agAbortIORequest->osData = (void *) smIORequestBody; 802 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */ 803 804 /* 805 * Issue abort 806 */ 807 saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agToBeAbortedIORequest, smaSATAAbortCB); 808 809 810 SM_DBG1(("satAbort: end!!!\n")); 811 812 return; 813 } 814 815 osGLOBAL bit32 816 smsatStartCheckPowerMode( 817 smRoot_t *smRoot, 818 smIORequest_t *currentTaskTag, 819 smDeviceHandle_t *smDeviceHandle, 820 smScsiInitiatorRequest_t *smScsiRequest, 821 smSatIOContext_t *satIOContext 822 ) 823 { 824 smSatInternalIo_t *satIntIo = agNULL; 825 smDeviceData_t *oneDeviceData = agNULL; 826 smSatIOContext_t *satNewIOContext; 827 bit32 status; 828 829 SM_DBG1(("smsatStartCheckPowerMode: start\n")); 830 831 oneDeviceData = satIOContext->pSatDevData; 832 833 SM_DBG6(("smsatStartCheckPowerMode: before alloc\n")); 834 835 /* allocate any fis for seting SRT bit in device control */ 836 satIntIo = smsatAllocIntIoResource( smRoot, 837 currentTaskTag, 838 oneDeviceData, 839 0, 840 satIntIo); 841 842 SM_DBG6(("smsatStartCheckPowerMode: before after\n")); 843 844 if (satIntIo == agNULL) 845 { 846 SM_DBG1(("smsatStartCheckPowerMode: can't alloacate!!!\n")); 847 /*smEnqueueIO(smRoot, satIOContext);*/ 848 return SM_RC_FAILURE; 849 } 850 851 satNewIOContext = smsatPrepareNewIO(satIntIo, 852 currentTaskTag, 853 oneDeviceData, 854 agNULL, 855 satIOContext); 856 857 SM_DBG6(("smsatStartCheckPowerMode: TD satIOContext %p \n", satIOContext)); 858 SM_DBG6(("smsatStartCheckPowerMode: SM satNewIOContext %p \n", satNewIOContext)); 859 SM_DBG6(("smsatStartCheckPowerMode: TD smScsiXchg %p \n", satIOContext->smScsiXchg)); 860 SM_DBG6(("smsatStartCheckPowerMode: SM smScsiXchg %p \n", satNewIOContext->smScsiXchg)); 861 862 863 864 SM_DBG2(("smsatStartCheckPowerMode: satNewIOContext %p \n", satNewIOContext)); 865 866 status = smsatCheckPowerMode(smRoot, 867 &satIntIo->satIntSmIORequest, /* New smIORequest */ 868 smDeviceHandle, 869 satNewIOContext->smScsiXchg, /* New tiScsiInitiatorRequest_t *smScsiRequest, */ 870 satNewIOContext); 871 872 if (status != SM_RC_SUCCESS) 873 { 874 SM_DBG1(("smsatStartCheckPowerMode: failed in sending!!!\n")); 875 876 smsatFreeIntIoResource( smRoot, 877 oneDeviceData, 878 satIntIo); 879 880 /*smEnqueueIO(smRoot, satIOContext);*/ 881 882 return SM_RC_FAILURE; 883 } 884 885 886 SM_DBG6(("smsatStartCheckPowerMode: end\n")); 887 888 return status; 889 } 890 891 osGLOBAL bit32 892 smsatStartResetDevice( 893 smRoot_t *smRoot, 894 smIORequest_t *currentTaskTag, 895 smDeviceHandle_t *smDeviceHandle, 896 smScsiInitiatorRequest_t *smScsiRequest, 897 smSatIOContext_t *satIOContext 898 ) 899 { 900 smSatInternalIo_t *satIntIo = agNULL; 901 smDeviceData_t *oneDeviceData = agNULL; 902 smSatIOContext_t *satNewIOContext; 903 bit32 status; 904 905 SM_DBG1(("smsatStartResetDevice: start\n")); 906 907 oneDeviceData = satIOContext->pSatDevData; 908 909 SM_DBG6(("smsatStartResetDevice: before alloc\n")); 910 911 /* allocate any fis for seting SRT bit in device control */ 912 satIntIo = smsatAllocIntIoResource( smRoot, 913 currentTaskTag, 914 oneDeviceData, 915 0, 916 satIntIo); 917 918 SM_DBG6(("smsatStartResetDevice: before after\n")); 919 920 if (satIntIo == agNULL) 921 { 922 SM_DBG1(("smsatStartResetDevice: can't alloacate!!!\n")); 923 /*smEnqueueIO(smRoot, satIOContext);*/ 924 return SM_RC_FAILURE; 925 } 926 927 satNewIOContext = smsatPrepareNewIO(satIntIo, 928 currentTaskTag, 929 oneDeviceData, 930 agNULL, 931 satIOContext); 932 933 SM_DBG6(("smsatStartResetDevice: TD satIOContext %p \n", satIOContext)); 934 SM_DBG6(("smsatStartResetDevice: SM satNewIOContext %p \n", satNewIOContext)); 935 SM_DBG6(("smsatStartResetDevice: TD smScsiXchg %p \n", satIOContext->smScsiXchg)); 936 SM_DBG6(("smsatStartResetDevice: SM smScsiXchg %p \n", satNewIOContext->smScsiXchg)); 937 938 939 940 SM_DBG6(("smsatStartResetDevice: satNewIOContext %p \n", satNewIOContext)); 941 942 if (oneDeviceData->satDeviceType == SATA_ATAPI_DEVICE) 943 { 944 /*if ATAPI device, send DEVICE RESET command to ATAPI device*/ 945 status = smsatDeviceReset(smRoot, 946 &satIntIo->satIntSmIORequest, /* New smIORequest */ 947 smDeviceHandle, 948 satNewIOContext->smScsiXchg, /* New smScsiInitiatorRequest_t *smScsiRequest, NULL */ 949 satNewIOContext); 950 } 951 else 952 { 953 status = smsatResetDevice(smRoot, 954 &satIntIo->satIntSmIORequest, /* New smIORequest */ 955 smDeviceHandle, 956 satNewIOContext->smScsiXchg, /* New smScsiInitiatorRequest_t *smScsiRequest, NULL */ 957 satNewIOContext); 958 } 959 960 if (status != SM_RC_SUCCESS) 961 { 962 SM_DBG1(("smsatStartResetDevice: failed in sending!!!\n")); 963 964 smsatFreeIntIoResource( smRoot, 965 oneDeviceData, 966 satIntIo); 967 968 /*smEnqueueIO(smRoot, satIOContext);*/ 969 970 return SM_RC_FAILURE; 971 } 972 973 974 SM_DBG6(("smsatStartResetDevice: end\n")); 975 976 return status; 977 } 978 979 osGLOBAL bit32 980 smsatTmAbortTask( 981 smRoot_t *smRoot, 982 smIORequest_t *currentTaskTag, /* task management */ 983 smDeviceHandle_t *smDeviceHandle, 984 smScsiInitiatorRequest_t *smScsiRequest, /* NULL */ 985 smSatIOContext_t *satIOContext, /* task management */ 986 smIORequest_t *taskTag) /* io to be aborted */ 987 { 988 smDeviceData_t *oneDeviceData = agNULL; 989 smSatIOContext_t *satTempIOContext = agNULL; 990 smList_t *elementHdr; 991 bit32 found = agFALSE; 992 smIORequestBody_t *smIORequestBody = agNULL; 993 smIORequest_t *smIOReq = agNULL; 994 bit32 status; 995 996 SM_DBG1(("smsatTmAbortTask: start\n")); 997 998 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData; 999 1000 /* 1001 * Check that the only pending I/O matches taskTag. If not return tiError. 1002 */ 1003 tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK); 1004 1005 elementHdr = oneDeviceData->satIoLinkList.flink; 1006 1007 while (elementHdr != &oneDeviceData->satIoLinkList) 1008 { 1009 satTempIOContext = SMLIST_OBJECT_BASE( smSatIOContext_t, 1010 satIoContextLink, 1011 elementHdr ); 1012 1013 if ( satTempIOContext != agNULL) 1014 { 1015 smIORequestBody = (smIORequestBody_t *) satTempIOContext->smRequestBody; 1016 smIOReq = smIORequestBody->smIORequest; 1017 } 1018 1019 elementHdr = elementHdr->flink; /* for the next while loop */ 1020 1021 /* 1022 * Check if the tag matches 1023 */ 1024 if ( smIOReq == taskTag) 1025 { 1026 found = agTRUE; 1027 satIOContext->satToBeAbortedIOContext = satTempIOContext; 1028 SM_DBG1(("smsatTmAbortTask: found matching tag.\n")); 1029 1030 break; 1031 1032 } /* if matching tag */ 1033 1034 } /* while loop */ 1035 1036 tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 1037 1038 if (found == agFALSE ) 1039 { 1040 SM_DBG1(("smsatTmAbortTask: *** REJECT *** no match!!!\n")); 1041 1042 /*smEnqueueIO(smRoot, satIOContext);*/ 1043 /* clean up TD layer's smIORequestBody */ 1044 if (smIORequestBody) 1045 { 1046 if (smIORequestBody->IOType.InitiatorTMIO.osMemHandle != agNULL) 1047 { 1048 tdsmFreeMemory( 1049 smRoot, 1050 smIORequestBody->IOType.InitiatorTMIO.osMemHandle, 1051 sizeof(smIORequestBody_t) 1052 ); 1053 } 1054 } 1055 else 1056 { 1057 SM_DBG1(("smsatTmAbortTask: smIORequestBody is NULL!!!\n")); 1058 } 1059 1060 return SM_RC_FAILURE; 1061 } 1062 1063 if (satTempIOContext == agNULL) 1064 { 1065 SM_DBG1(("smsatTmAbortTask: satTempIOContext is NULL!!!\n")); 1066 return SM_RC_FAILURE; 1067 } 1068 1069 /* 1070 * Save smIORequest, will be returned at device reset completion to return 1071 * the TM completion. 1072 */ 1073 oneDeviceData->satTmTaskTag = currentTaskTag; 1074 1075 /* 1076 * Set flag to indicate device in recovery mode. 1077 */ 1078 oneDeviceData->satDriveState = SAT_DEV_STATE_IN_RECOVERY; 1079 1080 1081 /* 1082 * Issue SATA device reset or check power mode.. Set flag to to automatically abort 1083 * at the completion of SATA device reset. 1084 * SAT r09 p25 1085 */ 1086 oneDeviceData->satAbortAfterReset = agTRUE; 1087 1088 if ( (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) || 1089 (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) 1090 ) 1091 { 1092 SM_DBG1(("smsatTmAbortTask: calling satStartCheckPowerMode!!!\n")); 1093 /* send check power mode */ 1094 status = smsatStartCheckPowerMode( 1095 smRoot, 1096 currentTaskTag, /* currentTaskTag */ 1097 smDeviceHandle, 1098 smScsiRequest, /* NULL */ 1099 satIOContext 1100 ); 1101 } 1102 else 1103 { 1104 SM_DBG1(("smsatTmAbortTask: calling satStartResetDevice!!!\n")); 1105 /* send AGSA_SATA_PROTOCOL_SRST_ASSERT */ 1106 status = smsatStartResetDevice( 1107 smRoot, 1108 currentTaskTag, /* currentTaskTag */ 1109 smDeviceHandle, 1110 smScsiRequest, /* NULL */ 1111 satIOContext 1112 ); 1113 } 1114 return status; 1115 } 1116 1117 /* satTM() */ 1118 osGLOBAL bit32 1119 smsatTaskManagement( 1120 smRoot_t *smRoot, 1121 smDeviceHandle_t *smDeviceHandle, 1122 bit32 task, 1123 smLUN_t *lun, 1124 smIORequest_t *taskTag, /* io to be aborted */ 1125 smIORequest_t *currentTaskTag, /* task management */ 1126 smIORequestBody_t *smIORequestBody 1127 ) 1128 { 1129 smSatIOContext_t *satIOContext = agNULL; 1130 smDeviceData_t *oneDeviceData = agNULL; 1131 bit32 status; 1132 1133 SM_DBG1(("smsatTaskManagement: start\n")); 1134 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData; 1135 1136 satIOContext = &(smIORequestBody->transport.SATA.satIOContext); 1137 1138 satIOContext->pSatDevData = oneDeviceData; 1139 satIOContext->pFis = 1140 &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 1141 1142 1143 satIOContext->smRequestBody = smIORequestBody; 1144 satIOContext->psmDeviceHandle = smDeviceHandle; 1145 satIOContext->satIntIoContext = agNULL; 1146 satIOContext->satOrgIOContext = agNULL; 1147 1148 /* followings are used only for internal IO */ 1149 satIOContext->currentLBA = 0; 1150 satIOContext->OrgTL = 0; 1151 1152 /* saving task in satIOContext */ 1153 satIOContext->TMF = task; 1154 1155 satIOContext->satToBeAbortedIOContext = agNULL; 1156 1157 if (task == AG_ABORT_TASK) 1158 { 1159 status = smsatTmAbortTask( smRoot, 1160 currentTaskTag, 1161 smDeviceHandle, 1162 agNULL, 1163 satIOContext, 1164 taskTag); 1165 1166 return status; 1167 } 1168 else 1169 { 1170 SM_DBG1(("smsatTaskManagement: UNSUPPORTED TM task=0x%x!!!\n", task )); 1171 1172 /*smEnqueueIO(smRoot, satIOContext);*/ 1173 1174 return SM_RC_FAILURE; 1175 } 1176 1177 return SM_RC_SUCCESS; 1178 } 1179 1180 1181 osGLOBAL bit32 1182 smPhyControlSend( 1183 smRoot_t *smRoot, 1184 smDeviceData_t *oneDeviceData, /* sata disk itself */ 1185 bit8 phyOp, 1186 smIORequest_t *CurrentTaskTag, 1187 bit32 queueNumber 1188 ) 1189 { 1190 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData; 1191 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 1192 agsaRoot_t *agRoot = smAllShared->agRoot; 1193 agsaDevHandle_t *agExpDevHandle; 1194 smpReqPhyControl_t smpPhyControlReq; 1195 void *osMemHandle; 1196 bit32 PhysUpper32; 1197 bit32 PhysLower32; 1198 bit32 memAllocStatus; 1199 bit32 expectedRspLen = 0; 1200 smSMPRequestBody_t *smSMPRequestBody; 1201 agsaSASRequestBody_t *agSASRequestBody; 1202 agsaSMPFrame_t *agSMPFrame; 1203 agsaIORequest_t *agIORequest; 1204 // agsaDevHandle_t *agDevHandle; 1205 smSMPFrameHeader_t smSMPFrameHeader; 1206 bit32 status; 1207 bit8 *pSmpBody; /* smp payload itself w/o first 4 bytes(header) */ 1208 bit32 smpBodySize; /* smp payload size w/o first 4 bytes(header) */ 1209 bit32 agRequestType; 1210 1211 SM_DBG2(("smPhyControlSend: start\n")); 1212 1213 agExpDevHandle = oneDeviceData->agExpDevHandle; 1214 1215 if (agExpDevHandle == agNULL) 1216 { 1217 SM_DBG1(("smPhyControlSend: agExpDevHandle is NULL!!!\n")); 1218 return SM_RC_FAILURE; 1219 } 1220 1221 SM_DBG5(("smPhyControlSend: phyID %d\n", oneDeviceData->phyID)); 1222 1223 sm_memset(&smpPhyControlReq, 0, sizeof(smpReqPhyControl_t)); 1224 1225 /* fill in SMP payload */ 1226 smpPhyControlReq.phyIdentifier = (bit8)oneDeviceData->phyID; 1227 smpPhyControlReq.phyOperation = phyOp; 1228 1229 /* allocate smp and send it */ 1230 memAllocStatus = tdsmAllocMemory( 1231 smRoot, 1232 &osMemHandle, 1233 (void **)&smSMPRequestBody, 1234 &PhysUpper32, 1235 &PhysLower32, 1236 8, 1237 sizeof(smSMPRequestBody_t), 1238 agTRUE 1239 ); 1240 1241 if (memAllocStatus != SM_RC_SUCCESS) 1242 { 1243 SM_DBG1(("smPhyControlSend: tdsmAllocMemory failed...!!!\n")); 1244 return SM_RC_FAILURE; 1245 } 1246 1247 if (smSMPRequestBody == agNULL) 1248 { 1249 SM_DBG1(("smPhyControlSend: tdsmAllocMemory returned NULL smSMPRequestBody!!!\n")); 1250 return SM_RC_FAILURE; 1251 } 1252 1253 /* saves mem handle for freeing later */ 1254 smSMPRequestBody->osMemHandle = osMemHandle; 1255 1256 /* saves oneDeviceData */ 1257 smSMPRequestBody->smDeviceData = oneDeviceData; /* sata disk */ 1258 1259 /* saves oneDeviceData */ 1260 smSMPRequestBody->smDevHandle = oneDeviceData->smDevHandle; 1261 1262 // agDevHandle = oneDeviceData->agDevHandle; 1263 1264 /* save the callback funtion */ 1265 smSMPRequestBody->SMPCompletionFunc = smSMPCompleted; /* in satcb.c */ 1266 1267 /* for simulate warm target reset */ 1268 smSMPRequestBody->CurrentTaskTag = CurrentTaskTag; 1269 1270 if (CurrentTaskTag != agNULL) 1271 { 1272 CurrentTaskTag->smData = smSMPRequestBody; 1273 } 1274 1275 /* initializes the number of SMP retries */ 1276 smSMPRequestBody->retries = 0; 1277 1278 #ifdef TD_INTERNAL_DEBUG /* debugging */ 1279 SM_DBG4(("smPhyControlSend: SMPRequestbody %p\n", smSMPRequestBody)); 1280 SM_DBG4(("smPhyControlSend: callback fn %p\n", smSMPRequestBody->SMPCompletionFunc)); 1281 #endif 1282 1283 agIORequest = &(smSMPRequestBody->agIORequest); 1284 agIORequest->osData = (void *) smSMPRequestBody; 1285 agIORequest->sdkData = agNULL; /* SALL takes care of this */ 1286 1287 1288 agSASRequestBody = &(smSMPRequestBody->agSASRequestBody); 1289 agSMPFrame = &(agSASRequestBody->smpFrame); 1290 1291 SM_DBG3(("smPhyControlSend: agIORequest %p\n", agIORequest)); 1292 SM_DBG3(("smPhyControlSend: SMPRequestbody %p\n", smSMPRequestBody)); 1293 1294 expectedRspLen = 4; 1295 1296 pSmpBody = (bit8 *)&smpPhyControlReq; 1297 smpBodySize = sizeof(smpReqPhyControl_t); 1298 agRequestType = AGSA_SMP_INIT_REQ; 1299 1300 if (SMIsSPC(agRoot)) 1301 { 1302 if ( (smpBodySize + 4) <= SMP_DIRECT_PAYLOAD_LIMIT) /* 48 */ 1303 { 1304 SM_DBG3(("smPhyControlSend: DIRECT smp payload\n")); 1305 sm_memset(&smSMPFrameHeader, 0, sizeof(smSMPFrameHeader_t)); 1306 sm_memset(smSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT); 1307 1308 /* SMP header */ 1309 smSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */ 1310 smSMPFrameHeader.smpFunction = (bit8)SMP_PHY_CONTROL; 1311 smSMPFrameHeader.smpFunctionResult = 0; 1312 smSMPFrameHeader.smpReserved = 0; 1313 1314 sm_memcpy(smSMPRequestBody->smpPayload, &smSMPFrameHeader, 4); 1315 sm_memcpy((smSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize); 1316 1317 /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */ 1318 agSMPFrame->outFrameBuf = smSMPRequestBody->smpPayload; 1319 agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */ 1320 /* to specify DIRECT SMP response */ 1321 agSMPFrame->inFrameLen = 0; 1322 1323 /* temporary solution for T2D Combo*/ 1324 #if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER) 1325 /* force smp repsonse to be direct */ 1326 agSMPFrame->expectedRespLen = 0; 1327 #else 1328 agSMPFrame->expectedRespLen = expectedRspLen; 1329 #endif 1330 // smhexdump("smPhyControlSend", (bit8*)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen); 1331 // smhexdump("smPhyControlSend new", (bit8*)smSMPRequestBody->smpPayload, agSMPFrame->outFrameLen); 1332 // smhexdump("smPhyControlSend - smSMPRequestBody", (bit8*)smSMPRequestBody, sizeof(smSMPRequestBody_t)); 1333 } 1334 else 1335 { 1336 SM_DBG1(("smPhyControlSend: INDIRECT smp payload, not supported!!!\n")); 1337 tdsmFreeMemory( 1338 smRoot, 1339 osMemHandle, 1340 sizeof(smSMPRequestBody_t) 1341 ); 1342 1343 return SM_RC_FAILURE; 1344 } 1345 } 1346 else /* SPCv controller */ 1347 { 1348 /* only direct mode for both request and response */ 1349 SM_DBG3(("smPhyControlSend: DIRECT smp payload\n")); 1350 agSMPFrame->flag = 0; 1351 sm_memset(&smSMPFrameHeader, 0, sizeof(smSMPFrameHeader_t)); 1352 sm_memset(smSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT); 1353 1354 /* SMP header */ 1355 smSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */ 1356 smSMPFrameHeader.smpFunction = (bit8)SMP_PHY_CONTROL; 1357 smSMPFrameHeader.smpFunctionResult = 0; 1358 smSMPFrameHeader.smpReserved = 0; 1359 1360 sm_memcpy(smSMPRequestBody->smpPayload, &smSMPFrameHeader, 4); 1361 sm_memcpy((smSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize); 1362 1363 /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */ 1364 agSMPFrame->outFrameBuf = smSMPRequestBody->smpPayload; 1365 agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */ 1366 /* to specify DIRECT SMP response */ 1367 agSMPFrame->inFrameLen = 0; 1368 1369 /* temporary solution for T2D Combo*/ 1370 #if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER) 1371 /* force smp repsonse to be direct */ 1372 agSMPFrame->expectedRespLen = 0; 1373 #else 1374 agSMPFrame->expectedRespLen = expectedRspLen; 1375 #endif 1376 // smhexdump("smPhyControlSend", (bit8*)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen); 1377 // smhexdump("smPhyControlSend new", (bit8*)smSMPRequestBody->smpPayload, agSMPFrame->outFrameLen); 1378 // smhexdump("smPhyControlSend - smSMPRequestBody", (bit8*)smSMPRequestBody, sizeof(smSMPRequestBody_t)); 1379 } 1380 1381 status = saSMPStart( 1382 agRoot, 1383 agIORequest, 1384 queueNumber, 1385 agExpDevHandle, 1386 agRequestType, 1387 agSASRequestBody, 1388 &smSMPCompletedCB 1389 ); 1390 1391 if (status == AGSA_RC_SUCCESS) 1392 { 1393 return SM_RC_SUCCESS; 1394 } 1395 else if (status == AGSA_RC_BUSY) 1396 { 1397 SM_DBG1(("smPhyControlSend: saSMPStart is busy!!!\n")); 1398 tdsmFreeMemory( 1399 smRoot, 1400 osMemHandle, 1401 sizeof(smSMPRequestBody_t) 1402 ); 1403 1404 return SM_RC_BUSY; 1405 } 1406 else /* AGSA_RC_FAILURE */ 1407 { 1408 SM_DBG1(("smPhyControlSend: saSMPStart is failed. status %d!!!\n", status)); 1409 tdsmFreeMemory( 1410 smRoot, 1411 osMemHandle, 1412 sizeof(smSMPRequestBody_t) 1413 ); 1414 1415 return SM_RC_FAILURE; 1416 } 1417 } 1418 1419 /* free IO which are internally completed within SM 1420 counterpart is 1421 osGLOBAL smIORequestBody_t * 1422 smDequeueIO(smRoot_t *smRoot) 1423 */ 1424 osGLOBAL void 1425 smEnqueueIO( 1426 smRoot_t *smRoot, 1427 smSatIOContext_t *satIOContext 1428 ) 1429 { 1430 smIntRoot_t *smIntRoot = agNULL; 1431 smIntContext_t *smAllShared = agNULL; 1432 smIORequestBody_t *smIORequestBody; 1433 1434 SM_DBG3(("smEnqueueIO: start\n")); 1435 smIORequestBody = (smIORequestBody_t *)satIOContext->smRequestBody; 1436 smIntRoot = (smIntRoot_t *)smRoot->smData; 1437 smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 1438 1439 /* enque back to smAllShared->freeIOList */ 1440 if (satIOContext->satIntIoContext == agNULL) 1441 { 1442 SM_DBG2(("smEnqueueIO: external command!!!, io ID %d!!!\n", smIORequestBody->id)); 1443 /* debugging only */ 1444 if (smIORequestBody->satIoBodyLink.flink == agNULL) 1445 { 1446 SM_DBG1(("smEnqueueIO: external command!!!, io ID %d, flink is NULL!!!\n", smIORequestBody->id)); 1447 } 1448 if (smIORequestBody->satIoBodyLink.blink == agNULL) 1449 { 1450 SM_DBG1(("smEnqueueIO: external command!!!, io ID %d, blink is NULL!!!\n", smIORequestBody->id)); 1451 } 1452 } 1453 else 1454 { 1455 SM_DBG2(("smEnqueueIO: internal command!!!, io ID %d!!!\n", smIORequestBody->id)); 1456 /* debugging only */ 1457 if (smIORequestBody->satIoBodyLink.flink == agNULL) 1458 { 1459 SM_DBG1(("smEnqueueIO: internal command!!!, io ID %d, flink is NULL!!!\n", smIORequestBody->id)); 1460 } 1461 if (smIORequestBody->satIoBodyLink.blink == agNULL) 1462 { 1463 SM_DBG1(("smEnqueueIO: internal command!!!, io ID %d, blink is NULL!!!\n", smIORequestBody->id)); 1464 } 1465 } 1466 1467 if (smIORequestBody->smIORequest == agNULL) 1468 { 1469 SM_DBG1(("smEnqueueIO: smIORequest is NULL, io ID %d!!!\n", smIORequestBody->id)); 1470 } 1471 1472 if (smIORequestBody->InUse == agTRUE) 1473 { 1474 smIORequestBody->InUse = agFALSE; 1475 tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK); 1476 SMLIST_DEQUEUE_THIS(&(smIORequestBody->satIoBodyLink)); 1477 SMLIST_ENQUEUE_AT_TAIL(&(smIORequestBody->satIoBodyLink), &(smAllShared->freeIOList)); 1478 tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK); 1479 } 1480 else 1481 { 1482 SM_DBG2(("smEnqueueIO: check!!!, io ID %d!!!\n", smIORequestBody->id)); 1483 } 1484 1485 1486 return; 1487 } 1488 1489 FORCEINLINE void 1490 smsatFreeIntIoResource( 1491 smRoot_t *smRoot, 1492 smDeviceData_t *satDevData, 1493 smSatInternalIo_t *satIntIo 1494 ) 1495 { 1496 SM_DBG3(("smsatFreeIntIoResource: start\n")); 1497 1498 if (satIntIo == agNULL) 1499 { 1500 SM_DBG2(("smsatFreeIntIoResource: allowed call\n")); 1501 return; 1502 } 1503 1504 /* sets the original smIOrequest to agNULL for internally generated ATA cmnd */ 1505 satIntIo->satOrgSmIORequest = agNULL; 1506 1507 /* 1508 * Free DMA memory if previosly alocated 1509 */ 1510 if (satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength != 0) 1511 { 1512 SM_DBG3(("smsatFreeIntIoResource: DMA len %d\n", satIntIo->satIntDmaMem.totalLength)); 1513 SM_DBG3(("smsatFreeIntIoResource: pointer %p\n", satIntIo->satIntDmaMem.osHandle)); 1514 1515 tdsmFreeMemory( smRoot, 1516 satIntIo->satIntDmaMem.osHandle, 1517 satIntIo->satIntDmaMem.totalLength); 1518 satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = 0; 1519 } 1520 1521 if (satIntIo->satIntReqBodyMem.totalLength != 0) 1522 { 1523 SM_DBG3(("smsatFreeIntIoResource: req body len %d\n", satIntIo->satIntReqBodyMem.totalLength)); 1524 /* 1525 * Free mem allocated for Req body 1526 */ 1527 tdsmFreeMemory( smRoot, 1528 satIntIo->satIntReqBodyMem.osHandle, 1529 satIntIo->satIntReqBodyMem.totalLength); 1530 1531 satIntIo->satIntReqBodyMem.totalLength = 0; 1532 } 1533 1534 SM_DBG3(("smsatFreeIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id)); 1535 /* 1536 * Return satIntIo to the free list 1537 */ 1538 tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK); 1539 SMLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink)); 1540 SMLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satFreeIntIoLinkList)); 1541 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK); 1542 1543 return; 1544 } 1545 //start here 1546 osGLOBAL smSatInternalIo_t * 1547 smsatAllocIntIoResource( 1548 smRoot_t *smRoot, 1549 smIORequest_t *smIORequest, 1550 smDeviceData_t *satDevData, 1551 bit32 dmaAllocLength, 1552 smSatInternalIo_t *satIntIo) 1553 { 1554 smList_t *smList = agNULL; 1555 bit32 memAllocStatus; 1556 1557 SM_DBG3(("smsatAllocIntIoResource: start\n")); 1558 SM_DBG3(("smsatAllocIntIoResource: satIntIo %p\n", satIntIo)); 1559 if (satDevData == agNULL) 1560 { 1561 SM_DBG1(("smsatAllocIntIoResource: ***** ASSERT satDevData is null!!!\n")); 1562 return agNULL; 1563 } 1564 1565 tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK); 1566 if (!SMLIST_EMPTY(&(satDevData->satFreeIntIoLinkList))) 1567 { 1568 SMLIST_DEQUEUE_FROM_HEAD(&smList, &(satDevData->satFreeIntIoLinkList)); 1569 } 1570 else 1571 { 1572 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK); 1573 SM_DBG1(("smsatAllocIntIoResource() no more internal free link!!!\n")); 1574 return agNULL; 1575 } 1576 1577 if (smList == agNULL) 1578 { 1579 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK); 1580 SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc satIntIo!!!\n")); 1581 return agNULL; 1582 } 1583 1584 satIntIo = SMLIST_OBJECT_BASE( smSatInternalIo_t, satIntIoLink, smList); 1585 SM_DBG3(("smsatAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id)); 1586 1587 /* Put in active list */ 1588 SMLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink)); 1589 SMLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satActiveIntIoLinkList)); 1590 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK); 1591 1592 #ifdef REMOVED 1593 /* Put in active list */ 1594 tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK); 1595 SMLIST_DEQUEUE_THIS (smList); 1596 SMLIST_ENQUEUE_AT_TAIL (smList, &(satDevData->satActiveIntIoLinkList)); 1597 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK); 1598 1599 satIntIo = SMLIST_OBJECT_BASE( smSatInternalIo_t, satIntIoLink, smList); 1600 SM_DBG3(("smsatAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id)); 1601 #endif 1602 1603 /* 1604 typedef struct 1605 { 1606 tdList_t satIntIoLink; 1607 smIORequest_t satIntSmIORequest; 1608 void *satIntRequestBody; 1609 smScsiInitiatorRequest_t satIntSmScsiXchg; 1610 smMem_t satIntDmaMem; 1611 smMem_t satIntReqBodyMem; 1612 bit32 satIntFlag; 1613 } smSatInternalIo_t; 1614 */ 1615 1616 /* 1617 * Allocate mem for Request Body 1618 */ 1619 satIntIo->satIntReqBodyMem.totalLength = sizeof(smIORequestBody_t); 1620 1621 memAllocStatus = tdsmAllocMemory( smRoot, 1622 &satIntIo->satIntReqBodyMem.osHandle, 1623 (void **)&satIntIo->satIntRequestBody, 1624 &satIntIo->satIntReqBodyMem.physAddrUpper, 1625 &satIntIo->satIntReqBodyMem.physAddrLower, 1626 8, 1627 satIntIo->satIntReqBodyMem.totalLength, 1628 agTRUE ); 1629 1630 if (memAllocStatus != SM_RC_SUCCESS) 1631 { 1632 SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc mem for Req Body!!!\n")); 1633 /* 1634 * Return satIntIo to the free list 1635 */ 1636 tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK); 1637 SMLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink); 1638 SMLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList); 1639 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK); 1640 1641 return agNULL; 1642 } 1643 1644 /* 1645 * Allocate DMA memory if required 1646 */ 1647 if (dmaAllocLength != 0) 1648 { 1649 satIntIo->satIntDmaMem.totalLength = dmaAllocLength; 1650 1651 memAllocStatus = tdsmAllocMemory( smRoot, 1652 &satIntIo->satIntDmaMem.osHandle, 1653 (void **)&satIntIo->satIntDmaMem.virtPtr, 1654 &satIntIo->satIntDmaMem.physAddrUpper, 1655 &satIntIo->satIntDmaMem.physAddrLower, 1656 8, 1657 satIntIo->satIntDmaMem.totalLength, 1658 agFALSE); 1659 SM_DBG3(("smsatAllocIntIoResource: len %d \n", satIntIo->satIntDmaMem.totalLength)); 1660 SM_DBG3(("smsatAllocIntIoResource: pointer %p \n", satIntIo->satIntDmaMem.osHandle)); 1661 1662 if (memAllocStatus != SM_RC_SUCCESS) 1663 { 1664 SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc mem for DMA mem!!!\n")); 1665 /* 1666 * Return satIntIo to the free list 1667 */ 1668 tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK); 1669 SMLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink); 1670 SMLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList); 1671 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK); 1672 1673 /* 1674 * Free mem allocated for Req body 1675 */ 1676 tdsmFreeMemory( smRoot, 1677 satIntIo->satIntReqBodyMem.osHandle, 1678 satIntIo->satIntReqBodyMem.totalLength); 1679 1680 return agNULL; 1681 } 1682 } 1683 1684 /* 1685 typedef struct 1686 { 1687 smList_t satIntIoLink; 1688 smIORequest_t satIntSmIORequest; 1689 void *satIntRequestBody; 1690 smScsiInitiatorRequest_t satIntSmScsiXchg; 1691 smMem_t satIntDmaMem; 1692 smMem_t satIntReqBodyMem; 1693 bit32 satIntFlag; 1694 } smSatInternalIo_t; 1695 */ 1696 1697 /* 1698 * Initialize satIntSmIORequest field 1699 */ 1700 satIntIo->satIntSmIORequest.tdData = agNULL; /* Not used for internal SAT I/O */ 1701 satIntIo->satIntSmIORequest.smData = satIntIo->satIntRequestBody; 1702 1703 /* 1704 * saves the original smIOrequest 1705 */ 1706 satIntIo->satOrgSmIORequest = smIORequest; 1707 /* 1708 typedef struct tiIniScsiCmnd 1709 { 1710 tiLUN_t lun; 1711 bit32 expDataLength; 1712 bit32 taskAttribute; 1713 bit32 crn; 1714 bit8 cdb[16]; 1715 } tiIniScsiCmnd_t; 1716 1717 typedef struct tiScsiInitiatorExchange 1718 { 1719 void *sglVirtualAddr; 1720 tiIniScsiCmnd_t scsiCmnd; 1721 tiSgl_t agSgl1; 1722 tiSgl_t agSgl2; 1723 tiDataDirection_t dataDirection; 1724 } tiScsiInitiatorRequest_t; 1725 1726 */ 1727 1728 /* 1729 * Initialize satIntSmScsiXchg. Since the internal SAT request is NOT 1730 * originated from SCSI request, only the following fields are initialized: 1731 * - sglVirtualAddr if DMA transfer is involved 1732 * - agSgl1 if DMA transfer is involved 1733 * - expDataLength in scsiCmnd since this field is read by smsataLLIOStart() 1734 */ 1735 if (dmaAllocLength != 0) 1736 { 1737 satIntIo->satIntSmScsiXchg.sglVirtualAddr = satIntIo->satIntDmaMem.virtPtr; 1738 1739 OSSA_WRITE_LE_32(agNULL, &satIntIo->satIntSmScsiXchg.smSgl1.len, 0, 1740 satIntIo->satIntDmaMem.totalLength); 1741 satIntIo->satIntSmScsiXchg.smSgl1.lower = satIntIo->satIntDmaMem.physAddrLower; 1742 satIntIo->satIntSmScsiXchg.smSgl1.upper = satIntIo->satIntDmaMem.physAddrUpper; 1743 satIntIo->satIntSmScsiXchg.smSgl1.type = tiSgl; 1744 1745 satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = satIntIo->satIntDmaMem.totalLength; 1746 } 1747 else 1748 { 1749 satIntIo->satIntSmScsiXchg.sglVirtualAddr = agNULL; 1750 1751 satIntIo->satIntSmScsiXchg.smSgl1.len = 0; 1752 satIntIo->satIntSmScsiXchg.smSgl1.lower = 0; 1753 satIntIo->satIntSmScsiXchg.smSgl1.upper = 0; 1754 satIntIo->satIntSmScsiXchg.smSgl1.type = tiSgl; 1755 1756 satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = 0; 1757 } 1758 1759 SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.len %d\n", satIntIo->satIntSmScsiXchg.smSgl1.len)); 1760 1761 SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.upper %d\n", satIntIo->satIntSmScsiXchg.smSgl1.upper)); 1762 1763 SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.lower %d\n", satIntIo->satIntSmScsiXchg.smSgl1.lower)); 1764 1765 SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.type %d\n", satIntIo->satIntSmScsiXchg.smSgl1.type)); 1766 SM_DBG5(("smsatAllocIntIoResource: return satIntIo %p\n", satIntIo)); 1767 return satIntIo; 1768 } 1769 1770 osGLOBAL smDeviceData_t * 1771 smAddToSharedcontext( 1772 smRoot_t *smRoot, 1773 agsaDevHandle_t *agDevHandle, 1774 smDeviceHandle_t *smDeviceHandle, 1775 agsaDevHandle_t *agExpDevHandle, 1776 bit32 phyID 1777 ) 1778 { 1779 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData; 1780 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 1781 smDeviceData_t *oneDeviceData = agNULL; 1782 smList_t *DeviceListList; 1783 bit32 new_device = agTRUE; 1784 1785 SM_DBG2(("smAddToSharedcontext: start\n")); 1786 1787 /* find a device's existence */ 1788 DeviceListList = smAllShared->MainDeviceList.flink; 1789 while (DeviceListList != &(smAllShared->MainDeviceList)) 1790 { 1791 oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, MainLink, DeviceListList); 1792 if (oneDeviceData == agNULL) 1793 { 1794 SM_DBG1(("smAddToSharedcontext: oneDeviceData is NULL!!!\n")); 1795 return agNULL; 1796 } 1797 if (oneDeviceData->agDevHandle == agDevHandle) 1798 { 1799 SM_DBG2(("smAddToSharedcontext: did %d\n", oneDeviceData->id)); 1800 new_device = agFALSE; 1801 break; 1802 } 1803 DeviceListList = DeviceListList->flink; 1804 } 1805 1806 /* new device */ 1807 if (new_device == agTRUE) 1808 { 1809 SM_DBG2(("smAddToSharedcontext: new device\n")); 1810 tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK); 1811 if (SMLIST_EMPTY(&(smAllShared->FreeDeviceList))) 1812 { 1813 tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK); 1814 SM_DBG1(("smAddToSharedcontext: empty DeviceData FreeLink!!!\n")); 1815 smDeviceHandle->smData = agNULL; 1816 return agNULL; 1817 } 1818 1819 SMLIST_DEQUEUE_FROM_HEAD(&DeviceListList, &(smAllShared->FreeDeviceList)); 1820 tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK); 1821 oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, FreeLink, DeviceListList); 1822 oneDeviceData->smRoot = smRoot; 1823 oneDeviceData->agDevHandle = agDevHandle; 1824 oneDeviceData->valid = agTRUE; 1825 smDeviceHandle->smData = oneDeviceData; 1826 oneDeviceData->smDevHandle = smDeviceHandle; 1827 if (agExpDevHandle == agNULL) 1828 { 1829 oneDeviceData->directlyAttached = agTRUE; 1830 } 1831 else 1832 { 1833 oneDeviceData->directlyAttached = agFALSE; 1834 } 1835 oneDeviceData->agExpDevHandle = agExpDevHandle; 1836 oneDeviceData->phyID = phyID; 1837 oneDeviceData->satPendingIO = 0; 1838 oneDeviceData->satPendingNCQIO = 0; 1839 oneDeviceData->satPendingNONNCQIO = 0; 1840 /* add the devicedata to the portcontext */ 1841 tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK); 1842 SMLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->MainLink), &(smAllShared->MainDeviceList)); 1843 tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK); 1844 SM_DBG2(("smAddToSharedcontext: new case did %d\n", oneDeviceData->id)); 1845 } 1846 else 1847 { 1848 SM_DBG2(("smAddToSharedcontext: old device\n")); 1849 oneDeviceData->smRoot = smRoot; 1850 oneDeviceData->agDevHandle = agDevHandle; 1851 oneDeviceData->valid = agTRUE; 1852 smDeviceHandle->smData = oneDeviceData; 1853 oneDeviceData->smDevHandle = smDeviceHandle; 1854 if (agExpDevHandle == agNULL) 1855 { 1856 oneDeviceData->directlyAttached = agTRUE; 1857 } 1858 else 1859 { 1860 oneDeviceData->directlyAttached = agFALSE; 1861 } 1862 oneDeviceData->agExpDevHandle = agExpDevHandle; 1863 oneDeviceData->phyID = phyID; 1864 oneDeviceData->satPendingIO = 0; 1865 oneDeviceData->satPendingNCQIO = 0; 1866 oneDeviceData->satPendingNONNCQIO = 0; 1867 SM_DBG2(("smAddToSharedcontext: old case did %d\n", oneDeviceData->id)); 1868 } 1869 1870 return oneDeviceData; 1871 } 1872 1873 osGLOBAL bit32 1874 smRemoveFromSharedcontext( 1875 smRoot_t *smRoot, 1876 agsaDevHandle_t *agDevHandle, 1877 smDeviceHandle_t *smDeviceHandle 1878 ) 1879 { 1880 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData; 1881 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 1882 smDeviceData_t *oneDeviceData = agNULL; 1883 1884 SM_DBG2(("smRemoveFromSharedcontext: start\n")); 1885 1886 //due to device all and completion 1887 //smDeviceHandle->smData = agNULL; 1888 1889 /* find oneDeviceData from MainLink */ 1890 oneDeviceData = smFindInSharedcontext(smRoot, agDevHandle); 1891 1892 if (oneDeviceData == agNULL) 1893 { 1894 return SM_RC_FAILURE; 1895 } 1896 else 1897 { 1898 if (oneDeviceData->valid == agTRUE) 1899 { 1900 smDeviceDataReInit(smRoot, oneDeviceData); 1901 tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK); 1902 SMLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink)); 1903 SMLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(smAllShared->FreeDeviceList)); 1904 tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK); 1905 return SM_RC_SUCCESS; 1906 } 1907 else 1908 { 1909 SM_DBG1(("smRemoveFromSharedcontext: did %d bad case!!!\n", oneDeviceData->id)); 1910 return SM_RC_FAILURE; 1911 } 1912 } 1913 1914 } 1915 1916 osGLOBAL smDeviceData_t * 1917 smFindInSharedcontext( 1918 smRoot_t *smRoot, 1919 agsaDevHandle_t *agDevHandle 1920 ) 1921 { 1922 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData; 1923 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared; 1924 smDeviceData_t *oneDeviceData = agNULL; 1925 smList_t *DeviceListList; 1926 1927 SM_DBG2(("smFindInSharedcontext: start\n")); 1928 1929 tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK); 1930 if (SMLIST_EMPTY(&(smAllShared->MainDeviceList))) 1931 { 1932 SM_DBG1(("smFindInSharedcontext: empty MainDeviceList!!!\n")); 1933 tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK); 1934 return agNULL; 1935 } 1936 else 1937 { 1938 tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK); 1939 } 1940 1941 DeviceListList = smAllShared->MainDeviceList.flink; 1942 while (DeviceListList != &(smAllShared->MainDeviceList)) 1943 { 1944 oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, MainLink, DeviceListList); 1945 if (oneDeviceData == agNULL) 1946 { 1947 SM_DBG1(("smFindInSharedcontext: oneDeviceData is NULL!!!\n")); 1948 return agNULL; 1949 } 1950 if ((oneDeviceData->agDevHandle == agDevHandle) && 1951 (oneDeviceData->valid == agTRUE) 1952 ) 1953 { 1954 SM_DBG2(("smFindInSharedcontext: found, did %d\n", oneDeviceData->id)); 1955 return oneDeviceData; 1956 } 1957 DeviceListList = DeviceListList->flink; 1958 } 1959 SM_DBG2(("smFindInSharedcontext: not found\n")); 1960 return agNULL; 1961 } 1962 1963 osGLOBAL smSatIOContext_t * 1964 smsatPrepareNewIO( 1965 smSatInternalIo_t *satNewIntIo, 1966 smIORequest_t *smOrgIORequest, 1967 smDeviceData_t *satDevData, 1968 smIniScsiCmnd_t *scsiCmnd, 1969 smSatIOContext_t *satOrgIOContext 1970 ) 1971 { 1972 smSatIOContext_t *satNewIOContext; 1973 smIORequestBody_t *smNewIORequestBody; 1974 1975 SM_DBG3(("smsatPrepareNewIO: start\n")); 1976 1977 /* the one to be used; good 8/2/07 */ 1978 satNewIntIo->satOrgSmIORequest = smOrgIORequest; /* this is already done in 1979 smsatAllocIntIoResource() */ 1980 1981 smNewIORequestBody = (smIORequestBody_t *)satNewIntIo->satIntRequestBody; 1982 satNewIOContext = &(smNewIORequestBody->transport.SATA.satIOContext); 1983 1984 satNewIOContext->pSatDevData = satDevData; 1985 satNewIOContext->pFis = &(smNewIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 1986 satNewIOContext->pScsiCmnd = &(satNewIntIo->satIntSmScsiXchg.scsiCmnd); 1987 if (scsiCmnd != agNULL) 1988 { 1989 /* saves only CBD; not scsi command for LBA and number of blocks */ 1990 sm_memcpy(satNewIOContext->pScsiCmnd->cdb, scsiCmnd->cdb, 16); 1991 } 1992 satNewIOContext->pSense = &(smNewIORequestBody->transport.SATA.sensePayload); 1993 satNewIOContext->pSmSenseData = &(smNewIORequestBody->transport.SATA.smSenseData); 1994 satNewIOContext->pSmSenseData->senseData = satNewIOContext->pSense; 1995 satNewIOContext->smRequestBody = satNewIntIo->satIntRequestBody; 1996 satNewIOContext->interruptContext = satNewIOContext->interruptContext; 1997 satNewIOContext->satIntIoContext = satNewIntIo; 1998 satNewIOContext->psmDeviceHandle = satOrgIOContext->psmDeviceHandle; 1999 satNewIOContext->satOrgIOContext = satOrgIOContext; 2000 /* saves tiScsiXchg; only for writesame10() */ 2001 satNewIOContext->smScsiXchg = satOrgIOContext->smScsiXchg; 2002 2003 return satNewIOContext; 2004 } 2005 2006 2007 osGLOBAL void 2008 smsatSetDevInfo( 2009 smDeviceData_t *oneDeviceData, 2010 agsaSATAIdentifyData_t *SATAIdData 2011 ) 2012 { 2013 SM_DBG3(("smsatSetDevInfo: start\n")); 2014 2015 oneDeviceData->satDriveState = SAT_DEV_STATE_NORMAL; 2016 oneDeviceData->satFormatState = agFALSE; 2017 oneDeviceData->satDeviceFaultState = agFALSE; 2018 oneDeviceData->satTmTaskTag = agNULL; 2019 oneDeviceData->satAbortAfterReset = agFALSE; 2020 oneDeviceData->satAbortCalled = agFALSE; 2021 oneDeviceData->satSectorDone = 0; 2022 2023 /* Qeueu depth, Word 75 */ 2024 oneDeviceData->satNCQMaxIO = SATAIdData->queueDepth + 1; 2025 SM_DBG3(("smsatSetDevInfo: max queue depth %d\n",oneDeviceData->satNCQMaxIO)); 2026 2027 /* Support NCQ, if Word 76 bit 8 is set */ 2028 if (SATAIdData->sataCapabilities & 0x100) 2029 { 2030 SM_DBG3(("smsatSetDevInfo: device supports NCQ\n")); 2031 oneDeviceData->satNCQ = agTRUE; 2032 } 2033 else 2034 { 2035 SM_DBG3(("smsatSetDevInfo: no NCQ\n")); 2036 oneDeviceData->satNCQ = agFALSE; 2037 } 2038 2039 /* Support 48 bit addressing, if Word 83 bit 10 and Word 86 bit 10 are set */ 2040 if ((SATAIdData->commandSetSupported1 & 0x400) && 2041 (SATAIdData->commandSetFeatureEnabled1 & 0x400) ) 2042 { 2043 SM_DBG3(("smsatSetDevInfo: support 48 bit addressing\n")); 2044 oneDeviceData->sat48BitSupport = agTRUE; 2045 } 2046 else 2047 { 2048 SM_DBG3(("smsatSetDevInfo: NO 48 bit addressing\n")); 2049 oneDeviceData->sat48BitSupport = agFALSE; 2050 } 2051 2052 /* Support SMART Self Test, word84 bit 1 */ 2053 if (SATAIdData->commandSetFeatureSupportedExt & 0x02) 2054 { 2055 SM_DBG3(("smsatSetDevInfo: SMART self-test supported \n")); 2056 oneDeviceData->satSMARTSelfTest = agTRUE; 2057 } 2058 else 2059 { 2060 SM_DBG3(("smsatSetDevInfo: no SMART self-test suppored\n")); 2061 oneDeviceData->satSMARTSelfTest = agFALSE; 2062 } 2063 2064 /* Support SMART feature set, word82 bit 0 */ 2065 if (SATAIdData->commandSetSupported & 0x01) 2066 { 2067 SM_DBG3(("smsatSetDevInfo: SMART feature set supported \n")); 2068 oneDeviceData->satSMARTFeatureSet = agTRUE; 2069 } 2070 else 2071 { 2072 SM_DBG3(("smsatSetDevInfo: no SMART feature set suppored\n")); 2073 oneDeviceData->satSMARTFeatureSet = agFALSE; 2074 } 2075 2076 /* Support SMART enabled, word85 bit 0 */ 2077 if (SATAIdData->commandSetFeatureEnabled & 0x01) 2078 { 2079 SM_DBG3(("smsatSetDevInfo: SMART enabled \n")); 2080 oneDeviceData->satSMARTEnabled = agTRUE; 2081 } 2082 else 2083 { 2084 SM_DBG3(("smsatSetDevInfo: no SMART enabled\n")); 2085 oneDeviceData->satSMARTEnabled = agFALSE; 2086 } 2087 2088 oneDeviceData->satVerifyState = 0; 2089 2090 /* Removable Media feature set support, word82 bit 2 */ 2091 if (SATAIdData->commandSetSupported & 0x4) 2092 { 2093 SM_DBG3(("smsatSetDevInfo: Removable Media supported \n")); 2094 oneDeviceData->satRemovableMedia = agTRUE; 2095 } 2096 else 2097 { 2098 SM_DBG3(("smsatSetDevInfo: no Removable Media suppored\n")); 2099 oneDeviceData->satRemovableMedia = agFALSE; 2100 } 2101 2102 /* Removable Media feature set enabled, word 85, bit 2 */ 2103 if (SATAIdData->commandSetFeatureEnabled & 0x4) 2104 { 2105 SM_DBG3(("smsatSetDevInfo: Removable Media enabled\n")); 2106 oneDeviceData->satRemovableMediaEnabled = agTRUE; 2107 } 2108 else 2109 { 2110 SM_DBG3(("smsatSetDevInfo: no Removable Media enabled\n")); 2111 oneDeviceData->satRemovableMediaEnabled = agFALSE; 2112 } 2113 2114 /* DMA Support, word49 bit8 */ 2115 if (SATAIdData->dma_lba_iod_ios_stimer & 0x100) 2116 { 2117 SM_DBG3(("smsatSetDevInfo: DMA supported \n")); 2118 oneDeviceData->satDMASupport = agTRUE; 2119 } 2120 else 2121 { 2122 SM_DBG3(("smsatSetDevInfo: no DMA suppored\n")); 2123 oneDeviceData->satDMASupport = agFALSE; 2124 } 2125 2126 /* Support DMADIR, if Word 62 bit 8 is set */ 2127 if (SATAIdData->word62_74[0] & 0x8000) 2128 { 2129 SM_DBG3(("satSetDevInfo: DMADIR enabled\n")); 2130 oneDeviceData->satDMADIRSupport = agTRUE; 2131 } 2132 else 2133 { 2134 SM_DBG3(("satSetDevInfo: DMADIR disabled\n")); 2135 oneDeviceData->satDMADIRSupport = agFALSE; 2136 } 2137 2138 /* DMA Enabled, word88 bit0-6, bit8-14*/ 2139 /* 0x7F7F = 0111 1111 0111 1111*/ 2140 if (SATAIdData->ultraDMAModes & 0x7F7F) 2141 { 2142 SM_DBG3(("smsatSetDevInfo: DMA enabled \n")); 2143 oneDeviceData->satDMAEnabled = agTRUE; 2144 if (SATAIdData->ultraDMAModes & 0x40) 2145 { 2146 oneDeviceData->satUltraDMAMode = 6; 2147 } 2148 else if (SATAIdData->ultraDMAModes & 0x20) 2149 { 2150 oneDeviceData->satUltraDMAMode = 5; 2151 } 2152 else if (SATAIdData->ultraDMAModes & 0x10) 2153 { 2154 oneDeviceData->satUltraDMAMode = 4; 2155 } 2156 else if (SATAIdData->ultraDMAModes & 0x08) 2157 { 2158 oneDeviceData->satUltraDMAMode = 3; 2159 } 2160 else if (SATAIdData->ultraDMAModes & 0x04) 2161 { 2162 oneDeviceData->satUltraDMAMode = 2; 2163 } 2164 else if (SATAIdData->ultraDMAModes & 0x01) 2165 { 2166 oneDeviceData->satUltraDMAMode = 1; 2167 } 2168 } 2169 else 2170 { 2171 SM_DBG3(("smsatSetDevInfo: no DMA enabled\n")); 2172 oneDeviceData->satDMAEnabled = agFALSE; 2173 oneDeviceData->satUltraDMAMode = 0; 2174 } 2175 2176 /* 2177 setting MaxUserAddrSectors: max user addressable setctors 2178 word60 - 61, should be 0x 0F FF FF FF 2179 */ 2180 oneDeviceData->satMaxUserAddrSectors 2181 = (SATAIdData->numOfUserAddressableSectorsHi << (8*2) ) 2182 + SATAIdData->numOfUserAddressableSectorsLo; 2183 SM_DBG3(("smsatSetDevInfo: MaxUserAddrSectors 0x%x decimal %d\n", oneDeviceData->satMaxUserAddrSectors, oneDeviceData->satMaxUserAddrSectors)); 2184 2185 /* Read Look-ahead is supported */ 2186 if (SATAIdData->commandSetSupported & 0x40) 2187 { 2188 SM_DBG3(("smsatSetDevInfo: Read Look-ahead is supported\n")); 2189 oneDeviceData->satReadLookAheadSupport= agTRUE; 2190 } 2191 else 2192 { 2193 SM_DBG3(("smsatSetDevInfo: Read Look-ahead is not supported\n")); 2194 oneDeviceData->satReadLookAheadSupport= agFALSE; 2195 } 2196 2197 /* Volatile Write Cache is supported */ 2198 if (SATAIdData->commandSetSupported & 0x20) 2199 { 2200 SM_DBG3(("smsatSetDevInfo: Volatile Write Cache is supported\n")); 2201 oneDeviceData->satVolatileWriteCacheSupport = agTRUE; 2202 } 2203 else 2204 { 2205 SM_DBG3(("smsatSetDevInfo: Volatile Write Cache is not supported\n")); 2206 oneDeviceData->satVolatileWriteCacheSupport = agFALSE; 2207 } 2208 2209 /* write cache enabled for caching mode page SAT Table 67 p69, word85 bit5 */ 2210 if (SATAIdData->commandSetFeatureEnabled & 0x20) 2211 { 2212 SM_DBG3(("smsatSetDevInfo: write cache enabled\n")); 2213 oneDeviceData->satWriteCacheEnabled = agTRUE; 2214 } 2215 else 2216 { 2217 SM_DBG3(("smsatSetDevInfo: no write cache enabled\n")); 2218 oneDeviceData->satWriteCacheEnabled = agFALSE; 2219 } 2220 2221 /* look ahead enabled for caching mode page SAT Table 67 p69, word85 bit6 */ 2222 if (SATAIdData->commandSetFeatureEnabled & 0x40) 2223 { 2224 SM_DBG3(("smsatSetDevInfo: look ahead enabled\n")); 2225 oneDeviceData->satLookAheadEnabled = agTRUE; 2226 } 2227 else 2228 { 2229 SM_DBG3(("smsatSetDevInfo: no look ahead enabled\n")); 2230 oneDeviceData->satLookAheadEnabled = agFALSE; 2231 } 2232 2233 /* Support WWN, if Word 87 bit 8 is set */ 2234 if (SATAIdData->commandSetFeatureDefault & 0x100) 2235 { 2236 SM_DBG3(("smsatSetDevInfo: device supports WWN\n")); 2237 oneDeviceData->satWWNSupport = agTRUE; 2238 } 2239 else 2240 { 2241 SM_DBG3(("smsatSetDevInfo: no WWN\n")); 2242 oneDeviceData->satWWNSupport = agFALSE; 2243 } 2244 2245 /* Support DMA Setup Auto-Activate, if Word 78 bit 2 is set */ 2246 if (SATAIdData->sataFeaturesSupported & 0x4) 2247 { 2248 SM_DBG3(("smsatSetDevInfo: device supports DMA Setup Auto-Activate\n")); 2249 oneDeviceData->satDMASetupAA = agTRUE; 2250 } 2251 else 2252 { 2253 SM_DBG3(("smsatSetDevInfo: no DMA Setup Auto-Activate\n")); 2254 oneDeviceData->satDMASetupAA = agFALSE; 2255 } 2256 2257 /* Support NCQ Queue Management Command, if Word 77 bit 5 is set */ 2258 if (SATAIdData->word77 & 0x10) 2259 { 2260 SM_DBG3(("smsatSetDevInfo: device supports NCQ Queue Management Command\n")); 2261 oneDeviceData->satNCQQMgntCmd = agTRUE; 2262 } 2263 else 2264 { 2265 SM_DBG3(("smsatSetDevInfo: no NCQ Queue Management Command\n")); 2266 oneDeviceData->satNCQQMgntCmd = agFALSE; 2267 } 2268 return; 2269 } 2270 2271 2272 osGLOBAL void 2273 smsatInquiryStandard( 2274 bit8 *pInquiry, 2275 agsaSATAIdentifyData_t *pSATAIdData, 2276 smIniScsiCmnd_t *scsiCmnd 2277 ) 2278 { 2279 smLUN_t *pLun; 2280 pLun = &scsiCmnd->lun; 2281 2282 /* 2283 Assumption: Basic Task Mangement is supported 2284 -> BQUE 1 and CMDQUE 0, SPC-4, Table96, p147 2285 */ 2286 /* 2287 See SPC-4, 6.4.2, p 143 2288 and SAT revision 8, 8.1.2, p 28 2289 */ 2290 SM_DBG5(("smsatInquiryStandard: start\n")); 2291 2292 if (pInquiry == agNULL) 2293 { 2294 SM_DBG1(("smsatInquiryStandard: pInquiry is NULL, wrong\n")); 2295 return; 2296 } 2297 else 2298 { 2299 SM_DBG5(("smsatInquiryStandard: pInquiry is NOT NULL\n")); 2300 } 2301 /* 2302 * Reject all other LUN other than LUN 0. 2303 */ 2304 if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] | 2305 pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) ) 2306 { 2307 /* SAT Spec Table 8, p27, footnote 'a' */ 2308 pInquiry[0] = 0x7F; 2309 2310 } 2311 else 2312 { 2313 pInquiry[0] = 0x00; 2314 } 2315 2316 if (pSATAIdData->rm_ataDevice & ATA_REMOVABLE_MEDIA_DEVICE_MASK ) 2317 { 2318 pInquiry[1] = 0x80; 2319 } 2320 else 2321 { 2322 pInquiry[1] = 0x00; 2323 } 2324 pInquiry[2] = 0x05; /* SPC-3 */ 2325 pInquiry[3] = 0x12; /* set HiSup 1; resp data format set to 2 */ 2326 pInquiry[4] = 0x1F; /* 35 - 4 = 31; Additional length */ 2327 pInquiry[5] = 0x00; 2328 /* The following two are for task management. SAT Rev8, p20 */ 2329 if (pSATAIdData->sataCapabilities & 0x100) 2330 { 2331 /* NCQ supported; multiple outstanding SCSI IO are supported */ 2332 pInquiry[6] = 0x00; /* BQUE bit is not set */ 2333 pInquiry[7] = 0x02; /* CMDQUE bit is set */ 2334 } 2335 else 2336 { 2337 pInquiry[6] = 0x80; /* BQUE bit is set */ 2338 pInquiry[7] = 0x00; /* CMDQUE bit is not set */ 2339 } 2340 /* 2341 * Vendor ID. 2342 */ 2343 sm_strncpy((char*)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8); /* 8 bytes */ 2344 2345 /* 2346 * Product ID 2347 */ 2348 /* when flipped by LL */ 2349 pInquiry[16] = pSATAIdData->modelNumber[1]; 2350 pInquiry[17] = pSATAIdData->modelNumber[0]; 2351 pInquiry[18] = pSATAIdData->modelNumber[3]; 2352 pInquiry[19] = pSATAIdData->modelNumber[2]; 2353 pInquiry[20] = pSATAIdData->modelNumber[5]; 2354 pInquiry[21] = pSATAIdData->modelNumber[4]; 2355 pInquiry[22] = pSATAIdData->modelNumber[7]; 2356 pInquiry[23] = pSATAIdData->modelNumber[6]; 2357 pInquiry[24] = pSATAIdData->modelNumber[9]; 2358 pInquiry[25] = pSATAIdData->modelNumber[8]; 2359 pInquiry[26] = pSATAIdData->modelNumber[11]; 2360 pInquiry[27] = pSATAIdData->modelNumber[10]; 2361 pInquiry[28] = pSATAIdData->modelNumber[13]; 2362 pInquiry[29] = pSATAIdData->modelNumber[12]; 2363 pInquiry[30] = pSATAIdData->modelNumber[15]; 2364 pInquiry[31] = pSATAIdData->modelNumber[14]; 2365 2366 /* when flipped */ 2367 /* 2368 * Product Revision level. 2369 */ 2370 2371 /* 2372 * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA 2373 * device are ASCII spaces (20h), do this translation. 2374 */ 2375 if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) && 2376 (pSATAIdData->firmwareVersion[5] == 0x20 ) && 2377 (pSATAIdData->firmwareVersion[6] == 0x20 ) && 2378 (pSATAIdData->firmwareVersion[7] == 0x20 ) 2379 ) 2380 { 2381 pInquiry[32] = pSATAIdData->firmwareVersion[1]; 2382 pInquiry[33] = pSATAIdData->firmwareVersion[0]; 2383 pInquiry[34] = pSATAIdData->firmwareVersion[3]; 2384 pInquiry[35] = pSATAIdData->firmwareVersion[2]; 2385 } 2386 else 2387 { 2388 pInquiry[32] = pSATAIdData->firmwareVersion[5]; 2389 pInquiry[33] = pSATAIdData->firmwareVersion[4]; 2390 pInquiry[34] = pSATAIdData->firmwareVersion[7]; 2391 pInquiry[35] = pSATAIdData->firmwareVersion[6]; 2392 } 2393 2394 2395 #ifdef REMOVED 2396 /* 2397 * Product ID 2398 */ 2399 /* when flipped by LL */ 2400 pInquiry[16] = pSATAIdData->modelNumber[0]; 2401 pInquiry[17] = pSATAIdData->modelNumber[1]; 2402 pInquiry[18] = pSATAIdData->modelNumber[2]; 2403 pInquiry[19] = pSATAIdData->modelNumber[3]; 2404 pInquiry[20] = pSATAIdData->modelNumber[4]; 2405 pInquiry[21] = pSATAIdData->modelNumber[5]; 2406 pInquiry[22] = pSATAIdData->modelNumber[6]; 2407 pInquiry[23] = pSATAIdData->modelNumber[7]; 2408 pInquiry[24] = pSATAIdData->modelNumber[8]; 2409 pInquiry[25] = pSATAIdData->modelNumber[9]; 2410 pInquiry[26] = pSATAIdData->modelNumber[10]; 2411 pInquiry[27] = pSATAIdData->modelNumber[11]; 2412 pInquiry[28] = pSATAIdData->modelNumber[12]; 2413 pInquiry[29] = pSATAIdData->modelNumber[13]; 2414 pInquiry[30] = pSATAIdData->modelNumber[14]; 2415 pInquiry[31] = pSATAIdData->modelNumber[15]; 2416 2417 /* when flipped */ 2418 /* 2419 * Product Revision level. 2420 */ 2421 2422 /* 2423 * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA 2424 * device are ASCII spaces (20h), do this translation. 2425 */ 2426 if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) && 2427 (pSATAIdData->firmwareVersion[5] == 0x20 ) && 2428 (pSATAIdData->firmwareVersion[6] == 0x20 ) && 2429 (pSATAIdData->firmwareVersion[7] == 0x20 ) 2430 ) 2431 { 2432 pInquiry[32] = pSATAIdData->firmwareVersion[0]; 2433 pInquiry[33] = pSATAIdData->firmwareVersion[1]; 2434 pInquiry[34] = pSATAIdData->firmwareVersion[2]; 2435 pInquiry[35] = pSATAIdData->firmwareVersion[3]; 2436 } 2437 else 2438 { 2439 pInquiry[32] = pSATAIdData->firmwareVersion[4]; 2440 pInquiry[33] = pSATAIdData->firmwareVersion[5]; 2441 pInquiry[34] = pSATAIdData->firmwareVersion[6]; 2442 pInquiry[35] = pSATAIdData->firmwareVersion[7]; 2443 } 2444 #endif 2445 2446 SM_DBG5(("smsatInquiryStandard: end\n")); 2447 2448 return; 2449 } 2450 2451 osGLOBAL void 2452 smsatInquiryPage0( 2453 bit8 *pInquiry, 2454 agsaSATAIdentifyData_t *pSATAIdData 2455 ) 2456 { 2457 SM_DBG5(("smsatInquiryPage0: start\n")); 2458 2459 /* 2460 See SPC-4, 7.6.9, p 345 2461 and SAT revision 8, 10.3.2, p 77 2462 */ 2463 pInquiry[0] = 0x00; 2464 pInquiry[1] = 0x00; /* page code */ 2465 pInquiry[2] = 0x00; /* reserved */ 2466 pInquiry[3] = 8 - 3; /* last index(in this case, 6) - 3; page length */ 2467 2468 /* supported vpd page list */ 2469 pInquiry[4] = 0x00; /* page 0x00 supported */ 2470 pInquiry[5] = 0x80; /* page 0x80 supported */ 2471 pInquiry[6] = 0x83; /* page 0x83 supported */ 2472 pInquiry[7] = 0x89; /* page 0x89 supported */ 2473 pInquiry[8] = 0xB1; /* page 0xB1 supported */ 2474 2475 return; 2476 } 2477 2478 osGLOBAL void 2479 smsatInquiryPage83( 2480 bit8 *pInquiry, 2481 agsaSATAIdentifyData_t *pSATAIdData, 2482 smDeviceData_t *oneDeviceData 2483 ) 2484 { 2485 satSimpleSATAIdentifyData_t *pSimpleData; 2486 2487 /* 2488 * When translating the fields, in some cases using the simple form of SATA 2489 * Identify Device Data is easier. So we define it here. 2490 * Both pSimpleData and pSATAIdData points to the same data. 2491 */ 2492 pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData; 2493 2494 SM_DBG5(("smsatInquiryPage83: start\n")); 2495 2496 pInquiry[0] = 0x00; 2497 pInquiry[1] = 0x83; /* page code */ 2498 pInquiry[2] = 0; /* Reserved */ 2499 /* 2500 * If the ATA device returns word 87 bit 8 set to one in its IDENTIFY DEVICE 2501 * data indicating that it supports the WORLD WIDE NAME field 2502 * (i.e., words 108-111), the SATL shall include an identification descriptor 2503 * containing a logical unit name. 2504 */ 2505 if ( oneDeviceData->satWWNSupport) 2506 { 2507 #ifndef PMC_FREEBSD 2508 /* Fill in SAT Rev8 Table85 */ 2509 /* 2510 * Logical unit name derived from the world wide name. 2511 */ 2512 pInquiry[3] = 12; /* 15-3; page length, no addition ID descriptor assumed*/ 2513 2514 /* 2515 * Identifier descriptor 2516 */ 2517 pInquiry[4] = 0x01; /* Code set: binary codes */ 2518 pInquiry[5] = 0x03; /* Identifier type : NAA */ 2519 pInquiry[6] = 0x00; /* Reserved */ 2520 pInquiry[7] = 0x08; /* Identifier length */ 2521 2522 /* Bit 4-7 NAA field, bit 0-3 MSB of IEEE Company ID */ 2523 pInquiry[8] = (bit8)((pSATAIdData->namingAuthority) >> 8); 2524 pInquiry[9] = (bit8)((pSATAIdData->namingAuthority) & 0xFF); /* IEEE Company ID */ 2525 pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8); /* IEEE Company ID */ 2526 /* Bit 4-7 LSB of IEEE Company ID, bit 0-3 MSB of Vendor Specific ID */ 2527 pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF); 2528 pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8); /* Vendor Specific ID */ 2529 pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF); /* Vendor Specific ID */ 2530 pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8); /* Vendor Specific ID */ 2531 pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF); /* Vendor Specific ID */ 2532 2533 #else 2534 2535 /* For FreeBSD */ 2536 2537 /* Fill in SAT Rev8 Table85 */ 2538 /* 2539 * Logical unit name derived from the world wide name. 2540 */ 2541 pInquiry[3] = 24; /* 35-3; page length, no addition ID descriptor assumed*/ 2542 /* 2543 * Identifier descriptor 2544 */ 2545 pInquiry[4] = 0x01; /* Code set: binary codes; this is proto_codeset in FreeBSD */ 2546 pInquiry[5] = 0x03; /* Identifier type : NAA ; this is id_type in FreeBSD*/ 2547 pInquiry[6] = 0x00; /* Reserved */ 2548 pInquiry[7] = 0x08; /* Identifier length */ 2549 2550 /* Bit 4-7 NAA field, bit 0-3 MSB of IEEE Company ID */ 2551 pInquiry[8] = (bit8)((pSATAIdData->namingAuthority) >> 8); 2552 pInquiry[9] = (bit8)((pSATAIdData->namingAuthority) & 0xFF); /* IEEE Company ID */ 2553 pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8); /* IEEE Company ID */ 2554 /* Bit 4-7 LSB of IEEE Company ID, bit 0-3 MSB of Vendor Specific ID */ 2555 pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF); 2556 pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8); /* Vendor Specific ID */ 2557 pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF); /* Vendor Specific ID */ 2558 pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8); /* Vendor Specific ID */ 2559 pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF); /* Vendor Specific ID */ 2560 2561 pInquiry[16] = 0x61; /* Code set: binary codes; this is proto_codeset in FreeBSD; SCSI_PROTO_SAS and SVPD_ID_CODESET_BINARY */ 2562 pInquiry[17] = 0x93; /* Identifier type : NAA ; this is id_type in FreeBSD; PIV set, ASSOCIATION is 01b and NAA (3h) */ 2563 pInquiry[18] = 0x00; /* Reserved */ 2564 pInquiry[19] = 0x08; /* Identifier length */ 2565 2566 SM_DBG5(("smsatInquiryPage83: sasAddressHi 0x%08x\n", oneDeviceData->sasAddressHi)); 2567 SM_DBG5(("smsatInquiryPage83: sasAddressLo 0x%08x\n", oneDeviceData->sasAddressLo)); 2568 2569 /* SAS address of SATA */ 2570 pInquiry[20] = ((oneDeviceData->sasAddressHi) & 0xFF000000 ) >> 24; 2571 pInquiry[21] = ((oneDeviceData->sasAddressHi) & 0xFF0000 ) >> 16; 2572 pInquiry[22] = ((oneDeviceData->sasAddressHi) & 0xFF00 ) >> 8; 2573 pInquiry[23] = (oneDeviceData->sasAddressHi) & 0xFF; 2574 pInquiry[24] = ((oneDeviceData->sasAddressLo) & 0xFF000000 ) >> 24; 2575 pInquiry[25] = ((oneDeviceData->sasAddressLo) & 0xFF0000 ) >> 16; 2576 pInquiry[26] = ((oneDeviceData->sasAddressLo) & 0xFF00 ) >> 8; 2577 pInquiry[27] = (oneDeviceData->sasAddressLo) & 0xFF; 2578 #endif 2579 } 2580 else 2581 { 2582 #ifndef PMC_FREEBSD 2583 /* Fill in SAT Rev8 Table86 */ 2584 /* 2585 * Logical unit name derived from the model number and serial number. 2586 */ 2587 pInquiry[3] = 72; /* 75 - 3; page length */ 2588 2589 /* 2590 * Identifier descriptor 2591 */ 2592 pInquiry[4] = 0x02; /* Code set: ASCII codes */ 2593 pInquiry[5] = 0x01; /* Identifier type : T10 vendor ID based */ 2594 pInquiry[6] = 0x00; /* Reserved */ 2595 pInquiry[7] = 0x44; /* 0x44, 68 Identifier length */ 2596 2597 /* Byte 8 to 15 is the vendor id string 'ATA '. */ 2598 sm_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8); 2599 2600 2601 /* 2602 * Byte 16 to 75 is vendor specific id 2603 */ 2604 pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8); 2605 pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff); 2606 pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8); 2607 pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff); 2608 pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8); 2609 pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff); 2610 pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8); 2611 pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff); 2612 pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8); 2613 pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff); 2614 pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8); 2615 pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff); 2616 pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8); 2617 pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff); 2618 pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8); 2619 pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff); 2620 pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8); 2621 pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff); 2622 pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8); 2623 pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff); 2624 pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8); 2625 pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff); 2626 pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8); 2627 pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff); 2628 pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8); 2629 pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff); 2630 pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8); 2631 pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff); 2632 pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8); 2633 pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff); 2634 pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8); 2635 pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff); 2636 pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8); 2637 pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff); 2638 pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8); 2639 pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff); 2640 pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8); 2641 pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff); 2642 pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8); 2643 pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff); 2644 2645 pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8); 2646 pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff); 2647 pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8); 2648 pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff); 2649 pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8); 2650 pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff); 2651 pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8); 2652 pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff); 2653 pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8); 2654 pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff); 2655 pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8); 2656 pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff); 2657 pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8); 2658 pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff); 2659 pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8); 2660 pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff); 2661 pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8); 2662 pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff); 2663 pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8); 2664 pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff); 2665 #else 2666 /* for the FreeBSD */ 2667 /* Fill in SAT Rev8 Table86 */ 2668 /* 2669 * Logical unit name derived from the model number and serial number. 2670 */ 2671 pInquiry[3] = 84; /* 87 - 3; page length */ 2672 2673 /* 2674 * Identifier descriptor 2675 */ 2676 pInquiry[4] = 0x02; /* Code set: ASCII codes */ 2677 pInquiry[5] = 0x01; /* Identifier type : T10 vendor ID based */ 2678 pInquiry[6] = 0x00; /* Reserved */ 2679 pInquiry[7] = 0x44; /* 0x44, 68 Identifier length */ 2680 2681 /* Byte 8 to 15 is the vendor id string 'ATA '. */ 2682 sm_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8); 2683 2684 2685 /* 2686 * Byte 16 to 75 is vendor specific id 2687 */ 2688 pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8); 2689 pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff); 2690 pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8); 2691 pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff); 2692 pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8); 2693 pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff); 2694 pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8); 2695 pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff); 2696 pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8); 2697 pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff); 2698 pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8); 2699 pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff); 2700 pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8); 2701 pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff); 2702 pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8); 2703 pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff); 2704 pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8); 2705 pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff); 2706 pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8); 2707 pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff); 2708 pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8); 2709 pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff); 2710 pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8); 2711 pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff); 2712 pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8); 2713 pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff); 2714 pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8); 2715 pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff); 2716 pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8); 2717 pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff); 2718 pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8); 2719 pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff); 2720 pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8); 2721 pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff); 2722 pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8); 2723 pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff); 2724 pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8); 2725 pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff); 2726 pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8); 2727 pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff); 2728 2729 pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8); 2730 pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff); 2731 pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8); 2732 pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff); 2733 pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8); 2734 pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff); 2735 pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8); 2736 pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff); 2737 pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8); 2738 pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff); 2739 pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8); 2740 pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff); 2741 pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8); 2742 pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff); 2743 pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8); 2744 pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff); 2745 pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8); 2746 pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff); 2747 pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8); 2748 pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff); 2749 2750 pInquiry[76] = 0x61; /* Code set: binary codes; this is proto_codeset in FreeBSD; SCSI_PROTO_SAS and SVPD_ID_CODESET_BINARY */ 2751 pInquiry[77] = 0x93; /* Identifier type : NAA ; this is id_type in FreeBSD; PIV set, ASSOCIATION is 01b and NAA (3h) */ 2752 pInquiry[78] = 0x00; /* Reserved */ 2753 pInquiry[79] = 0x08; /* Identifier length */ 2754 2755 SM_DBG5(("smsatInquiryPage83: NO WWN sasAddressHi 0x%08x\n", oneDeviceData->sasAddressHi)); 2756 SM_DBG5(("smsatInquiryPage83: No WWN sasAddressLo 0x%08x\n", oneDeviceData->sasAddressLo)); 2757 2758 /* SAS address of SATA */ 2759 pInquiry[80] = ((oneDeviceData->sasAddressHi) & 0xFF000000 ) >> 24; 2760 pInquiry[81] = ((oneDeviceData->sasAddressHi) & 0xFF0000 ) >> 16; 2761 pInquiry[82] = ((oneDeviceData->sasAddressHi) & 0xFF00 ) >> 8; 2762 pInquiry[83] = (oneDeviceData->sasAddressHi) & 0xFF; 2763 pInquiry[84] = ((oneDeviceData->sasAddressLo) & 0xFF000000 ) >> 24; 2764 pInquiry[85] = ((oneDeviceData->sasAddressLo) & 0xFF0000 ) >> 16; 2765 pInquiry[86] = ((oneDeviceData->sasAddressLo) & 0xFF00 ) >> 8; 2766 pInquiry[87] = (oneDeviceData->sasAddressLo) & 0xFF; 2767 2768 #endif 2769 } 2770 2771 return; 2772 } 2773 2774 osGLOBAL void 2775 smsatInquiryPage89( 2776 bit8 *pInquiry, 2777 agsaSATAIdentifyData_t *pSATAIdData, 2778 smDeviceData_t *oneDeviceData, 2779 bit32 len 2780 ) 2781 { 2782 /* 2783 SAT revision 8, 10.3.5, p 83 2784 */ 2785 satSimpleSATAIdentifyData_t *pSimpleData; 2786 2787 /* 2788 * When translating the fields, in some cases using the simple form of SATA 2789 * Identify Device Data is easier. So we define it here. 2790 * Both pSimpleData and pSATAIdData points to the same data. 2791 */ 2792 pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData; 2793 2794 SM_DBG5(("smsatInquiryPage89: start\n")); 2795 2796 pInquiry[0] = 0x00; /* Peripheral Qualifier and Peripheral Device Type */ 2797 pInquiry[1] = 0x89; /* page code */ 2798 2799 /* Page length 0x238 */ 2800 pInquiry[2] = 0x02; 2801 pInquiry[3] = 0x38; 2802 2803 pInquiry[4] = 0x0; /* reserved */ 2804 pInquiry[5] = 0x0; /* reserved */ 2805 pInquiry[6] = 0x0; /* reserved */ 2806 pInquiry[7] = 0x0; /* reserved */ 2807 2808 /* SAT Vendor Identification */ 2809 sm_strncpy((char*)&pInquiry[8], "PMC-SIERRA", 8); /* 8 bytes */ 2810 2811 /* SAT Product Idetification */ 2812 sm_strncpy((char*)&pInquiry[16], "Tachyon-SPC ", 16); /* 16 bytes */ 2813 2814 /* SAT Product Revision Level */ 2815 sm_strncpy((char*)&pInquiry[32], "01", 4); /* 4 bytes */ 2816 2817 /* Signature, SAT revision8, Table88, p85 */ 2818 2819 2820 pInquiry[36] = 0x34; /* FIS type */ 2821 if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE) 2822 { 2823 /* interrupt assume to be 0 */ 2824 pInquiry[37] = (bit8)((oneDeviceData->satPMField) >> (4 * 7)); /* first four bits of PM field */ 2825 } 2826 else 2827 { 2828 /* interrupt assume to be 1 */ 2829 pInquiry[37] = (bit8)(0x40 + (bit8)(((oneDeviceData->satPMField) >> (4 * 7)))); /* first four bits of PM field */ 2830 } 2831 pInquiry[38] = 0; 2832 pInquiry[39] = 0; 2833 2834 if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE) 2835 { 2836 pInquiry[40] = 0x01; /* LBA Low */ 2837 pInquiry[41] = 0x00; /* LBA Mid */ 2838 pInquiry[42] = 0x00; /* LBA High */ 2839 pInquiry[43] = 0x00; /* Device */ 2840 pInquiry[44] = 0x00; /* LBA Low Exp */ 2841 pInquiry[45] = 0x00; /* LBA Mid Exp */ 2842 pInquiry[46] = 0x00; /* LBA High Exp */ 2843 pInquiry[47] = 0x00; /* Reserved */ 2844 pInquiry[48] = 0x01; /* Sector Count */ 2845 pInquiry[49] = 0x00; /* Sector Count Exp */ 2846 } 2847 else 2848 { 2849 pInquiry[40] = 0x01; /* LBA Low */ 2850 pInquiry[41] = 0x00; /* LBA Mid */ 2851 pInquiry[42] = 0x00; /* LBA High */ 2852 pInquiry[43] = 0x00; /* Device */ 2853 pInquiry[44] = 0x00; /* LBA Low Exp */ 2854 pInquiry[45] = 0x00; /* LBA Mid Exp */ 2855 pInquiry[46] = 0x00; /* LBA High Exp */ 2856 pInquiry[47] = 0x00; /* Reserved */ 2857 pInquiry[48] = 0x01; /* Sector Count */ 2858 pInquiry[49] = 0x00; /* Sector Count Exp */ 2859 } 2860 2861 /* Reserved */ 2862 pInquiry[50] = 0x00; 2863 pInquiry[51] = 0x00; 2864 pInquiry[52] = 0x00; 2865 pInquiry[53] = 0x00; 2866 pInquiry[54] = 0x00; 2867 pInquiry[55] = 0x00; 2868 2869 /* Command Code */ 2870 if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE) 2871 { 2872 pInquiry[56] = 0xEC; /* IDENTIFY DEVICE */ 2873 } 2874 else 2875 { 2876 pInquiry[56] = 0xA1; /* IDENTIFY PACKET DEVICE */ 2877 } 2878 /* Reserved */ 2879 pInquiry[57] = 0x0; 2880 pInquiry[58] = 0x0; 2881 pInquiry[59] = 0x0; 2882 2883 /* check the length; len is assumed to be at least 60 */ 2884 if (len < SATA_PAGE89_INQUIRY_SIZE) 2885 { 2886 /* Identify Device */ 2887 sm_memcpy(&pInquiry[60], pSimpleData, MIN((len - 60), sizeof(satSimpleSATAIdentifyData_t))); 2888 } 2889 else 2890 { 2891 /* Identify Device */ 2892 sm_memcpy(&pInquiry[60], pSimpleData, sizeof(satSimpleSATAIdentifyData_t)); 2893 } 2894 2895 return; 2896 } 2897 2898 osGLOBAL void 2899 smsatInquiryPage80( 2900 bit8 *pInquiry, 2901 agsaSATAIdentifyData_t *pSATAIdData 2902 ) 2903 { 2904 SM_DBG5(("smsatInquiryPage89: start\n")); 2905 /* 2906 See SPC-4, 7.6.9, p 345 2907 and SAT revision 8, 10.3.3, p 77 2908 */ 2909 pInquiry[0] = 0x00; 2910 pInquiry[1] = 0x80; /* page code */ 2911 pInquiry[2] = 0x00; /* reserved */ 2912 pInquiry[3] = 0x14; /* page length */ 2913 2914 /* product serial number */ 2915 pInquiry[4] = pSATAIdData->serialNumber[1]; 2916 pInquiry[5] = pSATAIdData->serialNumber[0]; 2917 pInquiry[6] = pSATAIdData->serialNumber[3]; 2918 pInquiry[7] = pSATAIdData->serialNumber[2]; 2919 pInquiry[8] = pSATAIdData->serialNumber[5]; 2920 pInquiry[9] = pSATAIdData->serialNumber[4]; 2921 pInquiry[10] = pSATAIdData->serialNumber[7]; 2922 pInquiry[11] = pSATAIdData->serialNumber[6]; 2923 pInquiry[12] = pSATAIdData->serialNumber[9]; 2924 pInquiry[13] = pSATAIdData->serialNumber[8]; 2925 pInquiry[14] = pSATAIdData->serialNumber[11]; 2926 pInquiry[15] = pSATAIdData->serialNumber[10]; 2927 pInquiry[16] = pSATAIdData->serialNumber[13]; 2928 pInquiry[17] = pSATAIdData->serialNumber[12]; 2929 pInquiry[18] = pSATAIdData->serialNumber[15]; 2930 pInquiry[19] = pSATAIdData->serialNumber[14]; 2931 pInquiry[20] = pSATAIdData->serialNumber[17]; 2932 pInquiry[21] = pSATAIdData->serialNumber[16]; 2933 pInquiry[22] = pSATAIdData->serialNumber[19]; 2934 pInquiry[23] = pSATAIdData->serialNumber[18]; 2935 2936 return; 2937 } 2938 2939 osGLOBAL void 2940 smsatInquiryPageB1( 2941 bit8 *pInquiry, 2942 agsaSATAIdentifyData_t *pSATAIdData 2943 ) 2944 { 2945 bit32 i; 2946 satSimpleSATAIdentifyData_t *pSimpleData; 2947 2948 SM_DBG5(("smsatInquiryPageB1: start\n")); 2949 2950 pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData; 2951 /* 2952 See SBC-3, revision31, Table193, p273 2953 and SAT-3 revision 3, 10.3.6, p141 2954 */ 2955 pInquiry[0] = 0x00; /* Peripheral Qualifier and Peripheral Device Type */ 2956 pInquiry[1] = 0xB1; /* page code */ 2957 2958 /* page length */ 2959 pInquiry[2] = 0x0; 2960 pInquiry[3] = 0x3C; 2961 2962 /* medium rotation rate */ 2963 pInquiry[4] = (bit8) ((pSimpleData->word[217]) >> 8); 2964 pInquiry[5] = (bit8) ((pSimpleData->word[217]) & 0xFF); 2965 2966 /* reserved */ 2967 pInquiry[6] = 0x0; 2968 2969 /* nominal form factor bits 3:0 */ 2970 pInquiry[7] = (bit8) ((pSimpleData->word[168]) & 0xF); 2971 2972 2973 /* reserved */ 2974 for (i=8;i<64;i++) 2975 { 2976 pInquiry[i] = 0x0; 2977 } 2978 return; 2979 } 2980 2981 osGLOBAL void 2982 smsatDefaultTranslation( 2983 smRoot_t *smRoot, 2984 smIORequest_t *smIORequest, 2985 smSatIOContext_t *satIOContext, 2986 smScsiRspSense_t *pSense, 2987 bit8 ataStatus, 2988 bit8 ataError, 2989 bit32 interruptContext 2990 ) 2991 { 2992 SM_DBG5(("smsatDefaultTranslation: start\n")); 2993 /* 2994 * Check for device fault case 2995 */ 2996 if ( ataStatus & DF_ATA_STATUS_MASK ) 2997 { 2998 smsatSetSensePayload( pSense, 2999 SCSI_SNSKEY_HARDWARE_ERROR, 3000 0, 3001 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE, 3002 satIOContext); 3003 3004 tdsmIOCompletedCB( smRoot, 3005 smIORequest, 3006 smIOSuccess, 3007 SCSI_STAT_CHECK_CONDITION, 3008 satIOContext->pSmSenseData, 3009 interruptContext ); 3010 return; 3011 } 3012 3013 /* 3014 * If status error bit it set, need to check the error register 3015 */ 3016 if ( ataStatus & ERR_ATA_STATUS_MASK ) 3017 { 3018 if ( ataError & NM_ATA_ERROR_MASK ) 3019 { 3020 SM_DBG1(("smsatDefaultTranslation: NM_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n", 3021 ataError, smIORequest)); 3022 smsatSetSensePayload( pSense, 3023 SCSI_SNSKEY_NOT_READY, 3024 0, 3025 SCSI_SNSCODE_MEDIUM_NOT_PRESENT, 3026 satIOContext); 3027 } 3028 3029 else if (ataError & UNC_ATA_ERROR_MASK) 3030 { 3031 SM_DBG1(("smsatDefaultTranslation: UNC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n", 3032 ataError, smIORequest)); 3033 smsatSetSensePayload( pSense, 3034 SCSI_SNSKEY_MEDIUM_ERROR, 3035 0, 3036 SCSI_SNSCODE_UNRECOVERED_READ_ERROR, 3037 satIOContext); 3038 } 3039 3040 else if (ataError & IDNF_ATA_ERROR_MASK) 3041 { 3042 SM_DBG1(("smsatDefaultTranslation: IDNF_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n", 3043 ataError, smIORequest)); 3044 smsatSetSensePayload( pSense, 3045 SCSI_SNSKEY_MEDIUM_ERROR, 3046 0, 3047 SCSI_SNSCODE_RECORD_NOT_FOUND, 3048 satIOContext); 3049 } 3050 3051 else if (ataError & MC_ATA_ERROR_MASK) 3052 { 3053 SM_DBG1(("smsatDefaultTranslation: MC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n", 3054 ataError, smIORequest)); 3055 smsatSetSensePayload( pSense, 3056 SCSI_SNSKEY_UNIT_ATTENTION, 3057 0, 3058 SCSI_SNSCODE_NOT_READY_TO_READY_CHANGE, 3059 satIOContext); 3060 } 3061 3062 else if (ataError & MCR_ATA_ERROR_MASK) 3063 { 3064 SM_DBG1(("smsatDefaultTranslation: MCR_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n", 3065 ataError, smIORequest)); 3066 smsatSetSensePayload( pSense, 3067 SCSI_SNSKEY_UNIT_ATTENTION, 3068 0, 3069 SCSI_SNSCODE_OPERATOR_MEDIUM_REMOVAL_REQUEST, 3070 satIOContext); 3071 } 3072 3073 else if (ataError & ICRC_ATA_ERROR_MASK) 3074 { 3075 SM_DBG1(("smsatDefaultTranslation: ICRC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n", 3076 ataError, smIORequest)); 3077 smsatSetSensePayload( pSense, 3078 SCSI_SNSKEY_ABORTED_COMMAND, 3079 0, 3080 SCSI_SNSCODE_INFORMATION_UNIT_CRC_ERROR, 3081 satIOContext); 3082 } 3083 3084 else if (ataError & ABRT_ATA_ERROR_MASK) 3085 { 3086 SM_DBG1(("smsatDefaultTranslation: ABRT_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n", 3087 ataError, smIORequest)); 3088 smsatSetSensePayload( pSense, 3089 SCSI_SNSKEY_ABORTED_COMMAND, 3090 0, 3091 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 3092 satIOContext); 3093 } 3094 3095 else 3096 { 3097 SM_DBG1(("smsatDefaultTranslation: **** UNEXPECTED ATA_ERROR **** ataError= 0x%x, smIORequest=%p!!!\n", 3098 ataError, smIORequest)); 3099 smsatSetSensePayload( pSense, 3100 SCSI_SNSKEY_HARDWARE_ERROR, 3101 0, 3102 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE, 3103 satIOContext); 3104 } 3105 3106 /* Send the completion response now */ 3107 tdsmIOCompletedCB( smRoot, 3108 smIORequest, 3109 smIOSuccess, 3110 SCSI_STAT_CHECK_CONDITION, 3111 satIOContext->pSmSenseData, 3112 interruptContext ); 3113 return; 3114 3115 3116 } 3117 3118 else /* (ataStatus & ERR_ATA_STATUS_MASK ) is false */ 3119 { 3120 /* This case should never happen */ 3121 SM_DBG1(("smsatDefaultTranslation: *** UNEXPECTED ATA status 0x%x *** smIORequest=%p!!!\n", 3122 ataStatus, smIORequest)); 3123 smsatSetSensePayload( pSense, 3124 SCSI_SNSKEY_HARDWARE_ERROR, 3125 0, 3126 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE, 3127 satIOContext); 3128 3129 tdsmIOCompletedCB( smRoot, 3130 smIORequest, 3131 smIOSuccess, 3132 SCSI_STAT_CHECK_CONDITION, 3133 satIOContext->pSmSenseData, 3134 interruptContext ); 3135 return; 3136 3137 } 3138 3139 return; 3140 } 3141 3142 osGLOBAL bit32 3143 smIDStart( 3144 smRoot_t *smRoot, 3145 smIORequest_t *smIORequest, 3146 smDeviceHandle_t *smDeviceHandle 3147 ) 3148 { 3149 smDeviceData_t *oneDeviceData = agNULL; 3150 smIORequestBody_t *smIORequestBody = agNULL; 3151 smSatIOContext_t *satIOContext = agNULL; 3152 bit32 status = SM_RC_FAILURE; 3153 3154 SM_DBG2(("smIDStart: start, smIORequest %p\n", smIORequest)); 3155 3156 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData; 3157 if (oneDeviceData == agNULL) 3158 { 3159 SM_DBG1(("smIDStart: oneDeviceData is NULL!!!\n")); 3160 return SM_RC_FAILURE; 3161 } 3162 if (oneDeviceData->valid == agFALSE) 3163 { 3164 SM_DBG1(("smIDStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id)); 3165 return SM_RC_FAILURE; 3166 } 3167 3168 smIORequestBody = (smIORequestBody_t*)smIORequest->smData;//smDequeueIO(smRoot); 3169 3170 if (smIORequestBody == agNULL) 3171 { 3172 SM_DBG1(("smIDStart: smIORequestBody is NULL!!!\n")); 3173 return SM_RC_FAILURE; 3174 } 3175 3176 smIOReInit(smRoot, smIORequestBody); 3177 3178 SM_DBG3(("smIDStart: io ID %d!!!\n", smIORequestBody->id )); 3179 3180 smIORequestBody->smIORequest = smIORequest; 3181 smIORequestBody->smDevHandle = smDeviceHandle; 3182 satIOContext = &(smIORequestBody->transport.SATA.satIOContext); 3183 3184 /* setting up satIOContext */ 3185 satIOContext->pSatDevData = oneDeviceData; 3186 satIOContext->pFis = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 3187 satIOContext->smRequestBody = smIORequestBody; 3188 satIOContext->psmDeviceHandle = smDeviceHandle; 3189 satIOContext->smScsiXchg = agNULL; 3190 3191 /*smIORequest->smData = smIORequestBody;*/ 3192 SM_DBG3(("smIDStart: smIORequestBody %p smIORequestBody->smIORequest %p!!!\n", smIORequestBody, smIORequestBody->smIORequest)); 3193 SM_DBG1(("smIDStart: did %d\n", oneDeviceData->id)); 3194 3195 status = smsatIDSubStart( smRoot, 3196 smIORequest, 3197 smDeviceHandle, 3198 agNULL, 3199 satIOContext); 3200 3201 if (status != SM_RC_SUCCESS) 3202 { 3203 SM_DBG1(("smIDStart: smsatIDSubStart failure %d!!!\n", status)); 3204 /*smEnqueueIO(smRoot, satIOContext);*/ 3205 } 3206 SM_DBG2(("smIDStart: exit\n")); 3207 3208 return status; 3209 } 3210 3211 /* 3212 SM generated IO, needs to call smsatAllocIntIoResource() 3213 allocating using smsatAllocIntIoResource 3214 */ 3215 osGLOBAL bit32 3216 smsatIDSubStart( 3217 smRoot_t *smRoot, 3218 smIORequest_t *smIORequest, 3219 smDeviceHandle_t *smDeviceHandle, 3220 smScsiInitiatorRequest_t *smSCSIRequest, /* agNULL */ 3221 smSatIOContext_t *satIOContext 3222 ) 3223 { 3224 smSatInternalIo_t *satIntIo = agNULL; 3225 smDeviceData_t *satDevData = agNULL; 3226 smIORequestBody_t *smIORequestBody; 3227 smSatIOContext_t *satNewIOContext; 3228 bit32 status; 3229 SM_DBG2(("smsatIDSubStart: start\n")); 3230 3231 satDevData = satIOContext->pSatDevData; 3232 3233 /* allocate identify device command */ 3234 satIntIo = smsatAllocIntIoResource( smRoot, 3235 smIORequest, 3236 satDevData, 3237 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */ 3238 satIntIo); 3239 3240 if (satIntIo == agNULL) 3241 { 3242 SM_DBG1(("smsatIDSubStart: can't alloacate!!!\n")); 3243 return SM_RC_FAILURE; 3244 } 3245 3246 satIOContext->satIntIoContext = satIntIo; 3247 3248 /* fill in fields */ 3249 /* real ttttttthe one worked and the same; 5/21/07/ */ 3250 satIntIo->satOrgSmIORequest = smIORequest; /* changed */ 3251 smIORequestBody = satIntIo->satIntRequestBody; 3252 satNewIOContext = &(smIORequestBody->transport.SATA.satIOContext); 3253 3254 satNewIOContext->pSatDevData = satDevData; 3255 satNewIOContext->pFis = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 3256 satNewIOContext->pScsiCmnd = &(satIntIo->satIntSmScsiXchg.scsiCmnd); 3257 satNewIOContext->pSense = &(smIORequestBody->transport.SATA.sensePayload); 3258 satNewIOContext->pSmSenseData = &(smIORequestBody->transport.SATA.smSenseData); 3259 satNewIOContext->smRequestBody = satIntIo->satIntRequestBody; /* key fix */ 3260 // satNewIOContext->interruptContext = tiInterruptContext; 3261 satNewIOContext->satIntIoContext = satIntIo; 3262 3263 satNewIOContext->psmDeviceHandle = smDeviceHandle; 3264 satNewIOContext->satOrgIOContext = satIOContext; /* changed */ 3265 3266 /* this is valid only for TD layer generated (not triggered by OS at all) IO */ 3267 satNewIOContext->smScsiXchg = &(satIntIo->satIntSmScsiXchg); 3268 3269 3270 SM_DBG6(("smsatIDSubStart: SM satIOContext %p \n", satIOContext)); 3271 SM_DBG6(("smsatIDSubStart: SM satNewIOContext %p \n", satNewIOContext)); 3272 SM_DBG6(("smsatIDSubStart: SM tiScsiXchg %p \n", satIOContext->smScsiXchg)); 3273 SM_DBG6(("smsatIDSubStart: SM tiScsiXchg %p \n", satNewIOContext->smScsiXchg)); 3274 3275 3276 3277 SM_DBG3(("smsatIDSubStart: satNewIOContext %p smIORequestBody %p\n", satNewIOContext, smIORequestBody)); 3278 3279 status = smsatIDStart(smRoot, 3280 &satIntIo->satIntSmIORequest, /* New smIORequest */ 3281 smDeviceHandle, 3282 satNewIOContext->smScsiXchg, /* New smScsiInitiatorRequest_t *smScsiRequest, */ 3283 satNewIOContext); 3284 3285 if (status != SM_RC_SUCCESS) 3286 { 3287 SM_DBG1(("smsatIDSubStart: failed in sending %d!!!\n", status)); 3288 3289 smsatFreeIntIoResource( smRoot, 3290 satDevData, 3291 satIntIo); 3292 3293 return SM_RC_FAILURE; 3294 } 3295 3296 3297 SM_DBG2(("smsatIDSubStart: end\n")); 3298 3299 return status; 3300 3301 } 3302 3303 3304 osGLOBAL bit32 3305 smsatIDStart( 3306 smRoot_t *smRoot, 3307 smIORequest_t *smIORequest, 3308 smDeviceHandle_t *smDeviceHandle, 3309 smScsiInitiatorRequest_t *smSCSIRequest, 3310 smSatIOContext_t *satIOContext 3311 ) 3312 { 3313 bit32 status; 3314 bit32 agRequestType; 3315 smDeviceData_t *pSatDevData; 3316 agsaFisRegHostToDevice_t *fis; 3317 #ifdef SM_INTERNAL_DEBUG 3318 smIORequestBody_t *smIORequestBody; 3319 smSatInternalIo_t *satIntIoContext; 3320 #endif 3321 3322 pSatDevData = satIOContext->pSatDevData; 3323 fis = satIOContext->pFis; 3324 SM_DBG2(("smsatIDStart: start\n")); 3325 #ifdef SM_INTERNAL_DEBUG 3326 satIntIoContext = satIOContext->satIntIoContext; 3327 smIORequestBody = satIntIoContext->satIntRequestBody; 3328 #endif 3329 fis->h.fisType = 0x27; /* Reg host to device */ 3330 fis->h.c_pmPort = 0x80; /* C Bit is set */ 3331 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE) 3332 { 3333 SM_DBG2(("smsatIDStart: IDENTIFY_PACKET_DEVICE\n")); 3334 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0x40 */ 3335 } 3336 else 3337 { 3338 SM_DBG2(("smsatIDStart: IDENTIFY_DEVICE\n")); 3339 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */ 3340 } 3341 fis->h.features = 0; /* FIS reserve */ 3342 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 3343 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 3344 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 3345 fis->d.device = 0; /* FIS LBA mode */ 3346 fis->d.lbaLowExp = 0; 3347 fis->d.lbaMidExp = 0; 3348 fis->d.lbaHighExp = 0; 3349 fis->d.featuresExp = 0; 3350 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 3351 fis->d.sectorCountExp = 0; 3352 fis->d.reserved4 = 0; 3353 fis->d.control = 0; /* FIS HOB bit clear */ 3354 fis->d.reserved5 = 0; 3355 3356 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 3357 3358 /* Initialize CB for SATA completion. 3359 */ 3360 satIOContext->satCompleteCB = &smsatIDStartCB; 3361 3362 /* 3363 * Prepare SGL and send FIS to LL layer. 3364 */ 3365 satIOContext->reqType = agRequestType; /* Save it */ 3366 3367 #ifdef SM_INTERNAL_DEBUG 3368 smhexdump("smsatIDStart", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 3369 smhexdump("smsatIDStart LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t)); 3370 #endif 3371 status = smsataLLIOStart( smRoot, 3372 smIORequest, 3373 smDeviceHandle, 3374 smSCSIRequest, 3375 satIOContext); 3376 3377 SM_DBG2(("smsatIDStart: end status %d\n", status)); 3378 3379 return status; 3380 } 3381 3382 3383 osGLOBAL FORCEINLINE bit32 3384 smsatIOStart( 3385 smRoot_t *smRoot, 3386 smIORequest_t *smIORequest, 3387 smDeviceHandle_t *smDeviceHandle, 3388 smScsiInitiatorRequest_t *smSCSIRequest, 3389 smSatIOContext_t *satIOContext 3390 ) 3391 { 3392 smDeviceData_t *pSatDevData = satIOContext->pSatDevData; 3393 smScsiRspSense_t *pSense = satIOContext->pSense; 3394 smIniScsiCmnd_t *scsiCmnd = &smSCSIRequest->scsiCmnd; 3395 smLUN_t *pLun = &scsiCmnd->lun; 3396 smSatInternalIo_t *pSatIntIo = agNULL; 3397 bit32 status = SM_RC_FAILURE; 3398 3399 SM_DBG2(("smsatIOStart: start\n")); 3400 3401 /* 3402 * Reject all other LUN other than LUN 0. 3403 */ 3404 if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] | 3405 pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) && 3406 (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY) 3407 ) 3408 { 3409 SM_DBG1(("smsatIOStart: *** REJECT *** LUN not zero, cdb[0]=0x%x did %d !!!\n", 3410 scsiCmnd->cdb[0], pSatDevData->id)); 3411 smsatSetSensePayload( pSense, 3412 SCSI_SNSKEY_ILLEGAL_REQUEST, 3413 0, 3414 SCSI_SNSCODE_LOGICAL_NOT_SUPPORTED, 3415 satIOContext); 3416 3417 /*smEnqueueIO(smRoot, satIOContext);*/ 3418 3419 tdsmIOCompletedCB( smRoot, 3420 smIORequest, 3421 smIOSuccess, 3422 SCSI_STAT_CHECK_CONDITION, 3423 satIOContext->pSmSenseData, 3424 satIOContext->interruptContext ); 3425 3426 return SM_RC_SUCCESS; 3427 } 3428 3429 SM_DBG2(("smsatIOStart: satPendingIO %d satNCQMaxIO %d\n",pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO )); 3430 3431 /* this may happen after tiCOMReset until OS sends inquiry */ 3432 if (pSatDevData->IDDeviceValid == agFALSE && (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY)) 3433 { 3434 SM_DBG1(("smsatIOStart: invalid identify device data did %d !!!\n", pSatDevData->id)); 3435 SM_DBG1(("smsatIOStart: satPendingIO %d satNCQMaxIO %d\n", pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO )); 3436 SM_DBG1(("smsatIOStart: satPendingNCQIO %d satPendingNONNCQIO %d\n", pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO)); 3437 3438 /*smEnqueueIO(smRoot, satIOContext);*/ 3439 3440 return SM_RC_NODEVICE; 3441 } 3442 3443 /* 3444 * Check if we need to return BUSY, i.e. recovery in progress 3445 */ 3446 if (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY) 3447 { 3448 SM_DBG1(("smsatIOStart: IN RECOVERY STATE cdb[0]=0x%x did=%d !!!\n", 3449 scsiCmnd->cdb[0], pSatDevData->id)); 3450 SM_DBG2(("smsatIOStart: device %p satPendingIO %d satNCQMaxIO %d\n", pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO )); 3451 SM_DBG2(("smsatIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO)); 3452 3453 /*smEnqueueIO(smRoot, satIOContext);*/ 3454 3455 // return SM_RC_FAILURE; 3456 return SM_RC_DEVICE_BUSY; 3457 } 3458 3459 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE) 3460 { 3461 if (scsiCmnd->cdb[0] == SCSIOPC_REPORT_LUN) 3462 { 3463 return smsatReportLun(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext); 3464 } 3465 else 3466 { 3467 return smsatPacket(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext); 3468 } 3469 } 3470 else 3471 { 3472 /* Parse CDB */ 3473 switch(scsiCmnd->cdb[0]) 3474 { 3475 case SCSIOPC_READ_10: 3476 status = smsatRead10( smRoot, 3477 smIORequest, 3478 smDeviceHandle, 3479 smSCSIRequest, 3480 satIOContext); 3481 break; 3482 3483 case SCSIOPC_WRITE_10: 3484 status = smsatWrite10( smRoot, 3485 smIORequest, 3486 smDeviceHandle, 3487 smSCSIRequest, 3488 satIOContext); 3489 break; 3490 3491 case SCSIOPC_READ_6: 3492 status = smsatRead6( smRoot, 3493 smIORequest, 3494 smDeviceHandle, 3495 smSCSIRequest, 3496 satIOContext); 3497 break; 3498 3499 case SCSIOPC_READ_12: 3500 SM_DBG5(("smsatIOStart: SCSIOPC_READ_12\n")); 3501 status = smsatRead12( smRoot, 3502 smIORequest, 3503 smDeviceHandle, 3504 smSCSIRequest, 3505 satIOContext); 3506 break; 3507 3508 case SCSIOPC_READ_16: 3509 status = smsatRead16( smRoot, 3510 smIORequest, 3511 smDeviceHandle, 3512 smSCSIRequest, 3513 satIOContext); 3514 break; 3515 3516 case SCSIOPC_WRITE_6: 3517 status = smsatWrite6( smRoot, 3518 smIORequest, 3519 smDeviceHandle, 3520 smSCSIRequest, 3521 satIOContext); 3522 break; 3523 3524 case SCSIOPC_WRITE_12: 3525 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_12 \n")); 3526 status = smsatWrite12( smRoot, 3527 smIORequest, 3528 smDeviceHandle, 3529 smSCSIRequest, 3530 satIOContext); 3531 break; 3532 3533 case SCSIOPC_WRITE_16: 3534 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_16 \n")); 3535 status = smsatWrite16( smRoot, 3536 smIORequest, 3537 smDeviceHandle, 3538 smSCSIRequest, 3539 satIOContext); 3540 break; 3541 3542 case SCSIOPC_VERIFY_10: 3543 status = smsatVerify10( smRoot, 3544 smIORequest, 3545 smDeviceHandle, 3546 smSCSIRequest, 3547 satIOContext); 3548 break; 3549 3550 case SCSIOPC_VERIFY_12: 3551 SM_DBG5(("smsatIOStart: SCSIOPC_VERIFY_12\n")); 3552 status = smsatVerify12( smRoot, 3553 smIORequest, 3554 smDeviceHandle, 3555 smSCSIRequest, 3556 satIOContext); 3557 break; 3558 3559 case SCSIOPC_VERIFY_16: 3560 SM_DBG5(("smsatIOStart: SCSIOPC_VERIFY_16\n")); 3561 status = smsatVerify16( smRoot, 3562 smIORequest, 3563 smDeviceHandle, 3564 smSCSIRequest, 3565 satIOContext); 3566 break; 3567 3568 case SCSIOPC_TEST_UNIT_READY: 3569 status = smsatTestUnitReady( smRoot, 3570 smIORequest, 3571 smDeviceHandle, 3572 smSCSIRequest, 3573 satIOContext); 3574 break; 3575 3576 case SCSIOPC_INQUIRY: 3577 status = smsatInquiry( smRoot, 3578 smIORequest, 3579 smDeviceHandle, 3580 smSCSIRequest, 3581 satIOContext); 3582 break; 3583 3584 case SCSIOPC_REQUEST_SENSE: 3585 status = smsatRequestSense( smRoot, 3586 smIORequest, 3587 smDeviceHandle, 3588 smSCSIRequest, 3589 satIOContext); 3590 break; 3591 3592 case SCSIOPC_MODE_SENSE_6: 3593 status = smsatModeSense6( smRoot, 3594 smIORequest, 3595 smDeviceHandle, 3596 smSCSIRequest, 3597 satIOContext); 3598 break; 3599 3600 case SCSIOPC_MODE_SENSE_10: 3601 status = smsatModeSense10( smRoot, 3602 smIORequest, 3603 smDeviceHandle, 3604 smSCSIRequest, 3605 satIOContext); 3606 break; 3607 3608 case SCSIOPC_READ_CAPACITY_10: 3609 status = smsatReadCapacity10( smRoot, 3610 smIORequest, 3611 smDeviceHandle, 3612 smSCSIRequest, 3613 satIOContext); 3614 break; 3615 3616 case SCSIOPC_READ_CAPACITY_16: 3617 status = smsatReadCapacity16( smRoot, 3618 smIORequest, 3619 smDeviceHandle, 3620 smSCSIRequest, 3621 satIOContext); 3622 break; 3623 3624 3625 case SCSIOPC_REPORT_LUN: 3626 status = smsatReportLun( smRoot, 3627 smIORequest, 3628 smDeviceHandle, 3629 smSCSIRequest, 3630 satIOContext); 3631 break; 3632 3633 case SCSIOPC_FORMAT_UNIT: 3634 SM_DBG5(("smsatIOStart: SCSIOPC_FORMAT_UNIT\n")); 3635 status = smsatFormatUnit( smRoot, 3636 smIORequest, 3637 smDeviceHandle, 3638 smSCSIRequest, 3639 satIOContext); 3640 break; 3641 3642 case SCSIOPC_SEND_DIAGNOSTIC: 3643 SM_DBG5(("smsatIOStart: SCSIOPC_SEND_DIAGNOSTIC\n")); 3644 status = smsatSendDiagnostic( smRoot, 3645 smIORequest, 3646 smDeviceHandle, 3647 smSCSIRequest, 3648 satIOContext); 3649 break; 3650 3651 case SCSIOPC_START_STOP_UNIT: 3652 SM_DBG5(("smsatIOStart: SCSIOPC_START_STOP_UNIT\n")); 3653 status = smsatStartStopUnit( smRoot, 3654 smIORequest, 3655 smDeviceHandle, 3656 smSCSIRequest, 3657 satIOContext); 3658 break; 3659 3660 case SCSIOPC_WRITE_SAME_10: 3661 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_SAME_10\n")); 3662 status = smsatWriteSame10( smRoot, 3663 smIORequest, 3664 smDeviceHandle, 3665 smSCSIRequest, 3666 satIOContext); 3667 break; 3668 3669 case SCSIOPC_WRITE_SAME_16: /* no support due to transfer length(sector count) */ 3670 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_SAME_16\n")); 3671 status = smsatWriteSame16( smRoot, 3672 smIORequest, 3673 smDeviceHandle, 3674 smSCSIRequest, 3675 satIOContext); 3676 break; 3677 3678 case SCSIOPC_LOG_SENSE: 3679 SM_DBG5(("smsatIOStart: SCSIOPC_LOG_SENSE\n")); 3680 status = smsatLogSense( smRoot, 3681 smIORequest, 3682 smDeviceHandle, 3683 smSCSIRequest, 3684 satIOContext); 3685 break; 3686 3687 case SCSIOPC_MODE_SELECT_6: 3688 SM_DBG5(("smsatIOStart: SCSIOPC_MODE_SELECT_6\n")); 3689 status = smsatModeSelect6( smRoot, 3690 smIORequest, 3691 smDeviceHandle, 3692 smSCSIRequest, 3693 satIOContext); 3694 break; 3695 3696 case SCSIOPC_MODE_SELECT_10: 3697 SM_DBG5(("smsatIOStart: SCSIOPC_MODE_SELECT_10\n")); 3698 status = smsatModeSelect10( smRoot, 3699 smIORequest, 3700 smDeviceHandle, 3701 smSCSIRequest, 3702 satIOContext); 3703 break; 3704 3705 case SCSIOPC_SYNCHRONIZE_CACHE_10: /* on error what to return, sharing CB with 3706 satSynchronizeCache16 */ 3707 SM_DBG5(("smsatIOStart: SCSIOPC_SYNCHRONIZE_CACHE_10\n")); 3708 status = smsatSynchronizeCache10( smRoot, 3709 smIORequest, 3710 smDeviceHandle, 3711 smSCSIRequest, 3712 satIOContext); 3713 break; 3714 3715 case SCSIOPC_SYNCHRONIZE_CACHE_16:/* on error what to return, sharing CB with 3716 satSynchronizeCache16 */ 3717 3718 SM_DBG5(("smsatIOStart: SCSIOPC_SYNCHRONIZE_CACHE_16\n")); 3719 status = smsatSynchronizeCache16( smRoot, 3720 smIORequest, 3721 smDeviceHandle, 3722 smSCSIRequest, 3723 satIOContext); 3724 break; 3725 3726 case SCSIOPC_WRITE_AND_VERIFY_10: /* single write and multiple writes */ 3727 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_10\n")); 3728 status = smsatWriteAndVerify10( smRoot, 3729 smIORequest, 3730 smDeviceHandle, 3731 smSCSIRequest, 3732 satIOContext); 3733 break; 3734 3735 case SCSIOPC_WRITE_AND_VERIFY_12: 3736 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_12\n")); 3737 status = smsatWriteAndVerify12( smRoot, 3738 smIORequest, 3739 smDeviceHandle, 3740 smSCSIRequest, 3741 satIOContext); 3742 break; 3743 3744 case SCSIOPC_WRITE_AND_VERIFY_16: 3745 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_16\n")); 3746 status = smsatWriteAndVerify16( smRoot, 3747 smIORequest, 3748 smDeviceHandle, 3749 smSCSIRequest, 3750 satIOContext); 3751 3752 break; 3753 3754 case SCSIOPC_READ_MEDIA_SERIAL_NUMBER: 3755 SM_DBG5(("smsatIOStart: SCSIOPC_READ_MEDIA_SERIAL_NUMBER\n")); 3756 status = smsatReadMediaSerialNumber( smRoot, 3757 smIORequest, 3758 smDeviceHandle, 3759 smSCSIRequest, 3760 satIOContext); 3761 3762 break; 3763 3764 case SCSIOPC_READ_BUFFER: 3765 SM_DBG5(("smsatIOStart: SCSIOPC_READ_BUFFER\n")); 3766 status = smsatReadBuffer( smRoot, 3767 smIORequest, 3768 smDeviceHandle, 3769 smSCSIRequest, 3770 satIOContext); 3771 3772 break; 3773 3774 case SCSIOPC_WRITE_BUFFER: 3775 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_BUFFER\n")); 3776 status = smsatWriteBuffer( smRoot, 3777 smIORequest, 3778 smDeviceHandle, 3779 smSCSIRequest, 3780 satIOContext); 3781 3782 break; 3783 3784 case SCSIOPC_REASSIGN_BLOCKS: 3785 SM_DBG5(("smsatIOStart: SCSIOPC_REASSIGN_BLOCKS\n")); 3786 status = smsatReassignBlocks( smRoot, 3787 smIORequest, 3788 smDeviceHandle, 3789 smSCSIRequest, 3790 satIOContext); 3791 3792 break; 3793 3794 case SCSIOPC_ATA_PASS_THROUGH12: /* fall through */ 3795 case SCSIOPC_ATA_PASS_THROUGH16: 3796 SM_DBG5(("smsatIOStart: SCSIOPC_ATA_PASS_THROUGH\n")); 3797 status = smsatPassthrough( smRoot, 3798 smIORequest, 3799 smDeviceHandle, 3800 smSCSIRequest, 3801 satIOContext); 3802 break; 3803 3804 default: 3805 /* Not implemented SCSI cmd, set up error response */ 3806 SM_DBG1(("smsatIOStart: unsupported SCSI cdb[0]=0x%x did=%d !!!\n", 3807 scsiCmnd->cdb[0], pSatDevData->id)); 3808 3809 smsatSetSensePayload( pSense, 3810 SCSI_SNSKEY_ILLEGAL_REQUEST, 3811 0, 3812 SCSI_SNSCODE_INVALID_COMMAND, 3813 satIOContext); 3814 3815 /*smEnqueueIO(smRoot, satIOContext);*/ 3816 3817 tdsmIOCompletedCB( smRoot, 3818 smIORequest, 3819 smIOSuccess, 3820 SCSI_STAT_CHECK_CONDITION, 3821 satIOContext->pSmSenseData, 3822 satIOContext->interruptContext ); 3823 status = SM_RC_SUCCESS; 3824 3825 break; 3826 3827 } /* end switch */ 3828 } 3829 3830 if (status == SM_RC_BUSY || status == SM_RC_DEVICE_BUSY) 3831 { 3832 SM_DBG1(("smsatIOStart: BUSY did %d!!!\n", pSatDevData->id)); 3833 SM_DBG2(("smsatIOStart: LL is busy or target queue is full\n")); 3834 SM_DBG2(("smsatIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO )); 3835 SM_DBG2(("smsatIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO)); 3836 pSatIntIo = satIOContext->satIntIoContext; 3837 3838 /*smEnqueueIO(smRoot, satIOContext);*/ 3839 3840 /* interal structure free */ 3841 smsatFreeIntIoResource( smRoot, 3842 pSatDevData, 3843 pSatIntIo); 3844 } 3845 3846 return status; 3847 } 3848 3849 osGLOBAL void 3850 smsatSetSensePayload( 3851 smScsiRspSense_t *pSense, 3852 bit8 SnsKey, 3853 bit32 SnsInfo, 3854 bit16 SnsCode, 3855 smSatIOContext_t *satIOContext) 3856 { 3857 /* for fixed format sense data, SPC-4, p37 */ 3858 bit32 i; 3859 bit32 senseLength; 3860 bit8 tmp = 0; 3861 3862 SM_DBG2(("smsatSetSensePayload: start\n")); 3863 3864 senseLength = sizeof(smScsiRspSense_t); 3865 3866 /* zero out the data area */ 3867 for (i=0;i< senseLength;i++) 3868 { 3869 ((bit8*)pSense)[i] = 0; 3870 } 3871 3872 /* 3873 * SCSI Sense Data part of response data 3874 */ 3875 pSense->snsRespCode = 0x70; /* 0xC0 == vendor specific */ 3876 /* 0x70 == standard current error */ 3877 pSense->senseKey = SnsKey; 3878 /* 3879 * Put sense info in scsi order format 3880 */ 3881 pSense->info[0] = (bit8)((SnsInfo >> 24) & 0xff); 3882 pSense->info[1] = (bit8)((SnsInfo >> 16) & 0xff); 3883 pSense->info[2] = (bit8)((SnsInfo >> 8) & 0xff); 3884 pSense->info[3] = (bit8)((SnsInfo) & 0xff); 3885 pSense->addSenseLen = 11; /* fixed size of sense data = 18 */ 3886 pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF); 3887 pSense->senseQual = (bit8)(SnsCode & 0xFF); 3888 /* 3889 * Set pointer in scsi status 3890 */ 3891 switch(SnsKey) 3892 { 3893 /* 3894 * set illegal request sense key specific error in cdb, no bit pointer 3895 */ 3896 case SCSI_SNSKEY_ILLEGAL_REQUEST: 3897 pSense->skeySpecific[0] = 0xC8; 3898 break; 3899 3900 default: 3901 break; 3902 } 3903 /* setting sense data length */ 3904 if (satIOContext != agNULL) 3905 { 3906 satIOContext->pSmSenseData->senseLen = 18; 3907 } 3908 else 3909 { 3910 SM_DBG1(("smsatSetSensePayload: satIOContext is NULL!!!\n")); 3911 } 3912 3913 /* Only for SCSI_SNSCODE_ATA_PASS_THROUGH_INFORMATION_AVAILABLE */ 3914 if (SnsCode == SCSI_SNSCODE_ATA_PASS_THROUGH_INFORMATION_AVAILABLE) 3915 { 3916 /* filling in COMMAND-SPECIFIC INFORMATION */ 3917 tmp = satIOContext->extend << 7 | satIOContext->Sector_Cnt_Upper_Nonzero << 6 | satIOContext->LBA_Upper_Nonzero << 5; 3918 SM_DBG3(("smsatSetSensePayload: extend 0x%x Sector_Cnt_Upper_Nonzero 0x%x LBA_Upper_Nonzero 0x%x\n", 3919 satIOContext->extend, satIOContext->Sector_Cnt_Upper_Nonzero, satIOContext->LBA_Upper_Nonzero)); 3920 SM_DBG3(("smsatSetSensePayload: tmp 0x%x\n", tmp)); 3921 pSense->cmdSpecific[0] = tmp; 3922 pSense->cmdSpecific[1] = satIOContext->LBAHigh07; 3923 pSense->cmdSpecific[2] = satIOContext->LBAMid07; 3924 pSense->cmdSpecific[3] = satIOContext->LBALow07; 3925 // smhexdump("smsatSetSensePayload: cmdSpecific",(bit8 *)pSense->cmdSpecific, 4); 3926 // smhexdump("smsatSetSensePayload: info",(bit8 *)pSense->info, 4); 3927 3928 } 3929 return; 3930 } 3931 3932 /***************************************************************************** 3933 *! \brief smsatDecodeSATADeviceType 3934 * 3935 * This routine decodes ATA signature 3936 * 3937 * \param pSignature: ATA signature 3938 * 3939 * 3940 * \return: 3941 * TRUE if ATA signature 3942 * FALSE otherwise 3943 * 3944 *****************************************************************************/ 3945 /* 3946 ATA p65 3947 PM p65 3948 SATAII p79, p80 3949 */ 3950 GLOBAL bit32 3951 smsatDecodeSATADeviceType( 3952 bit8 *pSignature 3953 ) 3954 { 3955 bit32 deviceType = UNKNOWN_DEVICE; 3956 3957 if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01 3958 && (pSignature)[2] == 0x00 && (pSignature)[3] == 0x00 3959 && (pSignature)[4] == 0xA0 ) /* this is the signature of a Hitachi SATA HDD*/ 3960 { 3961 deviceType = SATA_ATA_DEVICE; 3962 } 3963 else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01 3964 && (pSignature)[2] == 0x00 && (pSignature)[3] == 0x00 3965 && (pSignature)[4] == 0x00 ) 3966 { 3967 deviceType = SATA_ATA_DEVICE; 3968 } 3969 else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01 3970 && (pSignature)[2] == 0x14 && (pSignature)[3] == 0xEB 3971 && ( (pSignature)[4] == 0x00 || (pSignature)[4] == 0x10) ) 3972 { 3973 deviceType = SATA_ATAPI_DEVICE; 3974 } 3975 else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01 3976 && (pSignature)[2] == 0x69 && (pSignature)[3] == 0x96 3977 && (pSignature)[4] == 0x00 ) 3978 { 3979 deviceType = SATA_PM_DEVICE; 3980 } 3981 else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01 3982 && (pSignature)[2] == 0x3C && (pSignature)[3] == 0xC3 3983 && (pSignature)[4] == 0x00 ) 3984 { 3985 deviceType = SATA_SEMB_DEVICE; 3986 } 3987 else if ( (pSignature)[0] == 0xFF && (pSignature)[1] == 0xFF 3988 && (pSignature)[2] == 0xFF && (pSignature)[3] == 0xFF 3989 && (pSignature)[4] == 0xFF ) 3990 { 3991 deviceType = SATA_SEMB_WO_SEP_DEVICE; 3992 } 3993 3994 return deviceType; 3995 } 3996 3997 3998 /*****************************************************************************/ 3999 /*! \brief SAT implementation for ATAPI Packet Command. 4000 * 4001 * SAT implementation for ATAPI Packet and send FIS request to LL layer. 4002 * 4003 * \param tiRoot: Pointer to TISA initiator driver/port instance. 4004 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 4005 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 4006 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 4007 * \param smSatIOContext_t: Pointer to the SAT IO Context 4008 * 4009 * \return If command is started successfully 4010 * - \e smIOSuccess: I/O request successfully initiated. 4011 * - \e smIOBusy: No resources available, try again later. 4012 * - \e smIONoDevice: Invalid device handle. 4013 * - \e smIOError: Other errors. 4014 */ 4015 /*****************************************************************************/ 4016 osGLOBAL bit32 4017 smsatPacket( 4018 smRoot_t *smRoot, 4019 smIORequest_t *smIORequest, 4020 smDeviceHandle_t *smDeviceHandle, 4021 smScsiInitiatorRequest_t *smScsiRequest, 4022 smSatIOContext_t *satIOContext 4023 ) 4024 { 4025 bit32 status; 4026 bit32 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT; 4027 smDeviceData_t *pSatDevData; 4028 smIniScsiCmnd_t *scsiCmnd; 4029 agsaFisRegHostToDevice_t *fis; 4030 4031 pSatDevData = satIOContext->pSatDevData; 4032 scsiCmnd = &smScsiRequest->scsiCmnd; 4033 fis = satIOContext->pFis; 4034 4035 SM_DBG3(("smsatPacket: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n", 4036 scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3], 4037 scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7], 4038 scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11])); 4039 4040 fis->h.fisType = 0x27; /* Reg host to device */ 4041 fis->h.c_pmPort = 0x80; /* C Bit is set 1*/ 4042 fis->h.command = SAT_PACKET; /* 0xA0 */ 4043 if (pSatDevData->satDMADIRSupport) /* DMADIR enabled*/ 4044 { 4045 fis->h.features = (smScsiRequest->dataDirection == smDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */ 4046 } 4047 else 4048 { 4049 fis->h.features = 0; /* FIS reserve */ 4050 } 4051 4052 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 4053 { 4054 /*DMA transfer mode*/ 4055 fis->h.features |= 0x01; 4056 } 4057 else 4058 { 4059 /*PIO transfer mode*/ 4060 fis->h.features |= 0x0; 4061 } 4062 /* Byte count low and byte count high */ 4063 if ( scsiCmnd->expDataLength > 0xFFFF ) 4064 { 4065 fis->d.lbaMid = 0xFF; /* FIS LBA (15:8 ) */ 4066 fis->d.lbaHigh = 0xFF; /* FIS LBA (23:16) */ 4067 } 4068 else 4069 { 4070 fis->d.lbaMid = (bit8)scsiCmnd->expDataLength; /* FIS LBA (15:8 ) */ 4071 fis->d.lbaHigh = (bit8)(scsiCmnd->expDataLength>>8); /* FIS LBA (23:16) */ 4072 } 4073 4074 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 4075 fis->d.device = 0; /* FIS LBA (27:24) and FIS LBA mode */ 4076 fis->d.lbaLowExp = 0; 4077 fis->d.lbaMidExp = 0; 4078 fis->d.lbaHighExp = 0; 4079 fis->d.featuresExp = 0; 4080 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 4081 fis->d.sectorCountExp = 0; 4082 fis->d.reserved4 = 0; 4083 fis->d.control = 0; /* FIS HOB bit clear */ 4084 fis->d.reserved5 = 0; 4085 4086 satIOContext->ATACmd = SAT_PACKET; 4087 4088 if (smScsiRequest->dataDirection == smDirectionIn) 4089 { 4090 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT; 4091 } 4092 else 4093 { 4094 agRequestType = AGSA_SATA_PROTOCOL_H2D_PKT; 4095 } 4096 4097 satIOContext->satCompleteCB = &smsatPacketCB; 4098 4099 /* 4100 * Prepare SGL and send FIS to LL layer. 4101 */ 4102 satIOContext->reqType = agRequestType; /* Save it */ 4103 4104 status = smsataLLIOStart(smRoot, 4105 smIORequest, 4106 smDeviceHandle, 4107 smScsiRequest, 4108 satIOContext); 4109 4110 SM_DBG3(("smsatPacket: return\n")); 4111 return (status); 4112 } 4113 4114 /*****************************************************************************/ 4115 /*! \brief SAT implementation for smsatSetFeaturePIO. 4116 * 4117 * This function creates Set Features fis and sends the request to LL layer 4118 * 4119 * \param tiRoot: Pointer to TISA initiator driver/port instance. 4120 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 4121 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 4122 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 4123 * \param smSatIOContext_t: Pointer to the SAT IO Context 4124 * 4125 * \return If command is started successfully 4126 * - \e smIOSuccess: I/O request successfully initiated. 4127 * - \e smIOBusy: No resources available, try again later. 4128 * - \e smIONoDevice: Invalid device handle. 4129 * - \e smIOError: Other errors. 4130 */ 4131 /*****************************************************************************/ 4132 osGLOBAL bit32 4133 smsatSetFeaturesPIO( 4134 smRoot_t *smRoot, 4135 smIORequest_t *smIORequest, 4136 smDeviceHandle_t *smDeviceHandle, 4137 smScsiInitiatorRequest_t *smScsiRequest, 4138 smSatIOContext_t *satIOContext 4139 ) 4140 { 4141 bit32 status = SM_RC_FAILURE; 4142 bit32 agRequestType; 4143 agsaFisRegHostToDevice_t *fis; 4144 4145 fis = satIOContext->pFis; 4146 SM_DBG2(("smsatSetFeaturesPIO: start\n")); 4147 /* 4148 * Send the Set Features command. 4149 */ 4150 fis->h.fisType = 0x27; /* Reg host to device */ 4151 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4152 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 4153 fis->h.features = 0x03; /* set transfer mode */ 4154 fis->d.lbaLow = 0; 4155 fis->d.lbaMid = 0; 4156 fis->d.lbaHigh = 0; 4157 fis->d.device = 0; 4158 fis->d.lbaLowExp = 0; 4159 fis->d.lbaMidExp = 0; 4160 fis->d.lbaHighExp = 0; 4161 fis->d.featuresExp = 0; 4162 fis->d.sectorCountExp = 0; 4163 fis->d.reserved4 = 0; 4164 fis->d.control = 0; /* FIS HOB bit clear */ 4165 fis->d.reserved5 = 0; 4166 4167 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 4168 4169 /* Initialize CB for SATA completion. 4170 */ 4171 fis->d.sectorCount = 0x0C; /*enable PIO transfer mode */ 4172 satIOContext->satCompleteCB = &smsatSetFeaturesPIOCB; 4173 4174 /* 4175 * Prepare SGL and send FIS to LL layer. 4176 */ 4177 satIOContext->reqType = agRequestType; /* Save it */ 4178 4179 status = smsataLLIOStart( smRoot, 4180 smIORequest, 4181 smDeviceHandle, 4182 smScsiRequest, 4183 satIOContext); 4184 4185 SM_DBG2(("smsatSetFeaturesPIO: return\n")); 4186 /* debugging code */ 4187 if (smIORequest->tdData == smIORequest->smData) 4188 { 4189 SM_DBG1(("smsatSetFeaturesPIO: incorrect smIORequest\n")); 4190 } 4191 4192 return status; 4193 } 4194 /*****************************************************************************/ 4195 /*! \brief SAT implementation for SCSI REQUEST SENSE to ATAPI device. 4196 * 4197 * SAT implementation for SCSI REQUEST SENSE. 4198 * 4199 * \param tiRoot: Pointer to TISA initiator driver/port instance. 4200 * \param tiIORequest: Pointer to TISA I/O request context for this I/O. 4201 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O. 4202 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 4203 * \param smSatIOContext_t: Pointer to the SAT IO Context 4204 * 4205 * \return If command is started successfully 4206 * - \e smIOSuccess: I/O request successfully initiated. 4207 * - \e smIOBusy: No resources available, try again later. 4208 * - \e smIONoDevice: Invalid device handle. 4209 * - \e smIOError: Other errors. 4210 */ 4211 /*****************************************************************************/ 4212 osGLOBAL bit32 4213 smsatRequestSenseForATAPI( 4214 smRoot_t *smRoot, 4215 smIORequest_t *smIORequest, 4216 smDeviceHandle_t *smDeviceHandle, 4217 smScsiInitiatorRequest_t *smScsiRequest, 4218 smSatIOContext_t *satIOContext 4219 ) 4220 { 4221 bit32 status; 4222 bit32 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT; 4223 smDeviceData_t *pSatDevData; 4224 smIniScsiCmnd_t *scsiCmnd; 4225 agsaFisRegHostToDevice_t *fis; 4226 4227 pSatDevData = satIOContext->pSatDevData; 4228 scsiCmnd = &smScsiRequest->scsiCmnd; 4229 fis = satIOContext->pFis; 4230 4231 scsiCmnd->cdb[0] = SCSIOPC_REQUEST_SENSE; 4232 scsiCmnd->cdb[1] = 0; 4233 scsiCmnd->cdb[2] = 0; 4234 scsiCmnd->cdb[3] = 0; 4235 scsiCmnd->cdb[4] = (bit8)scsiCmnd->expDataLength; 4236 scsiCmnd->cdb[5] = 0; 4237 SM_DBG3(("smsatRequestSenseForATAPI: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n", 4238 scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3], 4239 scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7], 4240 scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11])); 4241 4242 fis->h.fisType = 0x27; /* Reg host to device */ 4243 fis->h.c_pmPort = 0x80; /* C Bit is set 1*/ 4244 fis->h.command = SAT_PACKET; /* 0xA0 */ 4245 if (pSatDevData->satDMADIRSupport) /* DMADIR enabled*/ 4246 { 4247 fis->h.features = (smScsiRequest->dataDirection == smDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */ 4248 } 4249 else 4250 { 4251 fis->h.features = 0; /* FIS reserve */ 4252 } 4253 4254 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 4255 { 4256 fis->h.features |= 0x01; 4257 } 4258 else 4259 { 4260 fis->h.features |= 0x0; 4261 } 4262 4263 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 4264 fis->d.lbaMid = (bit8)scsiCmnd->expDataLength; /* FIS LBA (15:8 ) */ 4265 fis->d.lbaHigh = (bit8)(scsiCmnd->expDataLength>>8); /* FIS LBA (23:16) */ 4266 fis->d.device = 0; /* FIS LBA (27:24) and FIS LBA mode */ 4267 fis->d.lbaLowExp = 0; 4268 fis->d.lbaMidExp = 0; 4269 fis->d.lbaHighExp = 0; 4270 fis->d.featuresExp = 0; 4271 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 4272 fis->d.sectorCountExp = 0; 4273 fis->d.reserved4 = 0; 4274 fis->d.control = 0; /* FIS HOB bit clear */ 4275 fis->d.reserved5 = 0; 4276 4277 satIOContext->ATACmd = SAT_PACKET; 4278 4279 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT; 4280 4281 4282 satIOContext->satCompleteCB = &smsatRequestSenseForATAPICB; 4283 4284 /* 4285 * Prepare SGL and send FIS to LL layer. 4286 */ 4287 satIOContext->reqType = agRequestType; /* Save it */ 4288 4289 status = smsataLLIOStart( smRoot, 4290 smIORequest, 4291 smDeviceHandle, 4292 smScsiRequest, 4293 satIOContext); 4294 4295 SM_DBG3(("smsatRequestSenseForATAPI: return\n")); 4296 return (status); 4297 } 4298 /*****************************************************************************/ 4299 /*! \brief SAT implementation for smsatDeviceReset. 4300 * 4301 * This function creates DEVICE RESET fis and sends the request to LL layer 4302 * 4303 * \param smRoot: Pointer to TISA initiator driver/port instance. 4304 * \param smIORequest: Pointer to TISA I/O request context for this I/O. 4305 * \param smDeviceHandle: Pointer to TISA device handle for this I/O. 4306 * \param smScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 4307 * \param smSatIOContext_t: Pointer to the SAT IO Context 4308 * 4309 * \return If command is started successfully 4310 * - \e smIOSuccess: I/O request successfully initiated. 4311 * - \e smIOBusy: No resources available, try again later. 4312 * - \e smIONoDevice: Invalid device handle. 4313 * - \e smIOError: Other errors. 4314 */ 4315 /*****************************************************************************/ 4316 osGLOBAL bit32 4317 smsatDeviceReset( 4318 smRoot_t *smRoot, 4319 smIORequest_t *smIORequest, 4320 smDeviceHandle_t *smDeviceHandle, 4321 smScsiInitiatorRequest_t *smScsiRequest, 4322 smSatIOContext_t *satIOContext 4323 ) 4324 { 4325 bit32 status; 4326 bit32 agRequestType; 4327 agsaFisRegHostToDevice_t *fis; 4328 4329 fis = satIOContext->pFis; 4330 SM_DBG3(("smsatDeviceReset: start\n")); 4331 /* 4332 * Send the Execute Device Diagnostic command. 4333 */ 4334 fis->h.fisType = 0x27; /* Reg host to device */ 4335 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4336 fis->h.command = SAT_DEVICE_RESET; /* 0x08 */ 4337 fis->h.features = 0; 4338 fis->d.lbaLow = 0; 4339 fis->d.lbaMid = 0; 4340 fis->d.lbaHigh = 0; 4341 fis->d.device = 0; 4342 fis->d.lbaLowExp = 0; 4343 fis->d.lbaMidExp = 0; 4344 fis->d.lbaHighExp = 0; 4345 fis->d.featuresExp = 0; 4346 fis->d.sectorCount = 0; 4347 fis->d.sectorCountExp = 0; 4348 fis->d.reserved4 = 0; 4349 fis->d.control = 0; /* FIS HOB bit clear */ 4350 fis->d.reserved5 = 0; 4351 4352 agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET; 4353 4354 /* Initialize CB for SATA completion. 4355 */ 4356 satIOContext->satCompleteCB = &smsatDeviceResetCB; 4357 4358 /* 4359 * Prepare SGL and send FIS to LL layer. 4360 */ 4361 satIOContext->reqType = agRequestType; /* Save it */ 4362 4363 status = smsataLLIOStart( smRoot, 4364 smIORequest, 4365 smDeviceHandle, 4366 smScsiRequest, 4367 satIOContext); 4368 4369 SM_DBG3(("smsatDeviceReset: return\n")); 4370 4371 return status; 4372 } 4373 4374 4375 /*****************************************************************************/ 4376 /*! \brief SAT implementation for smsatExecuteDeviceDiagnostic. 4377 * 4378 * This function creates Execute Device Diagnostic fis and sends the request to LL layer 4379 * 4380 * \param smRoot: Pointer to TISA initiator driver/port instance. 4381 * \param smIORequest: Pointer to TISA I/O request context for this I/O. 4382 * \param smDeviceHandle: Pointer to TISA device handle for this I/O. 4383 * \param smScsiRequest: Pointer to TISA SCSI I/O request and SGL list. 4384 * \param smSatIOContext_t: Pointer to the SAT IO Context 4385 * 4386 * \return If command is started successfully 4387 * - \e smIOSuccess: I/O request successfully initiated. 4388 * - \e smIOBusy: No resources available, try again later. 4389 * - \e smIONoDevice: Invalid device handle. 4390 * - \e smIOError: Other errors. 4391 */ 4392 /*****************************************************************************/ 4393 osGLOBAL bit32 4394 smsatExecuteDeviceDiagnostic( 4395 smRoot_t *smRoot, 4396 smIORequest_t *smIORequest, 4397 smDeviceHandle_t *smDeviceHandle, 4398 smScsiInitiatorRequest_t *smScsiRequest, 4399 smSatIOContext_t *satIOContext 4400 ) 4401 { 4402 bit32 status; 4403 bit32 agRequestType; 4404 agsaFisRegHostToDevice_t *fis; 4405 4406 fis = satIOContext->pFis; 4407 SM_DBG3(("smsatExecuteDeviceDiagnostic: start\n")); 4408 /* 4409 * Send the Execute Device Diagnostic command. 4410 */ 4411 fis->h.fisType = 0x27; /* Reg host to device */ 4412 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4413 fis->h.command = SAT_EXECUTE_DEVICE_DIAGNOSTIC; /* 0x90 */ 4414 fis->h.features = 0; 4415 fis->d.lbaLow = 0; 4416 fis->d.lbaMid = 0; 4417 fis->d.lbaHigh = 0; 4418 fis->d.device = 0; 4419 fis->d.lbaLowExp = 0; 4420 fis->d.lbaMidExp = 0; 4421 fis->d.lbaHighExp = 0; 4422 fis->d.featuresExp = 0; 4423 fis->d.sectorCount = 0; 4424 fis->d.sectorCountExp = 0; 4425 fis->d.reserved4 = 0; 4426 fis->d.control = 0; /* FIS HOB bit clear */ 4427 fis->d.reserved5 = 0; 4428 4429 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 4430 4431 /* Initialize CB for SATA completion. 4432 */ 4433 satIOContext->satCompleteCB = &smsatExecuteDeviceDiagnosticCB; 4434 4435 /* 4436 * Prepare SGL and send FIS to LL layer. 4437 */ 4438 satIOContext->reqType = agRequestType; /* Save it */ 4439 4440 status = smsataLLIOStart( smRoot, 4441 smIORequest, 4442 smDeviceHandle, 4443 smScsiRequest, 4444 satIOContext); 4445 4446 SM_DBG3(("smsatExecuteDeviceDiagnostic: return\n")); 4447 4448 return status; 4449 } 4450 4451 4452 osGLOBAL void 4453 smsatSetDeferredSensePayload( 4454 smScsiRspSense_t *pSense, 4455 bit8 SnsKey, 4456 bit32 SnsInfo, 4457 bit16 SnsCode, 4458 smSatIOContext_t *satIOContext 4459 ) 4460 { 4461 SM_DBG2(("smsatSetDeferredSensePayload: start\n")); 4462 return; 4463 } 4464 4465 4466 GLOBAL bit32 4467 smsatRead6( 4468 smRoot_t *smRoot, 4469 smIORequest_t *smIORequest, 4470 smDeviceHandle_t *smDeviceHandle, 4471 smScsiInitiatorRequest_t *smScsiRequest, 4472 smSatIOContext_t *satIOContext 4473 ) 4474 { 4475 bit32 status; 4476 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 4477 smDeviceData_t *pSatDevData; 4478 smScsiRspSense_t *pSense; 4479 smIniScsiCmnd_t *scsiCmnd; 4480 agsaFisRegHostToDevice_t *fis; 4481 bit32 lba = 0; 4482 bit16 tl = 0; 4483 4484 pSense = satIOContext->pSense; 4485 pSatDevData = satIOContext->pSatDevData; 4486 scsiCmnd = &smScsiRequest->scsiCmnd; 4487 fis = satIOContext->pFis; 4488 4489 SM_DBG2(("smsatRead6: start\n")); 4490 4491 /* no FUA checking since read6 */ 4492 4493 4494 /* checking CONTROL */ 4495 /* NACA == 1 or LINK == 1*/ 4496 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 4497 { 4498 smsatSetSensePayload( pSense, 4499 SCSI_SNSKEY_ILLEGAL_REQUEST, 4500 0, 4501 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 4502 satIOContext); 4503 4504 /*smEnqueueIO(smRoot, satIOContext);*/ 4505 4506 tdsmIOCompletedCB( smRoot, 4507 smIORequest, 4508 smIOSuccess, 4509 SCSI_STAT_CHECK_CONDITION, 4510 satIOContext->pSmSenseData, 4511 satIOContext->interruptContext ); 4512 4513 SM_DBG1(("smsatRead6: return control!!!\n")); 4514 return SM_RC_SUCCESS; 4515 } 4516 4517 /* cbd6; computing LBA and transfer length */ 4518 lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2)) 4519 + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3]; 4520 tl = scsiCmnd->cdb[4]; 4521 4522 /* Table 34, 9.1, p 46 */ 4523 /* 4524 note: As of 2/10/2006, no support for DMA QUEUED 4525 */ 4526 4527 /* 4528 Table 34, 9.1, p 46, b 4529 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 4530 return check condition 4531 */ 4532 if (pSatDevData->satNCQ != agTRUE && 4533 pSatDevData->sat48BitSupport != agTRUE 4534 ) 4535 { 4536 if (lba > SAT_TR_LBA_LIMIT - 1) 4537 { 4538 smsatSetSensePayload( pSense, 4539 SCSI_SNSKEY_ILLEGAL_REQUEST, 4540 0, 4541 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 4542 satIOContext); 4543 4544 /*smEnqueueIO(smRoot, satIOContext);*/ 4545 4546 tdsmIOCompletedCB( smRoot, 4547 smIORequest, 4548 smIOSuccess, 4549 SCSI_STAT_CHECK_CONDITION, 4550 satIOContext->pSmSenseData, 4551 satIOContext->interruptContext ); 4552 4553 SM_DBG1(("smsatRead6: return LBA out of range!!!\n")); 4554 return SM_RC_SUCCESS; 4555 } 4556 } 4557 4558 /* case 1 and 2 */ 4559 if (lba + tl <= SAT_TR_LBA_LIMIT) 4560 { 4561 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 4562 { 4563 /* case 2 */ 4564 /* READ DMA*/ 4565 SM_DBG5(("smsatRead6: case 2\n")); 4566 4567 4568 fis->h.fisType = 0x27; /* Reg host to device */ 4569 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4570 fis->h.command = SAT_READ_DMA; /* 0xC8 */ 4571 fis->h.features = 0; /* FIS reserve */ 4572 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 4573 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 4574 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 4575 fis->d.device = 0x40; /* FIS LBA mode */ 4576 fis->d.lbaLowExp = 0; 4577 fis->d.lbaMidExp = 0; 4578 fis->d.lbaHighExp = 0; 4579 fis->d.featuresExp = 0; 4580 if (tl == 0) 4581 { 4582 /* temporary fix */ 4583 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */ 4584 } 4585 else 4586 { 4587 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 4588 } 4589 fis->d.sectorCountExp = 0; 4590 fis->d.reserved4 = 0; 4591 fis->d.control = 0; /* FIS HOB bit clear */ 4592 fis->d.reserved5 = 0; 4593 4594 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 4595 } 4596 else 4597 { 4598 /* case 1 */ 4599 /* READ SECTORS for easier implemetation */ 4600 SM_DBG5(("smsatRead6: case 1\n")); 4601 4602 fis->h.fisType = 0x27; /* Reg host to device */ 4603 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4604 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 4605 fis->h.features = 0; /* FIS reserve */ 4606 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 4607 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 4608 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 4609 fis->d.device = 0x40; /* FIS LBA mode */ 4610 fis->d.lbaLowExp = 0; 4611 fis->d.lbaMidExp = 0; 4612 fis->d.lbaHighExp = 0; 4613 fis->d.featuresExp = 0; 4614 if (tl == 0) 4615 { 4616 /* temporary fix */ 4617 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */ 4618 } 4619 else 4620 { 4621 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 4622 } 4623 fis->d.sectorCountExp = 0; 4624 fis->d.reserved4 = 0; 4625 fis->d.control = 0; /* FIS HOB bit clear */ 4626 fis->d.reserved5 = 0; 4627 4628 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 4629 4630 } 4631 } 4632 4633 /* case 3 and 4 */ 4634 if (pSatDevData->sat48BitSupport == agTRUE) 4635 { 4636 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 4637 { 4638 /* case 3 */ 4639 /* READ DMA EXT only */ 4640 SM_DBG5(("smsatRead6: case 3\n")); 4641 fis->h.fisType = 0x27; /* Reg host to device */ 4642 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4643 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */ 4644 fis->h.features = 0; /* FIS reserve */ 4645 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 4646 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 4647 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 4648 fis->d.device = 0x40; /* FIS LBA mode set */ 4649 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 4650 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4651 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4652 fis->d.featuresExp = 0; /* FIS reserve */ 4653 if (tl == 0) 4654 { 4655 /* sector count is 256, 0x100*/ 4656 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 4657 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */ 4658 } 4659 else 4660 { 4661 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 4662 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 4663 } 4664 fis->d.reserved4 = 0; 4665 fis->d.control = 0; /* FIS HOB bit clear */ 4666 fis->d.reserved5 = 0; 4667 4668 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 4669 } 4670 else 4671 { 4672 /* case 4 */ 4673 /* READ SECTORS EXT for easier implemetation */ 4674 SM_DBG5(("smsatRead6: case 4\n")); 4675 4676 fis->h.fisType = 0x27; /* Reg host to device */ 4677 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4678 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 4679 fis->h.features = 0; /* FIS reserve */ 4680 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 4681 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 4682 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 4683 fis->d.device = 0x40; /* FIS LBA mode set */ 4684 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 4685 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4686 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4687 fis->d.featuresExp = 0; /* FIS reserve */ 4688 if (tl == 0) 4689 { 4690 /* sector count is 256, 0x100*/ 4691 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 4692 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */ 4693 } 4694 else 4695 { 4696 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 4697 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 4698 } 4699 fis->d.reserved4 = 0; 4700 fis->d.control = 0; /* FIS HOB bit clear */ 4701 fis->d.reserved5 = 0; 4702 4703 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 4704 } 4705 } 4706 4707 /* case 5 */ 4708 if (pSatDevData->satNCQ == agTRUE) 4709 { 4710 /* READ FPDMA QUEUED */ 4711 if (pSatDevData->sat48BitSupport != agTRUE) 4712 { 4713 /* sanity check */ 4714 SM_DBG1(("smsatRead6: case 5 !!! error NCQ but 28 bit address support!!!\n")); 4715 smsatSetSensePayload( pSense, 4716 SCSI_SNSKEY_ILLEGAL_REQUEST, 4717 0, 4718 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 4719 satIOContext); 4720 4721 /*smEnqueueIO(smRoot, satIOContext);*/ 4722 4723 tdsmIOCompletedCB( smRoot, 4724 smIORequest, 4725 smIOSuccess, 4726 SCSI_STAT_CHECK_CONDITION, 4727 satIOContext->pSmSenseData, 4728 satIOContext->interruptContext ); 4729 return SM_RC_SUCCESS; 4730 } 4731 SM_DBG5(("smsatRead6: case 5\n")); 4732 4733 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */ 4734 4735 fis->h.fisType = 0x27; /* Reg host to device */ 4736 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4737 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */ 4738 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 4739 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 4740 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 4741 fis->d.device = 0x40; /* FIS FUA clear */ 4742 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 4743 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4744 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4745 if (tl == 0) 4746 { 4747 /* sector count is 256, 0x100*/ 4748 fis->h.features = 0; /* FIS sector count (7:0) */ 4749 fis->d.featuresExp = 0x01; /* FIS sector count (15:8) */ 4750 } 4751 else 4752 { 4753 fis->h.features = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 4754 fis->d.featuresExp = 0; /* FIS sector count (15:8) */ 4755 } 4756 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 4757 fis->d.sectorCountExp = 0; 4758 fis->d.reserved4 = 0; 4759 fis->d.control = 0; /* FIS HOB bit clear */ 4760 fis->d.reserved5 = 0; 4761 4762 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ; 4763 } 4764 4765 /* Initialize CB for SATA completion. 4766 */ 4767 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB; 4768 4769 /* 4770 * Prepare SGL and send FIS to LL layer. 4771 */ 4772 satIOContext->reqType = agRequestType; /* Save it */ 4773 4774 status = smsataLLIOStart( smRoot, 4775 smIORequest, 4776 smDeviceHandle, 4777 smScsiRequest, 4778 satIOContext); 4779 return (status); 4780 4781 } 4782 4783 osGLOBAL FORCEINLINE bit32 4784 smsatRead10( 4785 smRoot_t *smRoot, 4786 smIORequest_t *smIORequest, 4787 smDeviceHandle_t *smDeviceHandle, 4788 smScsiInitiatorRequest_t *smScsiRequest, 4789 smSatIOContext_t *satIOContext 4790 ) 4791 { 4792 smDeviceData_t *pSatDevData = satIOContext->pSatDevData; 4793 smScsiRspSense_t *pSense = satIOContext->pSense; 4794 smIniScsiCmnd_t *scsiCmnd = &smScsiRequest->scsiCmnd; 4795 agsaFisRegHostToDevice_t *fis = satIOContext->pFis; 4796 4797 bit32 status; 4798 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 4799 bit32 lba = 0; 4800 bit32 tl = 0; 4801 bit32 LoopNum = 1; 4802 bit8 LBA[8]; 4803 bit8 TL[8]; 4804 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 4805 4806 SM_DBG2(("smsatRead10: start\n")); 4807 SM_DBG2(("smsatRead10: pSatDevData did=%d\n", pSatDevData->id)); 4808 // smhexdump("smsatRead10", (bit8 *)scsiCmnd->cdb, 10); 4809 4810 /* checking FUA_NV */ 4811 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 4812 { 4813 smsatSetSensePayload( pSense, 4814 SCSI_SNSKEY_ILLEGAL_REQUEST, 4815 0, 4816 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 4817 satIOContext); 4818 4819 /*smEnqueueIO(smRoot, satIOContext);*/ 4820 4821 tdsmIOCompletedCB( smRoot, 4822 smIORequest, 4823 smIOSuccess, 4824 SCSI_STAT_CHECK_CONDITION, 4825 satIOContext->pSmSenseData, 4826 satIOContext->interruptContext ); 4827 4828 SM_DBG1(("smsatRead10: return FUA_NV!!!\n")); 4829 return SM_RC_SUCCESS; 4830 4831 } 4832 4833 /* checking CONTROL */ 4834 /* NACA == 1 or LINK == 1*/ 4835 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 4836 { 4837 smsatSetSensePayload( pSense, 4838 SCSI_SNSKEY_ILLEGAL_REQUEST, 4839 0, 4840 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 4841 satIOContext); 4842 4843 /*smEnqueueIO(smRoot, satIOContext);*/ 4844 4845 tdsmIOCompletedCB( smRoot, 4846 smIORequest, 4847 smIOSuccess, 4848 SCSI_STAT_CHECK_CONDITION, 4849 satIOContext->pSmSenseData, 4850 satIOContext->interruptContext ); 4851 4852 SM_DBG1(("smsatRead10: return control!!!\n")); 4853 return SM_RC_SUCCESS; 4854 } 4855 /* 4856 sm_memset(LBA, 0, sizeof(LBA)); 4857 sm_memset(TL, 0, sizeof(TL)); 4858 */ 4859 /* do not use memcpy due to indexing in LBA and TL */ 4860 LBA[0] = 0; /* MSB */ 4861 LBA[1] = 0; 4862 LBA[2] = 0; 4863 LBA[3] = 0; 4864 LBA[4] = scsiCmnd->cdb[2]; 4865 LBA[5] = scsiCmnd->cdb[3]; 4866 LBA[6] = scsiCmnd->cdb[4]; 4867 LBA[7] = scsiCmnd->cdb[5]; /* LSB */ 4868 4869 TL[0] = 0; 4870 TL[1] = 0; 4871 TL[2] = 0; 4872 TL[3] = 0; 4873 TL[4] = 0; 4874 TL[5] = 0; 4875 TL[6] = scsiCmnd->cdb[7]; 4876 TL[7] = scsiCmnd->cdb[8]; /* LSB */ 4877 4878 4879 /* cbd10; computing LBA and transfer length */ 4880 lba = (scsiCmnd->cdb[2] << 24) + (scsiCmnd->cdb[3] << 16) 4881 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 4882 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 4883 4884 4885 SM_DBG5(("smsatRead10: lba %d functioned lba %d\n", lba, smsatComputeCDB10LBA(satIOContext))); 4886 SM_DBG5(("smsatRead10: lba 0x%x functioned lba 0x%x\n", lba, smsatComputeCDB10LBA(satIOContext))); 4887 SM_DBG5(("smsatRead10: tl %d functioned tl %d\n", tl, smsatComputeCDB10TL(satIOContext))); 4888 4889 /* Table 34, 9.1, p 46 */ 4890 /* 4891 note: As of 2/10/2006, no support for DMA QUEUED 4892 */ 4893 4894 /* 4895 Table 34, 9.1, p 46, b 4896 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 4897 return check condition 4898 */ 4899 4900 if (pSatDevData->satNCQ != agTRUE && 4901 pSatDevData->sat48BitSupport != agTRUE 4902 ) 4903 { 4904 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 4905 if (AllChk) 4906 { 4907 SM_DBG1(("smsatRead10: return LBA out of range, not EXT!!!\n")); 4908 smsatSetSensePayload( pSense, 4909 SCSI_SNSKEY_ILLEGAL_REQUEST, 4910 0, 4911 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 4912 satIOContext); 4913 4914 /*smEnqueueIO(smRoot, satIOContext);*/ 4915 4916 tdsmIOCompletedCB( smRoot, 4917 smIORequest, 4918 smIOSuccess, 4919 SCSI_STAT_CHECK_CONDITION, 4920 satIOContext->pSmSenseData, 4921 satIOContext->interruptContext ); 4922 4923 return SM_RC_SUCCESS; 4924 } 4925 } 4926 else 4927 { 4928 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 4929 if (AllChk) 4930 { 4931 SM_DBG1(("smsatRead10: return LBA out of range, EXT!!!\n")); 4932 smsatSetSensePayload( pSense, 4933 SCSI_SNSKEY_ILLEGAL_REQUEST, 4934 0, 4935 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 4936 satIOContext); 4937 4938 /*smEnqueueIO(smRoot, satIOContext);*/ 4939 4940 tdsmIOCompletedCB( smRoot, 4941 smIORequest, 4942 smIOSuccess, 4943 SCSI_STAT_CHECK_CONDITION, 4944 satIOContext->pSmSenseData, 4945 satIOContext->interruptContext ); 4946 4947 return SM_RC_SUCCESS; 4948 } 4949 } 4950 /* case 5 */ 4951 if (pSatDevData->satNCQ == agTRUE) 4952 { 4953 /* READ FPDMA QUEUED */ 4954 if (pSatDevData->sat48BitSupport != agTRUE) 4955 { 4956 SM_DBG1(("smsatRead10: case 5 !!! error NCQ but 28 bit address support!!!\n")); 4957 smsatSetSensePayload( pSense, 4958 SCSI_SNSKEY_ILLEGAL_REQUEST, 4959 0, 4960 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 4961 satIOContext); 4962 4963 /*smEnqueueIO(smRoot, satIOContext);*/ 4964 4965 tdsmIOCompletedCB( smRoot, 4966 smIORequest, 4967 smIOSuccess, 4968 SCSI_STAT_CHECK_CONDITION, 4969 satIOContext->pSmSenseData, 4970 satIOContext->interruptContext ); 4971 return SM_RC_SUCCESS; 4972 } 4973 4974 SM_DBG6(("smsatRead10: case 5\n")); 4975 4976 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */ 4977 4978 fis->h.fisType = 0x27; /* Reg host to device */ 4979 fis->h.c_pmPort = 0x80; /* C Bit is set */ 4980 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */ 4981 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 4982 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 4983 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 4984 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 4985 4986 /* Check FUA bit */ 4987 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK) 4988 fis->d.device = 0xC0; /* FIS FUA set */ 4989 else 4990 fis->d.device = 0x40; /* FIS FUA clear */ 4991 4992 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 4993 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 4994 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 4995 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 4996 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 4997 fis->d.sectorCountExp = 0; 4998 fis->d.reserved4 = 0; 4999 fis->d.control = 0; /* FIS HOB bit clear */ 5000 fis->d.reserved5 = 0; 5001 5002 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ; 5003 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED; 5004 } 5005 else if (pSatDevData->sat48BitSupport == agTRUE) /* case 3 and 4 */ 5006 { 5007 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 5008 { 5009 /* case 3 */ 5010 /* READ DMA EXT */ 5011 SM_DBG5(("smsatRead10: case 3\n")); 5012 fis->h.fisType = 0x27; /* Reg host to device */ 5013 5014 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5015 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */ 5016 fis->h.features = 0; /* FIS reserve */ 5017 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 5018 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 5019 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 5020 fis->d.device = 0x40; /* FIS LBA mode set */ 5021 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 5022 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 5023 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 5024 fis->d.featuresExp = 0; /* FIS reserve */ 5025 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 5026 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 5027 fis->d.reserved4 = 0; 5028 fis->d.control = 0; /* FIS HOB bit clear */ 5029 fis->d.reserved5 = 0; 5030 5031 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 5032 satIOContext->ATACmd = SAT_READ_DMA_EXT; 5033 5034 } 5035 else 5036 { 5037 /* case 4 */ 5038 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/ 5039 /* READ SECTORS EXT for easier implemetation */ 5040 SM_DBG5(("smsatRead10: case 4\n")); 5041 fis->h.fisType = 0x27; /* Reg host to device */ 5042 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5043 5044 /* Check FUA bit */ 5045 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK) 5046 { 5047 5048 /* for now, no support for FUA */ 5049 smsatSetSensePayload( pSense, 5050 SCSI_SNSKEY_ILLEGAL_REQUEST, 5051 0, 5052 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5053 satIOContext); 5054 5055 /*smEnqueueIO(smRoot, satIOContext);*/ 5056 5057 tdsmIOCompletedCB( smRoot, 5058 smIORequest, 5059 smIOSuccess, 5060 SCSI_STAT_CHECK_CONDITION, 5061 satIOContext->pSmSenseData, 5062 satIOContext->interruptContext ); 5063 return SM_RC_SUCCESS; 5064 } 5065 5066 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 5067 5068 fis->h.features = 0; /* FIS reserve */ 5069 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 5070 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 5071 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 5072 fis->d.device = 0x40; /* FIS LBA mode set */ 5073 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 5074 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 5075 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 5076 fis->d.featuresExp = 0; /* FIS reserve */ 5077 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 5078 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 5079 fis->d.reserved4 = 0; 5080 fis->d.control = 0; /* FIS HOB bit clear */ 5081 fis->d.reserved5 = 0; 5082 5083 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 5084 satIOContext->ATACmd = SAT_READ_SECTORS_EXT; 5085 } 5086 } 5087 else/* case 1 and 2 */ 5088 { 5089 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 5090 { 5091 /* case 2 */ 5092 /* READ DMA*/ 5093 /* in case that we can't fit the transfer length, we need to make it fit by sending multiple ATA cmnds */ 5094 SM_DBG5(("smsatRead10: case 2\n")); 5095 5096 5097 fis->h.fisType = 0x27; /* Reg host to device */ 5098 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5099 fis->h.command = SAT_READ_DMA; /* 0xC8 */ 5100 fis->h.features = 0; /* FIS reserve */ 5101 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 5102 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 5103 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 5104 fis->d.device = 5105 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 5106 fis->d.lbaLowExp = 0; 5107 fis->d.lbaMidExp = 0; 5108 fis->d.lbaHighExp = 0; 5109 fis->d.featuresExp = 0; 5110 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 5111 fis->d.sectorCountExp = 0; 5112 fis->d.reserved4 = 0; 5113 fis->d.control = 0; /* FIS HOB bit clear */ 5114 fis->d.reserved5 = 0; 5115 5116 5117 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 5118 satIOContext->ATACmd = SAT_READ_DMA; 5119 } 5120 else 5121 { 5122 /* case 1 */ 5123 /* READ MULTIPLE or READ SECTOR(S) */ 5124 /* READ SECTORS for easier implemetation */ 5125 /* in case that we can't fit the transfer length, we need to make it fit by sending multiple ATA cmnds */ 5126 SM_DBG5(("smsatRead10: case 1\n")); 5127 5128 fis->h.fisType = 0x27; /* Reg host to device */ 5129 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5130 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 5131 fis->h.features = 0; /* FIS reserve */ 5132 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 5133 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 5134 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 5135 fis->d.device = 5136 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 5137 fis->d.lbaLowExp = 0; 5138 fis->d.lbaMidExp = 0; 5139 fis->d.lbaHighExp = 0; 5140 fis->d.featuresExp = 0; 5141 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 5142 fis->d.sectorCountExp = 0; 5143 fis->d.reserved4 = 0; 5144 fis->d.control = 0; /* FIS HOB bit clear */ 5145 fis->d.reserved5 = 0; 5146 5147 5148 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 5149 satIOContext->ATACmd = SAT_READ_SECTORS; 5150 } 5151 } 5152 // smhexdump("satRead10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t)); 5153 5154 /* saves the current LBA and orginal TL */ 5155 satIOContext->currentLBA = lba; 5156 satIOContext->OrgTL = tl; 5157 5158 /* 5159 computing number of loop and remainder for tl 5160 0xFF in case not ext 5161 0xFFFF in case EXT 5162 */ 5163 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 5164 { 5165 LoopNum = smsatComputeLoopNum(tl, 0x100); 5166 } 5167 else 5168 { 5169 /* SAT_READ_FPDMA_QUEUED */ 5170 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 5171 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 5172 } 5173 5174 satIOContext->LoopNum = LoopNum; 5175 5176 /* Initialize CB for SATA completion. 5177 */ 5178 if (LoopNum == 1) 5179 { 5180 SM_DBG5(("smsatRead10: NON CHAINED data\n")); 5181 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB; 5182 } 5183 else 5184 { 5185 SM_DBG2(("smsatRead10: CHAINED data!!!\n")); 5186 5187 /* re-setting tl */ 5188 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 5189 { 5190 fis->d.sectorCount = 0x0; 5191 smsatSplitSGL(smRoot, 5192 smIORequest, 5193 smDeviceHandle, 5194 smScsiRequest, 5195 satIOContext, 5196 NON_BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0x100 * 0x200 */ 5197 (satIOContext->OrgTL)*SATA_SECTOR_SIZE, 5198 agTRUE); 5199 } 5200 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 5201 { 5202 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 5203 fis->d.sectorCount = 0xFF; 5204 fis->d.sectorCountExp = 0xFF; 5205 smsatSplitSGL(smRoot, 5206 smIORequest, 5207 smDeviceHandle, 5208 smScsiRequest, 5209 satIOContext, 5210 BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */ 5211 (satIOContext->OrgTL)*SATA_SECTOR_SIZE, 5212 agTRUE); 5213 } 5214 else 5215 { 5216 /* SAT_READ_FPDMA_QUEUED */ 5217 fis->h.features = 0xFF; 5218 fis->d.featuresExp = 0xFF; 5219 smsatSplitSGL(smRoot, 5220 smIORequest, 5221 smDeviceHandle, 5222 smScsiRequest, 5223 satIOContext, 5224 BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */ 5225 (satIOContext->OrgTL)*SATA_SECTOR_SIZE, 5226 agTRUE); 5227 } 5228 5229 /* chained data */ 5230 satIOContext->satCompleteCB = &smsatChainedDataIOCB; 5231 5232 } 5233 5234 /* 5235 * Prepare SGL and send FIS to LL layer. 5236 */ 5237 satIOContext->reqType = agRequestType; /* Save it */ 5238 5239 status = smsataLLIOStart( smRoot, 5240 smIORequest, 5241 smDeviceHandle, 5242 smScsiRequest, 5243 satIOContext); 5244 5245 SM_DBG5(("smsatRead10: return\n")); 5246 return (status); 5247 5248 } 5249 5250 osGLOBAL bit32 5251 smsatRead12( 5252 smRoot_t *smRoot, 5253 smIORequest_t *smIORequest, 5254 smDeviceHandle_t *smDeviceHandle, 5255 smScsiInitiatorRequest_t *smScsiRequest, 5256 smSatIOContext_t *satIOContext 5257 ) 5258 { 5259 bit32 status; 5260 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 5261 smDeviceData_t *pSatDevData; 5262 smScsiRspSense_t *pSense; 5263 smIniScsiCmnd_t *scsiCmnd; 5264 agsaFisRegHostToDevice_t *fis; 5265 bit32 lba = 0; 5266 bit32 tl = 0; 5267 bit32 LoopNum = 1; 5268 bit8 LBA[8]; 5269 bit8 TL[8]; 5270 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 5271 5272 pSense = satIOContext->pSense; 5273 pSatDevData = satIOContext->pSatDevData; 5274 scsiCmnd = &smScsiRequest->scsiCmnd; 5275 fis = satIOContext->pFis; 5276 5277 SM_DBG5(("smsatRead12: start\n")); 5278 5279 /* checking FUA_NV */ 5280 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 5281 { 5282 smsatSetSensePayload( pSense, 5283 SCSI_SNSKEY_ILLEGAL_REQUEST, 5284 0, 5285 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5286 satIOContext); 5287 5288 /*smEnqueueIO(smRoot, satIOContext);*/ 5289 5290 tdsmIOCompletedCB( smRoot, 5291 smIORequest, 5292 smIOSuccess, 5293 SCSI_STAT_CHECK_CONDITION, 5294 satIOContext->pSmSenseData, 5295 satIOContext->interruptContext ); 5296 5297 SM_DBG1(("smsatRead12: return FUA_NV!!!\n")); 5298 return SM_RC_SUCCESS; 5299 5300 } 5301 5302 /* checking CONTROL */ 5303 /* NACA == 1 or LINK == 1*/ 5304 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) ) 5305 { 5306 smsatSetSensePayload( pSense, 5307 SCSI_SNSKEY_ILLEGAL_REQUEST, 5308 0, 5309 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5310 satIOContext); 5311 5312 /*smEnqueueIO(smRoot, satIOContext);*/ 5313 5314 tdsmIOCompletedCB( smRoot, 5315 smIORequest, 5316 smIOSuccess, 5317 SCSI_STAT_CHECK_CONDITION, 5318 satIOContext->pSmSenseData, 5319 satIOContext->interruptContext ); 5320 5321 SM_DBG1(("smsatRead12: return control!!!\n")); 5322 return SM_RC_SUCCESS; 5323 } 5324 5325 sm_memset(LBA, 0, sizeof(LBA)); 5326 sm_memset(TL, 0, sizeof(TL)); 5327 5328 /* do not use memcpy due to indexing in LBA and TL */ 5329 LBA[0] = 0; /* MSB */ 5330 LBA[1] = 0; 5331 LBA[2] = 0; 5332 LBA[3] = 0; 5333 LBA[4] = scsiCmnd->cdb[2]; 5334 LBA[5] = scsiCmnd->cdb[3]; 5335 LBA[6] = scsiCmnd->cdb[4]; 5336 LBA[7] = scsiCmnd->cdb[5]; /* LSB */ 5337 5338 TL[0] = 0; /* MSB */ 5339 TL[1] = 0; 5340 TL[2] = 0; 5341 TL[3] = 0; 5342 TL[4] = scsiCmnd->cdb[6]; 5343 TL[5] = scsiCmnd->cdb[7]; 5344 TL[6] = scsiCmnd->cdb[8]; 5345 TL[7] = scsiCmnd->cdb[9]; /* LSB */ 5346 5347 5348 lba = smsatComputeCDB12LBA(satIOContext); 5349 tl = smsatComputeCDB12TL(satIOContext); 5350 5351 /* Table 34, 9.1, p 46 */ 5352 /* 5353 note: As of 2/10/2006, no support for DMA QUEUED 5354 */ 5355 5356 /* 5357 Table 34, 9.1, p 46, b 5358 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 5359 return check condition 5360 */ 5361 if (pSatDevData->satNCQ != agTRUE && 5362 pSatDevData->sat48BitSupport != agTRUE 5363 ) 5364 { 5365 5366 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 5367 if (AllChk) 5368 { 5369 SM_DBG1(("smsatRead12: return LBA out of range, not EXT!!!\n")); 5370 smsatSetSensePayload( pSense, 5371 SCSI_SNSKEY_ILLEGAL_REQUEST, 5372 0, 5373 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 5374 satIOContext); 5375 5376 /*smEnqueueIO(smRoot, satIOContext);*/ 5377 5378 tdsmIOCompletedCB( smRoot, 5379 smIORequest, 5380 smIOSuccess, 5381 SCSI_STAT_CHECK_CONDITION, 5382 satIOContext->pSmSenseData, 5383 satIOContext->interruptContext ); 5384 5385 return SM_RC_SUCCESS; 5386 } 5387 } 5388 else 5389 { 5390 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 5391 if (AllChk) 5392 { 5393 SM_DBG1(("smsatRead12: return LBA out of range, EXT!!!\n")); 5394 smsatSetSensePayload( pSense, 5395 SCSI_SNSKEY_ILLEGAL_REQUEST, 5396 0, 5397 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 5398 satIOContext); 5399 5400 /*smEnqueueIO(smRoot, satIOContext);*/ 5401 5402 tdsmIOCompletedCB( smRoot, 5403 smIORequest, 5404 smIOSuccess, 5405 SCSI_STAT_CHECK_CONDITION, 5406 satIOContext->pSmSenseData, 5407 satIOContext->interruptContext ); 5408 5409 return SM_RC_SUCCESS; 5410 } 5411 } 5412 5413 /* case 1 and 2 */ 5414 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 5415 { 5416 /* case 2 */ 5417 /* READ DMA*/ 5418 /* in case that we can't fit the transfer length, 5419 we need to make it fit by sending multiple ATA cmnds */ 5420 SM_DBG5(("smsatRead12: case 2\n")); 5421 5422 5423 fis->h.fisType = 0x27; /* Reg host to device */ 5424 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5425 fis->h.command = SAT_READ_DMA; /* 0xC8 */ 5426 fis->h.features = 0; /* FIS reserve */ 5427 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 5428 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 5429 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 5430 fis->d.device = 5431 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 5432 fis->d.lbaLowExp = 0; 5433 fis->d.lbaMidExp = 0; 5434 fis->d.lbaHighExp = 0; 5435 fis->d.featuresExp = 0; 5436 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 5437 fis->d.sectorCountExp = 0; 5438 fis->d.reserved4 = 0; 5439 fis->d.control = 0; /* FIS HOB bit clear */ 5440 fis->d.reserved5 = 0; 5441 5442 5443 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 5444 satIOContext->ATACmd = SAT_READ_DMA; 5445 } 5446 else 5447 { 5448 /* case 1 */ 5449 /* READ MULTIPLE or READ SECTOR(S) */ 5450 /* READ SECTORS for easier implemetation */ 5451 /* can't fit the transfer length but need to make it fit by sending multiple*/ 5452 SM_DBG5(("smsatRead12: case 1\n")); 5453 5454 fis->h.fisType = 0x27; /* Reg host to device */ 5455 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5456 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 5457 fis->h.features = 0; /* FIS reserve */ 5458 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 5459 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 5460 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 5461 fis->d.device = 5462 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 5463 fis->d.lbaLowExp = 0; 5464 fis->d.lbaMidExp = 0; 5465 fis->d.lbaHighExp = 0; 5466 fis->d.featuresExp = 0; 5467 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 5468 fis->d.sectorCountExp = 0; 5469 fis->d.reserved4 = 0; 5470 fis->d.control = 0; /* FIS HOB bit clear */ 5471 fis->d.reserved5 = 0; 5472 5473 5474 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 5475 satIOContext->ATACmd = SAT_READ_SECTORS; 5476 } 5477 5478 /* case 3 and 4 */ 5479 if (pSatDevData->sat48BitSupport == agTRUE) 5480 { 5481 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 5482 { 5483 /* case 3 */ 5484 /* READ DMA EXT */ 5485 SM_DBG5(("smsatRead12: case 3\n")); 5486 fis->h.fisType = 0x27; /* Reg host to device */ 5487 5488 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5489 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */ 5490 fis->h.features = 0; /* FIS reserve */ 5491 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 5492 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 5493 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 5494 fis->d.device = 0x40; /* FIS LBA mode set */ 5495 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 5496 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 5497 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 5498 fis->d.featuresExp = 0; /* FIS reserve */ 5499 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 5500 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 5501 fis->d.reserved4 = 0; 5502 fis->d.control = 0; /* FIS HOB bit clear */ 5503 fis->d.reserved5 = 0; 5504 5505 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 5506 satIOContext->ATACmd = SAT_READ_DMA_EXT; 5507 5508 } 5509 else 5510 { 5511 /* case 4 */ 5512 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/ 5513 /* READ SECTORS EXT for easier implemetation */ 5514 SM_DBG5(("smsatRead12: case 4\n")); 5515 fis->h.fisType = 0x27; /* Reg host to device */ 5516 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5517 5518 /* Check FUA bit */ 5519 if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK) 5520 { 5521 5522 /* for now, no support for FUA */ 5523 smsatSetSensePayload( pSense, 5524 SCSI_SNSKEY_ILLEGAL_REQUEST, 5525 0, 5526 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5527 satIOContext); 5528 5529 /*smEnqueueIO(smRoot, satIOContext);*/ 5530 5531 tdsmIOCompletedCB( smRoot, 5532 smIORequest, 5533 smIOSuccess, 5534 SCSI_STAT_CHECK_CONDITION, 5535 satIOContext->pSmSenseData, 5536 satIOContext->interruptContext ); 5537 return SM_RC_SUCCESS; 5538 } 5539 5540 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 5541 5542 fis->h.features = 0; /* FIS reserve */ 5543 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 5544 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 5545 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 5546 fis->d.device = 0x40; /* FIS LBA mode set */ 5547 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 5548 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 5549 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 5550 fis->d.featuresExp = 0; /* FIS reserve */ 5551 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 5552 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 5553 fis->d.reserved4 = 0; 5554 fis->d.control = 0; /* FIS HOB bit clear */ 5555 fis->d.reserved5 = 0; 5556 5557 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 5558 satIOContext->ATACmd = SAT_READ_SECTORS_EXT; 5559 } 5560 } 5561 5562 /* case 5 */ 5563 if (pSatDevData->satNCQ == agTRUE) 5564 { 5565 /* READ FPDMA QUEUED */ 5566 if (pSatDevData->sat48BitSupport != agTRUE) 5567 { 5568 SM_DBG1(("smsatRead12: case 5 !!! error NCQ but 28 bit address support!!!\n")); 5569 smsatSetSensePayload( pSense, 5570 SCSI_SNSKEY_ILLEGAL_REQUEST, 5571 0, 5572 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5573 satIOContext); 5574 5575 /*smEnqueueIO(smRoot, satIOContext);*/ 5576 5577 tdsmIOCompletedCB( smRoot, 5578 smIORequest, 5579 smIOSuccess, 5580 SCSI_STAT_CHECK_CONDITION, 5581 satIOContext->pSmSenseData, 5582 satIOContext->interruptContext ); 5583 return SM_RC_SUCCESS; 5584 } 5585 5586 SM_DBG6(("smsatRead12: case 5\n")); 5587 5588 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */ 5589 5590 fis->h.fisType = 0x27; /* Reg host to device */ 5591 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5592 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */ 5593 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 5594 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 5595 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 5596 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 5597 5598 /* Check FUA bit */ 5599 if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK) 5600 fis->d.device = 0xC0; /* FIS FUA set */ 5601 else 5602 fis->d.device = 0x40; /* FIS FUA clear */ 5603 5604 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 5605 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 5606 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 5607 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 5608 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 5609 fis->d.sectorCountExp = 0; 5610 fis->d.reserved4 = 0; 5611 fis->d.control = 0; /* FIS HOB bit clear */ 5612 fis->d.reserved5 = 0; 5613 5614 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ; 5615 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED; 5616 } 5617 5618 /* saves the current LBA and orginal TL */ 5619 satIOContext->currentLBA = lba; 5620 satIOContext->OrgTL = tl; 5621 5622 /* 5623 computing number of loop and remainder for tl 5624 0xFF in case not ext 5625 0xFFFF in case EXT 5626 */ 5627 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 5628 { 5629 LoopNum = smsatComputeLoopNum(tl, 0xFF); 5630 } 5631 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 5632 { 5633 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 5634 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 5635 } 5636 else 5637 { 5638 /* SAT_READ_FPDMA_QUEUEDK */ 5639 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 5640 } 5641 5642 satIOContext->LoopNum = LoopNum; 5643 5644 if (LoopNum == 1) 5645 { 5646 SM_DBG5(("smsatRead12: NON CHAINED data\n")); 5647 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB; 5648 } 5649 else 5650 { 5651 SM_DBG1(("smsatRead12: CHAINED data\n")); 5652 /* re-setting tl */ 5653 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 5654 { 5655 fis->d.sectorCount = 0xFF; 5656 } 5657 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 5658 { 5659 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 5660 fis->d.sectorCount = 0xFF; 5661 fis->d.sectorCountExp = 0xFF; 5662 } 5663 else 5664 { 5665 /* SAT_READ_FPDMA_QUEUED */ 5666 fis->h.features = 0xFF; 5667 fis->d.featuresExp = 0xFF; 5668 } 5669 5670 /* chained data */ 5671 satIOContext->satCompleteCB = &smsatChainedDataIOCB; 5672 } 5673 5674 /* 5675 * Prepare SGL and send FIS to LL layer. 5676 */ 5677 satIOContext->reqType = agRequestType; /* Save it */ 5678 5679 status = smsataLLIOStart( smRoot, 5680 smIORequest, 5681 smDeviceHandle, 5682 smScsiRequest, 5683 satIOContext); 5684 5685 SM_DBG5(("smsatRead12: return\n")); 5686 return (status); 5687 } 5688 5689 osGLOBAL bit32 5690 smsatRead16( 5691 smRoot_t *smRoot, 5692 smIORequest_t *smIORequest, 5693 smDeviceHandle_t *smDeviceHandle, 5694 smScsiInitiatorRequest_t *smScsiRequest, 5695 smSatIOContext_t *satIOContext 5696 ) 5697 { 5698 bit32 status; 5699 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 5700 smDeviceData_t *pSatDevData; 5701 smScsiRspSense_t *pSense; 5702 smIniScsiCmnd_t *scsiCmnd; 5703 agsaFisRegHostToDevice_t *fis; 5704 bit32 lba = 0; 5705 bit32 tl = 0; 5706 bit32 LoopNum = 1; 5707 bit8 LBA[8]; 5708 bit8 TL[8]; 5709 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 5710 // bit32 limitExtChk = agFALSE; /* lba limit check for bit48 addressing check */ 5711 5712 pSense = satIOContext->pSense; 5713 pSatDevData = satIOContext->pSatDevData; 5714 scsiCmnd = &smScsiRequest->scsiCmnd; 5715 fis = satIOContext->pFis; 5716 5717 SM_DBG5(("smsatRead16: start\n")); 5718 5719 /* checking FUA_NV */ 5720 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 5721 { 5722 smsatSetSensePayload( pSense, 5723 SCSI_SNSKEY_ILLEGAL_REQUEST, 5724 0, 5725 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5726 satIOContext); 5727 5728 /*smEnqueueIO(smRoot, satIOContext);*/ 5729 5730 tdsmIOCompletedCB( smRoot, 5731 smIORequest, 5732 smIOSuccess, 5733 SCSI_STAT_CHECK_CONDITION, 5734 satIOContext->pSmSenseData, 5735 satIOContext->interruptContext ); 5736 5737 SM_DBG1(("smsatRead16: return FUA_NV!!!\n")); 5738 return SM_RC_SUCCESS; 5739 5740 } 5741 5742 /* checking CONTROL */ 5743 /* NACA == 1 or LINK == 1*/ 5744 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 5745 { 5746 smsatSetSensePayload( pSense, 5747 SCSI_SNSKEY_ILLEGAL_REQUEST, 5748 0, 5749 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5750 satIOContext); 5751 5752 /*smEnqueueIO(smRoot, satIOContext);*/ 5753 5754 tdsmIOCompletedCB( smRoot, 5755 smIORequest, 5756 smIOSuccess, 5757 SCSI_STAT_CHECK_CONDITION, 5758 satIOContext->pSmSenseData, 5759 satIOContext->interruptContext ); 5760 5761 SM_DBG1(("smsatRead16: return control!!!\n")); 5762 return SM_RC_SUCCESS; 5763 } 5764 5765 5766 sm_memset(LBA, 0, sizeof(LBA)); 5767 sm_memset(TL, 0, sizeof(TL)); 5768 5769 5770 /* do not use memcpy due to indexing in LBA and TL */ 5771 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 5772 LBA[1] = scsiCmnd->cdb[3]; 5773 LBA[2] = scsiCmnd->cdb[4]; 5774 LBA[3] = scsiCmnd->cdb[5]; 5775 LBA[4] = scsiCmnd->cdb[6]; 5776 LBA[5] = scsiCmnd->cdb[7]; 5777 LBA[6] = scsiCmnd->cdb[8]; 5778 LBA[7] = scsiCmnd->cdb[9]; /* LSB */ 5779 5780 TL[0] = 0; 5781 TL[1] = 0; 5782 TL[2] = 0; 5783 TL[3] = 0; 5784 TL[4] = scsiCmnd->cdb[10]; /* MSB */ 5785 TL[5] = scsiCmnd->cdb[11]; 5786 TL[6] = scsiCmnd->cdb[12]; 5787 TL[7] = scsiCmnd->cdb[13]; /* LSB */ 5788 5789 5790 5791 5792 lba = smsatComputeCDB16LBA(satIOContext); 5793 tl = smsatComputeCDB16TL(satIOContext); 5794 5795 5796 /* Table 34, 9.1, p 46 */ 5797 /* 5798 note: As of 2/10/2006, no support for DMA QUEUED 5799 */ 5800 5801 /* 5802 Table 34, 9.1, p 46, b 5803 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 5804 return check condition 5805 */ 5806 if (pSatDevData->satNCQ != agTRUE && 5807 pSatDevData->sat48BitSupport != agTRUE 5808 ) 5809 { 5810 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 5811 if (AllChk) 5812 { 5813 SM_DBG1(("smsatRead16: return LBA out of range, not EXT!!!\n")); 5814 5815 /*smEnqueueIO(smRoot, satIOContext);*/ 5816 5817 5818 smsatSetSensePayload( pSense, 5819 SCSI_SNSKEY_ILLEGAL_REQUEST, 5820 0, 5821 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 5822 satIOContext); 5823 5824 /*smEnqueueIO(smRoot, satIOContext);*/ 5825 5826 tdsmIOCompletedCB( smRoot, 5827 smIORequest, 5828 smIOSuccess, 5829 SCSI_STAT_CHECK_CONDITION, 5830 satIOContext->pSmSenseData, 5831 satIOContext->interruptContext ); 5832 5833 return SM_RC_SUCCESS; 5834 } 5835 } 5836 else 5837 { 5838 // rangeChk = smsatAddNComparebit64(LBA, TL); 5839 5840 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 5841 5842 5843 if (AllChk) 5844 { 5845 SM_DBG1(("smsatRead16: return LBA out of range, EXT!!!\n")); 5846 smsatSetSensePayload( pSense, 5847 SCSI_SNSKEY_ILLEGAL_REQUEST, 5848 0, 5849 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 5850 satIOContext); 5851 5852 /*smEnqueueIO(smRoot, satIOContext);*/ 5853 5854 tdsmIOCompletedCB( smRoot, 5855 smIORequest, 5856 smIOSuccess, 5857 SCSI_STAT_CHECK_CONDITION, 5858 satIOContext->pSmSenseData, 5859 satIOContext->interruptContext ); 5860 5861 return SM_RC_SUCCESS; 5862 } 5863 } 5864 5865 /* case 1 and 2 */ 5866 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 5867 { 5868 /* case 2 */ 5869 /* READ DMA*/ 5870 /* in case that we can't fit the transfer length, 5871 we need to make it fit by sending multiple ATA cmnds */ 5872 SM_DBG5(("smsatRead16: case 2\n")); 5873 5874 5875 fis->h.fisType = 0x27; /* Reg host to device */ 5876 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5877 fis->h.command = SAT_READ_DMA; /* 0xC8 */ 5878 fis->h.features = 0; /* FIS reserve */ 5879 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 5880 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 5881 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 5882 fis->d.device = 5883 (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 5884 fis->d.lbaLowExp = 0; 5885 fis->d.lbaMidExp = 0; 5886 fis->d.lbaHighExp = 0; 5887 fis->d.featuresExp = 0; 5888 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 5889 fis->d.sectorCountExp = 0; 5890 fis->d.reserved4 = 0; 5891 fis->d.control = 0; /* FIS HOB bit clear */ 5892 fis->d.reserved5 = 0; 5893 5894 5895 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 5896 satIOContext->ATACmd = SAT_READ_DMA; 5897 } 5898 else 5899 { 5900 /* case 1 */ 5901 /* READ MULTIPLE or READ SECTOR(S) */ 5902 /* READ SECTORS for easier implemetation */ 5903 /* can't fit the transfer length but need to make it fit by sending multiple*/ 5904 SM_DBG5(("smsatRead16: case 1\n")); 5905 5906 fis->h.fisType = 0x27; /* Reg host to device */ 5907 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5908 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 5909 fis->h.features = 0; /* FIS reserve */ 5910 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 5911 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 5912 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 5913 fis->d.device = 5914 (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 5915 fis->d.lbaLowExp = 0; 5916 fis->d.lbaMidExp = 0; 5917 fis->d.lbaHighExp = 0; 5918 fis->d.featuresExp = 0; 5919 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 5920 fis->d.sectorCountExp = 0; 5921 fis->d.reserved4 = 0; 5922 fis->d.control = 0; /* FIS HOB bit clear */ 5923 fis->d.reserved5 = 0; 5924 5925 5926 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 5927 satIOContext->ATACmd = SAT_READ_SECTORS; 5928 } 5929 5930 /* case 3 and 4 */ 5931 if (pSatDevData->sat48BitSupport == agTRUE) 5932 { 5933 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 5934 { 5935 /* case 3 */ 5936 /* READ DMA EXT */ 5937 SM_DBG5(("smsatRead16: case 3\n")); 5938 fis->h.fisType = 0x27; /* Reg host to device */ 5939 5940 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5941 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */ 5942 fis->h.features = 0; /* FIS reserve */ 5943 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 5944 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 5945 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 5946 fis->d.device = 0x40; /* FIS LBA mode set */ 5947 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 5948 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 5949 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 5950 fis->d.featuresExp = 0; /* FIS reserve */ 5951 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 5952 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 5953 fis->d.reserved4 = 0; 5954 fis->d.control = 0; /* FIS HOB bit clear */ 5955 fis->d.reserved5 = 0; 5956 5957 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 5958 satIOContext->ATACmd = SAT_READ_DMA_EXT; 5959 5960 } 5961 else 5962 { 5963 /* case 4 */ 5964 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/ 5965 /* READ SECTORS EXT for easier implemetation */ 5966 SM_DBG5(("smsatRead16: case 4\n")); 5967 fis->h.fisType = 0x27; /* Reg host to device */ 5968 fis->h.c_pmPort = 0x80; /* C Bit is set */ 5969 5970 /* Check FUA bit */ 5971 if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK) 5972 { 5973 /* for now, no support for FUA */ 5974 smsatSetSensePayload( pSense, 5975 SCSI_SNSKEY_ILLEGAL_REQUEST, 5976 0, 5977 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 5978 satIOContext); 5979 5980 /*smEnqueueIO(smRoot, satIOContext);*/ 5981 5982 tdsmIOCompletedCB( smRoot, 5983 smIORequest, 5984 smIOSuccess, 5985 SCSI_STAT_CHECK_CONDITION, 5986 satIOContext->pSmSenseData, 5987 satIOContext->interruptContext ); 5988 return SM_RC_SUCCESS; 5989 } 5990 5991 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 5992 5993 fis->h.features = 0; /* FIS reserve */ 5994 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 5995 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 5996 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 5997 fis->d.device = 0x40; /* FIS LBA mode set */ 5998 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 5999 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 6000 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 6001 fis->d.featuresExp = 0; /* FIS reserve */ 6002 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 6003 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 6004 fis->d.reserved4 = 0; 6005 fis->d.control = 0; /* FIS HOB bit clear */ 6006 fis->d.reserved5 = 0; 6007 6008 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 6009 satIOContext->ATACmd = SAT_READ_SECTORS_EXT; 6010 } 6011 } 6012 6013 6014 /* case 5 */ 6015 if (pSatDevData->satNCQ == agTRUE) 6016 { 6017 /* READ FPDMA QUEUED */ 6018 if (pSatDevData->sat48BitSupport != agTRUE) 6019 { 6020 SM_DBG1(("smsatRead16: case 5 !!! error NCQ but 28 bit address support!!!\n")); 6021 smsatSetSensePayload( pSense, 6022 SCSI_SNSKEY_ILLEGAL_REQUEST, 6023 0, 6024 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6025 satIOContext); 6026 6027 /*smEnqueueIO(smRoot, satIOContext);*/ 6028 6029 tdsmIOCompletedCB( smRoot, 6030 smIORequest, 6031 smIOSuccess, 6032 SCSI_STAT_CHECK_CONDITION, 6033 satIOContext->pSmSenseData, 6034 satIOContext->interruptContext ); 6035 return SM_RC_SUCCESS; 6036 } 6037 6038 SM_DBG6(("smsatRead16: case 5\n")); 6039 6040 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */ 6041 6042 fis->h.fisType = 0x27; /* Reg host to device */ 6043 fis->h.c_pmPort = 0x80; /* C Bit is set */ 6044 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */ 6045 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 6046 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 6047 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 6048 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 6049 6050 /* Check FUA bit */ 6051 if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK) 6052 fis->d.device = 0xC0; /* FIS FUA set */ 6053 else 6054 fis->d.device = 0x40; /* FIS FUA clear */ 6055 6056 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 6057 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 6058 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 6059 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 6060 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 6061 fis->d.sectorCountExp = 0; 6062 fis->d.reserved4 = 0; 6063 fis->d.control = 0; /* FIS HOB bit clear */ 6064 fis->d.reserved5 = 0; 6065 6066 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ; 6067 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED; 6068 } 6069 6070 /* saves the current LBA and orginal TL */ 6071 satIOContext->currentLBA = lba; 6072 satIOContext->OrgTL = tl; 6073 6074 /* 6075 computing number of loop and remainder for tl 6076 0xFF in case not ext 6077 0xFFFF in case EXT 6078 */ 6079 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 6080 { 6081 LoopNum = smsatComputeLoopNum(tl, 0xFF); 6082 } 6083 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 6084 { 6085 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 6086 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 6087 } 6088 else 6089 { 6090 /* SAT_READ_FPDMA_QUEUEDK */ 6091 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 6092 } 6093 satIOContext->LoopNum = LoopNum; 6094 6095 if (LoopNum == 1) 6096 { 6097 SM_DBG5(("smsatRead16: NON CHAINED data\n")); 6098 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB; 6099 } 6100 else 6101 { 6102 SM_DBG1(("smsatRead16: CHAINED data!!!\n")); 6103 /* re-setting tl */ 6104 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA) 6105 { 6106 fis->d.sectorCount = 0xFF; 6107 } 6108 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT) 6109 { 6110 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 6111 fis->d.sectorCount = 0xFF; 6112 fis->d.sectorCountExp = 0xFF; 6113 } 6114 else 6115 { 6116 /* SAT_READ_FPDMA_QUEUED */ 6117 fis->h.features = 0xFF; 6118 fis->d.featuresExp = 0xFF; 6119 } 6120 6121 /* chained data */ 6122 satIOContext->satCompleteCB = &smsatChainedDataIOCB; 6123 } 6124 6125 /* 6126 * Prepare SGL and send FIS to LL layer. 6127 */ 6128 satIOContext->reqType = agRequestType; /* Save it */ 6129 6130 status = smsataLLIOStart( smRoot, 6131 smIORequest, 6132 smDeviceHandle, 6133 smScsiRequest, 6134 satIOContext); 6135 6136 SM_DBG5(("smsatRead16: return\n")); 6137 return (status); 6138 6139 } 6140 6141 osGLOBAL bit32 6142 smsatWrite6( 6143 smRoot_t *smRoot, 6144 smIORequest_t *smIORequest, 6145 smDeviceHandle_t *smDeviceHandle, 6146 smScsiInitiatorRequest_t *smScsiRequest, 6147 smSatIOContext_t *satIOContext 6148 ) 6149 { 6150 6151 bit32 status; 6152 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 6153 smDeviceData_t *pSatDevData; 6154 smScsiRspSense_t *pSense; 6155 smIniScsiCmnd_t *scsiCmnd; 6156 agsaFisRegHostToDevice_t *fis; 6157 bit32 lba = 0; 6158 bit16 tl = 0; 6159 6160 pSense = satIOContext->pSense; 6161 pSatDevData = satIOContext->pSatDevData; 6162 scsiCmnd = &smScsiRequest->scsiCmnd; 6163 fis = satIOContext->pFis; 6164 6165 SM_DBG5(("smsatWrite6: start\n")); 6166 6167 /* checking CONTROL */ 6168 /* NACA == 1 or LINK == 1*/ 6169 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 6170 { 6171 smsatSetSensePayload( pSense, 6172 SCSI_SNSKEY_ILLEGAL_REQUEST, 6173 0, 6174 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6175 satIOContext); 6176 6177 /*smEnqueueIO(smRoot, satIOContext);*/ 6178 6179 tdsmIOCompletedCB( smRoot, 6180 smIORequest, 6181 smIOSuccess, 6182 SCSI_STAT_CHECK_CONDITION, 6183 satIOContext->pSmSenseData, 6184 satIOContext->interruptContext ); 6185 6186 SM_DBG1(("smsatWrite6: return control!!!\n")); 6187 return SM_RC_SUCCESS; 6188 } 6189 6190 6191 /* cbd6; computing LBA and transfer length */ 6192 lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2)) 6193 + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3]; 6194 tl = scsiCmnd->cdb[4]; 6195 6196 6197 /* Table 34, 9.1, p 46 */ 6198 /* 6199 note: As of 2/10/2006, no support for DMA QUEUED 6200 */ 6201 6202 /* 6203 Table 34, 9.1, p 46, b 6204 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 6205 return check condition 6206 */ 6207 if (pSatDevData->satNCQ != agTRUE && 6208 pSatDevData->sat48BitSupport != agTRUE 6209 ) 6210 { 6211 if (lba > SAT_TR_LBA_LIMIT - 1) 6212 { 6213 smsatSetSensePayload( pSense, 6214 SCSI_SNSKEY_ILLEGAL_REQUEST, 6215 0, 6216 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 6217 satIOContext); 6218 6219 /*smEnqueueIO(smRoot, satIOContext);*/ 6220 6221 tdsmIOCompletedCB( smRoot, 6222 smIORequest, 6223 smIOSuccess, 6224 SCSI_STAT_CHECK_CONDITION, 6225 satIOContext->pSmSenseData, 6226 satIOContext->interruptContext ); 6227 6228 SM_DBG1(("smsatWrite6: return LBA out of range!!!\n")); 6229 return SM_RC_SUCCESS; 6230 } 6231 } 6232 6233 /* case 1 and 2 */ 6234 if (lba + tl <= SAT_TR_LBA_LIMIT) 6235 { 6236 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 6237 { 6238 /* case 2 */ 6239 /* WRITE DMA*/ 6240 SM_DBG5(("smsatWrite6: case 2\n")); 6241 6242 6243 fis->h.fisType = 0x27; /* Reg host to device */ 6244 fis->h.c_pmPort = 0x80; /* C Bit is set */ 6245 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 6246 fis->h.features = 0; /* FIS reserve */ 6247 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 6248 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 6249 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 6250 fis->d.device = 0x40; /* FIS LBA mode */ 6251 fis->d.lbaLowExp = 0; 6252 fis->d.lbaMidExp = 0; 6253 fis->d.lbaHighExp = 0; 6254 fis->d.featuresExp = 0; 6255 if (tl == 0) 6256 { 6257 /* temporary fix */ 6258 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */ 6259 } 6260 else 6261 { 6262 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 6263 } 6264 fis->d.sectorCountExp = 0; 6265 fis->d.reserved4 = 0; 6266 fis->d.control = 0; /* FIS HOB bit clear */ 6267 fis->d.reserved5 = 0; 6268 6269 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 6270 } 6271 else 6272 { 6273 /* case 1 */ 6274 /* WRITE SECTORS for easier implemetation */ 6275 SM_DBG5(("smsatWrite6: case 1\n")); 6276 6277 fis->h.fisType = 0x27; /* Reg host to device */ 6278 fis->h.c_pmPort = 0x80; /* C Bit is set */ 6279 fis->h.command = SAT_WRITE_SECTORS; /* 0xCA */ 6280 fis->h.features = 0; /* FIS reserve */ 6281 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 6282 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 6283 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 6284 fis->d.device = 0x40; /* FIS LBA mode */ 6285 fis->d.lbaLowExp = 0; 6286 fis->d.lbaMidExp = 0; 6287 fis->d.lbaHighExp = 0; 6288 fis->d.featuresExp = 0; 6289 if (tl == 0) 6290 { 6291 /* temporary fix */ 6292 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */ 6293 } 6294 else 6295 { 6296 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 6297 } 6298 fis->d.sectorCountExp = 0; 6299 fis->d.reserved4 = 0; 6300 fis->d.control = 0; /* FIS HOB bit clear */ 6301 fis->d.reserved5 = 0; 6302 6303 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 6304 6305 } 6306 } 6307 6308 /* case 3 and 4 */ 6309 if (pSatDevData->sat48BitSupport == agTRUE) 6310 { 6311 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 6312 { 6313 /* case 3 */ 6314 /* WRITE DMA EXT only */ 6315 SM_DBG5(("smsatWrite6: case 3\n")); 6316 fis->h.fisType = 0x27; /* Reg host to device */ 6317 fis->h.c_pmPort = 0x80; /* C Bit is set */ 6318 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 6319 fis->h.features = 0; /* FIS reserve */ 6320 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 6321 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 6322 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 6323 fis->d.device = 0x40; /* FIS LBA mode set */ 6324 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 6325 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 6326 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 6327 fis->d.featuresExp = 0; /* FIS reserve */ 6328 if (tl == 0) 6329 { 6330 /* sector count is 256, 0x100*/ 6331 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 6332 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */ 6333 } 6334 else 6335 { 6336 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 6337 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 6338 } 6339 fis->d.reserved4 = 0; 6340 fis->d.control = 0; /* FIS HOB bit clear */ 6341 fis->d.reserved5 = 0; 6342 6343 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 6344 } 6345 else 6346 { 6347 /* case 4 */ 6348 /* WRITE SECTORS EXT for easier implemetation */ 6349 SM_DBG5(("smsatWrite6: case 4\n")); 6350 6351 fis->h.fisType = 0x27; /* Reg host to device */ 6352 fis->h.c_pmPort = 0x80; /* C Bit is set */ 6353 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 6354 fis->h.features = 0; /* FIS reserve */ 6355 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 6356 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 6357 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 6358 fis->d.device = 0x40; /* FIS LBA mode set */ 6359 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 6360 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 6361 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 6362 fis->d.featuresExp = 0; /* FIS reserve */ 6363 if (tl == 0) 6364 { 6365 /* sector count is 256, 0x100*/ 6366 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 6367 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */ 6368 } 6369 else 6370 { 6371 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 6372 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 6373 } 6374 fis->d.reserved4 = 0; 6375 fis->d.control = 0; /* FIS HOB bit clear */ 6376 fis->d.reserved5 = 0; 6377 6378 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 6379 } 6380 } 6381 6382 /* case 5 */ 6383 if (pSatDevData->satNCQ == agTRUE) 6384 { 6385 /* WRITE FPDMA QUEUED */ 6386 if (pSatDevData->sat48BitSupport != agTRUE) 6387 { 6388 /* sanity check */ 6389 SM_DBG5(("smsatWrite6: case 5 !!! error NCQ but 28 bit address support!!!\n")); 6390 smsatSetSensePayload( pSense, 6391 SCSI_SNSKEY_ILLEGAL_REQUEST, 6392 0, 6393 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6394 satIOContext); 6395 6396 /*smEnqueueIO(smRoot, satIOContext);*/ 6397 6398 tdsmIOCompletedCB( smRoot, 6399 smIORequest, 6400 smIOSuccess, 6401 SCSI_STAT_CHECK_CONDITION, 6402 satIOContext->pSmSenseData, 6403 satIOContext->interruptContext ); 6404 return SM_RC_SUCCESS; 6405 } 6406 SM_DBG5(("smsatWrite6: case 5\n")); 6407 6408 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 6409 6410 fis->h.fisType = 0x27; /* Reg host to device */ 6411 fis->h.c_pmPort = 0x80; /* C Bit is set */ 6412 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 6413 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */ 6414 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */ 6415 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */ 6416 fis->d.device = 0x40; /* FIS FUA clear */ 6417 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 6418 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 6419 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 6420 if (tl == 0) 6421 { 6422 /* sector count is 256, 0x100*/ 6423 fis->h.features = 0; /* FIS sector count (7:0) */ 6424 fis->d.featuresExp = 0x01; /* FIS sector count (15:8) */ 6425 } 6426 else 6427 { 6428 fis->h.features = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */ 6429 fis->d.featuresExp = 0; /* FIS sector count (15:8) */ 6430 } 6431 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 6432 fis->d.sectorCountExp = 0; 6433 fis->d.reserved4 = 0; 6434 fis->d.control = 0; /* FIS HOB bit clear */ 6435 fis->d.reserved5 = 0; 6436 6437 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 6438 } 6439 6440 /* Initialize CB for SATA completion. 6441 */ 6442 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB; 6443 6444 /* 6445 * Prepare SGL and send FIS to LL layer. 6446 */ 6447 satIOContext->reqType = agRequestType; /* Save it */ 6448 6449 status = smsataLLIOStart( smRoot, 6450 smIORequest, 6451 smDeviceHandle, 6452 smScsiRequest, 6453 satIOContext); 6454 return (status); 6455 } 6456 6457 osGLOBAL FORCEINLINE bit32 6458 smsatWrite10( 6459 smRoot_t *smRoot, 6460 smIORequest_t *smIORequest, 6461 smDeviceHandle_t *smDeviceHandle, 6462 smScsiInitiatorRequest_t *smScsiRequest, 6463 smSatIOContext_t *satIOContext 6464 ) 6465 { 6466 smDeviceData_t *pSatDevData = satIOContext->pSatDevData; 6467 smScsiRspSense_t *pSense = satIOContext->pSense; 6468 smIniScsiCmnd_t *scsiCmnd = &smScsiRequest->scsiCmnd; 6469 agsaFisRegHostToDevice_t *fis = satIOContext->pFis; 6470 bit32 status = SM_RC_FAILURE; 6471 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 6472 bit32 lba = 0; 6473 bit32 tl = 0; 6474 bit32 LoopNum = 1; 6475 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 6476 bit8 LBA[8]; 6477 bit8 TL[8]; 6478 6479 SM_DBG2(("smsatWrite10: start\n")); 6480 6481 /* checking FUA_NV */ 6482 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 6483 { 6484 smsatSetSensePayload( pSense, 6485 SCSI_SNSKEY_ILLEGAL_REQUEST, 6486 0, 6487 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6488 satIOContext); 6489 6490 /*smEnqueueIO(smRoot, satIOContext);*/ 6491 6492 tdsmIOCompletedCB( smRoot, 6493 smIORequest, 6494 smIOSuccess, 6495 SCSI_STAT_CHECK_CONDITION, 6496 satIOContext->pSmSenseData, 6497 satIOContext->interruptContext ); 6498 6499 SM_DBG1(("smsatWrite10: return FUA_NV!!!\n")); 6500 return SM_RC_SUCCESS; 6501 6502 } 6503 6504 /* checking CONTROL */ 6505 /* NACA == 1 or LINK == 1*/ 6506 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 6507 { 6508 smsatSetSensePayload( pSense, 6509 SCSI_SNSKEY_ILLEGAL_REQUEST, 6510 0, 6511 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6512 satIOContext); 6513 6514 /*smEnqueueIO(smRoot, satIOContext);*/ 6515 6516 tdsmIOCompletedCB( smRoot, 6517 smIORequest, 6518 smIOSuccess, 6519 SCSI_STAT_CHECK_CONDITION, 6520 satIOContext->pSmSenseData, 6521 satIOContext->interruptContext ); 6522 6523 SM_DBG1(("smsatWrite10: return control!!!\n")); 6524 return SM_RC_SUCCESS; 6525 } 6526 /* 6527 sm_memset(LBA, 0, sizeof(LBA)); 6528 sm_memset(TL, 0, sizeof(TL)); 6529 */ 6530 /* do not use memcpy due to indexing in LBA and TL */ 6531 LBA[0] = 0; /* MSB */ 6532 LBA[1] = 0; 6533 LBA[2] = 0; 6534 LBA[3] = 0; 6535 LBA[4] = scsiCmnd->cdb[2]; 6536 LBA[5] = scsiCmnd->cdb[3]; 6537 LBA[6] = scsiCmnd->cdb[4]; 6538 LBA[7] = scsiCmnd->cdb[5]; /* LSB */ 6539 6540 TL[0] = 0; 6541 TL[1] = 0; 6542 TL[2] = 0; 6543 TL[3] = 0; 6544 TL[4] = 0; 6545 TL[5] = 0; 6546 TL[6] = scsiCmnd->cdb[7]; 6547 TL[7] = scsiCmnd->cdb[8]; /* LSB */ 6548 6549 6550 6551 /* cbd10; computing LBA and transfer length */ 6552 lba = (scsiCmnd->cdb[2] << (24)) + (scsiCmnd->cdb[3] << (16)) 6553 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 6554 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 6555 6556 SM_DBG5(("smsatWrite10: lba %d functioned lba %d\n", lba, smsatComputeCDB10LBA(satIOContext))); 6557 SM_DBG5(("smsatWrite10: tl %d functioned tl %d\n", tl, smsatComputeCDB10TL(satIOContext))); 6558 6559 /* Table 34, 9.1, p 46 */ 6560 /* 6561 note: As of 2/10/2006, no support for DMA QUEUED 6562 */ 6563 6564 /* 6565 Table 34, 9.1, p 46, b 6566 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 6567 return check condition 6568 */ 6569 if (pSatDevData->satNCQ != agTRUE && 6570 pSatDevData->sat48BitSupport != agTRUE 6571 ) 6572 { 6573 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 6574 if (AllChk) 6575 { 6576 SM_DBG1(("smsatWrite10: return LBA out of range, not EXT!!!\n")); 6577 SM_DBG1(("smsatWrite10: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3], 6578 scsiCmnd->cdb[4], scsiCmnd->cdb[5])); 6579 SM_DBG1(("smsatWrite10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT)); 6580 smsatSetSensePayload( pSense, 6581 SCSI_SNSKEY_ILLEGAL_REQUEST, 6582 0, 6583 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 6584 satIOContext); 6585 6586 /*smEnqueueIO(smRoot, satIOContext);*/ 6587 6588 tdsmIOCompletedCB( smRoot, 6589 smIORequest, 6590 smIOSuccess, 6591 SCSI_STAT_CHECK_CONDITION, 6592 satIOContext->pSmSenseData, 6593 satIOContext->interruptContext ); 6594 6595 return SM_RC_SUCCESS; 6596 } 6597 } 6598 else 6599 { 6600 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 6601 if (AllChk) 6602 { 6603 SM_DBG1(("smsatWrite10: return LBA out of range, EXT!!!\n")); 6604 smsatSetSensePayload( pSense, 6605 SCSI_SNSKEY_ILLEGAL_REQUEST, 6606 0, 6607 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 6608 satIOContext); 6609 6610 /*smEnqueueIO(smRoot, satIOContext);*/ 6611 6612 tdsmIOCompletedCB( smRoot, 6613 smIORequest, 6614 smIOSuccess, 6615 SCSI_STAT_CHECK_CONDITION, 6616 satIOContext->pSmSenseData, 6617 satIOContext->interruptContext ); 6618 6619 return SM_RC_SUCCESS; 6620 } 6621 6622 } 6623 6624 /* case 5 */ 6625 if (pSatDevData->satNCQ == agTRUE) 6626 { 6627 /* WRITE FPDMA QUEUED */ 6628 if (pSatDevData->sat48BitSupport != agTRUE) 6629 { 6630 SM_DBG1(("smsatWrite10: case 5 !!! error NCQ but 28 bit address support!!!\n")); 6631 smsatSetSensePayload( pSense, 6632 SCSI_SNSKEY_ILLEGAL_REQUEST, 6633 0, 6634 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6635 satIOContext); 6636 6637 /*smEnqueueIO(smRoot, satIOContext);*/ 6638 6639 tdsmIOCompletedCB( smRoot, 6640 smIORequest, 6641 smIOSuccess, 6642 SCSI_STAT_CHECK_CONDITION, 6643 satIOContext->pSmSenseData, 6644 satIOContext->interruptContext ); 6645 return SM_RC_SUCCESS; 6646 } 6647 SM_DBG6(("smsatWrite10: case 5\n")); 6648 6649 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 6650 6651 fis->h.fisType = 0x27; /* Reg host to device */ 6652 fis->h.c_pmPort = 0x80; /* C Bit is set */ 6653 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 6654 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 6655 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 6656 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 6657 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 6658 6659 /* Check FUA bit */ 6660 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK) 6661 fis->d.device = 0xC0; /* FIS FUA set */ 6662 else 6663 fis->d.device = 0x40; /* FIS FUA clear */ 6664 6665 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 6666 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 6667 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 6668 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 6669 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 6670 fis->d.sectorCountExp = 0; 6671 fis->d.reserved4 = 0; 6672 fis->d.control = 0; /* FIS HOB bit clear */ 6673 fis->d.reserved5 = 0; 6674 6675 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 6676 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 6677 } 6678 /* case 3 and 4 */ 6679 else if (pSatDevData->sat48BitSupport == agTRUE) 6680 { 6681 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 6682 { 6683 /* case 3 */ 6684 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 6685 SM_DBG5(("smsatWrite10: case 3\n")); 6686 fis->h.fisType = 0x27; /* Reg host to device */ 6687 fis->h.c_pmPort = 0x80; /* C Bit is set */ 6688 6689 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 6690 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 6691 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 6692 6693 fis->h.features = 0; /* FIS reserve */ 6694 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 6695 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 6696 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 6697 fis->d.device = 0x40; /* FIS LBA mode set */ 6698 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 6699 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 6700 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 6701 fis->d.featuresExp = 0; /* FIS reserve */ 6702 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 6703 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 6704 fis->d.reserved4 = 0; 6705 fis->d.control = 0; /* FIS HOB bit clear */ 6706 fis->d.reserved5 = 0; 6707 6708 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 6709 } 6710 else 6711 { 6712 /* case 4 */ 6713 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 6714 /* WRITE SECTORS EXT for easier implemetation */ 6715 SM_DBG5(("smsatWrite10: case 4\n")); 6716 fis->h.fisType = 0x27; /* Reg host to device */ 6717 fis->h.c_pmPort = 0x80; /* C Bit is set */ 6718 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 6719 6720 fis->h.features = 0; /* FIS reserve */ 6721 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 6722 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 6723 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 6724 fis->d.device = 0x40; /* FIS LBA mode set */ 6725 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 6726 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 6727 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 6728 fis->d.featuresExp = 0; /* FIS reserve */ 6729 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 6730 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 6731 fis->d.reserved4 = 0; 6732 fis->d.control = 0; /* FIS HOB bit clear */ 6733 fis->d.reserved5 = 0; 6734 6735 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 6736 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 6737 } 6738 } 6739 else /* case 1 and 2 */ 6740 { 6741 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 6742 { 6743 /* case 2 */ 6744 /* WRITE DMA*/ 6745 /* can't fit the transfer length */ 6746 SM_DBG5(("smsatWrite10: case 2\n")); 6747 fis->h.fisType = 0x27; /* Reg host to device */ 6748 fis->h.c_pmPort = 0x80; /* C bit is set */ 6749 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 6750 fis->h.features = 0; /* FIS reserve */ 6751 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 6752 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 6753 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 6754 6755 /* FIS LBA mode set LBA (27:24) */ 6756 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 6757 6758 fis->d.lbaLowExp = 0; 6759 fis->d.lbaMidExp = 0; 6760 fis->d.lbaHighExp = 0; 6761 fis->d.featuresExp = 0; 6762 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 6763 fis->d.sectorCountExp = 0; 6764 fis->d.reserved4 = 0; 6765 fis->d.control = 0; /* FIS HOB bit clear */ 6766 fis->d.reserved5 = 0; 6767 6768 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 6769 satIOContext->ATACmd = SAT_WRITE_DMA; 6770 } 6771 else 6772 { 6773 /* case 1 */ 6774 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 6775 /* WRITE SECTORS for easier implemetation */ 6776 /* can't fit the transfer length */ 6777 SM_DBG5(("smsatWrite10: case 1\n")); 6778 fis->h.fisType = 0x27; /* Reg host to device */ 6779 fis->h.c_pmPort = 0x80; /* C bit is set */ 6780 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 6781 fis->h.features = 0; /* FIS reserve */ 6782 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 6783 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 6784 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 6785 6786 /* FIS LBA mode set LBA (27:24) */ 6787 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 6788 6789 fis->d.lbaLowExp = 0; 6790 fis->d.lbaMidExp = 0; 6791 fis->d.lbaHighExp = 0; 6792 fis->d.featuresExp = 0; 6793 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 6794 fis->d.sectorCountExp = 0; 6795 fis->d.reserved4 = 0; 6796 fis->d.control = 0; /* FIS HOB bit clear */ 6797 fis->d.reserved5 = 0; 6798 6799 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 6800 satIOContext->ATACmd = SAT_WRITE_SECTORS; 6801 } 6802 } 6803 6804 // smhexdump("satWrite10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t)); 6805 6806 satIOContext->currentLBA = lba; 6807 satIOContext->OrgTL = tl; 6808 6809 /* 6810 computing number of loop and remainder for tl 6811 0xFF in case not ext 6812 0xFFFF in case EXT 6813 */ 6814 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 6815 { 6816 LoopNum = smsatComputeLoopNum(tl, 0x100); 6817 } 6818 else 6819 { 6820 /* SAT_WRITE_FPDMA_QUEUEDK */ 6821 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 6822 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 6823 } 6824 6825 satIOContext->LoopNum = LoopNum; 6826 6827 6828 if (LoopNum == 1) 6829 { 6830 SM_DBG5(("smsatWrite10: NON CHAINED data\n")); 6831 /* Initialize CB for SATA completion. 6832 */ 6833 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB; 6834 } 6835 else 6836 { 6837 SM_DBG2(("smsatWrite10: CHAINED data!!!\n")); 6838 /* re-setting tl */ 6839 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 6840 { 6841 fis->d.sectorCount = 0x0; 6842 smsatSplitSGL(smRoot, 6843 smIORequest, 6844 smDeviceHandle, 6845 smScsiRequest, 6846 satIOContext, 6847 NON_BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0x100 * 0x200 */ 6848 (satIOContext->OrgTL)*SATA_SECTOR_SIZE, 6849 agTRUE); 6850 } 6851 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 6852 fis->h.command == SAT_WRITE_DMA_EXT || 6853 fis->h.command == SAT_WRITE_DMA_FUA_EXT 6854 ) 6855 { 6856 fis->d.sectorCount = 0xFF; 6857 fis->d.sectorCountExp = 0xFF; 6858 smsatSplitSGL(smRoot, 6859 smIORequest, 6860 smDeviceHandle, 6861 smScsiRequest, 6862 satIOContext, 6863 BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */ 6864 (satIOContext->OrgTL)*SATA_SECTOR_SIZE, 6865 agTRUE); 6866 } 6867 else 6868 { 6869 /* SAT_WRITE_FPDMA_QUEUED */ 6870 fis->h.features = 0xFF; 6871 fis->d.featuresExp = 0xFF; 6872 smsatSplitSGL(smRoot, 6873 smIORequest, 6874 smDeviceHandle, 6875 smScsiRequest, 6876 satIOContext, 6877 BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */ 6878 (satIOContext->OrgTL)*SATA_SECTOR_SIZE, 6879 agTRUE); 6880 } 6881 6882 /* Initialize CB for SATA completion. 6883 */ 6884 satIOContext->satCompleteCB = &smsatChainedDataIOCB; 6885 } 6886 6887 6888 /* 6889 * Prepare SGL and send FIS to LL layer. 6890 */ 6891 satIOContext->reqType = agRequestType; /* Save it */ 6892 6893 status = smsataLLIOStart( smRoot, 6894 smIORequest, 6895 smDeviceHandle, 6896 smScsiRequest, 6897 satIOContext); 6898 return (status); 6899 } 6900 6901 osGLOBAL bit32 6902 smsatWrite12( 6903 smRoot_t *smRoot, 6904 smIORequest_t *smIORequest, 6905 smDeviceHandle_t *smDeviceHandle, 6906 smScsiInitiatorRequest_t *smScsiRequest, 6907 smSatIOContext_t *satIOContext 6908 ) 6909 { 6910 bit32 status; 6911 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 6912 smDeviceData_t *pSatDevData; 6913 smScsiRspSense_t *pSense; 6914 smIniScsiCmnd_t *scsiCmnd; 6915 agsaFisRegHostToDevice_t *fis; 6916 bit32 lba = 0; 6917 bit32 tl = 0; 6918 bit32 LoopNum = 1; 6919 bit8 LBA[8]; 6920 bit8 TL[8]; 6921 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 6922 6923 pSense = satIOContext->pSense; 6924 pSatDevData = satIOContext->pSatDevData; 6925 scsiCmnd = &smScsiRequest->scsiCmnd; 6926 fis = satIOContext->pFis; 6927 6928 SM_DBG5(("smsatWrite12: start\n")); 6929 6930 /* checking FUA_NV */ 6931 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 6932 { 6933 smsatSetSensePayload( pSense, 6934 SCSI_SNSKEY_ILLEGAL_REQUEST, 6935 0, 6936 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6937 satIOContext); 6938 6939 /*smEnqueueIO(smRoot, satIOContext);*/ 6940 6941 tdsmIOCompletedCB( smRoot, 6942 smIORequest, 6943 smIOSuccess, 6944 SCSI_STAT_CHECK_CONDITION, 6945 satIOContext->pSmSenseData, 6946 satIOContext->interruptContext ); 6947 6948 SM_DBG1(("smsatWrite12: return FUA_NV!!!\n")); 6949 return SM_RC_SUCCESS; 6950 6951 } 6952 6953 6954 /* checking CONTROL */ 6955 /* NACA == 1 or LINK == 1*/ 6956 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) ) 6957 { 6958 smsatSetSensePayload( pSense, 6959 SCSI_SNSKEY_ILLEGAL_REQUEST, 6960 0, 6961 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 6962 satIOContext); 6963 6964 /*smEnqueueIO(smRoot, satIOContext);*/ 6965 6966 tdsmIOCompletedCB( smRoot, 6967 smIORequest, 6968 smIOSuccess, 6969 SCSI_STAT_CHECK_CONDITION, 6970 satIOContext->pSmSenseData, 6971 satIOContext->interruptContext ); 6972 6973 SM_DBG1(("smsatWrite10: return control!!!\n")); 6974 return SM_RC_SUCCESS; 6975 } 6976 6977 6978 sm_memset(LBA, 0, sizeof(LBA)); 6979 sm_memset(TL, 0, sizeof(TL)); 6980 6981 /* do not use memcpy due to indexing in LBA and TL */ 6982 LBA[0] = 0; /* MSB */ 6983 LBA[1] = 0; 6984 LBA[2] = 0; 6985 LBA[3] = 0; 6986 LBA[4] = scsiCmnd->cdb[2]; 6987 LBA[5] = scsiCmnd->cdb[3]; 6988 LBA[6] = scsiCmnd->cdb[4]; 6989 LBA[7] = scsiCmnd->cdb[5]; /* LSB */ 6990 6991 TL[0] = 0; /* MSB */ 6992 TL[1] = 0; 6993 TL[2] = 0; 6994 TL[3] = 0; 6995 TL[4] = scsiCmnd->cdb[6]; 6996 TL[5] = scsiCmnd->cdb[7]; 6997 TL[6] = scsiCmnd->cdb[8]; 6998 TL[7] = scsiCmnd->cdb[9]; /* LSB */ 6999 7000 7001 lba = smsatComputeCDB12LBA(satIOContext); 7002 tl = smsatComputeCDB12TL(satIOContext); 7003 7004 7005 /* Table 34, 9.1, p 46 */ 7006 /* 7007 note: As of 2/10/2006, no support for DMA QUEUED 7008 */ 7009 7010 /* 7011 Table 34, 9.1, p 46, b 7012 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 7013 return check condition 7014 */ 7015 if (pSatDevData->satNCQ != agTRUE && 7016 pSatDevData->sat48BitSupport != agTRUE 7017 ) 7018 { 7019 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 7020 7021 /*smEnqueueIO(smRoot, satIOContext);*/ 7022 7023 7024 7025 if (AllChk) 7026 { 7027 SM_DBG1(("smsatWrite12: return LBA out of range, not EXT!!!\n")); 7028 smsatSetSensePayload( pSense, 7029 SCSI_SNSKEY_ILLEGAL_REQUEST, 7030 0, 7031 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 7032 satIOContext); 7033 7034 /*smEnqueueIO(smRoot, satIOContext);*/ 7035 7036 tdsmIOCompletedCB( smRoot, 7037 smIORequest, 7038 smIOSuccess, 7039 SCSI_STAT_CHECK_CONDITION, 7040 satIOContext->pSmSenseData, 7041 satIOContext->interruptContext ); 7042 7043 return SM_RC_SUCCESS; 7044 } 7045 } 7046 else 7047 { 7048 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 7049 if (AllChk) 7050 { 7051 SM_DBG1(("smsatWrite12: return LBA out of range, EXT!!!\n")); 7052 smsatSetSensePayload( pSense, 7053 SCSI_SNSKEY_ILLEGAL_REQUEST, 7054 0, 7055 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 7056 satIOContext); 7057 tdsmIOCompletedCB( smRoot, 7058 smIORequest, 7059 smIOSuccess, 7060 SCSI_STAT_CHECK_CONDITION, 7061 satIOContext->pSmSenseData, 7062 satIOContext->interruptContext ); 7063 return SM_RC_SUCCESS; 7064 } 7065 } 7066 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 7067 { 7068 /* case 2 */ 7069 /* WRITE DMA*/ 7070 /* In case that we can't fit the transfer length, we loop */ 7071 SM_DBG5(("smsatWrite10: case 2\n")); 7072 fis->h.fisType = 0x27; /* Reg host to device */ 7073 fis->h.c_pmPort = 0x80; /* C bit is set */ 7074 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 7075 fis->h.features = 0; /* FIS reserve */ 7076 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 7077 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 7078 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 7079 7080 /* FIS LBA mode set LBA (27:24) */ 7081 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 7082 7083 fis->d.lbaLowExp = 0; 7084 fis->d.lbaMidExp = 0; 7085 fis->d.lbaHighExp = 0; 7086 fis->d.featuresExp = 0; 7087 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 7088 fis->d.sectorCountExp = 0; 7089 fis->d.reserved4 = 0; 7090 fis->d.control = 0; /* FIS HOB bit clear */ 7091 fis->d.reserved5 = 0; 7092 7093 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 7094 satIOContext->ATACmd = SAT_WRITE_DMA; 7095 } 7096 else 7097 { 7098 /* case 1 */ 7099 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 7100 /* WRITE SECTORS for easier implemetation */ 7101 /* In case that we can't fit the transfer length, we loop */ 7102 SM_DBG5(("smsatWrite10: case 1\n")); 7103 fis->h.fisType = 0x27; /* Reg host to device */ 7104 fis->h.c_pmPort = 0x80; /* C bit is set */ 7105 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 7106 fis->h.features = 0; /* FIS reserve */ 7107 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 7108 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 7109 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 7110 7111 /* FIS LBA mode set LBA (27:24) */ 7112 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 7113 7114 fis->d.lbaLowExp = 0; 7115 fis->d.lbaMidExp = 0; 7116 fis->d.lbaHighExp = 0; 7117 fis->d.featuresExp = 0; 7118 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 7119 fis->d.sectorCountExp = 0; 7120 fis->d.reserved4 = 0; 7121 fis->d.control = 0; /* FIS HOB bit clear */ 7122 fis->d.reserved5 = 0; 7123 7124 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 7125 satIOContext->ATACmd = SAT_WRITE_SECTORS; 7126 } 7127 7128 /* case 3 and 4 */ 7129 if (pSatDevData->sat48BitSupport == agTRUE) 7130 { 7131 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 7132 { 7133 /* case 3 */ 7134 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 7135 SM_DBG5(("smsatWrite10: case 3\n")); 7136 fis->h.fisType = 0x27; /* Reg host to device */ 7137 fis->h.c_pmPort = 0x80; /* C Bit is set */ 7138 7139 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 7140 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 7141 7142 fis->h.features = 0; /* FIS reserve */ 7143 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 7144 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 7145 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 7146 fis->d.device = 0x40; /* FIS LBA mode set */ 7147 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 7148 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 7149 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 7150 fis->d.featuresExp = 0; /* FIS reserve */ 7151 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 7152 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 7153 fis->d.reserved4 = 0; 7154 fis->d.control = 0; /* FIS HOB bit clear */ 7155 fis->d.reserved5 = 0; 7156 7157 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 7158 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 7159 } 7160 else 7161 { 7162 /* case 4 */ 7163 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 7164 /* WRITE SECTORS EXT for easier implemetation */ 7165 SM_DBG5(("smsatWrite10: case 4\n")); 7166 fis->h.fisType = 0x27; /* Reg host to device */ 7167 fis->h.c_pmPort = 0x80; /* C Bit is set */ 7168 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 7169 7170 fis->h.features = 0; /* FIS reserve */ 7171 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 7172 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 7173 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 7174 fis->d.device = 0x40; /* FIS LBA mode set */ 7175 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 7176 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 7177 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 7178 fis->d.featuresExp = 0; /* FIS reserve */ 7179 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 7180 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 7181 fis->d.reserved4 = 0; 7182 fis->d.control = 0; /* FIS HOB bit clear */ 7183 fis->d.reserved5 = 0; 7184 7185 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 7186 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 7187 } 7188 } 7189 7190 /* case 5 */ 7191 if (pSatDevData->satNCQ == agTRUE) 7192 { 7193 /* WRITE FPDMA QUEUED */ 7194 if (pSatDevData->sat48BitSupport != agTRUE) 7195 { 7196 SM_DBG5(("smsatWrite10: case 5 !!! error NCQ but 28 bit address support!!!\n")); 7197 smsatSetSensePayload( pSense, 7198 SCSI_SNSKEY_ILLEGAL_REQUEST, 7199 0, 7200 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 7201 satIOContext); 7202 7203 /*smEnqueueIO(smRoot, satIOContext);*/ 7204 7205 tdsmIOCompletedCB( smRoot, 7206 smIORequest, 7207 smIOSuccess, 7208 SCSI_STAT_CHECK_CONDITION, 7209 satIOContext->pSmSenseData, 7210 satIOContext->interruptContext ); 7211 return SM_RC_SUCCESS; 7212 } 7213 SM_DBG6(("smsatWrite10: case 5\n")); 7214 7215 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 7216 7217 fis->h.fisType = 0x27; /* Reg host to device */ 7218 fis->h.c_pmPort = 0x80; /* C Bit is set */ 7219 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 7220 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 7221 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 7222 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 7223 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 7224 7225 /* Check FUA bit */ 7226 if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK) 7227 fis->d.device = 0xC0; /* FIS FUA set */ 7228 else 7229 fis->d.device = 0x40; /* FIS FUA clear */ 7230 7231 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 7232 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 7233 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 7234 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 7235 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 7236 fis->d.sectorCountExp = 0; 7237 fis->d.reserved4 = 0; 7238 fis->d.control = 0; /* FIS HOB bit clear */ 7239 fis->d.reserved5 = 0; 7240 7241 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 7242 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 7243 } 7244 7245 satIOContext->currentLBA = lba; 7246 satIOContext->OrgTL = tl; 7247 7248 /* 7249 computing number of loop and remainder for tl 7250 0xFF in case not ext 7251 0xFFFF in case EXT 7252 */ 7253 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 7254 { 7255 LoopNum = smsatComputeLoopNum(tl, 0xFF); 7256 } 7257 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 7258 fis->h.command == SAT_WRITE_DMA_EXT || 7259 fis->h.command == SAT_WRITE_DMA_FUA_EXT 7260 ) 7261 { 7262 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 7263 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 7264 } 7265 else 7266 { 7267 /* SAT_WRITE_FPDMA_QUEUEDK */ 7268 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 7269 } 7270 7271 satIOContext->LoopNum = LoopNum; 7272 7273 7274 if (LoopNum == 1) 7275 { 7276 SM_DBG5(("smsatWrite10: NON CHAINED data\n")); 7277 /* Initialize CB for SATA completion. 7278 */ 7279 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB; 7280 } 7281 else 7282 { 7283 SM_DBG1(("smsatWrite10: CHAINED data\n")); 7284 /* re-setting tl */ 7285 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 7286 { 7287 fis->d.sectorCount = 0xFF; 7288 } 7289 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 7290 fis->h.command == SAT_WRITE_DMA_EXT || 7291 fis->h.command == SAT_WRITE_DMA_FUA_EXT 7292 ) 7293 { 7294 fis->d.sectorCount = 0xFF; 7295 fis->d.sectorCountExp = 0xFF; 7296 } 7297 else 7298 { 7299 /* SAT_WRITE_FPDMA_QUEUED */ 7300 fis->h.features = 0xFF; 7301 fis->d.featuresExp = 0xFF; 7302 } 7303 7304 /* Initialize CB for SATA completion. 7305 */ 7306 satIOContext->satCompleteCB = &smsatChainedDataIOCB; 7307 } 7308 7309 7310 /* 7311 * Prepare SGL and send FIS to LL layer. 7312 */ 7313 satIOContext->reqType = agRequestType; /* Save it */ 7314 7315 status = smsataLLIOStart( smRoot, 7316 smIORequest, 7317 smDeviceHandle, 7318 smScsiRequest, 7319 satIOContext); 7320 return (status); 7321 } 7322 7323 osGLOBAL bit32 7324 smsatWrite16( 7325 smRoot_t *smRoot, 7326 smIORequest_t *smIORequest, 7327 smDeviceHandle_t *smDeviceHandle, 7328 smScsiInitiatorRequest_t *smScsiRequest, 7329 smSatIOContext_t *satIOContext 7330 ) 7331 { 7332 bit32 status; 7333 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 7334 smDeviceData_t *pSatDevData; 7335 smScsiRspSense_t *pSense; 7336 smIniScsiCmnd_t *scsiCmnd; 7337 agsaFisRegHostToDevice_t *fis; 7338 bit32 lba = 0; 7339 bit32 tl = 0; 7340 bit32 LoopNum = 1; 7341 bit8 LBA[8]; 7342 bit8 TL[8]; 7343 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 7344 7345 pSense = satIOContext->pSense; 7346 pSatDevData = satIOContext->pSatDevData; 7347 scsiCmnd = &smScsiRequest->scsiCmnd; 7348 fis = satIOContext->pFis; 7349 7350 SM_DBG5(("smsatWrite16: start\n")); 7351 7352 /* checking FUA_NV */ 7353 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK) 7354 { 7355 smsatSetSensePayload( pSense, 7356 SCSI_SNSKEY_ILLEGAL_REQUEST, 7357 0, 7358 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 7359 satIOContext); 7360 7361 /*smEnqueueIO(smRoot, satIOContext);*/ 7362 7363 tdsmIOCompletedCB( smRoot, 7364 smIORequest, 7365 smIOSuccess, 7366 SCSI_STAT_CHECK_CONDITION, 7367 satIOContext->pSmSenseData, 7368 satIOContext->interruptContext ); 7369 7370 SM_DBG1(("smsatWrite16: return FUA_NV!!!\n")); 7371 return SM_RC_SUCCESS; 7372 7373 } 7374 7375 /* checking CONTROL */ 7376 /* NACA == 1 or LINK == 1*/ 7377 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 7378 { 7379 smsatSetSensePayload( pSense, 7380 SCSI_SNSKEY_ILLEGAL_REQUEST, 7381 0, 7382 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 7383 satIOContext); 7384 7385 /*smEnqueueIO(smRoot, satIOContext);*/ 7386 7387 tdsmIOCompletedCB( smRoot, 7388 smIORequest, 7389 smIOSuccess, 7390 SCSI_STAT_CHECK_CONDITION, 7391 satIOContext->pSmSenseData, 7392 satIOContext->interruptContext ); 7393 7394 SM_DBG1(("smsatWrite16: return control!!!\n")); 7395 return SM_RC_SUCCESS; 7396 } 7397 7398 7399 sm_memset(LBA, 0, sizeof(LBA)); 7400 sm_memset(TL, 0, sizeof(TL)); 7401 7402 7403 /* do not use memcpy due to indexing in LBA and TL */ 7404 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 7405 LBA[1] = scsiCmnd->cdb[3]; 7406 LBA[2] = scsiCmnd->cdb[4]; 7407 LBA[3] = scsiCmnd->cdb[5]; 7408 LBA[4] = scsiCmnd->cdb[6]; 7409 LBA[5] = scsiCmnd->cdb[7]; 7410 LBA[6] = scsiCmnd->cdb[8]; 7411 LBA[7] = scsiCmnd->cdb[9]; /* LSB */ 7412 7413 TL[0] = 0; 7414 TL[1] = 0; 7415 TL[2] = 0; 7416 TL[3] = 0; 7417 TL[4] = scsiCmnd->cdb[10]; /* MSB */ 7418 TL[5] = scsiCmnd->cdb[11]; 7419 TL[6] = scsiCmnd->cdb[12]; 7420 TL[7] = scsiCmnd->cdb[13]; /* LSB */ 7421 7422 7423 7424 lba = smsatComputeCDB16LBA(satIOContext); 7425 tl = smsatComputeCDB16TL(satIOContext); 7426 7427 7428 7429 /* Table 34, 9.1, p 46 */ 7430 /* 7431 note: As of 2/10/2006, no support for DMA QUEUED 7432 */ 7433 7434 /* 7435 Table 34, 9.1, p 46, b 7436 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 7437 return check condition 7438 */ 7439 if (pSatDevData->satNCQ != agTRUE && 7440 pSatDevData->sat48BitSupport != agTRUE 7441 ) 7442 { 7443 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 7444 if (AllChk) 7445 { 7446 SM_DBG1(("smsatWrite16: return LBA out of range, not EXT!!!\n")); 7447 smsatSetSensePayload( pSense, 7448 SCSI_SNSKEY_ILLEGAL_REQUEST, 7449 0, 7450 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 7451 satIOContext); 7452 7453 /*smEnqueueIO(smRoot, satIOContext);*/ 7454 7455 tdsmIOCompletedCB( smRoot, 7456 smIORequest, 7457 smIOSuccess, 7458 SCSI_STAT_CHECK_CONDITION, 7459 satIOContext->pSmSenseData, 7460 satIOContext->interruptContext ); 7461 7462 return SM_RC_SUCCESS; 7463 } 7464 } 7465 else 7466 { 7467 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 7468 if (AllChk) 7469 { 7470 SM_DBG1(("smsatWrite16: return LBA out of range, EXT!!!\n")); 7471 smsatSetSensePayload( pSense, 7472 SCSI_SNSKEY_ILLEGAL_REQUEST, 7473 0, 7474 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 7475 satIOContext); 7476 7477 /*smEnqueueIO(smRoot, satIOContext);*/ 7478 7479 tdsmIOCompletedCB( smRoot, 7480 smIORequest, 7481 smIOSuccess, 7482 SCSI_STAT_CHECK_CONDITION, 7483 satIOContext->pSmSenseData, 7484 satIOContext->interruptContext ); 7485 7486 return SM_RC_SUCCESS; 7487 } 7488 } 7489 7490 /* case 1 and 2 */ 7491 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 7492 { 7493 /* case 2 */ 7494 /* WRITE DMA*/ 7495 /* In case that we can't fit the transfer length, we loop */ 7496 SM_DBG5(("smsatWrite16: case 2\n")); 7497 fis->h.fisType = 0x27; /* Reg host to device */ 7498 fis->h.c_pmPort = 0x80; /* C bit is set */ 7499 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 7500 fis->h.features = 0; /* FIS reserve */ 7501 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 7502 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 7503 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 7504 7505 /* FIS LBA mode set LBA (27:24) */ 7506 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); 7507 7508 fis->d.lbaLowExp = 0; 7509 fis->d.lbaMidExp = 0; 7510 fis->d.lbaHighExp = 0; 7511 fis->d.featuresExp = 0; 7512 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 7513 fis->d.sectorCountExp = 0; 7514 fis->d.reserved4 = 0; 7515 fis->d.control = 0; /* FIS HOB bit clear */ 7516 fis->d.reserved5 = 0; 7517 7518 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 7519 satIOContext->ATACmd = SAT_WRITE_DMA; 7520 } 7521 else 7522 { 7523 /* case 1 */ 7524 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 7525 /* WRITE SECTORS for easier implemetation */ 7526 /* In case that we can't fit the transfer length, we loop */ 7527 SM_DBG5(("smsatWrite16: case 1\n")); 7528 fis->h.fisType = 0x27; /* Reg host to device */ 7529 fis->h.c_pmPort = 0x80; /* C bit is set */ 7530 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 7531 fis->h.features = 0; /* FIS reserve */ 7532 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 7533 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 7534 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 7535 7536 /* FIS LBA mode set LBA (27:24) */ 7537 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); 7538 7539 fis->d.lbaLowExp = 0; 7540 fis->d.lbaMidExp = 0; 7541 fis->d.lbaHighExp = 0; 7542 fis->d.featuresExp = 0; 7543 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 7544 fis->d.sectorCountExp = 0; 7545 fis->d.reserved4 = 0; 7546 fis->d.control = 0; /* FIS HOB bit clear */ 7547 fis->d.reserved5 = 0; 7548 7549 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 7550 satIOContext->ATACmd = SAT_WRITE_SECTORS; 7551 } 7552 7553 /* case 3 and 4 */ 7554 if (pSatDevData->sat48BitSupport == agTRUE) 7555 { 7556 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 7557 { 7558 /* case 3 */ 7559 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 7560 SM_DBG5(("smsatWrite16: case 3\n")); 7561 fis->h.fisType = 0x27; /* Reg host to device */ 7562 fis->h.c_pmPort = 0x80; /* C Bit is set */ 7563 7564 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 7565 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 7566 7567 fis->h.features = 0; /* FIS reserve */ 7568 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 7569 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 7570 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 7571 fis->d.device = 0x40; /* FIS LBA mode set */ 7572 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 7573 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 7574 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 7575 fis->d.featuresExp = 0; /* FIS reserve */ 7576 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 7577 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 7578 fis->d.reserved4 = 0; 7579 fis->d.control = 0; /* FIS HOB bit clear */ 7580 fis->d.reserved5 = 0; 7581 7582 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 7583 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 7584 } 7585 else 7586 { 7587 /* case 4 */ 7588 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 7589 /* WRITE SECTORS EXT for easier implemetation */ 7590 SM_DBG5(("smsatWrite16: case 4\n")); 7591 fis->h.fisType = 0x27; /* Reg host to device */ 7592 fis->h.c_pmPort = 0x80; /* C Bit is set */ 7593 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 7594 7595 fis->h.features = 0; /* FIS reserve */ 7596 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 7597 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 7598 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 7599 fis->d.device = 0x40; /* FIS LBA mode set */ 7600 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 7601 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 7602 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 7603 fis->d.featuresExp = 0; /* FIS reserve */ 7604 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 7605 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 7606 fis->d.reserved4 = 0; 7607 fis->d.control = 0; /* FIS HOB bit clear */ 7608 fis->d.reserved5 = 0; 7609 7610 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 7611 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 7612 } 7613 } 7614 7615 /* case 5 */ 7616 if (pSatDevData->satNCQ == agTRUE) 7617 { 7618 /* WRITE FPDMA QUEUED */ 7619 if (pSatDevData->sat48BitSupport != agTRUE) 7620 { 7621 SM_DBG5(("smsatWrite16: case 5 !!! error NCQ but 28 bit address support!!!\n")); 7622 smsatSetSensePayload( pSense, 7623 SCSI_SNSKEY_ILLEGAL_REQUEST, 7624 0, 7625 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 7626 satIOContext); 7627 7628 /*smEnqueueIO(smRoot, satIOContext);*/ 7629 7630 tdsmIOCompletedCB( smRoot, 7631 smIORequest, 7632 smIOSuccess, 7633 SCSI_STAT_CHECK_CONDITION, 7634 satIOContext->pSmSenseData, 7635 satIOContext->interruptContext ); 7636 return SM_RC_SUCCESS; 7637 } 7638 SM_DBG6(("smsatWrite16: case 5\n")); 7639 7640 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 7641 7642 fis->h.fisType = 0x27; /* Reg host to device */ 7643 fis->h.c_pmPort = 0x80; /* C Bit is set */ 7644 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 7645 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 7646 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 7647 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 7648 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 7649 7650 /* Check FUA bit */ 7651 if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK) 7652 fis->d.device = 0xC0; /* FIS FUA set */ 7653 else 7654 fis->d.device = 0x40; /* FIS FUA clear */ 7655 7656 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 7657 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 7658 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 7659 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 7660 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 7661 fis->d.sectorCountExp = 0; 7662 fis->d.reserved4 = 0; 7663 fis->d.control = 0; /* FIS HOB bit clear */ 7664 fis->d.reserved5 = 0; 7665 7666 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 7667 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 7668 } 7669 7670 satIOContext->currentLBA = lba; 7671 satIOContext->OrgTL = tl; 7672 7673 /* 7674 computing number of loop and remainder for tl 7675 0xFF in case not ext 7676 0xFFFF in case EXT 7677 */ 7678 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 7679 { 7680 LoopNum = smsatComputeLoopNum(tl, 0xFF); 7681 } 7682 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 7683 fis->h.command == SAT_WRITE_DMA_EXT || 7684 fis->h.command == SAT_WRITE_DMA_FUA_EXT 7685 ) 7686 { 7687 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 7688 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 7689 } 7690 else 7691 { 7692 /* SAT_WRITE_FPDMA_QUEUEDK */ 7693 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 7694 } 7695 7696 satIOContext->LoopNum = LoopNum; 7697 7698 7699 if (LoopNum == 1) 7700 { 7701 SM_DBG5(("smsatWrite16: NON CHAINED data\n")); 7702 /* Initialize CB for SATA completion. 7703 */ 7704 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB; 7705 } 7706 else 7707 { 7708 SM_DBG1(("smsatWrite16: CHAINED data!!!\n")); 7709 /* re-setting tl */ 7710 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 7711 { 7712 fis->d.sectorCount = 0xFF; 7713 } 7714 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 7715 fis->h.command == SAT_WRITE_DMA_EXT || 7716 fis->h.command == SAT_WRITE_DMA_FUA_EXT 7717 ) 7718 { 7719 fis->d.sectorCount = 0xFF; 7720 fis->d.sectorCountExp = 0xFF; 7721 } 7722 else 7723 { 7724 /* SAT_WRITE_FPDMA_QUEUED */ 7725 fis->h.features = 0xFF; 7726 fis->d.featuresExp = 0xFF; 7727 } 7728 7729 /* Initialize CB for SATA completion. 7730 */ 7731 satIOContext->satCompleteCB = &smsatChainedDataIOCB; 7732 } 7733 7734 7735 /* 7736 * Prepare SGL and send FIS to LL layer. 7737 */ 7738 satIOContext->reqType = agRequestType; /* Save it */ 7739 7740 status = smsataLLIOStart( smRoot, 7741 smIORequest, 7742 smDeviceHandle, 7743 smScsiRequest, 7744 satIOContext); 7745 return (status); 7746 } 7747 7748 7749 osGLOBAL bit32 7750 smsatVerify10( 7751 smRoot_t *smRoot, 7752 smIORequest_t *smIORequest, 7753 smDeviceHandle_t *smDeviceHandle, 7754 smScsiInitiatorRequest_t *smScsiRequest, 7755 smSatIOContext_t *satIOContext 7756 ) 7757 { 7758 /* 7759 For simple implementation, 7760 no byte comparison supported as of 4/5/06 7761 */ 7762 smScsiRspSense_t *pSense; 7763 smIniScsiCmnd_t *scsiCmnd; 7764 smDeviceData_t *pSatDevData; 7765 agsaFisRegHostToDevice_t *fis; 7766 bit32 status; 7767 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 7768 bit32 lba = 0; 7769 bit32 tl = 0; 7770 bit32 LoopNum = 1; 7771 bit8 LBA[8]; 7772 bit8 TL[8]; 7773 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 7774 7775 pSense = satIOContext->pSense; 7776 scsiCmnd = &smScsiRequest->scsiCmnd; 7777 pSatDevData = satIOContext->pSatDevData; 7778 fis = satIOContext->pFis; 7779 SM_DBG5(("smsatVerify10: start\n")); 7780 /* checking BYTCHK */ 7781 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK) 7782 { 7783 /* 7784 should do the byte check 7785 but not supported in this version 7786 */ 7787 smsatSetSensePayload( pSense, 7788 SCSI_SNSKEY_ILLEGAL_REQUEST, 7789 0, 7790 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 7791 satIOContext); 7792 /*smEnqueueIO(smRoot, satIOContext);*/ 7793 tdsmIOCompletedCB( smRoot, 7794 smIORequest, 7795 smIOSuccess, 7796 SCSI_STAT_CHECK_CONDITION, 7797 satIOContext->pSmSenseData, 7798 satIOContext->interruptContext ); 7799 7800 SM_DBG1(("smsatVerify10: no byte checking!!!\n")); 7801 return SM_RC_SUCCESS; 7802 } 7803 7804 /* checking CONTROL */ 7805 /* NACA == 1 or LINK == 1*/ 7806 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 7807 { 7808 smsatSetSensePayload( pSense, 7809 SCSI_SNSKEY_ILLEGAL_REQUEST, 7810 0, 7811 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 7812 satIOContext); 7813 7814 /*smEnqueueIO(smRoot, satIOContext);*/ 7815 7816 tdsmIOCompletedCB( smRoot, 7817 smIORequest, 7818 smIOSuccess, 7819 SCSI_STAT_CHECK_CONDITION, 7820 satIOContext->pSmSenseData, 7821 satIOContext->interruptContext ); 7822 7823 SM_DBG1(("smsatVerify10: return control!!!\n")); 7824 return SM_RC_SUCCESS; 7825 } 7826 7827 7828 sm_memset(LBA, 0, sizeof(LBA)); 7829 sm_memset(TL, 0, sizeof(TL)); 7830 7831 /* do not use memcpy due to indexing in LBA and TL */ 7832 LBA[0] = 0; /* MSB */ 7833 LBA[1] = 0; 7834 LBA[2] = 0; 7835 LBA[3] = 0; 7836 LBA[4] = scsiCmnd->cdb[2]; 7837 LBA[5] = scsiCmnd->cdb[3]; 7838 LBA[6] = scsiCmnd->cdb[4]; 7839 LBA[7] = scsiCmnd->cdb[5]; /* LSB */ 7840 7841 TL[0] = 0; 7842 TL[1] = 0; 7843 TL[2] = 0; 7844 TL[3] = 0; 7845 TL[4] = 0; 7846 TL[5] = 0; 7847 TL[6] = scsiCmnd->cdb[7]; 7848 TL[7] = scsiCmnd->cdb[8]; /* LSB */ 7849 7850 7851 /* cbd10; computing LBA and transfer length */ 7852 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 7853 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 7854 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 7855 7856 if (pSatDevData->satNCQ != agTRUE && 7857 pSatDevData->sat48BitSupport != agTRUE 7858 ) 7859 { 7860 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 7861 if (AllChk) 7862 { 7863 SM_DBG1(("smsatVerify10: return LBA out of range, not EXT!!!\n")); 7864 SM_DBG1(("smsatVerify10: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3], 7865 scsiCmnd->cdb[4], scsiCmnd->cdb[5])); 7866 SM_DBG1(("smsatVerify10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT)); 7867 smsatSetSensePayload( pSense, 7868 SCSI_SNSKEY_ILLEGAL_REQUEST, 7869 0, 7870 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 7871 satIOContext); 7872 7873 /*smEnqueueIO(smRoot, satIOContext);*/ 7874 7875 tdsmIOCompletedCB( smRoot, 7876 smIORequest, 7877 smIOSuccess, 7878 SCSI_STAT_CHECK_CONDITION, 7879 satIOContext->pSmSenseData, 7880 satIOContext->interruptContext ); 7881 7882 return SM_RC_SUCCESS; 7883 } 7884 } 7885 else 7886 { 7887 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 7888 if (AllChk) 7889 { 7890 SM_DBG1(("smsatVerify10: return LBA out of range, EXT!!!\n")); 7891 smsatSetSensePayload( pSense, 7892 SCSI_SNSKEY_ILLEGAL_REQUEST, 7893 0, 7894 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 7895 satIOContext); 7896 7897 /*smEnqueueIO(smRoot, satIOContext);*/ 7898 7899 tdsmIOCompletedCB( smRoot, 7900 smIORequest, 7901 smIOSuccess, 7902 SCSI_STAT_CHECK_CONDITION, 7903 satIOContext->pSmSenseData, 7904 satIOContext->interruptContext ); 7905 7906 return SM_RC_SUCCESS; 7907 } 7908 } 7909 7910 if (pSatDevData->sat48BitSupport == agTRUE) 7911 { 7912 SM_DBG5(("smsatVerify10: SAT_READ_VERIFY_SECTORS_EXT\n")); 7913 fis->h.fisType = 0x27; /* Reg host to device */ 7914 fis->h.c_pmPort = 0x80; /* C Bit is set */ 7915 7916 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 7917 fis->h.features = 0; /* FIS reserve */ 7918 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 7919 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 7920 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 7921 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 7922 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 7923 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 7924 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 7925 fis->d.featuresExp = 0; /* FIS reserve */ 7926 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 7927 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 7928 7929 fis->d.reserved4 = 0; 7930 fis->d.control = 0; /* FIS HOB bit clear */ 7931 fis->d.reserved5 = 0; 7932 7933 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 7934 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT; 7935 } 7936 else 7937 { 7938 SM_DBG5(("smsatVerify10: SAT_READ_VERIFY_SECTORS\n")); 7939 fis->h.fisType = 0x27; /* Reg host to device */ 7940 fis->h.c_pmPort = 0x80; /* C bit is set */ 7941 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 7942 fis->h.features = 0; /* FIS reserve */ 7943 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 7944 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 7945 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 7946 /* FIS LBA mode set LBA (27:24) */ 7947 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 7948 fis->d.lbaLowExp = 0; 7949 fis->d.lbaMidExp = 0; 7950 fis->d.lbaHighExp = 0; 7951 fis->d.featuresExp = 0; 7952 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 7953 fis->d.sectorCountExp = 0; 7954 fis->d.reserved4 = 0; 7955 fis->d.control = 0; /* FIS HOB bit clear */ 7956 fis->d.reserved5 = 0; 7957 7958 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 7959 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS; 7960 7961 } 7962 7963 satIOContext->currentLBA = lba; 7964 satIOContext->OrgTL = tl; 7965 7966 /* 7967 computing number of loop and remainder for tl 7968 0xFF in case not ext 7969 0xFFFF in case EXT 7970 */ 7971 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 7972 { 7973 LoopNum = smsatComputeLoopNum(tl, 0xFF); 7974 } 7975 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 7976 { 7977 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 7978 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 7979 } 7980 else 7981 { 7982 SM_DBG1(("smsatVerify10: error case 1!!!\n")); 7983 LoopNum = 1; 7984 } 7985 7986 satIOContext->LoopNum = LoopNum; 7987 7988 if (LoopNum == 1) 7989 { 7990 SM_DBG5(("smsatVerify10: NON CHAINED data\n")); 7991 /* Initialize CB for SATA completion. 7992 */ 7993 satIOContext->satCompleteCB = &smsatNonChainedVerifyCB; 7994 } 7995 else 7996 { 7997 SM_DBG1(("smsatVerify10: CHAINED data!!!\n")); 7998 /* re-setting tl */ 7999 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 8000 { 8001 fis->d.sectorCount = 0xFF; 8002 } 8003 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 8004 { 8005 fis->d.sectorCount = 0xFF; 8006 fis->d.sectorCountExp = 0xFF; 8007 } 8008 else 8009 { 8010 SM_DBG1(("smsatVerify10: error case 2!!!\n")); 8011 } 8012 8013 /* Initialize CB for SATA completion. 8014 */ 8015 satIOContext->satCompleteCB = &smsatChainedVerifyCB; 8016 } 8017 8018 8019 /* 8020 * Prepare SGL and send FIS to LL layer. 8021 */ 8022 satIOContext->reqType = agRequestType; /* Save it */ 8023 8024 status = smsataLLIOStart( smRoot, 8025 smIORequest, 8026 smDeviceHandle, 8027 smScsiRequest, 8028 satIOContext); 8029 return (status); 8030 } 8031 8032 osGLOBAL bit32 8033 smsatVerify12( 8034 smRoot_t *smRoot, 8035 smIORequest_t *smIORequest, 8036 smDeviceHandle_t *smDeviceHandle, 8037 smScsiInitiatorRequest_t *smScsiRequest, 8038 smSatIOContext_t *satIOContext 8039 ) 8040 { 8041 /* 8042 For simple implementation, 8043 no byte comparison supported as of 4/5/06 8044 */ 8045 smScsiRspSense_t *pSense; 8046 smIniScsiCmnd_t *scsiCmnd; 8047 smDeviceData_t *pSatDevData; 8048 agsaFisRegHostToDevice_t *fis; 8049 bit32 status; 8050 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8051 bit32 lba = 0; 8052 bit32 tl = 0; 8053 bit32 LoopNum = 1; 8054 bit8 LBA[8]; 8055 bit8 TL[8]; 8056 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 8057 8058 pSense = satIOContext->pSense; 8059 scsiCmnd = &smScsiRequest->scsiCmnd; 8060 pSatDevData = satIOContext->pSatDevData; 8061 fis = satIOContext->pFis; 8062 SM_DBG5(("smsatVerify12: start\n")); 8063 /* checking BYTCHK */ 8064 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK) 8065 { 8066 /* 8067 should do the byte check 8068 but not supported in this version 8069 */ 8070 smsatSetSensePayload( pSense, 8071 SCSI_SNSKEY_ILLEGAL_REQUEST, 8072 0, 8073 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8074 satIOContext); 8075 8076 /*smEnqueueIO(smRoot, satIOContext);*/ 8077 8078 tdsmIOCompletedCB( smRoot, 8079 smIORequest, 8080 smIOSuccess, 8081 SCSI_STAT_CHECK_CONDITION, 8082 satIOContext->pSmSenseData, 8083 satIOContext->interruptContext ); 8084 8085 SM_DBG1(("smsatVerify12: no byte checking!!!\n")); 8086 return SM_RC_SUCCESS; 8087 } 8088 8089 /* checking CONTROL */ 8090 /* NACA == 1 or LINK == 1*/ 8091 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) ) 8092 { 8093 smsatSetSensePayload( pSense, 8094 SCSI_SNSKEY_ILLEGAL_REQUEST, 8095 0, 8096 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8097 satIOContext); 8098 8099 /*smEnqueueIO(smRoot, satIOContext);*/ 8100 8101 tdsmIOCompletedCB( smRoot, 8102 smIORequest, 8103 smIOSuccess, 8104 SCSI_STAT_CHECK_CONDITION, 8105 satIOContext->pSmSenseData, 8106 satIOContext->interruptContext ); 8107 8108 SM_DBG1(("smsatVerify12: return control!!!\n")); 8109 return SM_RC_SUCCESS; 8110 } 8111 8112 sm_memset(LBA, 0, sizeof(LBA)); 8113 sm_memset(TL, 0, sizeof(TL)); 8114 8115 /* do not use memcpy due to indexing in LBA and TL */ 8116 LBA[0] = 0; /* MSB */ 8117 LBA[1] = 0; 8118 LBA[2] = 0; 8119 LBA[3] = 0; 8120 LBA[4] = scsiCmnd->cdb[2]; 8121 LBA[5] = scsiCmnd->cdb[3]; 8122 LBA[6] = scsiCmnd->cdb[4]; 8123 LBA[7] = scsiCmnd->cdb[5]; /* LSB */ 8124 8125 TL[0] = 0; /* MSB */ 8126 TL[1] = 0; 8127 TL[2] = 0; 8128 TL[3] = 0; 8129 TL[4] = scsiCmnd->cdb[6]; 8130 TL[5] = scsiCmnd->cdb[7]; 8131 TL[6] = scsiCmnd->cdb[8]; 8132 TL[7] = scsiCmnd->cdb[9]; /* LSB */ 8133 8134 8135 lba = smsatComputeCDB12LBA(satIOContext); 8136 tl = smsatComputeCDB12TL(satIOContext); 8137 8138 if (pSatDevData->satNCQ != agTRUE && 8139 pSatDevData->sat48BitSupport != agTRUE 8140 ) 8141 { 8142 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 8143 if (AllChk) 8144 { 8145 SM_DBG1(("smsatVerify12: return LBA out of range, not EXT!!!\n")); 8146 SM_DBG1(("smsatVerify12: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3], 8147 scsiCmnd->cdb[4], scsiCmnd->cdb[5])); 8148 SM_DBG1(("smsatVerify12: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT)); 8149 smsatSetSensePayload( pSense, 8150 SCSI_SNSKEY_ILLEGAL_REQUEST, 8151 0, 8152 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 8153 satIOContext); 8154 8155 /*smEnqueueIO(smRoot, satIOContext);*/ 8156 8157 tdsmIOCompletedCB( smRoot, 8158 smIORequest, 8159 smIOSuccess, 8160 SCSI_STAT_CHECK_CONDITION, 8161 satIOContext->pSmSenseData, 8162 satIOContext->interruptContext ); 8163 8164 return SM_RC_SUCCESS; 8165 } 8166 } 8167 else 8168 { 8169 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 8170 if (AllChk) 8171 { 8172 SM_DBG1(("smsatVerify12: return LBA out of range, EXT!!!\n")); 8173 smsatSetSensePayload( pSense, 8174 SCSI_SNSKEY_ILLEGAL_REQUEST, 8175 0, 8176 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 8177 satIOContext); 8178 8179 /*smEnqueueIO(smRoot, satIOContext);*/ 8180 8181 tdsmIOCompletedCB( smRoot, 8182 smIORequest, 8183 smIOSuccess, 8184 SCSI_STAT_CHECK_CONDITION, 8185 satIOContext->pSmSenseData, 8186 satIOContext->interruptContext ); 8187 8188 return SM_RC_SUCCESS; 8189 } 8190 } 8191 8192 if (pSatDevData->sat48BitSupport == agTRUE) 8193 { 8194 SM_DBG5(("smsatVerify12: SAT_READ_VERIFY_SECTORS_EXT\n")); 8195 fis->h.fisType = 0x27; /* Reg host to device */ 8196 fis->h.c_pmPort = 0x80; /* C Bit is set */ 8197 8198 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 8199 fis->h.features = 0; /* FIS reserve */ 8200 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 8201 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 8202 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 8203 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 8204 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 8205 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 8206 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 8207 fis->d.featuresExp = 0; /* FIS reserve */ 8208 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 8209 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 8210 8211 fis->d.reserved4 = 0; 8212 fis->d.control = 0; /* FIS HOB bit clear */ 8213 fis->d.reserved5 = 0; 8214 8215 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8216 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT; 8217 } 8218 else 8219 { 8220 SM_DBG5(("smsatVerify12: SAT_READ_VERIFY_SECTORS\n")); 8221 fis->h.fisType = 0x27; /* Reg host to device */ 8222 fis->h.c_pmPort = 0x80; /* C bit is set */ 8223 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 8224 fis->h.features = 0; /* FIS reserve */ 8225 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 8226 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 8227 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 8228 /* FIS LBA mode set LBA (27:24) */ 8229 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 8230 fis->d.lbaLowExp = 0; 8231 fis->d.lbaMidExp = 0; 8232 fis->d.lbaHighExp = 0; 8233 fis->d.featuresExp = 0; 8234 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 8235 fis->d.sectorCountExp = 0; 8236 fis->d.reserved4 = 0; 8237 fis->d.control = 0; /* FIS HOB bit clear */ 8238 fis->d.reserved5 = 0; 8239 8240 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8241 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS; 8242 8243 } 8244 8245 satIOContext->currentLBA = lba; 8246 satIOContext->OrgTL = tl; 8247 8248 /* 8249 computing number of loop and remainder for tl 8250 0xFF in case not ext 8251 0xFFFF in case EXT 8252 */ 8253 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 8254 { 8255 LoopNum = smsatComputeLoopNum(tl, 0xFF); 8256 } 8257 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 8258 { 8259 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 8260 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 8261 } 8262 else 8263 { 8264 SM_DBG1(("smsatVerify12: error case 1!!!\n")); 8265 LoopNum = 1; 8266 } 8267 8268 satIOContext->LoopNum = LoopNum; 8269 8270 if (LoopNum == 1) 8271 { 8272 SM_DBG5(("smsatVerify12: NON CHAINED data\n")); 8273 /* Initialize CB for SATA completion. 8274 */ 8275 satIOContext->satCompleteCB = &smsatNonChainedVerifyCB; 8276 } 8277 else 8278 { 8279 SM_DBG1(("smsatVerify12: CHAINED data!!!\n")); 8280 /* re-setting tl */ 8281 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 8282 { 8283 fis->d.sectorCount = 0xFF; 8284 } 8285 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 8286 { 8287 fis->d.sectorCount = 0xFF; 8288 fis->d.sectorCountExp = 0xFF; 8289 } 8290 else 8291 { 8292 SM_DBG1(("smsatVerify12: error case 2!!!\n")); 8293 } 8294 8295 /* Initialize CB for SATA completion. 8296 */ 8297 satIOContext->satCompleteCB = &smsatChainedVerifyCB; 8298 } 8299 8300 8301 /* 8302 * Prepare SGL and send FIS to LL layer. 8303 */ 8304 satIOContext->reqType = agRequestType; /* Save it */ 8305 8306 status = smsataLLIOStart( smRoot, 8307 smIORequest, 8308 smDeviceHandle, 8309 smScsiRequest, 8310 satIOContext); 8311 return (status); 8312 } 8313 8314 osGLOBAL bit32 8315 smsatVerify16( 8316 smRoot_t *smRoot, 8317 smIORequest_t *smIORequest, 8318 smDeviceHandle_t *smDeviceHandle, 8319 smScsiInitiatorRequest_t *smScsiRequest, 8320 smSatIOContext_t *satIOContext 8321 ) 8322 { 8323 /* 8324 For simple implementation, 8325 no byte comparison supported as of 4/5/06 8326 */ 8327 smScsiRspSense_t *pSense; 8328 smIniScsiCmnd_t *scsiCmnd; 8329 smDeviceData_t *pSatDevData; 8330 agsaFisRegHostToDevice_t *fis; 8331 bit32 status; 8332 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8333 bit32 lba = 0; 8334 bit32 tl = 0; 8335 bit32 LoopNum = 1; 8336 bit8 LBA[8]; 8337 bit8 TL[8]; 8338 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 8339 8340 pSense = satIOContext->pSense; 8341 scsiCmnd = &smScsiRequest->scsiCmnd; 8342 pSatDevData = satIOContext->pSatDevData; 8343 fis = satIOContext->pFis; 8344 SM_DBG5(("smsatVerify16: start\n")); 8345 /* checking BYTCHK */ 8346 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK) 8347 { 8348 /* 8349 should do the byte check 8350 but not supported in this version 8351 */ 8352 smsatSetSensePayload( pSense, 8353 SCSI_SNSKEY_ILLEGAL_REQUEST, 8354 0, 8355 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8356 satIOContext); 8357 /*smEnqueueIO(smRoot, satIOContext);*/ 8358 tdsmIOCompletedCB( smRoot, 8359 smIORequest, 8360 smIOSuccess, 8361 SCSI_STAT_CHECK_CONDITION, 8362 satIOContext->pSmSenseData, 8363 satIOContext->interruptContext ); 8364 SM_DBG1(("smsatVerify16: no byte checking!!!\n")); 8365 return SM_RC_SUCCESS; 8366 } 8367 /* checking CONTROL */ 8368 /* NACA == 1 or LINK == 1*/ 8369 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 8370 { 8371 smsatSetSensePayload( pSense, 8372 SCSI_SNSKEY_ILLEGAL_REQUEST, 8373 0, 8374 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8375 satIOContext); 8376 /*smEnqueueIO(smRoot, satIOContext);*/ 8377 tdsmIOCompletedCB( smRoot, 8378 smIORequest, 8379 smIOSuccess, 8380 SCSI_STAT_CHECK_CONDITION, 8381 satIOContext->pSmSenseData, 8382 satIOContext->interruptContext ); 8383 SM_DBG1(("smsatVerify16: return control!!!\n")); 8384 return SM_RC_SUCCESS; 8385 } 8386 sm_memset(LBA, 0, sizeof(LBA)); 8387 sm_memset(TL, 0, sizeof(TL)); 8388 8389 /* do not use memcpy due to indexing in LBA and TL */ 8390 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 8391 LBA[1] = scsiCmnd->cdb[3]; 8392 LBA[2] = scsiCmnd->cdb[4]; 8393 LBA[3] = scsiCmnd->cdb[5]; 8394 LBA[4] = scsiCmnd->cdb[6]; 8395 LBA[5] = scsiCmnd->cdb[7]; 8396 LBA[6] = scsiCmnd->cdb[8]; 8397 LBA[7] = scsiCmnd->cdb[9]; /* LSB */ 8398 8399 TL[0] = 0; 8400 TL[1] = 0; 8401 TL[2] = 0; 8402 TL[3] = 0; 8403 TL[4] = scsiCmnd->cdb[10]; /* MSB */ 8404 TL[5] = scsiCmnd->cdb[11]; 8405 TL[6] = scsiCmnd->cdb[12]; 8406 TL[7] = scsiCmnd->cdb[13]; /* LSB */ 8407 lba = smsatComputeCDB16LBA(satIOContext); 8408 tl = smsatComputeCDB16TL(satIOContext); 8409 8410 if (pSatDevData->satNCQ != agTRUE && 8411 pSatDevData->sat48BitSupport != agTRUE 8412 ) 8413 { 8414 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 8415 if (AllChk) 8416 { 8417 SM_DBG1(("smsatVerify16: return LBA out of range, not EXT!!!\n")); 8418 smsatSetSensePayload( pSense, 8419 SCSI_SNSKEY_ILLEGAL_REQUEST, 8420 0, 8421 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 8422 satIOContext); 8423 /*smEnqueueIO(smRoot, satIOContext);*/ 8424 tdsmIOCompletedCB( smRoot, 8425 smIORequest, 8426 smIOSuccess, 8427 SCSI_STAT_CHECK_CONDITION, 8428 satIOContext->pSmSenseData, 8429 satIOContext->interruptContext ); 8430 return SM_RC_SUCCESS; 8431 } 8432 } 8433 else 8434 { 8435 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 8436 if (AllChk) 8437 { 8438 SM_DBG1(("smsatVerify16: return LBA out of range, EXT!!!\n")); 8439 smsatSetSensePayload( pSense, 8440 SCSI_SNSKEY_ILLEGAL_REQUEST, 8441 0, 8442 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 8443 satIOContext); 8444 /*smEnqueueIO(smRoot, satIOContext);*/ 8445 tdsmIOCompletedCB( smRoot, 8446 smIORequest, 8447 smIOSuccess, 8448 SCSI_STAT_CHECK_CONDITION, 8449 satIOContext->pSmSenseData, 8450 satIOContext->interruptContext ); 8451 return SM_RC_SUCCESS; 8452 } 8453 } 8454 8455 if (pSatDevData->sat48BitSupport == agTRUE) 8456 { 8457 SM_DBG5(("smsatVerify16: SAT_READ_VERIFY_SECTORS_EXT\n")); 8458 fis->h.fisType = 0x27; /* Reg host to device */ 8459 fis->h.c_pmPort = 0x80; /* C Bit is set */ 8460 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 8461 fis->h.features = 0; /* FIS reserve */ 8462 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 8463 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 8464 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 8465 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 8466 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 8467 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 8468 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 8469 fis->d.featuresExp = 0; /* FIS reserve */ 8470 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 8471 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 8472 8473 fis->d.reserved4 = 0; 8474 fis->d.control = 0; /* FIS HOB bit clear */ 8475 fis->d.reserved5 = 0; 8476 8477 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8478 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT; 8479 } 8480 else 8481 { 8482 SM_DBG5(("smsatVerify16: SAT_READ_VERIFY_SECTORS\n")); 8483 fis->h.fisType = 0x27; /* Reg host to device */ 8484 fis->h.c_pmPort = 0x80; /* C bit is set */ 8485 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 8486 fis->h.features = 0; /* FIS reserve */ 8487 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 8488 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 8489 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 8490 /* FIS LBA mode set LBA (27:24) */ 8491 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); 8492 fis->d.lbaLowExp = 0; 8493 fis->d.lbaMidExp = 0; 8494 fis->d.lbaHighExp = 0; 8495 fis->d.featuresExp = 0; 8496 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 8497 fis->d.sectorCountExp = 0; 8498 fis->d.reserved4 = 0; 8499 fis->d.control = 0; /* FIS HOB bit clear */ 8500 fis->d.reserved5 = 0; 8501 8502 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8503 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS; 8504 8505 } 8506 8507 satIOContext->currentLBA = lba; 8508 satIOContext->OrgTL = tl; 8509 8510 /* 8511 computing number of loop and remainder for tl 8512 0xFF in case not ext 8513 0xFFFF in case EXT 8514 */ 8515 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 8516 { 8517 LoopNum = smsatComputeLoopNum(tl, 0xFF); 8518 } 8519 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 8520 { 8521 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 8522 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 8523 } 8524 else 8525 { 8526 SM_DBG1(("smsatVerify16: error case 1!!!\n")); 8527 LoopNum = 1; 8528 } 8529 8530 satIOContext->LoopNum = LoopNum; 8531 8532 if (LoopNum == 1) 8533 { 8534 SM_DBG5(("smsatVerify16: NON CHAINED data\n")); 8535 /* Initialize CB for SATA completion. 8536 */ 8537 satIOContext->satCompleteCB = &smsatNonChainedVerifyCB; 8538 } 8539 else 8540 { 8541 SM_DBG1(("smsatVerify16: CHAINED data!!!\n")); 8542 /* re-setting tl */ 8543 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 8544 { 8545 fis->d.sectorCount = 0xFF; 8546 } 8547 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 8548 { 8549 fis->d.sectorCount = 0xFF; 8550 fis->d.sectorCountExp = 0xFF; 8551 } 8552 else 8553 { 8554 SM_DBG1(("smsatVerify16: error case 2!!!\n")); 8555 } 8556 8557 /* Initialize CB for SATA completion. 8558 */ 8559 satIOContext->satCompleteCB = &smsatChainedVerifyCB; 8560 } 8561 8562 8563 /* 8564 * Prepare SGL and send FIS to LL layer. 8565 */ 8566 satIOContext->reqType = agRequestType; /* Save it */ 8567 8568 status = smsataLLIOStart( smRoot, 8569 smIORequest, 8570 smDeviceHandle, 8571 smScsiRequest, 8572 satIOContext); 8573 return (status); 8574 } 8575 8576 osGLOBAL bit32 8577 smsatTestUnitReady( 8578 smRoot_t *smRoot, 8579 smIORequest_t *smIORequest, 8580 smDeviceHandle_t *smDeviceHandle, 8581 smScsiInitiatorRequest_t *smScsiRequest, 8582 smSatIOContext_t *satIOContext 8583 ) 8584 { 8585 bit32 status; 8586 bit32 agRequestType; 8587 smDeviceData_t *pSatDevData; 8588 smScsiRspSense_t *pSense; 8589 smIniScsiCmnd_t *scsiCmnd; 8590 agsaFisRegHostToDevice_t *fis; 8591 8592 pSense = satIOContext->pSense; 8593 pSatDevData = satIOContext->pSatDevData; 8594 scsiCmnd = &smScsiRequest->scsiCmnd; 8595 fis = satIOContext->pFis; 8596 8597 SM_DBG5(("smsatTestUnitReady: start\n")); 8598 8599 /* checking CONTROL */ 8600 /* NACA == 1 or LINK == 1*/ 8601 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 8602 { 8603 smsatSetSensePayload( pSense, 8604 SCSI_SNSKEY_ILLEGAL_REQUEST, 8605 0, 8606 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8607 satIOContext); 8608 8609 /*smEnqueueIO(smRoot, satIOContext);*/ 8610 8611 tdsmIOCompletedCB( smRoot, 8612 smIORequest, 8613 smIOSuccess, 8614 SCSI_STAT_CHECK_CONDITION, 8615 satIOContext->pSmSenseData, 8616 satIOContext->interruptContext ); 8617 8618 SM_DBG1(("smsatTestUnitReady: return control!!!\n")); 8619 return SM_RC_SUCCESS; 8620 } 8621 8622 /* SAT revision 8, 8.11.2, p42*/ 8623 if (pSatDevData->satStopState == agTRUE) 8624 { 8625 smsatSetSensePayload( pSense, 8626 SCSI_SNSKEY_NOT_READY, 8627 0, 8628 SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED, 8629 satIOContext); 8630 8631 /*smEnqueueIO(smRoot, satIOContext);*/ 8632 8633 tdsmIOCompletedCB( smRoot, 8634 smIORequest, 8635 smIOSuccess, 8636 SCSI_STAT_CHECK_CONDITION, 8637 satIOContext->pSmSenseData, 8638 satIOContext->interruptContext ); 8639 SM_DBG1(("smsatTestUnitReady: stop state!!!\n")); 8640 return SM_RC_SUCCESS; 8641 } 8642 8643 /* 8644 * Check if format is in progress 8645 */ 8646 if (pSatDevData->satDriveState == SAT_DEV_STATE_FORMAT_IN_PROGRESS) 8647 { 8648 SM_DBG1(("smsatTestUnitReady: FORMAT_IN_PROGRESS!!!\n")); 8649 8650 smsatSetSensePayload( pSense, 8651 SCSI_SNSKEY_NOT_READY, 8652 0, 8653 SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_FORMAT_IN_PROGRESS, 8654 satIOContext); 8655 8656 /*smEnqueueIO(smRoot, satIOContext);*/ 8657 8658 tdsmIOCompletedCB( smRoot, 8659 smIORequest, 8660 smIOSuccess, 8661 SCSI_STAT_CHECK_CONDITION, 8662 satIOContext->pSmSenseData, 8663 satIOContext->interruptContext ); 8664 SM_DBG1(("smsatTestUnitReady: format in progress!!!\n")); 8665 return SM_RC_SUCCESS; 8666 } 8667 8668 /* 8669 check previously issued ATA command 8670 */ 8671 if (pSatDevData->satPendingIO != 0) 8672 { 8673 if (pSatDevData->satDeviceFaultState == agTRUE) 8674 { 8675 smsatSetSensePayload( pSense, 8676 SCSI_SNSKEY_HARDWARE_ERROR, 8677 0, 8678 SCSI_SNSCODE_LOGICAL_UNIT_FAILURE, 8679 satIOContext); 8680 8681 /*smEnqueueIO(smRoot, satIOContext);*/ 8682 8683 tdsmIOCompletedCB( smRoot, 8684 smIORequest, 8685 smIOSuccess, 8686 SCSI_STAT_CHECK_CONDITION, 8687 satIOContext->pSmSenseData, 8688 satIOContext->interruptContext ); 8689 SM_DBG1(("smsatTestUnitReady: previous command ended in error!!!\n")); 8690 return SM_RC_SUCCESS; 8691 } 8692 } 8693 8694 /* 8695 check removalbe media feature set 8696 */ 8697 if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled) 8698 { 8699 SM_DBG5(("smsatTestUnitReady: sending get media status cmnd\n")); 8700 /* send GET MEDIA STATUS command */ 8701 fis->h.fisType = 0x27; /* Reg host to device */ 8702 fis->h.c_pmPort = 0x80; /* C Bit is set */ 8703 fis->h.command = SAT_GET_MEDIA_STATUS; /* 0xDA */ 8704 fis->h.features = 0; /* FIS features NA */ 8705 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 8706 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 8707 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 8708 fis->d.device = 0; /* FIS DEV is discared in SATA */ 8709 fis->d.lbaLowExp = 0; 8710 fis->d.lbaMidExp = 0; 8711 fis->d.lbaHighExp = 0; 8712 fis->d.featuresExp = 0; 8713 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 8714 fis->d.sectorCountExp = 0; 8715 fis->d.reserved4 = 0; 8716 fis->d.control = 0; /* FIS HOB bit clear */ 8717 fis->d.reserved5 = 0; 8718 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8719 8720 /* Initialize CB for SATA completion. 8721 */ 8722 satIOContext->satCompleteCB = &smsatTestUnitReadyCB; 8723 8724 /* 8725 * Prepare SGL and send FIS to LL layer. 8726 */ 8727 satIOContext->reqType = agRequestType; /* Save it */ 8728 8729 status = smsataLLIOStart( smRoot, 8730 smIORequest, 8731 smDeviceHandle, 8732 smScsiRequest, 8733 satIOContext); 8734 8735 return (status); 8736 } 8737 /* 8738 number 6) in SAT p42 8739 send ATA CHECK POWER MODE 8740 */ 8741 SM_DBG5(("smsatTestUnitReady: sending check power mode cmnd\n")); 8742 status = smsatTestUnitReady_1( smRoot, 8743 smIORequest, 8744 smDeviceHandle, 8745 smScsiRequest, 8746 satIOContext); 8747 return (status); 8748 } 8749 8750 osGLOBAL bit32 8751 smsatTestUnitReady_1( 8752 smRoot_t *smRoot, 8753 smIORequest_t *smIORequest, 8754 smDeviceHandle_t *smDeviceHandle, 8755 smScsiInitiatorRequest_t *smScsiRequest, 8756 smSatIOContext_t *satIOContext 8757 ) 8758 { 8759 /* 8760 sends SAT_CHECK_POWER_MODE as a part of TESTUNITREADY 8761 internally generated - no directly corresponding scsi 8762 called in satIOCompleted as a part of satTestUnitReady(), SAT, revision8, 8.11.2, p42 8763 */ 8764 bit32 status; 8765 bit32 agRequestType; 8766 agsaFisRegHostToDevice_t *fis; 8767 8768 fis = satIOContext->pFis; 8769 SM_DBG5(("smsatTestUnitReady_1: start\n")); 8770 /* 8771 * Send the ATA CHECK POWER MODE command. 8772 */ 8773 fis->h.fisType = 0x27; /* Reg host to device */ 8774 fis->h.c_pmPort = 0x80; /* C Bit is set */ 8775 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */ 8776 fis->h.features = 0; 8777 fis->d.lbaLow = 0; 8778 fis->d.lbaMid = 0; 8779 fis->d.lbaHigh = 0; 8780 fis->d.device = 0; 8781 fis->d.lbaLowExp = 0; 8782 fis->d.lbaMidExp = 0; 8783 fis->d.lbaHighExp = 0; 8784 fis->d.featuresExp = 0; 8785 fis->d.sectorCount = 0; 8786 fis->d.sectorCountExp = 0; 8787 fis->d.reserved4 = 0; 8788 fis->d.control = 0; /* FIS HOB bit clear */ 8789 fis->d.reserved5 = 0; 8790 8791 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 8792 8793 /* Initialize CB for SATA completion. 8794 */ 8795 satIOContext->satCompleteCB = &smsatTestUnitReadyCB; 8796 8797 /* 8798 * Prepare SGL and send FIS to LL layer. 8799 */ 8800 satIOContext->reqType = agRequestType; /* Save it */ 8801 8802 status = smsataLLIOStart( smRoot, 8803 smIORequest, 8804 smDeviceHandle, 8805 smScsiRequest, 8806 satIOContext); 8807 8808 SM_DBG5(("smsatTestUnitReady_1: return\n")); 8809 8810 return status; 8811 } 8812 8813 osGLOBAL bit32 8814 smsatInquiry( 8815 smRoot_t *smRoot, 8816 smIORequest_t *smIORequest, 8817 smDeviceHandle_t *smDeviceHandle, 8818 smScsiInitiatorRequest_t *smScsiRequest, 8819 smSatIOContext_t *satIOContext 8820 ) 8821 { 8822 /* 8823 CMDDT bit is obsolete in SPC-3 and this is assumed in SAT revision 8 8824 */ 8825 smScsiRspSense_t *pSense; 8826 smIniScsiCmnd_t *scsiCmnd; 8827 smDeviceData_t *pSatDevData; 8828 bit32 status; 8829 8830 pSense = satIOContext->pSense; 8831 scsiCmnd = &smScsiRequest->scsiCmnd; 8832 pSatDevData = satIOContext->pSatDevData; 8833 SM_DBG5(("smsatInquiry: start\n")); 8834 SM_DBG5(("smsatInquiry: pSatDevData did %d\n", pSatDevData->id)); 8835 //smhexdump("smsatInquiry", (bit8 *)scsiCmnd->cdb, 6); 8836 /* checking CONTROL */ 8837 /* NACA == 1 or LINK == 1*/ 8838 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 8839 { 8840 smsatSetSensePayload( pSense, 8841 SCSI_SNSKEY_ILLEGAL_REQUEST, 8842 0, 8843 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8844 satIOContext); 8845 /*smEnqueueIO(smRoot, satIOContext);*/ 8846 tdsmIOCompletedCB( smRoot, 8847 smIORequest, 8848 smIOSuccess, 8849 SCSI_STAT_CHECK_CONDITION, 8850 satIOContext->pSmSenseData, 8851 satIOContext->interruptContext ); 8852 SM_DBG1(("smsatInquiry: return control!!!\n")); 8853 return SM_RC_SUCCESS; 8854 } 8855 8856 /* checking EVPD and Allocation Length */ 8857 /* SPC-4 spec 6.4 p141 */ 8858 /* EVPD bit == 0 && PAGE CODE != 0 */ 8859 if ( !(scsiCmnd->cdb[1] & SCSI_EVPD_MASK) && 8860 (scsiCmnd->cdb[2] != 0) 8861 ) 8862 { 8863 smsatSetSensePayload( pSense, 8864 SCSI_SNSKEY_ILLEGAL_REQUEST, 8865 0, 8866 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 8867 satIOContext); 8868 /*smEnqueueIO(smRoot, satIOContext);*/ 8869 tdsmIOCompletedCB( smRoot, 8870 smIORequest, 8871 smIOSuccess, 8872 SCSI_STAT_CHECK_CONDITION, 8873 satIOContext->pSmSenseData, 8874 satIOContext->interruptContext ); 8875 SM_DBG1(("smsatInquiry: return EVPD and PAGE CODE!!!\n")); 8876 return SM_RC_SUCCESS; 8877 } 8878 SM_DBG6(("smsatInquiry: allocation length 0x%x %d\n", ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4], ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4])); 8879 /* convert OS IO to TD internal IO */ 8880 if ( pSatDevData->IDDeviceValid == agFALSE) 8881 { 8882 status = smsatStartIDDev( 8883 smRoot, 8884 smIORequest, 8885 smDeviceHandle, 8886 smScsiRequest, 8887 satIOContext 8888 ); 8889 SM_DBG6(("smsatInquiry: end status %d\n", status)); 8890 return status; 8891 } 8892 else 8893 { 8894 SM_DBG6(("smsatInquiry: calling satInquiryIntCB\n")); 8895 smsatInquiryIntCB( 8896 smRoot, 8897 smIORequest, 8898 smDeviceHandle, 8899 smScsiRequest, 8900 satIOContext 8901 ); 8902 /*smEnqueueIO(smRoot, satIOContext);*/ 8903 return SM_RC_SUCCESS; 8904 } 8905 } 8906 8907 8908 osGLOBAL bit32 8909 smsatStartIDDev( 8910 smRoot_t *smRoot, 8911 smIORequest_t *smIORequest, 8912 smDeviceHandle_t *smDeviceHandle, 8913 smScsiInitiatorRequest_t *smScsiRequest, 8914 smSatIOContext_t *satIOContext 8915 ) 8916 { 8917 smSatInternalIo_t *satIntIo = agNULL; 8918 smDeviceData_t *satDevData = agNULL; 8919 smIORequestBody_t *smIORequestBody; 8920 smSatIOContext_t *satNewIOContext; 8921 bit32 status; 8922 8923 SM_DBG5(("smsatStartIDDev: start\n")); 8924 8925 satDevData = satIOContext->pSatDevData; 8926 8927 SM_DBG6(("smsatStartIDDev: before alloc\n")); 8928 8929 /* allocate identify device command */ 8930 satIntIo = smsatAllocIntIoResource( smRoot, 8931 smIORequest, 8932 satDevData, 8933 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */ 8934 satIntIo); 8935 8936 SM_DBG6(("smsatStartIDDev: before after\n")); 8937 8938 if (satIntIo == agNULL) 8939 { 8940 SM_DBG1(("smsatStartIDDev: can't alloacate!!!\n")); 8941 8942 /*smEnqueueIO(smRoot, satIOContext);*/ 8943 8944 return SM_RC_FAILURE; 8945 } 8946 8947 satIntIo->satOrgSmIORequest = smIORequest; /* changed */ 8948 smIORequestBody = satIntIo->satIntRequestBody; 8949 satNewIOContext = &(smIORequestBody->transport.SATA.satIOContext); 8950 8951 satNewIOContext->pSatDevData = satDevData; 8952 satNewIOContext->pFis = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 8953 satNewIOContext->pScsiCmnd = &(satIntIo->satIntSmScsiXchg.scsiCmnd); 8954 satNewIOContext->pSense = &(smIORequestBody->transport.SATA.sensePayload); 8955 satNewIOContext->pSmSenseData = &(smIORequestBody->transport.SATA.smSenseData); 8956 satNewIOContext->smRequestBody = satIntIo->satIntRequestBody; /* key fix */ 8957 satNewIOContext->interruptContext = tiInterruptContext; 8958 satNewIOContext->satIntIoContext = satIntIo; 8959 8960 satNewIOContext->psmDeviceHandle = agNULL; 8961 satNewIOContext->satOrgIOContext = satIOContext; /* changed */ 8962 8963 /* this is valid only for TD layer generated (not triggered by OS at all) IO */ 8964 satNewIOContext->smScsiXchg = &(satIntIo->satIntSmScsiXchg); 8965 8966 8967 SM_DBG6(("smsatStartIDDev: OS satIOContext %p \n", satIOContext)); 8968 SM_DBG6(("smsatStartIDDev: TD satNewIOContext %p \n", satNewIOContext)); 8969 SM_DBG6(("smsatStartIDDev: OS tiScsiXchg %p \n", satIOContext->smScsiXchg)); 8970 SM_DBG6(("smsatStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->smScsiXchg)); 8971 8972 8973 8974 SM_DBG1(("smsatStartIDDev: satNewIOContext %p smIORequestBody %p!!!\n", satNewIOContext, smIORequestBody)); 8975 8976 status = smsatSendIDDev( smRoot, 8977 &satIntIo->satIntSmIORequest, /* New smIORequest */ 8978 smDeviceHandle, 8979 satNewIOContext->smScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */ 8980 satNewIOContext); 8981 8982 if (status != SM_RC_SUCCESS) 8983 { 8984 SM_DBG1(("smsatStartIDDev: failed in sending!!!\n")); 8985 8986 smsatFreeIntIoResource( smRoot, 8987 satDevData, 8988 satIntIo); 8989 /*smEnqueueIO(smRoot, satIOContext);*/ 8990 8991 return SM_RC_FAILURE; 8992 } 8993 8994 8995 SM_DBG6(("smsatStartIDDev: end\n")); 8996 8997 return status; 8998 } 8999 9000 osGLOBAL bit32 9001 smsatSendIDDev( 9002 smRoot_t *smRoot, 9003 smIORequest_t *smIORequest, 9004 smDeviceHandle_t *smDeviceHandle, 9005 smScsiInitiatorRequest_t *smScsiRequest, 9006 smSatIOContext_t *satIOContext 9007 ) 9008 { 9009 bit32 status; 9010 bit32 agRequestType; 9011 smDeviceData_t *pSatDevData; 9012 agsaFisRegHostToDevice_t *fis; 9013 #ifdef SM_INTERNAL_DEBUG 9014 smIORequestBody_t *smIORequestBody; 9015 smSatInternalIo_t *satIntIoContext; 9016 #endif 9017 9018 pSatDevData = satIOContext->pSatDevData; 9019 fis = satIOContext->pFis; 9020 SM_DBG6(("smsatSendIDDev: start\n")); 9021 SM_DBG6(("smsatSendIDDev: did %d\n", pSatDevData->id)); 9022 #ifdef SM_INTERNAL_DEBUG 9023 satIntIoContext = satIOContext->satIntIoContext; 9024 smIORequestBody = satIntIoContext->satIntRequestBody; 9025 #endif 9026 fis->h.fisType = 0x27; /* Reg host to device */ 9027 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9028 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE) 9029 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0x40 */ 9030 else 9031 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */ 9032 fis->h.features = 0; /* FIS reserve */ 9033 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 9034 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 9035 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 9036 fis->d.device = 0; /* FIS LBA mode */ 9037 fis->d.lbaLowExp = 0; 9038 fis->d.lbaMidExp = 0; 9039 fis->d.lbaHighExp = 0; 9040 fis->d.featuresExp = 0; 9041 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 9042 fis->d.sectorCountExp = 0; 9043 fis->d.reserved4 = 0; 9044 fis->d.control = 0; /* FIS HOB bit clear */ 9045 fis->d.reserved5 = 0; 9046 9047 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 9048 9049 /* Initialize CB for SATA completion. 9050 */ 9051 satIOContext->satCompleteCB = &smsatInquiryCB; 9052 9053 /* 9054 * Prepare SGL and send FIS to LL layer. 9055 */ 9056 satIOContext->reqType = agRequestType; /* Save it */ 9057 9058 #ifdef SM_INTERNAL_DEBUG 9059 smhexdump("smsatSendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 9060 smhexdump("smsatSendIDDev LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t)); 9061 #endif 9062 status = smsataLLIOStart( smRoot, 9063 smIORequest, 9064 smDeviceHandle, 9065 smScsiRequest, 9066 satIOContext); 9067 9068 SM_DBG6(("smsatSendIDDev: end status %d\n", status)); 9069 return status; 9070 } 9071 9072 osGLOBAL bit32 9073 smsatRequestSense( 9074 smRoot_t *smRoot, 9075 smIORequest_t *smIORequest, 9076 smDeviceHandle_t *smDeviceHandle, 9077 smScsiInitiatorRequest_t *smScsiRequest, 9078 smSatIOContext_t *satIOContext 9079 ) 9080 { 9081 /* 9082 SAT Rev 8 p38, Table25 9083 sending SMART RETURN STATUS 9084 Checking SMART Treshold Exceeded Condition is done in satRequestSenseCB() 9085 Only fixed format sense data is support. In other words, we don't support DESC bit is set 9086 in Request Sense 9087 */ 9088 bit32 status; 9089 bit32 agRequestType; 9090 smScsiRspSense_t *pSense; 9091 smDeviceData_t *pSatDevData; 9092 smIniScsiCmnd_t *scsiCmnd; 9093 agsaFisRegHostToDevice_t *fis; 9094 smIORequestBody_t *smIORequestBody; 9095 smSatInternalIo_t *satIntIo = agNULL; 9096 smSatIOContext_t *satIOContext2; 9097 bit8 *pDataBuffer = agNULL; 9098 bit32 allocationLen = 0; 9099 9100 pSense = satIOContext->pSense; 9101 pSatDevData = satIOContext->pSatDevData; 9102 scsiCmnd = &smScsiRequest->scsiCmnd; 9103 fis = satIOContext->pFis; 9104 pDataBuffer = (bit8 *) smScsiRequest->sglVirtualAddr; 9105 allocationLen = scsiCmnd->cdb[4]; 9106 allocationLen = MIN(allocationLen, scsiCmnd->expDataLength); 9107 SM_DBG5(("smsatRequestSense: start\n")); 9108 9109 /* checking CONTROL */ 9110 /* NACA == 1 or LINK == 1*/ 9111 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 9112 { 9113 smsatSetSensePayload( pSense, 9114 SCSI_SNSKEY_ILLEGAL_REQUEST, 9115 0, 9116 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9117 satIOContext); 9118 sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen)); 9119 9120 /*smEnqueueIO(smRoot, satIOContext);*/ 9121 9122 tdsmIOCompletedCB( smRoot, 9123 smIORequest, 9124 smIOSuccess, 9125 SCSI_STAT_CHECK_CONDITION, 9126 satIOContext->pSmSenseData, 9127 satIOContext->interruptContext ); 9128 9129 SM_DBG1(("smsatRequestSense: return control!!!\n")); 9130 return SM_RC_SUCCESS; 9131 } 9132 9133 /* 9134 Only fixed format sense data is support. In other words, we don't support DESC bit is set 9135 in Request Sense 9136 */ 9137 if ( scsiCmnd->cdb[1] & ATA_REMOVABLE_MEDIA_DEVICE_MASK ) 9138 { 9139 smsatSetSensePayload( pSense, 9140 SCSI_SNSKEY_ILLEGAL_REQUEST, 9141 0, 9142 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9143 satIOContext); 9144 sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen)); 9145 9146 /*smEnqueueIO(smRoot, satIOContext);*/ 9147 9148 tdsmIOCompletedCB( smRoot, 9149 smIORequest, 9150 smIOSuccess, 9151 SCSI_STAT_CHECK_CONDITION, 9152 satIOContext->pSmSenseData, 9153 satIOContext->interruptContext ); 9154 9155 SM_DBG1(("smsatRequestSense: DESC bit is set, which we don't support!!!\n")); 9156 return SM_RC_SUCCESS; 9157 } 9158 9159 9160 if (pSatDevData->satSMARTEnabled == agTRUE) 9161 { 9162 /* sends SMART RETURN STATUS */ 9163 fis->h.fisType = 0x27; /* Reg host to device */ 9164 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9165 9166 fis->h.command = SAT_SMART; /* 0xB0 */ 9167 fis->h.features = SAT_SMART_RETURN_STATUS; /* FIS features */ 9168 fis->d.featuresExp = 0; /* FIS reserve */ 9169 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 9170 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 9171 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 9172 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 9173 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 9174 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 9175 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 9176 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 9177 fis->d.device = 0; /* FIS DEV is discared in SATA */ 9178 fis->d.control = 0; /* FIS HOB bit clear */ 9179 fis->d.reserved4 = 0; 9180 fis->d.reserved5 = 0; 9181 9182 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9183 /* Initialize CB for SATA completion. 9184 */ 9185 satIOContext->satCompleteCB = &smsatRequestSenseCB; 9186 9187 /* 9188 * Prepare SGL and send FIS to LL layer. 9189 */ 9190 satIOContext->reqType = agRequestType; /* Save it */ 9191 9192 status = smsataLLIOStart( smRoot, 9193 smIORequest, 9194 smDeviceHandle, 9195 smScsiRequest, 9196 satIOContext); 9197 9198 SM_DBG4(("smsatRequestSense: if return, status %d\n", status)); 9199 return (status); 9200 } 9201 else 9202 { 9203 /*allocate iocontext for xmitting xmit SAT_CHECK_POWER_MODE 9204 then call satRequestSense2 */ 9205 9206 SM_DBG4(("smsatRequestSense: before satIntIo %p\n", satIntIo)); 9207 /* allocate iocontext */ 9208 satIntIo = smsatAllocIntIoResource( smRoot, 9209 smIORequest, /* original request */ 9210 pSatDevData, 9211 smScsiRequest->scsiCmnd.expDataLength, 9212 satIntIo); 9213 9214 SM_DBG4(("smsatRequestSense: after satIntIo %p\n", satIntIo)); 9215 9216 if (satIntIo == agNULL) 9217 { 9218 /* failed during sending SMART RETURN STATUS */ 9219 smsatSetSensePayload( pSense, 9220 SCSI_SNSKEY_NO_SENSE, 9221 0, 9222 SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE, 9223 satIOContext); 9224 sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen)); 9225 9226 /*smEnqueueIO(smRoot, satIOContext);*/ 9227 9228 tdsmIOCompletedCB( smRoot, 9229 smIORequest, 9230 smIOSuccess, 9231 SCSI_STAT_GOOD, 9232 agNULL, 9233 satIOContext->interruptContext ); 9234 9235 SM_DBG1(("smsatRequestSense: else fail 1!!!\n")); 9236 return SM_RC_SUCCESS; 9237 } /* end of memory allocation failure */ 9238 9239 9240 /* 9241 * Need to initialize all the fields within satIOContext except 9242 * reqType and satCompleteCB which will be set depending on cmd. 9243 */ 9244 9245 if (satIntIo == agNULL) 9246 { 9247 SM_DBG4(("smsatRequestSense: satIntIo is NULL\n")); 9248 } 9249 else 9250 { 9251 SM_DBG4(("smsatRequestSense: satIntIo is NOT NULL\n")); 9252 } 9253 /* use this --- tttttthe one the same */ 9254 9255 9256 satIntIo->satOrgSmIORequest = smIORequest; 9257 smIORequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody; 9258 satIOContext2 = &(smIORequestBody->transport.SATA.satIOContext); 9259 9260 satIOContext2->pSatDevData = pSatDevData; 9261 satIOContext2->pFis = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 9262 satIOContext2->pScsiCmnd = &(satIntIo->satIntSmScsiXchg.scsiCmnd); 9263 satIOContext2->pSense = &(smIORequestBody->transport.SATA.sensePayload); 9264 satIOContext2->pSmSenseData = &(smIORequestBody->transport.SATA.smSenseData); 9265 satIOContext2->pSmSenseData->senseData = satIOContext2->pSense; 9266 satIOContext2->smRequestBody = satIntIo->satIntRequestBody; 9267 satIOContext2->interruptContext = satIOContext->interruptContext; 9268 satIOContext2->satIntIoContext = satIntIo; 9269 satIOContext2->psmDeviceHandle = smDeviceHandle; 9270 satIOContext2->satOrgIOContext = satIOContext; 9271 9272 SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.len %d\n", satIntIo->satIntSmScsiXchg.smSgl1.len)); 9273 9274 SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.upper %d\n", satIntIo->satIntSmScsiXchg.smSgl1.upper)); 9275 9276 SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.lower %d\n", satIntIo->satIntSmScsiXchg.smSgl1.lower)); 9277 9278 SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.type %d\n", satIntIo->satIntSmScsiXchg.smSgl1.type)); 9279 9280 status = smsatRequestSense_1( smRoot, 9281 &(satIntIo->satIntSmIORequest), 9282 smDeviceHandle, 9283 &(satIntIo->satIntSmScsiXchg), 9284 satIOContext2); 9285 9286 if (status != SM_RC_SUCCESS) 9287 { 9288 smsatFreeIntIoResource( smRoot, 9289 pSatDevData, 9290 satIntIo); 9291 9292 /* failed during sending SMART RETURN STATUS */ 9293 smsatSetSensePayload( pSense, 9294 SCSI_SNSKEY_NO_SENSE, 9295 0, 9296 SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE, 9297 satIOContext); 9298 sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen)); 9299 9300 /*smEnqueueIO(smRoot, satIOContext);*/ 9301 9302 tdsmIOCompletedCB( smRoot, 9303 smIORequest, 9304 smIOSuccess, 9305 SCSI_STAT_CHECK_CONDITION, 9306 agNULL, 9307 satIOContext->interruptContext ); 9308 9309 SM_DBG1(("smsatRequestSense: else fail 2!!!\n")); 9310 return SM_RC_SUCCESS; 9311 } 9312 SM_DBG4(("smsatRequestSense: else return success\n")); 9313 return SM_RC_SUCCESS; 9314 } 9315 } 9316 9317 osGLOBAL bit32 9318 smsatRequestSense_1( 9319 smRoot_t *smRoot, 9320 smIORequest_t *smIORequest, 9321 smDeviceHandle_t *smDeviceHandle, 9322 smScsiInitiatorRequest_t *smScsiRequest, 9323 smSatIOContext_t *satIOContext 9324 ) 9325 { 9326 /* 9327 sends SAT_CHECK_POWER_MODE 9328 */ 9329 bit32 status; 9330 bit32 agRequestType; 9331 agsaFisRegHostToDevice_t *fis; 9332 9333 fis = satIOContext->pFis; 9334 SM_DBG5(("smsatRequestSense_1: start\n")); 9335 /* 9336 * Send the ATA CHECK POWER MODE command. 9337 */ 9338 fis->h.fisType = 0x27; /* Reg host to device */ 9339 fis->h.c_pmPort = 0x80; /* C Bit is set */ 9340 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */ 9341 fis->h.features = 0; 9342 fis->d.lbaLow = 0; 9343 fis->d.lbaMid = 0; 9344 fis->d.lbaHigh = 0; 9345 fis->d.device = 0; 9346 fis->d.lbaLowExp = 0; 9347 fis->d.lbaMidExp = 0; 9348 fis->d.lbaHighExp = 0; 9349 fis->d.featuresExp = 0; 9350 fis->d.sectorCount = 0; 9351 fis->d.sectorCountExp = 0; 9352 fis->d.reserved4 = 0; 9353 fis->d.control = 0; /* FIS HOB bit clear */ 9354 fis->d.reserved5 = 0; 9355 9356 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 9357 9358 /* Initialize CB for SATA completion. 9359 */ 9360 satIOContext->satCompleteCB = &smsatRequestSenseCB; 9361 9362 /* 9363 * Prepare SGL and send FIS to LL layer. 9364 */ 9365 satIOContext->reqType = agRequestType; /* Save it */ 9366 9367 9368 SM_DBG4(("smsatRequestSense_1: smSgl1.len %d\n", smScsiRequest->smSgl1.len)); 9369 9370 SM_DBG4(("smsatRequestSense_1: smSgl1.upper %d\n", smScsiRequest->smSgl1.upper)); 9371 9372 SM_DBG4(("smsatRequestSense_1: smSgl1.lower %d\n", smScsiRequest->smSgl1.lower)); 9373 9374 SM_DBG4(("smsatRequestSense_1: smSgl1.type %d\n", smScsiRequest->smSgl1.type)); 9375 9376 // smhexdump("smsatRequestSense_1", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t)); 9377 9378 status = smsataLLIOStart( smRoot, 9379 smIORequest, 9380 smDeviceHandle, 9381 smScsiRequest, 9382 satIOContext); 9383 9384 9385 9386 return status; 9387 } 9388 9389 osGLOBAL bit32 9390 smsatModeSense6( 9391 smRoot_t *smRoot, 9392 smIORequest_t *smIORequest, 9393 smDeviceHandle_t *smDeviceHandle, 9394 smScsiInitiatorRequest_t *smScsiRequest, 9395 smSatIOContext_t *satIOContext 9396 ) 9397 { 9398 smScsiRspSense_t *pSense; 9399 bit32 allocationLen; 9400 smIniScsiCmnd_t *scsiCmnd; 9401 bit32 pageSupported; 9402 bit8 page; 9403 bit8 *pModeSense; /* Mode Sense data buffer */ 9404 smDeviceData_t *pSatDevData; 9405 bit8 PC; 9406 bit8 AllPages[MODE_SENSE6_RETURN_ALL_PAGES_LEN]; 9407 bit8 Control[MODE_SENSE6_CONTROL_PAGE_LEN]; 9408 bit8 RWErrorRecovery[MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN]; 9409 bit8 Caching[MODE_SENSE6_CACHING_LEN]; 9410 bit8 InfoExceptionCtrl[MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN]; 9411 bit8 lenRead = 0; 9412 9413 9414 pSense = satIOContext->pSense; 9415 scsiCmnd = &smScsiRequest->scsiCmnd; 9416 pModeSense = (bit8 *) smScsiRequest->sglVirtualAddr; 9417 pSatDevData = satIOContext->pSatDevData; 9418 9419 //smhexdump("smsatModeSense6", (bit8 *)scsiCmnd->cdb, 6); 9420 SM_DBG5(("smsatModeSense6: start\n")); 9421 /* checking CONTROL */ 9422 /* NACA == 1 or LINK == 1*/ 9423 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 9424 { 9425 smsatSetSensePayload( pSense, 9426 SCSI_SNSKEY_ILLEGAL_REQUEST, 9427 0, 9428 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9429 satIOContext); 9430 /*smEnqueueIO(smRoot, satIOContext);*/ 9431 tdsmIOCompletedCB( smRoot, 9432 smIORequest, 9433 smIOSuccess, 9434 SCSI_STAT_CHECK_CONDITION, 9435 satIOContext->pSmSenseData, 9436 satIOContext->interruptContext ); 9437 SM_DBG1(("smsatModeSense6: return control!!!\n")); 9438 return SM_RC_SUCCESS; 9439 } 9440 /* checking PC(Page Control) 9441 SAT revion 8, 8.5.3 p33 and 10.1.2, p66 9442 */ 9443 PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PC_MASK); 9444 if (PC != 0) 9445 { 9446 smsatSetSensePayload( pSense, 9447 SCSI_SNSKEY_ILLEGAL_REQUEST, 9448 0, 9449 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9450 satIOContext); 9451 /*smEnqueueIO(smRoot, satIOContext);*/ 9452 tdsmIOCompletedCB( smRoot, 9453 smIORequest, 9454 smIOSuccess, 9455 SCSI_STAT_CHECK_CONDITION, 9456 satIOContext->pSmSenseData, 9457 satIOContext->interruptContext ); 9458 SM_DBG1(("smsatModeSense6: return due to PC value pc 0x%x!!!\n", PC >> 6)); 9459 return SM_RC_SUCCESS; 9460 } 9461 /* reading PAGE CODE */ 9462 page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PAGE_CODE_MASK); 9463 9464 9465 SM_DBG5(("smsatModeSense6: page=0x%x\n", page)); 9466 9467 allocationLen = scsiCmnd->cdb[4]; 9468 allocationLen = MIN(allocationLen, scsiCmnd->expDataLength); 9469 /* 9470 Based on page code value, returns a corresponding mode page 9471 note: no support for subpage 9472 */ 9473 switch(page) 9474 { 9475 case MODESENSE_RETURN_ALL_PAGES: 9476 case MODESENSE_CONTROL_PAGE: /* control */ 9477 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */ 9478 case MODESENSE_CACHING: /* caching */ 9479 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/ 9480 pageSupported = agTRUE; 9481 break; 9482 case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */ 9483 default: 9484 pageSupported = agFALSE; 9485 break; 9486 } 9487 9488 if (pageSupported == agFALSE) 9489 { 9490 9491 SM_DBG1(("smsatModeSense6 *** ERROR *** not supported page 0x%x did %d!!!\n", 9492 page, pSatDevData->id)); 9493 9494 smsatSetSensePayload( pSense, 9495 SCSI_SNSKEY_ILLEGAL_REQUEST, 9496 0, 9497 SCSI_SNSCODE_INVALID_COMMAND, 9498 satIOContext); 9499 9500 /*smEnqueueIO(smRoot, satIOContext);*/ 9501 9502 tdsmIOCompletedCB( smRoot, 9503 smIORequest, 9504 smIOSuccess, 9505 SCSI_STAT_CHECK_CONDITION, 9506 satIOContext->pSmSenseData, 9507 satIOContext->interruptContext ); 9508 return SM_RC_SUCCESS; 9509 } 9510 9511 switch(page) 9512 { 9513 case MODESENSE_RETURN_ALL_PAGES: 9514 lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_RETURN_ALL_PAGES_LEN); 9515 break; 9516 case MODESENSE_CONTROL_PAGE: /* control */ 9517 lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_CONTROL_PAGE_LEN); 9518 break; 9519 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */ 9520 lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN); 9521 break; 9522 case MODESENSE_CACHING: /* caching */ 9523 lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_CACHING_LEN); 9524 break; 9525 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/ 9526 lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN); 9527 break; 9528 default: 9529 SM_DBG1(("smsatModeSense6: default error page %d!!!\n", page)); 9530 break; 9531 } 9532 9533 if (page == MODESENSE_RETURN_ALL_PAGES) 9534 { 9535 SM_DBG5(("smsatModeSense6: MODESENSE_RETURN_ALL_PAGES\n")); 9536 AllPages[0] = (bit8)(lenRead - 1); 9537 AllPages[1] = 0x00; /* default medium type (currently mounted medium type) */ 9538 AllPages[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 9539 AllPages[3] = 0x08; /* block descriptor length */ 9540 9541 /* 9542 * Fill-up direct-access device block-descriptor, SAT, Table 19 9543 */ 9544 9545 /* density code */ 9546 AllPages[4] = 0x04; /* density-code : reserved for direct-access */ 9547 /* number of blocks */ 9548 AllPages[5] = 0x00; /* unspecified */ 9549 AllPages[6] = 0x00; /* unspecified */ 9550 AllPages[7] = 0x00; /* unspecified */ 9551 /* reserved */ 9552 AllPages[8] = 0x00; /* reserved */ 9553 /* Block size */ 9554 AllPages[9] = 0x00; 9555 AllPages[10] = 0x02; /* Block size is always 512 bytes */ 9556 AllPages[11] = 0x00; 9557 9558 /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */ 9559 AllPages[12] = 0x01; /* page code */ 9560 AllPages[13] = 0x0A; /* page length */ 9561 AllPages[14] = 0x40; /* ARRE is set */ 9562 AllPages[15] = 0x00; 9563 AllPages[16] = 0x00; 9564 AllPages[17] = 0x00; 9565 AllPages[18] = 0x00; 9566 AllPages[19] = 0x00; 9567 AllPages[20] = 0x00; 9568 AllPages[21] = 0x00; 9569 AllPages[22] = 0x00; 9570 AllPages[23] = 0x00; 9571 /* MODESENSE_CACHING */ 9572 AllPages[24] = 0x08; /* page code */ 9573 AllPages[25] = 0x12; /* page length */ 9574 if (pSatDevData->satWriteCacheEnabled == agTRUE) 9575 { 9576 AllPages[26] = 0x04;/* WCE bit is set */ 9577 } 9578 else 9579 { 9580 AllPages[26] = 0x00;/* WCE bit is NOT set */ 9581 } 9582 9583 AllPages[27] = 0x00; 9584 AllPages[28] = 0x00; 9585 AllPages[29] = 0x00; 9586 AllPages[30] = 0x00; 9587 AllPages[31] = 0x00; 9588 AllPages[32] = 0x00; 9589 AllPages[33] = 0x00; 9590 AllPages[34] = 0x00; 9591 AllPages[35] = 0x00; 9592 if (pSatDevData->satLookAheadEnabled == agTRUE) 9593 { 9594 AllPages[36] = 0x00;/* DRA bit is NOT set */ 9595 } 9596 else 9597 { 9598 AllPages[36] = 0x20;/* DRA bit is set */ 9599 } 9600 AllPages[37] = 0x00; 9601 AllPages[38] = 0x00; 9602 AllPages[39] = 0x00; 9603 AllPages[40] = 0x00; 9604 AllPages[41] = 0x00; 9605 AllPages[42] = 0x00; 9606 AllPages[43] = 0x00; 9607 /* MODESENSE_CONTROL_PAGE */ 9608 AllPages[44] = 0x0A; /* page code */ 9609 AllPages[45] = 0x0A; /* page length */ 9610 AllPages[46] = 0x02; /* only GLTSD bit is set */ 9611 if (pSatDevData->satNCQ == agTRUE) 9612 { 9613 AllPages[47] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/ 9614 } 9615 else 9616 { 9617 AllPages[47] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */ 9618 } 9619 AllPages[48] = 0x00; 9620 AllPages[49] = 0x00; 9621 AllPages[50] = 0x00; /* obsolete */ 9622 AllPages[51] = 0x00; /* obsolete */ 9623 AllPages[52] = 0xFF; /* Busy Timeout Period */ 9624 AllPages[53] = 0xFF; /* Busy Timeout Period */ 9625 AllPages[54] = 0x00; /* we don't support non-000b value for the self-test code */ 9626 AllPages[55] = 0x00; /* we don't support non-000b value for the self-test code */ 9627 /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */ 9628 AllPages[56] = 0x1C; /* page code */ 9629 AllPages[57] = 0x0A; /* page length */ 9630 if (pSatDevData->satSMARTEnabled == agTRUE) 9631 { 9632 AllPages[58] = 0x00;/* DEXCPT bit is NOT set */ 9633 } 9634 else 9635 { 9636 AllPages[58] = 0x08;/* DEXCPT bit is set */ 9637 } 9638 AllPages[59] = 0x00; /* We don't support MRIE */ 9639 AllPages[60] = 0x00; /* Interval timer vendor-specific */ 9640 AllPages[61] = 0x00; 9641 AllPages[62] = 0x00; 9642 AllPages[63] = 0x00; 9643 AllPages[64] = 0x00; /* REPORT-COUNT */ 9644 AllPages[65] = 0x00; 9645 AllPages[66] = 0x00; 9646 AllPages[67] = 0x00; 9647 9648 sm_memcpy(pModeSense, &AllPages, lenRead); 9649 } 9650 else if (page == MODESENSE_CONTROL_PAGE) 9651 { 9652 SM_DBG5(("smsatModeSense6: MODESENSE_CONTROL_PAGE\n")); 9653 Control[0] = MODE_SENSE6_CONTROL_PAGE_LEN - 1; 9654 Control[1] = 0x00; /* default medium type (currently mounted medium type) */ 9655 Control[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 9656 Control[3] = 0x08; /* block descriptor length */ 9657 /* 9658 * Fill-up direct-access device block-descriptor, SAT, Table 19 9659 */ 9660 9661 /* density code */ 9662 Control[4] = 0x04; /* density-code : reserved for direct-access */ 9663 /* number of blocks */ 9664 Control[5] = 0x00; /* unspecified */ 9665 Control[6] = 0x00; /* unspecified */ 9666 Control[7] = 0x00; /* unspecified */ 9667 /* reserved */ 9668 Control[8] = 0x00; /* reserved */ 9669 /* Block size */ 9670 Control[9] = 0x00; 9671 Control[10] = 0x02; /* Block size is always 512 bytes */ 9672 Control[11] = 0x00; 9673 /* 9674 * Fill-up control mode page, SAT, Table 65 9675 */ 9676 Control[12] = 0x0A; /* page code */ 9677 Control[13] = 0x0A; /* page length */ 9678 Control[14] = 0x02; /* only GLTSD bit is set */ 9679 if (pSatDevData->satNCQ == agTRUE) 9680 { 9681 Control[15] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/ 9682 } 9683 else 9684 { 9685 Control[15] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */ 9686 } 9687 Control[16] = 0x00; 9688 Control[17] = 0x00; 9689 Control[18] = 0x00; /* obsolete */ 9690 Control[19] = 0x00; /* obsolete */ 9691 Control[20] = 0xFF; /* Busy Timeout Period */ 9692 Control[21] = 0xFF; /* Busy Timeout Period */ 9693 Control[22] = 0x00; /* we don't support non-000b value for the self-test code */ 9694 Control[23] = 0x00; /* we don't support non-000b value for the self-test code */ 9695 9696 sm_memcpy(pModeSense, &Control, lenRead); 9697 9698 } 9699 else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE) 9700 { 9701 SM_DBG5(("smsatModeSense6: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n")); 9702 RWErrorRecovery[0] = MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN - 1; 9703 RWErrorRecovery[1] = 0x00; /* default medium type (currently mounted medium type) */ 9704 RWErrorRecovery[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 9705 RWErrorRecovery[3] = 0x08; /* block descriptor length */ 9706 /* 9707 * Fill-up direct-access device block-descriptor, SAT, Table 19 9708 */ 9709 9710 /* density code */ 9711 RWErrorRecovery[4] = 0x04; /* density-code : reserved for direct-access */ 9712 /* number of blocks */ 9713 RWErrorRecovery[5] = 0x00; /* unspecified */ 9714 RWErrorRecovery[6] = 0x00; /* unspecified */ 9715 RWErrorRecovery[7] = 0x00; /* unspecified */ 9716 /* reserved */ 9717 RWErrorRecovery[8] = 0x00; /* reserved */ 9718 /* Block size */ 9719 RWErrorRecovery[9] = 0x00; 9720 RWErrorRecovery[10] = 0x02; /* Block size is always 512 bytes */ 9721 RWErrorRecovery[11] = 0x00; 9722 /* 9723 * Fill-up Read-Write Error Recovery mode page, SAT, Table 66 9724 */ 9725 RWErrorRecovery[12] = 0x01; /* page code */ 9726 RWErrorRecovery[13] = 0x0A; /* page length */ 9727 RWErrorRecovery[14] = 0x40; /* ARRE is set */ 9728 RWErrorRecovery[15] = 0x00; 9729 RWErrorRecovery[16] = 0x00; 9730 RWErrorRecovery[17] = 0x00; 9731 RWErrorRecovery[18] = 0x00; 9732 RWErrorRecovery[19] = 0x00; 9733 RWErrorRecovery[20] = 0x00; 9734 RWErrorRecovery[21] = 0x00; 9735 RWErrorRecovery[22] = 0x00; 9736 RWErrorRecovery[23] = 0x00; 9737 9738 sm_memcpy(pModeSense, &RWErrorRecovery, lenRead); 9739 9740 } 9741 else if (page == MODESENSE_CACHING) 9742 { 9743 SM_DBG5(("smsatModeSense6: MODESENSE_CACHING\n")); 9744 /* special case */ 9745 if (allocationLen == 4 && page == MODESENSE_CACHING) 9746 { 9747 SM_DBG5(("smsatModeSense6: linux 2.6.8.24 support\n")); 9748 9749 Caching[0] = 0x20 - 1; /* 32 - 1 */ 9750 Caching[1] = 0x00; /* default medium type (currently mounted medium type) */ 9751 Caching[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 9752 Caching[3] = 0x08; /* block descriptor length */ 9753 9754 sm_memcpy(pModeSense, &Caching, 4); 9755 /*smEnqueueIO(smRoot, satIOContext);*/ 9756 9757 tdsmIOCompletedCB( smRoot, 9758 smIORequest, 9759 smIOSuccess, 9760 SCSI_STAT_GOOD, 9761 agNULL, 9762 satIOContext->interruptContext); 9763 return SM_RC_SUCCESS; 9764 } 9765 Caching[0] = MODE_SENSE6_CACHING_LEN - 1; 9766 Caching[1] = 0x00; /* default medium type (currently mounted medium type) */ 9767 Caching[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 9768 Caching[3] = 0x08; /* block descriptor length */ 9769 /* 9770 * Fill-up direct-access device block-descriptor, SAT, Table 19 9771 */ 9772 9773 /* density code */ 9774 Caching[4] = 0x04; /* density-code : reserved for direct-access */ 9775 /* number of blocks */ 9776 Caching[5] = 0x00; /* unspecified */ 9777 Caching[6] = 0x00; /* unspecified */ 9778 Caching[7] = 0x00; /* unspecified */ 9779 /* reserved */ 9780 Caching[8] = 0x00; /* reserved */ 9781 /* Block size */ 9782 Caching[9] = 0x00; 9783 Caching[10] = 0x02; /* Block size is always 512 bytes */ 9784 Caching[11] = 0x00; 9785 /* 9786 * Fill-up Caching mode page, SAT, Table 67 9787 */ 9788 /* length 20 */ 9789 Caching[12] = 0x08; /* page code */ 9790 Caching[13] = 0x12; /* page length */ 9791 if (pSatDevData->satWriteCacheEnabled == agTRUE) 9792 { 9793 Caching[14] = 0x04;/* WCE bit is set */ 9794 } 9795 else 9796 { 9797 Caching[14] = 0x00;/* WCE bit is NOT set */ 9798 } 9799 9800 Caching[15] = 0x00; 9801 Caching[16] = 0x00; 9802 Caching[17] = 0x00; 9803 Caching[18] = 0x00; 9804 Caching[19] = 0x00; 9805 Caching[20] = 0x00; 9806 Caching[21] = 0x00; 9807 Caching[22] = 0x00; 9808 Caching[23] = 0x00; 9809 if (pSatDevData->satLookAheadEnabled == agTRUE) 9810 { 9811 Caching[24] = 0x00;/* DRA bit is NOT set */ 9812 } 9813 else 9814 { 9815 Caching[24] = 0x20;/* DRA bit is set */ 9816 } 9817 Caching[25] = 0x00; 9818 Caching[26] = 0x00; 9819 Caching[27] = 0x00; 9820 Caching[28] = 0x00; 9821 Caching[29] = 0x00; 9822 Caching[30] = 0x00; 9823 Caching[31] = 0x00; 9824 9825 sm_memcpy(pModeSense, &Caching, lenRead); 9826 9827 } 9828 else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE) 9829 { 9830 SM_DBG5(("smsatModeSense6: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n")); 9831 InfoExceptionCtrl[0] = MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN - 1; 9832 InfoExceptionCtrl[1] = 0x00; /* default medium type (currently mounted medium type) */ 9833 InfoExceptionCtrl[2] = 0x00; /* no write-protect, no support for DPO-FUA */ 9834 InfoExceptionCtrl[3] = 0x08; /* block descriptor length */ 9835 /* 9836 * Fill-up direct-access device block-descriptor, SAT, Table 19 9837 */ 9838 9839 /* density code */ 9840 InfoExceptionCtrl[4] = 0x04; /* density-code : reserved for direct-access */ 9841 /* number of blocks */ 9842 InfoExceptionCtrl[5] = 0x00; /* unspecified */ 9843 InfoExceptionCtrl[6] = 0x00; /* unspecified */ 9844 InfoExceptionCtrl[7] = 0x00; /* unspecified */ 9845 /* reserved */ 9846 InfoExceptionCtrl[8] = 0x00; /* reserved */ 9847 /* Block size */ 9848 InfoExceptionCtrl[9] = 0x00; 9849 InfoExceptionCtrl[10] = 0x02; /* Block size is always 512 bytes */ 9850 InfoExceptionCtrl[11] = 0x00; 9851 /* 9852 * Fill-up informational-exceptions control mode page, SAT, Table 68 9853 */ 9854 InfoExceptionCtrl[12] = 0x1C; /* page code */ 9855 InfoExceptionCtrl[13] = 0x0A; /* page length */ 9856 if (pSatDevData->satSMARTEnabled == agTRUE) 9857 { 9858 InfoExceptionCtrl[14] = 0x00;/* DEXCPT bit is NOT set */ 9859 } 9860 else 9861 { 9862 InfoExceptionCtrl[14] = 0x08;/* DEXCPT bit is set */ 9863 } 9864 InfoExceptionCtrl[15] = 0x00; /* We don't support MRIE */ 9865 InfoExceptionCtrl[16] = 0x00; /* Interval timer vendor-specific */ 9866 InfoExceptionCtrl[17] = 0x00; 9867 InfoExceptionCtrl[18] = 0x00; 9868 InfoExceptionCtrl[19] = 0x00; 9869 InfoExceptionCtrl[20] = 0x00; /* REPORT-COUNT */ 9870 InfoExceptionCtrl[21] = 0x00; 9871 InfoExceptionCtrl[22] = 0x00; 9872 InfoExceptionCtrl[23] = 0x00; 9873 sm_memcpy(pModeSense, &InfoExceptionCtrl, lenRead); 9874 9875 } 9876 else 9877 { 9878 /* Error */ 9879 SM_DBG1(("smsatModeSense6: Error page %d!!!\n", page)); 9880 smsatSetSensePayload( pSense, 9881 SCSI_SNSKEY_ILLEGAL_REQUEST, 9882 0, 9883 SCSI_SNSCODE_INVALID_COMMAND, 9884 satIOContext); 9885 9886 /*smEnqueueIO(smRoot, satIOContext);*/ 9887 9888 tdsmIOCompletedCB( smRoot, 9889 smIORequest, 9890 smIOSuccess, 9891 SCSI_STAT_CHECK_CONDITION, 9892 satIOContext->pSmSenseData, 9893 satIOContext->interruptContext ); 9894 return SM_RC_SUCCESS; 9895 } 9896 9897 /* there can be only underrun not overrun in error case */ 9898 if (allocationLen > lenRead) 9899 { 9900 SM_DBG6(("smsatModeSense6 reporting underrun lenRead=0x%x allocationLen=0x%x\n", lenRead, allocationLen)); 9901 9902 /*smEnqueueIO(smRoot, satIOContext);*/ 9903 9904 tdsmIOCompletedCB( smRoot, 9905 smIORequest, 9906 smIOUnderRun, 9907 allocationLen - lenRead, 9908 agNULL, 9909 satIOContext->interruptContext ); 9910 9911 9912 } 9913 else 9914 { 9915 /*smEnqueueIO(smRoot, satIOContext);*/ 9916 9917 tdsmIOCompletedCB( smRoot, 9918 smIORequest, 9919 smIOSuccess, 9920 SCSI_STAT_GOOD, 9921 agNULL, 9922 satIOContext->interruptContext); 9923 } 9924 9925 return SM_RC_SUCCESS; 9926 9927 } 9928 9929 osGLOBAL bit32 9930 smsatModeSense10( 9931 smRoot_t *smRoot, 9932 smIORequest_t *smIORequest, 9933 smDeviceHandle_t *smDeviceHandle, 9934 smScsiInitiatorRequest_t *smScsiRequest, 9935 smSatIOContext_t *satIOContext 9936 ) 9937 { 9938 smScsiRspSense_t *pSense; 9939 bit32 allocationLen; 9940 smIniScsiCmnd_t *scsiCmnd; 9941 bit32 pageSupported; 9942 bit8 page; 9943 bit8 *pModeSense; /* Mode Sense data buffer */ 9944 smDeviceData_t *pSatDevData; 9945 bit8 PC; /* page control */ 9946 bit8 LLBAA; /* Long LBA Accepted */ 9947 bit32 index; 9948 bit8 AllPages[MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN]; 9949 bit8 Control[MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN]; 9950 bit8 RWErrorRecovery[MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN]; 9951 bit8 Caching[MODE_SENSE10_CACHING_LLBAA_LEN]; 9952 bit8 InfoExceptionCtrl[MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN]; 9953 bit8 lenRead = 0; 9954 9955 pSense = satIOContext->pSense; 9956 scsiCmnd = &smScsiRequest->scsiCmnd; 9957 pModeSense = (bit8 *) smScsiRequest->sglVirtualAddr; 9958 pSatDevData = satIOContext->pSatDevData; 9959 SM_DBG5(("smsatModeSense10: start\n")); 9960 /* checking CONTROL */ 9961 /* NACA == 1 or LINK == 1*/ 9962 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 9963 { 9964 smsatSetSensePayload( pSense, 9965 SCSI_SNSKEY_ILLEGAL_REQUEST, 9966 0, 9967 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9968 satIOContext); 9969 9970 /*smEnqueueIO(smRoot, satIOContext);*/ 9971 9972 tdsmIOCompletedCB( smRoot, 9973 smIORequest, 9974 smIOSuccess, 9975 SCSI_STAT_CHECK_CONDITION, 9976 satIOContext->pSmSenseData, 9977 satIOContext->interruptContext ); 9978 9979 SM_DBG1(("smsatModeSense10: return control!!!\n")); 9980 return SM_RC_SUCCESS; 9981 } 9982 9983 /* checking PC(Page Control) 9984 SAT revion 8, 8.5.3 p33 and 10.1.2, p66 9985 */ 9986 PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PC_MASK); 9987 if (PC != 0) 9988 { 9989 smsatSetSensePayload( pSense, 9990 SCSI_SNSKEY_ILLEGAL_REQUEST, 9991 0, 9992 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 9993 satIOContext); 9994 9995 /*smEnqueueIO(smRoot, satIOContext);*/ 9996 9997 tdsmIOCompletedCB( smRoot, 9998 smIORequest, 9999 smIOSuccess, 10000 SCSI_STAT_CHECK_CONDITION, 10001 satIOContext->pSmSenseData, 10002 satIOContext->interruptContext ); 10003 10004 SM_DBG1(("smsatModeSense10: return due to PC value pc 0x%x!!!\n", PC)); 10005 return SM_RC_SUCCESS; 10006 } 10007 10008 /* finding LLBAA bit */ 10009 LLBAA = (bit8)((scsiCmnd->cdb[1]) & SCSI_MODE_SENSE10_LLBAA_MASK); 10010 10011 /* reading PAGE CODE */ 10012 page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PAGE_CODE_MASK); 10013 SM_DBG5(("smsatModeSense10: page=0x%x, did %d\n", page, pSatDevData->id)); 10014 allocationLen = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 10015 allocationLen = MIN(allocationLen, scsiCmnd->expDataLength); 10016 10017 /* 10018 Based on page code value, returns a corresponding mode page 10019 note: no support for subpage 10020 */ 10021 switch(page) 10022 { 10023 case MODESENSE_RETURN_ALL_PAGES: /* return all pages */ 10024 case MODESENSE_CONTROL_PAGE: /* control */ 10025 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */ 10026 case MODESENSE_CACHING: /* caching */ 10027 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/ 10028 pageSupported = agTRUE; 10029 break; 10030 case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */ 10031 default: 10032 pageSupported = agFALSE; 10033 break; 10034 } 10035 if (pageSupported == agFALSE) 10036 { 10037 SM_DBG1(("smsatModeSense10 *** ERROR *** not supported page 0x%x did %d!!!\n", page, pSatDevData->id)); 10038 10039 smsatSetSensePayload( pSense, 10040 SCSI_SNSKEY_ILLEGAL_REQUEST, 10041 0, 10042 SCSI_SNSCODE_INVALID_COMMAND, 10043 satIOContext); 10044 /*smEnqueueIO(smRoot, satIOContext);*/ 10045 tdsmIOCompletedCB( smRoot, 10046 smIORequest, 10047 smIOSuccess, 10048 SCSI_STAT_CHECK_CONDITION, 10049 satIOContext->pSmSenseData, 10050 satIOContext->interruptContext ); 10051 return SM_RC_SUCCESS; 10052 } 10053 switch(page) 10054 { 10055 case MODESENSE_RETURN_ALL_PAGES: 10056 if (LLBAA) 10057 { 10058 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN); 10059 } 10060 else 10061 { 10062 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_RETURN_ALL_PAGES_LEN); 10063 } 10064 break; 10065 case MODESENSE_CONTROL_PAGE: /* control */ 10066 if (LLBAA) 10067 { 10068 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN); 10069 } 10070 else 10071 { 10072 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CONTROL_PAGE_LEN); 10073 } 10074 break; 10075 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */ 10076 if (LLBAA) 10077 { 10078 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN); 10079 } 10080 else 10081 { 10082 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LEN); 10083 } 10084 break; 10085 case MODESENSE_CACHING: /* caching */ 10086 if (LLBAA) 10087 { 10088 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CACHING_LLBAA_LEN); 10089 } 10090 else 10091 { 10092 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CACHING_LEN); 10093 } 10094 break; 10095 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/ 10096 if (LLBAA) 10097 { 10098 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN); 10099 } 10100 else 10101 { 10102 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN); 10103 } 10104 break; 10105 default: 10106 SM_DBG1(("smsatModeSense10: default error page %d!!!\n", page)); 10107 break; 10108 } 10109 10110 if (page == MODESENSE_RETURN_ALL_PAGES) 10111 { 10112 SM_DBG5(("smsatModeSense10: MODESENSE_RETURN_ALL_PAGES\n")); 10113 AllPages[0] = 0; 10114 AllPages[1] = (bit8)(lenRead - 2); 10115 AllPages[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */ 10116 AllPages[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */ 10117 if (LLBAA) 10118 { 10119 AllPages[4] = 0x00; /* reserved and LONGLBA */ 10120 AllPages[4] = (bit8)(AllPages[4] | 0x1); /* LONGLBA is set */ 10121 } 10122 else 10123 { 10124 AllPages[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */ 10125 } 10126 AllPages[5] = 0x00; /* reserved */ 10127 AllPages[6] = 0x00; /* block descriptot length */ 10128 if (LLBAA) 10129 { 10130 AllPages[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */ 10131 } 10132 else 10133 { 10134 AllPages[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */ 10135 } 10136 10137 /* 10138 * Fill-up direct-access device block-descriptor, SAT, Table 19 10139 */ 10140 10141 if (LLBAA) 10142 { 10143 /* density code */ 10144 AllPages[8] = 0x04; /* density-code : reserved for direct-access */ 10145 /* number of blocks */ 10146 AllPages[9] = 0x00; /* unspecified */ 10147 AllPages[10] = 0x00; /* unspecified */ 10148 AllPages[11] = 0x00; /* unspecified */ 10149 AllPages[12] = 0x00; /* unspecified */ 10150 AllPages[13] = 0x00; /* unspecified */ 10151 AllPages[14] = 0x00; /* unspecified */ 10152 AllPages[15] = 0x00; /* unspecified */ 10153 /* reserved */ 10154 AllPages[16] = 0x00; /* reserved */ 10155 AllPages[17] = 0x00; /* reserved */ 10156 AllPages[18] = 0x00; /* reserved */ 10157 AllPages[19] = 0x00; /* reserved */ 10158 /* Block size */ 10159 AllPages[20] = 0x00; 10160 AllPages[21] = 0x00; 10161 AllPages[22] = 0x02; /* Block size is always 512 bytes */ 10162 AllPages[23] = 0x00; 10163 } 10164 else 10165 { 10166 /* density code */ 10167 AllPages[8] = 0x04; /* density-code : reserved for direct-access */ 10168 /* number of blocks */ 10169 AllPages[9] = 0x00; /* unspecified */ 10170 AllPages[10] = 0x00; /* unspecified */ 10171 AllPages[11] = 0x00; /* unspecified */ 10172 /* reserved */ 10173 AllPages[12] = 0x00; /* reserved */ 10174 /* Block size */ 10175 AllPages[13] = 0x00; 10176 AllPages[14] = 0x02; /* Block size is always 512 bytes */ 10177 AllPages[15] = 0x00; 10178 } 10179 10180 if (LLBAA) 10181 { 10182 index = 24; 10183 } 10184 else 10185 { 10186 index = 16; 10187 } 10188 /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */ 10189 AllPages[index+0] = 0x01; /* page code */ 10190 AllPages[index+1] = 0x0A; /* page length */ 10191 AllPages[index+2] = 0x40; /* ARRE is set */ 10192 AllPages[index+3] = 0x00; 10193 AllPages[index+4] = 0x00; 10194 AllPages[index+5] = 0x00; 10195 AllPages[index+6] = 0x00; 10196 AllPages[index+7] = 0x00; 10197 AllPages[index+8] = 0x00; 10198 AllPages[index+9] = 0x00; 10199 AllPages[index+10] = 0x00; 10200 AllPages[index+11] = 0x00; 10201 10202 /* MODESENSE_CACHING */ 10203 /* 10204 * Fill-up Caching mode page, SAT, Table 67 10205 */ 10206 /* length 20 */ 10207 AllPages[index+12] = 0x08; /* page code */ 10208 AllPages[index+13] = 0x12; /* page length */ 10209 if (pSatDevData->satWriteCacheEnabled == agTRUE) 10210 { 10211 AllPages[index+14] = 0x04;/* WCE bit is set */ 10212 } 10213 else 10214 { 10215 AllPages[index+14] = 0x00;/* WCE bit is NOT set */ 10216 } 10217 10218 AllPages[index+15] = 0x00; 10219 AllPages[index+16] = 0x00; 10220 AllPages[index+17] = 0x00; 10221 AllPages[index+18] = 0x00; 10222 AllPages[index+19] = 0x00; 10223 AllPages[index+20] = 0x00; 10224 AllPages[index+21] = 0x00; 10225 AllPages[index+22] = 0x00; 10226 AllPages[index+23] = 0x00; 10227 if (pSatDevData->satLookAheadEnabled == agTRUE) 10228 { 10229 AllPages[index+24] = 0x00;/* DRA bit is NOT set */ 10230 } 10231 else 10232 { 10233 AllPages[index+24] = 0x20;/* DRA bit is set */ 10234 } 10235 AllPages[index+25] = 0x00; 10236 AllPages[index+26] = 0x00; 10237 AllPages[index+27] = 0x00; 10238 AllPages[index+28] = 0x00; 10239 AllPages[index+29] = 0x00; 10240 AllPages[index+30] = 0x00; 10241 AllPages[index+31] = 0x00; 10242 10243 /* MODESENSE_CONTROL_PAGE */ 10244 /* 10245 * Fill-up control mode page, SAT, Table 65 10246 */ 10247 AllPages[index+32] = 0x0A; /* page code */ 10248 AllPages[index+33] = 0x0A; /* page length */ 10249 AllPages[index+34] = 0x02; /* only GLTSD bit is set */ 10250 if (pSatDevData->satNCQ == agTRUE) 10251 { 10252 AllPages[index+35] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/ 10253 } 10254 else 10255 { 10256 AllPages[index+35] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */ 10257 } 10258 AllPages[index+36] = 0x00; 10259 AllPages[index+37] = 0x00; 10260 AllPages[index+38] = 0x00; /* obsolete */ 10261 AllPages[index+39] = 0x00; /* obsolete */ 10262 AllPages[index+40] = 0xFF; /* Busy Timeout Period */ 10263 AllPages[index+41] = 0xFF; /* Busy Timeout Period */ 10264 AllPages[index+42] = 0x00; /* we don't support non-000b value for the self-test code */ 10265 AllPages[index+43] = 0x00; /* we don't support non-000b value for the self-test code */ 10266 10267 /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */ 10268 /* 10269 * Fill-up informational-exceptions control mode page, SAT, Table 68 10270 */ 10271 AllPages[index+44] = 0x1C; /* page code */ 10272 AllPages[index+45] = 0x0A; /* page length */ 10273 if (pSatDevData->satSMARTEnabled == agTRUE) 10274 { 10275 AllPages[index+46] = 0x00;/* DEXCPT bit is NOT set */ 10276 } 10277 else 10278 { 10279 AllPages[index+46] = 0x08;/* DEXCPT bit is set */ 10280 } 10281 AllPages[index+47] = 0x00; /* We don't support MRIE */ 10282 AllPages[index+48] = 0x00; /* Interval timer vendor-specific */ 10283 AllPages[index+49] = 0x00; 10284 AllPages[index+50] = 0x00; 10285 AllPages[index+51] = 0x00; 10286 AllPages[index+52] = 0x00; /* REPORT-COUNT */ 10287 AllPages[index+53] = 0x00; 10288 AllPages[index+54] = 0x00; 10289 AllPages[index+55] = 0x00; 10290 10291 sm_memcpy(pModeSense, &AllPages, lenRead); 10292 } 10293 else if (page == MODESENSE_CONTROL_PAGE) 10294 { 10295 SM_DBG5(("smsatModeSense10: MODESENSE_CONTROL_PAGE\n")); 10296 Control[0] = 0; 10297 Control[1] = (bit8)(lenRead - 2); 10298 Control[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */ 10299 Control[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */ 10300 if (LLBAA) 10301 { 10302 Control[4] = 0x00; /* reserved and LONGLBA */ 10303 Control[4] = (bit8)(Control[4] | 0x1); /* LONGLBA is set */ 10304 } 10305 else 10306 { 10307 Control[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */ 10308 } 10309 Control[5] = 0x00; /* reserved */ 10310 Control[6] = 0x00; /* block descriptot length */ 10311 if (LLBAA) 10312 { 10313 Control[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */ 10314 } 10315 else 10316 { 10317 Control[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */ 10318 } 10319 10320 /* 10321 * Fill-up direct-access device block-descriptor, SAT, Table 19 10322 */ 10323 10324 if (LLBAA) 10325 { 10326 /* density code */ 10327 Control[8] = 0x04; /* density-code : reserved for direct-access */ 10328 /* number of blocks */ 10329 Control[9] = 0x00; /* unspecified */ 10330 Control[10] = 0x00; /* unspecified */ 10331 Control[11] = 0x00; /* unspecified */ 10332 Control[12] = 0x00; /* unspecified */ 10333 Control[13] = 0x00; /* unspecified */ 10334 Control[14] = 0x00; /* unspecified */ 10335 Control[15] = 0x00; /* unspecified */ 10336 /* reserved */ 10337 Control[16] = 0x00; /* reserved */ 10338 Control[17] = 0x00; /* reserved */ 10339 Control[18] = 0x00; /* reserved */ 10340 Control[19] = 0x00; /* reserved */ 10341 /* Block size */ 10342 Control[20] = 0x00; 10343 Control[21] = 0x00; 10344 Control[22] = 0x02; /* Block size is always 512 bytes */ 10345 Control[23] = 0x00; 10346 } 10347 else 10348 { 10349 /* density code */ 10350 Control[8] = 0x04; /* density-code : reserved for direct-access */ 10351 /* number of blocks */ 10352 Control[9] = 0x00; /* unspecified */ 10353 Control[10] = 0x00; /* unspecified */ 10354 Control[11] = 0x00; /* unspecified */ 10355 /* reserved */ 10356 Control[12] = 0x00; /* reserved */ 10357 /* Block size */ 10358 Control[13] = 0x00; 10359 Control[14] = 0x02; /* Block size is always 512 bytes */ 10360 Control[15] = 0x00; 10361 } 10362 10363 if (LLBAA) 10364 { 10365 index = 24; 10366 } 10367 else 10368 { 10369 index = 16; 10370 } 10371 /* 10372 * Fill-up control mode page, SAT, Table 65 10373 */ 10374 Control[index+0] = 0x0A; /* page code */ 10375 Control[index+1] = 0x0A; /* page length */ 10376 Control[index+2] = 0x02; /* only GLTSD bit is set */ 10377 if (pSatDevData->satNCQ == agTRUE) 10378 { 10379 Control[index+3] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/ 10380 } 10381 else 10382 { 10383 Control[index+3] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */ 10384 } 10385 Control[index+4] = 0x00; 10386 Control[index+5] = 0x00; 10387 Control[index+6] = 0x00; /* obsolete */ 10388 Control[index+7] = 0x00; /* obsolete */ 10389 Control[index+8] = 0xFF; /* Busy Timeout Period */ 10390 Control[index+9] = 0xFF; /* Busy Timeout Period */ 10391 Control[index+10] = 0x00; /* we don't support non-000b value for the self-test code */ 10392 Control[index+11] = 0x00; /* we don't support non-000b value for the self-test code */ 10393 10394 sm_memcpy(pModeSense, &Control, lenRead); 10395 } 10396 else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE) 10397 { 10398 SM_DBG5(("smsatModeSense10: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n")); 10399 RWErrorRecovery[0] = 0; 10400 RWErrorRecovery[1] = (bit8)(lenRead - 2); 10401 RWErrorRecovery[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */ 10402 RWErrorRecovery[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */ 10403 if (LLBAA) 10404 { 10405 RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA */ 10406 RWErrorRecovery[4] = (bit8)(RWErrorRecovery[4] | 0x1); /* LONGLBA is set */ 10407 } 10408 else 10409 { 10410 RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */ 10411 } 10412 RWErrorRecovery[5] = 0x00; /* reserved */ 10413 RWErrorRecovery[6] = 0x00; /* block descriptot length */ 10414 if (LLBAA) 10415 { 10416 RWErrorRecovery[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */ 10417 } 10418 else 10419 { 10420 RWErrorRecovery[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */ 10421 } 10422 10423 /* 10424 * Fill-up direct-access device block-descriptor, SAT, Table 19 10425 */ 10426 10427 if (LLBAA) 10428 { 10429 /* density code */ 10430 RWErrorRecovery[8] = 0x04; /* density-code : reserved for direct-access */ 10431 /* number of blocks */ 10432 RWErrorRecovery[9] = 0x00; /* unspecified */ 10433 RWErrorRecovery[10] = 0x00; /* unspecified */ 10434 RWErrorRecovery[11] = 0x00; /* unspecified */ 10435 RWErrorRecovery[12] = 0x00; /* unspecified */ 10436 RWErrorRecovery[13] = 0x00; /* unspecified */ 10437 RWErrorRecovery[14] = 0x00; /* unspecified */ 10438 RWErrorRecovery[15] = 0x00; /* unspecified */ 10439 /* reserved */ 10440 RWErrorRecovery[16] = 0x00; /* reserved */ 10441 RWErrorRecovery[17] = 0x00; /* reserved */ 10442 RWErrorRecovery[18] = 0x00; /* reserved */ 10443 RWErrorRecovery[19] = 0x00; /* reserved */ 10444 /* Block size */ 10445 RWErrorRecovery[20] = 0x00; 10446 RWErrorRecovery[21] = 0x00; 10447 RWErrorRecovery[22] = 0x02; /* Block size is always 512 bytes */ 10448 RWErrorRecovery[23] = 0x00; 10449 } 10450 else 10451 { 10452 /* density code */ 10453 RWErrorRecovery[8] = 0x04; /* density-code : reserved for direct-access */ 10454 /* number of blocks */ 10455 RWErrorRecovery[9] = 0x00; /* unspecified */ 10456 RWErrorRecovery[10] = 0x00; /* unspecified */ 10457 RWErrorRecovery[11] = 0x00; /* unspecified */ 10458 /* reserved */ 10459 RWErrorRecovery[12] = 0x00; /* reserved */ 10460 /* Block size */ 10461 RWErrorRecovery[13] = 0x00; 10462 RWErrorRecovery[14] = 0x02; /* Block size is always 512 bytes */ 10463 RWErrorRecovery[15] = 0x00; 10464 } 10465 10466 if (LLBAA) 10467 { 10468 index = 24; 10469 } 10470 else 10471 { 10472 index = 16; 10473 } 10474 /* 10475 * Fill-up Read-Write Error Recovery mode page, SAT, Table 66 10476 */ 10477 RWErrorRecovery[index+0] = 0x01; /* page code */ 10478 RWErrorRecovery[index+1] = 0x0A; /* page length */ 10479 RWErrorRecovery[index+2] = 0x40; /* ARRE is set */ 10480 RWErrorRecovery[index+3] = 0x00; 10481 RWErrorRecovery[index+4] = 0x00; 10482 RWErrorRecovery[index+5] = 0x00; 10483 RWErrorRecovery[index+6] = 0x00; 10484 RWErrorRecovery[index+7] = 0x00; 10485 RWErrorRecovery[index+8] = 0x00; 10486 RWErrorRecovery[index+9] = 0x00; 10487 RWErrorRecovery[index+10] = 0x00; 10488 RWErrorRecovery[index+11] = 0x00; 10489 10490 sm_memcpy(pModeSense, &RWErrorRecovery, lenRead); 10491 } 10492 else if (page == MODESENSE_CACHING) 10493 { 10494 SM_DBG5(("smsatModeSense10: MODESENSE_CACHING\n")); 10495 Caching[0] = 0; 10496 Caching[1] = (bit8)(lenRead - 2); 10497 Caching[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */ 10498 Caching[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */ 10499 if (LLBAA) 10500 { 10501 Caching[4] = 0x00; /* reserved and LONGLBA */ 10502 Caching[4] = (bit8)(Caching[4] | 0x1); /* LONGLBA is set */ 10503 } 10504 else 10505 { 10506 Caching[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */ 10507 } 10508 Caching[5] = 0x00; /* reserved */ 10509 Caching[6] = 0x00; /* block descriptot length */ 10510 if (LLBAA) 10511 { 10512 Caching[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */ 10513 } 10514 else 10515 { 10516 Caching[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */ 10517 } 10518 10519 /* 10520 * Fill-up direct-access device block-descriptor, SAT, Table 19 10521 */ 10522 10523 if (LLBAA) 10524 { 10525 /* density code */ 10526 Caching[8] = 0x04; /* density-code : reserved for direct-access */ 10527 /* number of blocks */ 10528 Caching[9] = 0x00; /* unspecified */ 10529 Caching[10] = 0x00; /* unspecified */ 10530 Caching[11] = 0x00; /* unspecified */ 10531 Caching[12] = 0x00; /* unspecified */ 10532 Caching[13] = 0x00; /* unspecified */ 10533 Caching[14] = 0x00; /* unspecified */ 10534 Caching[15] = 0x00; /* unspecified */ 10535 /* reserved */ 10536 Caching[16] = 0x00; /* reserved */ 10537 Caching[17] = 0x00; /* reserved */ 10538 Caching[18] = 0x00; /* reserved */ 10539 Caching[19] = 0x00; /* reserved */ 10540 /* Block size */ 10541 Caching[20] = 0x00; 10542 Caching[21] = 0x00; 10543 Caching[22] = 0x02; /* Block size is always 512 bytes */ 10544 Caching[23] = 0x00; 10545 } 10546 else 10547 { 10548 /* density code */ 10549 Caching[8] = 0x04; /* density-code : reserved for direct-access */ 10550 /* number of blocks */ 10551 Caching[9] = 0x00; /* unspecified */ 10552 Caching[10] = 0x00; /* unspecified */ 10553 Caching[11] = 0x00; /* unspecified */ 10554 /* reserved */ 10555 Caching[12] = 0x00; /* reserved */ 10556 /* Block size */ 10557 Caching[13] = 0x00; 10558 Caching[14] = 0x02; /* Block size is always 512 bytes */ 10559 Caching[15] = 0x00; 10560 } 10561 10562 if (LLBAA) 10563 { 10564 index = 24; 10565 } 10566 else 10567 { 10568 index = 16; 10569 } 10570 /* 10571 * Fill-up Caching mode page, SAT, Table 67 10572 */ 10573 /* length 20 */ 10574 Caching[index+0] = 0x08; /* page code */ 10575 Caching[index+1] = 0x12; /* page length */ 10576 if (pSatDevData->satWriteCacheEnabled == agTRUE) 10577 { 10578 Caching[index+2] = 0x04;/* WCE bit is set */ 10579 } 10580 else 10581 { 10582 Caching[index+2] = 0x00;/* WCE bit is NOT set */ 10583 } 10584 10585 Caching[index+3] = 0x00; 10586 Caching[index+4] = 0x00; 10587 Caching[index+5] = 0x00; 10588 Caching[index+6] = 0x00; 10589 Caching[index+7] = 0x00; 10590 Caching[index+8] = 0x00; 10591 Caching[index+9] = 0x00; 10592 Caching[index+10] = 0x00; 10593 Caching[index+11] = 0x00; 10594 if (pSatDevData->satLookAheadEnabled == agTRUE) 10595 { 10596 Caching[index+12] = 0x00;/* DRA bit is NOT set */ 10597 } 10598 else 10599 { 10600 Caching[index+12] = 0x20;/* DRA bit is set */ 10601 } 10602 Caching[index+13] = 0x00; 10603 Caching[index+14] = 0x00; 10604 Caching[index+15] = 0x00; 10605 Caching[index+16] = 0x00; 10606 Caching[index+17] = 0x00; 10607 Caching[index+18] = 0x00; 10608 Caching[index+19] = 0x00; 10609 sm_memcpy(pModeSense, &Caching, lenRead); 10610 10611 } 10612 else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE) 10613 { 10614 SM_DBG5(("smsatModeSense10: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n")); 10615 InfoExceptionCtrl[0] = 0; 10616 InfoExceptionCtrl[1] = (bit8)(lenRead - 2); 10617 InfoExceptionCtrl[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */ 10618 InfoExceptionCtrl[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */ 10619 if (LLBAA) 10620 { 10621 InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA */ 10622 InfoExceptionCtrl[4] = (bit8)(InfoExceptionCtrl[4] | 0x1); /* LONGLBA is set */ 10623 } 10624 else 10625 { 10626 InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */ 10627 } 10628 InfoExceptionCtrl[5] = 0x00; /* reserved */ 10629 InfoExceptionCtrl[6] = 0x00; /* block descriptot length */ 10630 if (LLBAA) 10631 { 10632 InfoExceptionCtrl[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */ 10633 } 10634 else 10635 { 10636 InfoExceptionCtrl[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */ 10637 } 10638 10639 /* 10640 * Fill-up direct-access device block-descriptor, SAT, Table 19 10641 */ 10642 10643 if (LLBAA) 10644 { 10645 /* density code */ 10646 InfoExceptionCtrl[8] = 0x04; /* density-code : reserved for direct-access */ 10647 /* number of blocks */ 10648 InfoExceptionCtrl[9] = 0x00; /* unspecified */ 10649 InfoExceptionCtrl[10] = 0x00; /* unspecified */ 10650 InfoExceptionCtrl[11] = 0x00; /* unspecified */ 10651 InfoExceptionCtrl[12] = 0x00; /* unspecified */ 10652 InfoExceptionCtrl[13] = 0x00; /* unspecified */ 10653 InfoExceptionCtrl[14] = 0x00; /* unspecified */ 10654 InfoExceptionCtrl[15] = 0x00; /* unspecified */ 10655 /* reserved */ 10656 InfoExceptionCtrl[16] = 0x00; /* reserved */ 10657 InfoExceptionCtrl[17] = 0x00; /* reserved */ 10658 InfoExceptionCtrl[18] = 0x00; /* reserved */ 10659 InfoExceptionCtrl[19] = 0x00; /* reserved */ 10660 /* Block size */ 10661 InfoExceptionCtrl[20] = 0x00; 10662 InfoExceptionCtrl[21] = 0x00; 10663 InfoExceptionCtrl[22] = 0x02; /* Block size is always 512 bytes */ 10664 InfoExceptionCtrl[23] = 0x00; 10665 } 10666 else 10667 { 10668 /* density code */ 10669 InfoExceptionCtrl[8] = 0x04; /* density-code : reserved for direct-access */ 10670 /* number of blocks */ 10671 InfoExceptionCtrl[9] = 0x00; /* unspecified */ 10672 InfoExceptionCtrl[10] = 0x00; /* unspecified */ 10673 InfoExceptionCtrl[11] = 0x00; /* unspecified */ 10674 /* reserved */ 10675 InfoExceptionCtrl[12] = 0x00; /* reserved */ 10676 /* Block size */ 10677 InfoExceptionCtrl[13] = 0x00; 10678 InfoExceptionCtrl[14] = 0x02; /* Block size is always 512 bytes */ 10679 InfoExceptionCtrl[15] = 0x00; 10680 } 10681 10682 if (LLBAA) 10683 { 10684 index = 24; 10685 } 10686 else 10687 { 10688 index = 16; 10689 } 10690 /* 10691 * Fill-up informational-exceptions control mode page, SAT, Table 68 10692 */ 10693 InfoExceptionCtrl[index+0] = 0x1C; /* page code */ 10694 InfoExceptionCtrl[index+1] = 0x0A; /* page length */ 10695 if (pSatDevData->satSMARTEnabled == agTRUE) 10696 { 10697 InfoExceptionCtrl[index+2] = 0x00;/* DEXCPT bit is NOT set */ 10698 } 10699 else 10700 { 10701 InfoExceptionCtrl[index+2] = 0x08;/* DEXCPT bit is set */ 10702 } 10703 InfoExceptionCtrl[index+3] = 0x00; /* We don't support MRIE */ 10704 InfoExceptionCtrl[index+4] = 0x00; /* Interval timer vendor-specific */ 10705 InfoExceptionCtrl[index+5] = 0x00; 10706 InfoExceptionCtrl[index+6] = 0x00; 10707 InfoExceptionCtrl[index+7] = 0x00; 10708 InfoExceptionCtrl[index+8] = 0x00; /* REPORT-COUNT */ 10709 InfoExceptionCtrl[index+9] = 0x00; 10710 InfoExceptionCtrl[index+10] = 0x00; 10711 InfoExceptionCtrl[index+11] = 0x00; 10712 sm_memcpy(pModeSense, &InfoExceptionCtrl, lenRead); 10713 10714 } 10715 else 10716 { 10717 /* Error */ 10718 SM_DBG1(("smsatModeSense10: Error page %d!!!\n", page)); 10719 smsatSetSensePayload( pSense, 10720 SCSI_SNSKEY_ILLEGAL_REQUEST, 10721 0, 10722 SCSI_SNSCODE_INVALID_COMMAND, 10723 satIOContext); 10724 10725 /*smEnqueueIO(smRoot, satIOContext);*/ 10726 10727 tdsmIOCompletedCB( smRoot, 10728 smIORequest, 10729 smIOSuccess, 10730 SCSI_STAT_CHECK_CONDITION, 10731 satIOContext->pSmSenseData, 10732 satIOContext->interruptContext ); 10733 return SM_RC_SUCCESS; 10734 } 10735 10736 if (allocationLen > lenRead) 10737 { 10738 SM_DBG1(("smsatModeSense10: reporting underrun lenRead=0x%x allocationLen=0x%x smIORequest=%p\n", lenRead, allocationLen, smIORequest)); 10739 10740 /*smEnqueueIO(smRoot, satIOContext);*/ 10741 10742 tdsmIOCompletedCB( smRoot, 10743 smIORequest, 10744 smIOUnderRun, 10745 allocationLen - lenRead, 10746 agNULL, 10747 satIOContext->interruptContext ); 10748 10749 10750 } 10751 else 10752 { 10753 /*smEnqueueIO(smRoot, satIOContext);*/ 10754 10755 tdsmIOCompletedCB( smRoot, 10756 smIORequest, 10757 smIOSuccess, 10758 SCSI_STAT_GOOD, 10759 agNULL, 10760 satIOContext->interruptContext); 10761 } 10762 10763 return SM_RC_SUCCESS; 10764 } 10765 10766 osGLOBAL bit32 10767 smsatReadCapacity10( 10768 smRoot_t *smRoot, 10769 smIORequest_t *smIORequest, 10770 smDeviceHandle_t *smDeviceHandle, 10771 smScsiInitiatorRequest_t *smScsiRequest, 10772 smSatIOContext_t *satIOContext 10773 ) 10774 { 10775 smScsiRspSense_t *pSense; 10776 smIniScsiCmnd_t *scsiCmnd; 10777 bit8 dataBuffer[8] = {0}; 10778 bit32 allocationLen; 10779 bit8 *pVirtAddr = agNULL; 10780 smDeviceData_t *pSatDevData; 10781 agsaSATAIdentifyData_t *pSATAIdData; 10782 bit32 lastLba; 10783 bit32 word117_118; 10784 bit32 word117; 10785 bit32 word118; 10786 10787 pSense = satIOContext->pSense; 10788 pVirtAddr = (bit8 *) smScsiRequest->sglVirtualAddr; 10789 scsiCmnd = &smScsiRequest->scsiCmnd; 10790 pSatDevData = satIOContext->pSatDevData; 10791 pSATAIdData = &pSatDevData->satIdentifyData; 10792 allocationLen = scsiCmnd->expDataLength; 10793 10794 SM_DBG5(("smsatReadCapacity10: start\n")); 10795 10796 /* checking CONTROL */ 10797 /* NACA == 1 or LINK == 1*/ 10798 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 10799 { 10800 smsatSetSensePayload( pSense, 10801 SCSI_SNSKEY_ILLEGAL_REQUEST, 10802 0, 10803 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10804 satIOContext); 10805 10806 /*smEnqueueIO(smRoot, satIOContext);*/ 10807 10808 tdsmIOCompletedCB( smRoot, 10809 smIORequest, 10810 smIOSuccess, 10811 SCSI_STAT_CHECK_CONDITION, 10812 satIOContext->pSmSenseData, 10813 satIOContext->interruptContext ); 10814 10815 SM_DBG1(("smsatReadCapacity10: return control!!!\n")); 10816 return SM_RC_SUCCESS; 10817 } 10818 10819 10820 /* 10821 * If Logical block address is not set to zero, return error 10822 */ 10823 if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5])) 10824 { 10825 SM_DBG1(("smsatReadCapacity10: *** ERROR *** logical address non zero, did %d!!!\n", 10826 pSatDevData->id)); 10827 10828 smsatSetSensePayload( pSense, 10829 SCSI_SNSKEY_ILLEGAL_REQUEST, 10830 0, 10831 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10832 satIOContext); 10833 10834 /*smEnqueueIO(smRoot, satIOContext);*/ 10835 10836 tdsmIOCompletedCB( smRoot, 10837 smIORequest, 10838 smIOSuccess, 10839 SCSI_STAT_CHECK_CONDITION, 10840 satIOContext->pSmSenseData, 10841 satIOContext->interruptContext ); 10842 return SM_RC_SUCCESS; 10843 10844 } 10845 10846 /* 10847 * If PMI bit is not zero, return error 10848 */ 10849 if ( ((scsiCmnd->cdb[8]) & SCSI_READ_CAPACITY10_PMI_MASK) != 0 ) 10850 { 10851 SM_DBG1(("smsatReadCapacity10: *** ERROR *** PMI is not zero, did %d\n", 10852 pSatDevData->id)); 10853 10854 smsatSetSensePayload( pSense, 10855 SCSI_SNSKEY_ILLEGAL_REQUEST, 10856 0, 10857 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 10858 satIOContext); 10859 10860 /*smEnqueueIO(smRoot, satIOContext);*/ 10861 10862 tdsmIOCompletedCB( smRoot, 10863 smIORequest, 10864 smIOSuccess, 10865 SCSI_STAT_CHECK_CONDITION, 10866 satIOContext->pSmSenseData, 10867 satIOContext->interruptContext ); 10868 return SM_RC_SUCCESS; 10869 10870 } 10871 10872 /* 10873 filling in Read Capacity parameter data 10874 saved identify device has been already flipped 10875 See ATA spec p125 and p136 and SBC spec p54 10876 */ 10877 /* 10878 * If 48-bit addressing is supported, set capacity information from Identify 10879 * Device Word 100-103. 10880 */ 10881 if (pSatDevData->sat48BitSupport == agTRUE) 10882 { 10883 /* 10884 * Setting RETURNED LOGICAL BLOCK ADDRESS in READ CAPACITY(10) response data: 10885 * SBC-2 specifies that if the capacity exceeded the 4-byte RETURNED LOGICAL 10886 * BLOCK ADDRESS in READ CAPACITY(10) parameter data, the RETURNED LOGICAL 10887 * BLOCK ADDRESS should be set to 0xFFFFFFFF so the application client would 10888 * then issue a READ CAPACITY(16) command. 10889 */ 10890 /* ATA Identify Device information word 100 - 103 */ 10891 if ( (pSATAIdData->maxLBA32_47 != 0 ) || (pSATAIdData->maxLBA48_63 != 0)) 10892 { 10893 dataBuffer[0] = 0xFF; /* MSB number of block */ 10894 dataBuffer[1] = 0xFF; 10895 dataBuffer[2] = 0xFF; 10896 dataBuffer[3] = 0xFF; /* LSB number of block */ 10897 SM_DBG1(("smsatReadCapacity10: returns 0xFFFFFFFF!!!\n")); 10898 } 10899 else /* Fit the Readcapacity10 4-bytes response length */ 10900 { 10901 lastLba = (((pSATAIdData->maxLBA16_31) << 16) ) | 10902 (pSATAIdData->maxLBA0_15); 10903 lastLba = lastLba - 1; /* LBA starts from zero */ 10904 10905 /* 10906 for testing 10907 lastLba = lastLba - (512*10) - 1; 10908 */ 10909 10910 10911 dataBuffer[0] = (bit8)((lastLba >> 24) & 0xFF); /* MSB */ 10912 dataBuffer[1] = (bit8)((lastLba >> 16) & 0xFF); 10913 dataBuffer[2] = (bit8)((lastLba >> 8) & 0xFF); 10914 dataBuffer[3] = (bit8)((lastLba ) & 0xFF); /* LSB */ 10915 10916 SM_DBG3(("smsatReadCapacity10: lastLba is 0x%x %d\n", lastLba, lastLba)); 10917 SM_DBG3(("smsatReadCapacity10: LBA 0 is 0x%x %d\n", dataBuffer[0], dataBuffer[0])); 10918 SM_DBG3(("smsatReadCapacity10: LBA 1 is 0x%x %d\n", dataBuffer[1], dataBuffer[1])); 10919 SM_DBG3(("smsatReadCapacity10: LBA 2 is 0x%x %d\n", dataBuffer[2], dataBuffer[2])); 10920 SM_DBG3(("smsatReadCapacity10: LBA 3 is 0x%x %d\n", dataBuffer[3], dataBuffer[3])); 10921 10922 } 10923 } 10924 10925 /* 10926 * For 28-bit addressing, set capacity information from Identify 10927 * Device Word 60-61. 10928 */ 10929 else 10930 { 10931 /* ATA Identify Device information word 60 - 61 */ 10932 lastLba = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) | 10933 (pSATAIdData->numOfUserAddressableSectorsLo); 10934 lastLba = lastLba - 1; /* LBA starts from zero */ 10935 10936 dataBuffer[0] = (bit8)((lastLba >> 24) & 0xFF); /* MSB */ 10937 dataBuffer[1] = (bit8)((lastLba >> 16) & 0xFF); 10938 dataBuffer[2] = (bit8)((lastLba >> 8) & 0xFF); 10939 dataBuffer[3] = (bit8)((lastLba ) & 0xFF); /* LSB */ 10940 } 10941 /* SAT Rev 8d */ 10942 if (((pSATAIdData->word104_107[2]) & 0x1000) == 0) 10943 { 10944 SM_DBG5(("smsatReadCapacity10: Default Block Length is 512\n")); 10945 /* 10946 * Set the block size, fixed at 512 bytes. 10947 */ 10948 dataBuffer[4] = 0x00; /* MSB block size in bytes */ 10949 dataBuffer[5] = 0x00; 10950 dataBuffer[6] = 0x02; 10951 dataBuffer[7] = 0x00; /* LSB block size in bytes */ 10952 } 10953 else 10954 { 10955 word118 = pSATAIdData->word112_126[6]; 10956 word117 = pSATAIdData->word112_126[5]; 10957 10958 word117_118 = (word118 << 16) + word117; 10959 word117_118 = word117_118 * 2; 10960 dataBuffer[4] = (bit8)((word117_118 >> 24) & 0xFF); /* MSB block size in bytes */ 10961 dataBuffer[5] = (bit8)((word117_118 >> 16) & 0xFF); 10962 dataBuffer[6] = (bit8)((word117_118 >> 8) & 0xFF); 10963 dataBuffer[7] = (bit8)(word117_118 & 0xFF); /* LSB block size in bytes */ 10964 10965 SM_DBG1(("smsatReadCapacity10: Nondefault word118 %d 0x%x !!!\n", word118, word118)); 10966 SM_DBG1(("smsatReadCapacity10: Nondefault word117 %d 0x%x !!!\n", word117, word117)); 10967 SM_DBG1(("smsatReadCapacity10: Nondefault Block Length is %d 0x%x !!!\n",word117_118, word117_118)); 10968 10969 } 10970 10971 /* fill in MAX LBA, which is used in satSendDiagnostic_1() */ 10972 pSatDevData->satMaxLBA[0] = 0; /* MSB */ 10973 pSatDevData->satMaxLBA[1] = 0; 10974 pSatDevData->satMaxLBA[2] = 0; 10975 pSatDevData->satMaxLBA[3] = 0; 10976 pSatDevData->satMaxLBA[4] = dataBuffer[0]; 10977 pSatDevData->satMaxLBA[5] = dataBuffer[1]; 10978 pSatDevData->satMaxLBA[6] = dataBuffer[2]; 10979 pSatDevData->satMaxLBA[7] = dataBuffer[3]; /* LSB */ 10980 10981 10982 SM_DBG4(("smsatReadCapacity10: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , did %d\n", 10983 dataBuffer[0], dataBuffer[1], dataBuffer[2], dataBuffer[3], 10984 dataBuffer[4], dataBuffer[5], dataBuffer[6], dataBuffer[7], 10985 pSatDevData->id)); 10986 10987 sm_memcpy(pVirtAddr, dataBuffer, MIN(allocationLen, 8)); 10988 10989 /* 10990 * Send the completion response now. 10991 */ 10992 /*smEnqueueIO(smRoot, satIOContext);*/ 10993 10994 tdsmIOCompletedCB( smRoot, 10995 smIORequest, 10996 smIOSuccess, 10997 SCSI_STAT_GOOD, 10998 agNULL, 10999 satIOContext->interruptContext); 11000 return SM_RC_SUCCESS; 11001 } 11002 11003 osGLOBAL bit32 11004 smsatReadCapacity16( 11005 smRoot_t *smRoot, 11006 smIORequest_t *smIORequest, 11007 smDeviceHandle_t *smDeviceHandle, 11008 smScsiInitiatorRequest_t *smScsiRequest, 11009 smSatIOContext_t *satIOContext 11010 ) 11011 { 11012 smScsiRspSense_t *pSense; 11013 smIniScsiCmnd_t *scsiCmnd; 11014 bit8 dataBuffer[32] = {0}; 11015 bit8 *pVirtAddr = agNULL; 11016 smDeviceData_t *pSatDevData; 11017 agsaSATAIdentifyData_t *pSATAIdData; 11018 bit32 lastLbaLo; 11019 bit32 allocationLen; 11020 bit32 readCapacityLen = 32; 11021 bit32 i = 0; 11022 11023 pSense = satIOContext->pSense; 11024 pVirtAddr = (bit8 *) smScsiRequest->sglVirtualAddr; 11025 scsiCmnd = &smScsiRequest->scsiCmnd; 11026 pSatDevData = satIOContext->pSatDevData; 11027 pSATAIdData = &pSatDevData->satIdentifyData; 11028 11029 SM_DBG5(("smsatReadCapacity16: start\n")); 11030 11031 /* Find the buffer size allocated by Initiator */ 11032 allocationLen = (((bit32)scsiCmnd->cdb[10]) << 24) | 11033 (((bit32)scsiCmnd->cdb[11]) << 16) | 11034 (((bit32)scsiCmnd->cdb[12]) << 8 ) | 11035 (((bit32)scsiCmnd->cdb[13]) ); 11036 allocationLen = MIN(allocationLen, scsiCmnd->expDataLength); 11037 11038 #ifdef REMOVED 11039 if (allocationLen < readCapacityLen) 11040 { 11041 SM_DBG1(("smsatReadCapacity16: *** ERROR *** insufficient len=0x%x readCapacityLen=0x%x!!!\n", allocationLen, readCapacityLen)); 11042 11043 smsatSetSensePayload( pSense, 11044 SCSI_SNSKEY_ILLEGAL_REQUEST, 11045 0, 11046 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11047 satIOContext); 11048 11049 /*smEnqueueIO(smRoot, satIOContext);*/ 11050 11051 tdsmIOCompletedCB( smRoot, 11052 smIORequest, 11053 smIOSuccess, 11054 SCSI_STAT_CHECK_CONDITION, 11055 satIOContext->pSmSenseData, 11056 satIOContext->interruptContext ); 11057 return SM_RC_SUCCESS; 11058 11059 } 11060 #endif 11061 11062 /* checking CONTROL */ 11063 /* NACA == 1 or LINK == 1*/ 11064 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 11065 { 11066 smsatSetSensePayload( pSense, 11067 SCSI_SNSKEY_ILLEGAL_REQUEST, 11068 0, 11069 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11070 satIOContext); 11071 11072 /*smEnqueueIO(smRoot, satIOContext);*/ 11073 11074 tdsmIOCompletedCB( smRoot, 11075 smIORequest, 11076 smIOSuccess, 11077 SCSI_STAT_CHECK_CONDITION, 11078 satIOContext->pSmSenseData, 11079 satIOContext->interruptContext ); 11080 11081 SM_DBG1(("smsatReadCapacity16: return control!!!\n")); 11082 return SM_RC_SUCCESS; 11083 } 11084 11085 /* 11086 * If Logical blcok address is not set to zero, return error 11087 */ 11088 if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]) || 11089 (scsiCmnd->cdb[6] || scsiCmnd->cdb[7] || scsiCmnd->cdb[8] || scsiCmnd->cdb[9]) ) 11090 { 11091 SM_DBG1(("smsatReadCapacity16: *** ERROR *** logical address non zero, did %d\n", 11092 pSatDevData->id)); 11093 11094 smsatSetSensePayload( pSense, 11095 SCSI_SNSKEY_ILLEGAL_REQUEST, 11096 0, 11097 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11098 satIOContext); 11099 11100 /*smEnqueueIO(smRoot, satIOContext);*/ 11101 11102 tdsmIOCompletedCB( smRoot, 11103 smIORequest, 11104 smIOSuccess, 11105 SCSI_STAT_CHECK_CONDITION, 11106 satIOContext->pSmSenseData, 11107 satIOContext->interruptContext ); 11108 return SM_RC_SUCCESS; 11109 11110 } 11111 11112 /* 11113 * If PMI bit is not zero, return error 11114 */ 11115 if ( ((scsiCmnd->cdb[14]) & SCSI_READ_CAPACITY16_PMI_MASK) != 0 ) 11116 { 11117 SM_DBG1(("smsatReadCapacity16: *** ERROR *** PMI is not zero, did %d\n", 11118 pSatDevData->id)); 11119 11120 smsatSetSensePayload( pSense, 11121 SCSI_SNSKEY_ILLEGAL_REQUEST, 11122 0, 11123 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11124 satIOContext); 11125 11126 /*smEnqueueIO(smRoot, satIOContext);*/ 11127 11128 tdsmIOCompletedCB( smRoot, 11129 smIORequest, 11130 smIOSuccess, 11131 SCSI_STAT_CHECK_CONDITION, 11132 satIOContext->pSmSenseData, 11133 satIOContext->interruptContext ); 11134 return SM_RC_SUCCESS; 11135 11136 } 11137 11138 /* 11139 filling in Read Capacity parameter data 11140 */ 11141 11142 /* 11143 * If 48-bit addressing is supported, set capacity information from Identify 11144 * Device Word 100-103. 11145 */ 11146 if (pSatDevData->sat48BitSupport == agTRUE) 11147 { 11148 dataBuffer[0] = (bit8)(((pSATAIdData->maxLBA48_63) >> 8) & 0xff); /* MSB */ 11149 dataBuffer[1] = (bit8)((pSATAIdData->maxLBA48_63) & 0xff); 11150 dataBuffer[2] = (bit8)(((pSATAIdData->maxLBA32_47) >> 8) & 0xff); 11151 dataBuffer[3] = (bit8)((pSATAIdData->maxLBA32_47) & 0xff); 11152 11153 lastLbaLo = (((pSATAIdData->maxLBA16_31) << 16) ) | (pSATAIdData->maxLBA0_15); 11154 lastLbaLo = lastLbaLo - 1; /* LBA starts from zero */ 11155 11156 dataBuffer[4] = (bit8)((lastLbaLo >> 24) & 0xFF); 11157 dataBuffer[5] = (bit8)((lastLbaLo >> 16) & 0xFF); 11158 dataBuffer[6] = (bit8)((lastLbaLo >> 8) & 0xFF); 11159 dataBuffer[7] = (bit8)((lastLbaLo ) & 0xFF); /* LSB */ 11160 11161 } 11162 11163 /* 11164 * For 28-bit addressing, set capacity information from Identify 11165 * Device Word 60-61. 11166 */ 11167 else 11168 { 11169 dataBuffer[0] = 0; /* MSB */ 11170 dataBuffer[1] = 0; 11171 dataBuffer[2] = 0; 11172 dataBuffer[3] = 0; 11173 11174 lastLbaLo = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) | 11175 (pSATAIdData->numOfUserAddressableSectorsLo); 11176 lastLbaLo = lastLbaLo - 1; /* LBA starts from zero */ 11177 11178 dataBuffer[4] = (bit8)((lastLbaLo >> 24) & 0xFF); 11179 dataBuffer[5] = (bit8)((lastLbaLo >> 16) & 0xFF); 11180 dataBuffer[6] = (bit8)((lastLbaLo >> 8) & 0xFF); 11181 dataBuffer[7] = (bit8)((lastLbaLo ) & 0xFF); /* LSB */ 11182 11183 } 11184 11185 /* 11186 * Set the block size, fixed at 512 bytes. 11187 */ 11188 dataBuffer[8] = 0x00; /* MSB block size in bytes */ 11189 dataBuffer[9] = 0x00; 11190 dataBuffer[10] = 0x02; 11191 dataBuffer[11] = 0x00; /* LSB block size in bytes */ 11192 11193 11194 /* fill in MAX LBA, which is used in satSendDiagnostic_1() */ 11195 pSatDevData->satMaxLBA[0] = dataBuffer[0]; /* MSB */ 11196 pSatDevData->satMaxLBA[1] = dataBuffer[1]; 11197 pSatDevData->satMaxLBA[2] = dataBuffer[2]; 11198 pSatDevData->satMaxLBA[3] = dataBuffer[3]; 11199 pSatDevData->satMaxLBA[4] = dataBuffer[4]; 11200 pSatDevData->satMaxLBA[5] = dataBuffer[5]; 11201 pSatDevData->satMaxLBA[6] = dataBuffer[6]; 11202 pSatDevData->satMaxLBA[7] = dataBuffer[7]; /* LSB */ 11203 11204 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", 11205 dataBuffer[0], dataBuffer[1], dataBuffer[2], dataBuffer[3], 11206 dataBuffer[4], dataBuffer[5], dataBuffer[6], dataBuffer[7], 11207 dataBuffer[8], dataBuffer[9], dataBuffer[10], dataBuffer[11], 11208 pSatDevData->id)); 11209 11210 if (allocationLen > 0xC) /* 0xc = 12 */ 11211 { 11212 for(i=12;i<=31;i++) 11213 { 11214 dataBuffer[i] = 0x00; 11215 } 11216 } 11217 11218 sm_memcpy(pVirtAddr, dataBuffer, MIN(allocationLen, readCapacityLen)); 11219 /* 11220 * Send the completion response now. 11221 */ 11222 if (allocationLen > readCapacityLen) 11223 { 11224 /* underrun */ 11225 SM_DBG1(("smsatReadCapacity16: reporting underrun readCapacityLen=0x%x allocationLen=0x%x !!!\n", readCapacityLen, allocationLen)); 11226 11227 /*smEnqueueIO(smRoot, satIOContext);*/ 11228 11229 tdsmIOCompletedCB( smRoot, 11230 smIORequest, 11231 smIOUnderRun, 11232 allocationLen - readCapacityLen, 11233 agNULL, 11234 satIOContext->interruptContext ); 11235 11236 11237 } 11238 else 11239 { 11240 /*smEnqueueIO(smRoot, satIOContext);*/ 11241 11242 tdsmIOCompletedCB( smRoot, 11243 smIORequest, 11244 smIOSuccess, 11245 SCSI_STAT_GOOD, 11246 agNULL, 11247 satIOContext->interruptContext); 11248 } 11249 return SM_RC_SUCCESS; 11250 } 11251 11252 osGLOBAL bit32 11253 smsatReportLun( 11254 smRoot_t *smRoot, 11255 smIORequest_t *smIORequest, 11256 smDeviceHandle_t *smDeviceHandle, 11257 smScsiInitiatorRequest_t *smScsiRequest, 11258 smSatIOContext_t *satIOContext 11259 ) 11260 { 11261 smScsiRspSense_t *pSense; 11262 bit8 dataBuffer[16] = {0}; 11263 bit32 allocationLen; 11264 bit32 reportLunLen; 11265 smScsiReportLun_t *pReportLun; 11266 smIniScsiCmnd_t *scsiCmnd; 11267 #ifdef TD_DEBUG_ENABLE 11268 smDeviceData_t *pSatDevData; 11269 #endif 11270 11271 pSense = satIOContext->pSense; 11272 pReportLun = (smScsiReportLun_t *) dataBuffer; 11273 scsiCmnd = &smScsiRequest->scsiCmnd; 11274 #ifdef TD_DEBUG_ENABLE 11275 pSatDevData = satIOContext->pSatDevData; 11276 #endif 11277 SM_DBG5(("smsatReportLun: start\n")); 11278 // smhexdump("smsatReportLun: cdb", (bit8 *)scsiCmnd, 16); 11279 /* Find the buffer size allocated by Initiator */ 11280 allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) | 11281 (((bit32)scsiCmnd->cdb[7]) << 16) | 11282 (((bit32)scsiCmnd->cdb[8]) << 8 ) | 11283 (((bit32)scsiCmnd->cdb[9]) ); 11284 allocationLen = MIN(allocationLen, scsiCmnd->expDataLength); 11285 reportLunLen = 16; /* 8 byte header and 8 bytes of LUN0 */ 11286 if (allocationLen < reportLunLen) 11287 { 11288 SM_DBG1(("smsatReportLun: *** ERROR *** insufficient len=0x%x did %d\n", 11289 reportLunLen, pSatDevData->id)); 11290 smsatSetSensePayload( pSense, 11291 SCSI_SNSKEY_ILLEGAL_REQUEST, 11292 0, 11293 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11294 satIOContext); 11295 /*smEnqueueIO(smRoot, satIOContext);*/ 11296 tdsmIOCompletedCB( smRoot, 11297 smIORequest, 11298 smIOSuccess, 11299 SCSI_STAT_CHECK_CONDITION, 11300 satIOContext->pSmSenseData, 11301 satIOContext->interruptContext ); 11302 return SM_RC_SUCCESS; 11303 } 11304 /* Set length to one entry */ 11305 pReportLun->len[0] = 0; 11306 pReportLun->len[1] = 0; 11307 pReportLun->len[2] = 0; 11308 pReportLun->len[3] = sizeof (tiLUN_t); 11309 pReportLun->reserved = 0; 11310 /* Set to LUN 0: 11311 * - address method to 0x00: Peripheral device addressing method, 11312 * - bus identifier to 0 11313 */ 11314 pReportLun->lunList[0].lun[0] = 0; 11315 pReportLun->lunList[0].lun[1] = 0; 11316 pReportLun->lunList[0].lun[2] = 0; 11317 pReportLun->lunList[0].lun[3] = 0; 11318 pReportLun->lunList[0].lun[4] = 0; 11319 pReportLun->lunList[0].lun[5] = 0; 11320 pReportLun->lunList[0].lun[6] = 0; 11321 pReportLun->lunList[0].lun[7] = 0; 11322 11323 sm_memcpy(smScsiRequest->sglVirtualAddr, dataBuffer, MIN(allocationLen, reportLunLen)); 11324 if (allocationLen > reportLunLen) 11325 { 11326 /* underrun */ 11327 SM_DBG1(("smsatReportLun: reporting underrun reportLunLen=0x%x allocationLen=0x%x !!!\n", reportLunLen, allocationLen)); 11328 11329 /*smEnqueueIO(smRoot, satIOContext);*/ 11330 11331 tdsmIOCompletedCB( smRoot, 11332 smIORequest, 11333 smIOUnderRun, 11334 allocationLen - reportLunLen, 11335 agNULL, 11336 satIOContext->interruptContext ); 11337 11338 11339 } 11340 else 11341 { 11342 /*smEnqueueIO(smRoot, satIOContext);*/ 11343 11344 tdsmIOCompletedCB( smRoot, 11345 smIORequest, 11346 smIOSuccess, 11347 SCSI_STAT_GOOD, 11348 agNULL, 11349 satIOContext->interruptContext); 11350 } 11351 return SM_RC_SUCCESS; 11352 } 11353 11354 osGLOBAL bit32 11355 smsatFormatUnit( 11356 smRoot_t *smRoot, 11357 smIORequest_t *smIORequest, 11358 smDeviceHandle_t *smDeviceHandle, 11359 smScsiInitiatorRequest_t *smScsiRequest, 11360 smSatIOContext_t *satIOContext 11361 ) 11362 { 11363 /* 11364 note: we don't support media certification in this version and IP bit 11365 satDevData->satFormatState will be agFalse since SAT does not actually sends 11366 any ATA command 11367 */ 11368 11369 smScsiRspSense_t *pSense; 11370 smIniScsiCmnd_t *scsiCmnd; 11371 bit32 index = 0; 11372 11373 pSense = satIOContext->pSense; 11374 scsiCmnd = &smScsiRequest->scsiCmnd; 11375 SM_DBG5(("smsatFormatUnit: start\n")); 11376 /* 11377 checking opcode 11378 1. FMTDATA bit == 0(no defect list header) 11379 2. FMTDATA bit == 1 and DCRT bit == 1(defect list header is provided 11380 with DCRT bit set) 11381 */ 11382 if ( ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) == 0) || 11383 ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) && 11384 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK)) 11385 ) 11386 { 11387 /*smEnqueueIO(smRoot, satIOContext);*/ 11388 11389 tdsmIOCompletedCB( smRoot, 11390 smIORequest, 11391 smIOSuccess, 11392 SCSI_STAT_GOOD, 11393 agNULL, 11394 satIOContext->interruptContext); 11395 11396 SM_DBG1(("smsatFormatUnit: return opcode!!!\n")); 11397 return SM_RC_SUCCESS; 11398 } 11399 11400 /* 11401 checking DEFECT LIST FORMAT and defect list length 11402 */ 11403 if ( (((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x00) || 11404 ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x06)) ) 11405 { 11406 /* short parameter header */ 11407 if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x00) 11408 { 11409 index = 8; 11410 } 11411 /* long parameter header */ 11412 if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x01) 11413 { 11414 index = 10; 11415 } 11416 /* defect list length */ 11417 if ((scsiCmnd->cdb[index] != 0) || (scsiCmnd->cdb[index+1] != 0)) 11418 { 11419 smsatSetSensePayload( pSense, 11420 SCSI_SNSKEY_ILLEGAL_REQUEST, 11421 0, 11422 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11423 satIOContext); 11424 11425 /*smEnqueueIO(smRoot, satIOContext);*/ 11426 11427 tdsmIOCompletedCB( smRoot, 11428 smIORequest, 11429 smIOSuccess, 11430 SCSI_STAT_CHECK_CONDITION, 11431 satIOContext->pSmSenseData, 11432 satIOContext->interruptContext ); 11433 11434 SM_DBG1(("smsatFormatUnit: return defect list format!!!\n")); 11435 return SM_RC_SUCCESS; 11436 } 11437 } 11438 11439 if ( (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) && 11440 (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_CMPLIST_MASK) ) 11441 { 11442 smsatSetSensePayload( pSense, 11443 SCSI_SNSKEY_ILLEGAL_REQUEST, 11444 0, 11445 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11446 satIOContext); 11447 11448 /*smEnqueueIO(smRoot, satIOContext);*/ 11449 11450 tdsmIOCompletedCB( smRoot, 11451 smIORequest, 11452 smIOSuccess, 11453 SCSI_STAT_CHECK_CONDITION, 11454 satIOContext->pSmSenseData, 11455 satIOContext->interruptContext ); 11456 11457 SM_DBG1(("smsatFormatUnit: return cmplist!!!\n")); 11458 return SM_RC_SUCCESS; 11459 11460 } 11461 11462 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 11463 { 11464 smsatSetSensePayload( pSense, 11465 SCSI_SNSKEY_ILLEGAL_REQUEST, 11466 0, 11467 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11468 satIOContext); 11469 11470 /*smEnqueueIO(smRoot, satIOContext);*/ 11471 11472 tdsmIOCompletedCB( smRoot, 11473 smIORequest, 11474 smIOSuccess, 11475 SCSI_STAT_CHECK_CONDITION, 11476 satIOContext->pSmSenseData, 11477 satIOContext->interruptContext ); 11478 11479 SM_DBG1(("smsatFormatUnit: return control!!!\n")); 11480 return SM_RC_SUCCESS; 11481 } 11482 11483 /* defect list header filed, if exists, SAT rev8, Table 37, p48 */ 11484 if (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) 11485 { 11486 /* case 1,2,3 */ 11487 /* IMMED 1; FOV 0; FOV 1, DCRT 1, IP 0 */ 11488 if ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) || 11489 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK)) || 11490 ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) && 11491 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) && 11492 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK)) 11493 ) 11494 { 11495 /*smEnqueueIO(smRoot, satIOContext);*/ 11496 11497 tdsmIOCompletedCB( smRoot, 11498 smIORequest, 11499 smIOSuccess, 11500 SCSI_STAT_GOOD, 11501 agNULL, 11502 satIOContext->interruptContext); 11503 11504 SM_DBG5(("smsatFormatUnit: return defect list case 1\n")); 11505 return SM_RC_SUCCESS; 11506 } 11507 /* case 4,5,6 */ 11508 /* 11509 1. IMMED 0, FOV 1, DCRT 0, IP 0 11510 2. IMMED 0, FOV 1, DCRT 0, IP 1 11511 3. IMMED 0, FOV 1, DCRT 1, IP 1 11512 */ 11513 11514 if ( ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) && 11515 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) && 11516 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) && 11517 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) ) 11518 || 11519 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) && 11520 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) && 11521 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) && 11522 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) ) 11523 || 11524 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) && 11525 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) && 11526 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) && 11527 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) ) 11528 ) 11529 { 11530 11531 smsatSetSensePayload( pSense, 11532 SCSI_SNSKEY_ILLEGAL_REQUEST, 11533 0, 11534 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 11535 satIOContext); 11536 11537 /*smEnqueueIO(smRoot, satIOContext);*/ 11538 11539 tdsmIOCompletedCB( smRoot, 11540 smIORequest, 11541 smIOSuccess, 11542 SCSI_STAT_CHECK_CONDITION, 11543 satIOContext->pSmSenseData, 11544 satIOContext->interruptContext ); 11545 11546 SM_DBG5(("smsatFormatUnit: return defect list case 2\n")); 11547 return SM_RC_SUCCESS; 11548 11549 } 11550 } 11551 11552 11553 /* 11554 * Send the completion response now. 11555 */ 11556 /*smEnqueueIO(smRoot, satIOContext);*/ 11557 11558 tdsmIOCompletedCB( smRoot, 11559 smIORequest, 11560 smIOSuccess, 11561 SCSI_STAT_GOOD, 11562 agNULL, 11563 satIOContext->interruptContext); 11564 11565 SM_DBG5(("smsatFormatUnit: return last\n")); 11566 return SM_RC_SUCCESS; 11567 } 11568 11569 osGLOBAL bit32 11570 smsatSendDiagnostic( 11571 smRoot_t *smRoot, 11572 smIORequest_t *smIORequest, 11573 smDeviceHandle_t *smDeviceHandle, 11574 smScsiInitiatorRequest_t *smScsiRequest, 11575 smSatIOContext_t *satIOContext 11576 ) 11577 { 11578 bit32 status; 11579 bit32 agRequestType; 11580 smDeviceData_t *pSatDevData; 11581 smScsiRspSense_t *pSense; 11582 smIniScsiCmnd_t *scsiCmnd; 11583 agsaFisRegHostToDevice_t *fis; 11584 bit32 parmLen; 11585 11586 pSense = satIOContext->pSense; 11587 pSatDevData = satIOContext->pSatDevData; 11588 scsiCmnd = &smScsiRequest->scsiCmnd; 11589 fis = satIOContext->pFis; 11590 11591 SM_DBG5(("smsatSendDiagnostic: start\n")); 11592 11593 /* reset satVerifyState */ 11594 pSatDevData->satVerifyState = 0; 11595 /* no pending diagnostic in background */ 11596 pSatDevData->satBGPendingDiag = agFALSE; 11597 11598 /* table 27, 8.10 p39 SAT Rev8 */ 11599 /* 11600 1. checking PF == 1 11601 2. checking DEVOFFL == 1 11602 3. checking UNITOFFL == 1 11603 4. checking PARAMETER LIST LENGTH != 0 11604 11605 */ 11606 if ( (scsiCmnd->cdb[1] & SCSI_PF_MASK) || 11607 (scsiCmnd->cdb[1] & SCSI_DEVOFFL_MASK) || 11608 (scsiCmnd->cdb[1] & SCSI_UNITOFFL_MASK) || 11609 ( (scsiCmnd->cdb[3] != 0) || (scsiCmnd->cdb[4] != 0) ) 11610 ) 11611 { 11612 smsatSetSensePayload( pSense, 11613 SCSI_SNSKEY_ILLEGAL_REQUEST, 11614 0, 11615 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11616 satIOContext); 11617 11618 /*smEnqueueIO(smRoot, satIOContext);*/ 11619 11620 tdsmIOCompletedCB( smRoot, 11621 smIORequest, 11622 smIOSuccess, 11623 SCSI_STAT_CHECK_CONDITION, 11624 satIOContext->pSmSenseData, 11625 satIOContext->interruptContext ); 11626 11627 SM_DBG1(("smsatSendDiagnostic: return PF, DEVOFFL, UNITOFFL, PARAM LIST!!!\n")); 11628 return SM_RC_SUCCESS; 11629 } 11630 11631 /* checking CONTROL */ 11632 /* NACA == 1 or LINK == 1*/ 11633 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 11634 { 11635 smsatSetSensePayload( pSense, 11636 SCSI_SNSKEY_ILLEGAL_REQUEST, 11637 0, 11638 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11639 satIOContext); 11640 11641 /*smEnqueueIO(smRoot, satIOContext);*/ 11642 11643 tdsmIOCompletedCB( smRoot, 11644 smIORequest, 11645 smIOSuccess, 11646 SCSI_STAT_CHECK_CONDITION, 11647 satIOContext->pSmSenseData, 11648 satIOContext->interruptContext ); 11649 11650 SM_DBG1(("smsatSendDiagnostic: return control!!!\n")); 11651 return SM_RC_SUCCESS; 11652 } 11653 11654 parmLen = (scsiCmnd->cdb[3] << 8) + scsiCmnd->cdb[4]; 11655 11656 /* checking SELFTEST bit*/ 11657 /* table 29, 8.10.3, p41 SAT Rev8 */ 11658 /* case 1 */ 11659 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 11660 (pSatDevData->satSMARTSelfTest == agFALSE) 11661 ) 11662 { 11663 smsatSetSensePayload( pSense, 11664 SCSI_SNSKEY_ILLEGAL_REQUEST, 11665 0, 11666 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11667 satIOContext); 11668 11669 /*smEnqueueIO(smRoot, satIOContext);*/ 11670 11671 tdsmIOCompletedCB( smRoot, 11672 smIORequest, 11673 smIOSuccess, 11674 SCSI_STAT_CHECK_CONDITION, 11675 satIOContext->pSmSenseData, 11676 satIOContext->interruptContext ); 11677 11678 SM_DBG1(("smsatSendDiagnostic: return Table 29 case 1!!!\n")); 11679 return SM_RC_SUCCESS; 11680 } 11681 11682 /* case 2 */ 11683 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 11684 (pSatDevData->satSMARTSelfTest == agTRUE) && 11685 (pSatDevData->satSMARTEnabled == agFALSE) 11686 ) 11687 { 11688 smsatSetSensePayload( pSense, 11689 SCSI_SNSKEY_ABORTED_COMMAND, 11690 0, 11691 SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED, 11692 satIOContext); 11693 11694 /*smEnqueueIO(smRoot, satIOContext);*/ 11695 11696 tdsmIOCompletedCB( smRoot, 11697 smIORequest, 11698 smIOSuccess, 11699 SCSI_STAT_CHECK_CONDITION, 11700 satIOContext->pSmSenseData, 11701 satIOContext->interruptContext ); 11702 11703 SM_DBG5(("smsatSendDiagnostic: return Table 29 case 2\n")); 11704 return SM_RC_SUCCESS; 11705 } 11706 /* 11707 case 3 11708 see SELF TEST CODE later 11709 */ 11710 11711 11712 11713 /* case 4 */ 11714 11715 /* 11716 sends three ATA verify commands 11717 11718 */ 11719 if ( ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 11720 (pSatDevData->satSMARTSelfTest == agFALSE)) 11721 || 11722 ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 11723 (pSatDevData->satSMARTSelfTest == agTRUE) && 11724 (pSatDevData->satSMARTEnabled == agFALSE)) 11725 ) 11726 { 11727 /* 11728 sector count 1, LBA 0 11729 sector count 1, LBA MAX 11730 sector count 1, LBA random 11731 */ 11732 if (pSatDevData->sat48BitSupport == agTRUE) 11733 { 11734 /* sends READ VERIFY SECTOR(S) EXT*/ 11735 fis->h.fisType = 0x27; /* Reg host to device */ 11736 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11737 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 11738 fis->h.features = 0; /* FIS reserve */ 11739 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 11740 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 11741 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 11742 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 11743 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 11744 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 11745 fis->d.featuresExp = 0; /* FIS reserve */ 11746 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 11747 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 11748 fis->d.reserved4 = 0; 11749 fis->d.device = 0x40; /* 01000000 */ 11750 fis->d.control = 0; /* FIS HOB bit clear */ 11751 fis->d.reserved5 = 0; 11752 11753 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 11754 } 11755 else 11756 { 11757 /* READ VERIFY SECTOR(S)*/ 11758 fis->h.fisType = 0x27; /* Reg host to device */ 11759 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11760 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 11761 fis->h.features = 0; /* FIS features NA */ 11762 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 11763 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 11764 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 11765 fis->d.lbaLowExp = 0; 11766 fis->d.lbaMidExp = 0; 11767 fis->d.lbaHighExp = 0; 11768 fis->d.featuresExp = 0; 11769 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 11770 fis->d.sectorCountExp = 0; 11771 fis->d.reserved4 = 0; 11772 fis->d.device = 0x40; /* 01000000 */ 11773 fis->d.control = 0; /* FIS HOB bit clear */ 11774 fis->d.reserved5 = 0; 11775 11776 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 11777 } 11778 11779 /* Initialize CB for SATA completion. 11780 */ 11781 satIOContext->satCompleteCB = &smsatSendDiagnosticCB; 11782 11783 /* 11784 * Prepare SGL and send FIS to LL layer. 11785 */ 11786 satIOContext->reqType = agRequestType; /* Save it */ 11787 11788 status = smsataLLIOStart( smRoot, 11789 smIORequest, 11790 smDeviceHandle, 11791 smScsiRequest, 11792 satIOContext); 11793 11794 11795 SM_DBG5(("smsatSendDiagnostic: return Table 29 case 4\n")); 11796 return (status); 11797 } 11798 /* case 5 */ 11799 if ( (scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 11800 (pSatDevData->satSMARTSelfTest == agTRUE) && 11801 (pSatDevData->satSMARTEnabled == agTRUE) 11802 ) 11803 { 11804 /* sends SMART EXECUTE OFF-LINE IMMEDIATE */ 11805 fis->h.fisType = 0x27; /* Reg host to device */ 11806 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11807 fis->h.command = SAT_SMART; /* 0xB0 */ 11808 fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA */ 11809 fis->d.lbaLow = 0x81; /* FIS LBA (7 :0 ) */ 11810 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 11811 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 11812 fis->d.lbaLowExp = 0; 11813 fis->d.lbaMidExp = 0; 11814 fis->d.lbaHighExp = 0; 11815 fis->d.featuresExp = 0; 11816 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 11817 fis->d.sectorCountExp = 0; 11818 fis->d.reserved4 = 0; 11819 fis->d.device = 0; /* FIS DEV is discared in SATA */ 11820 fis->d.control = 0; /* FIS HOB bit clear */ 11821 fis->d.reserved5 = 0; 11822 11823 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 11824 11825 /* Initialize CB for SATA completion. 11826 */ 11827 satIOContext->satCompleteCB = &smsatSendDiagnosticCB; 11828 11829 /* 11830 * Prepare SGL and send FIS to LL layer. 11831 */ 11832 satIOContext->reqType = agRequestType; /* Save it */ 11833 11834 status = smsataLLIOStart( smRoot, 11835 smIORequest, 11836 smDeviceHandle, 11837 smScsiRequest, 11838 satIOContext); 11839 11840 11841 SM_DBG5(("smsatSendDiagnostic: return Table 29 case 5\n")); 11842 return (status); 11843 } 11844 11845 11846 11847 11848 /* SAT rev8 Table29 p41 case 3*/ 11849 /* checking SELF TEST CODE*/ 11850 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) && 11851 (pSatDevData->satSMARTSelfTest == agTRUE) && 11852 (pSatDevData->satSMARTEnabled == agTRUE) 11853 ) 11854 { 11855 /* SAT rev8 Table28 p40 */ 11856 /* finding self-test code */ 11857 switch ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_TEST_CODE_MASK) >> 5) 11858 { 11859 case 1: 11860 pSatDevData->satBGPendingDiag = agTRUE; 11861 11862 tdsmIOCompletedCB( smRoot, 11863 smIORequest, 11864 smIOSuccess, 11865 SCSI_STAT_GOOD, 11866 agNULL, 11867 satIOContext->interruptContext ); 11868 /* sends SMART EXECUTE OFF-LINE IMMEDIATE */ 11869 fis->h.fisType = 0x27; /* Reg host to device */ 11870 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11871 fis->h.command = SAT_SMART; /* 0x40 */ 11872 fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA */ 11873 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */ 11874 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 11875 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 11876 11877 fis->d.lbaLowExp = 0; 11878 fis->d.lbaMidExp = 0; 11879 fis->d.lbaHighExp = 0; 11880 fis->d.featuresExp = 0; 11881 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 11882 fis->d.sectorCountExp = 0; 11883 fis->d.reserved4 = 0; 11884 fis->d.device = 0; /* FIS DEV is discared in SATA */ 11885 fis->d.control = 0; /* FIS HOB bit clear */ 11886 fis->d.reserved5 = 0; 11887 11888 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 11889 11890 /* Initialize CB for SATA completion. 11891 */ 11892 satIOContext->satCompleteCB = &smsatSendDiagnosticCB; 11893 11894 /* 11895 * Prepare SGL and send FIS to LL layer. 11896 */ 11897 satIOContext->reqType = agRequestType; /* Save it */ 11898 11899 status = smsataLLIOStart( smRoot, 11900 smIORequest, 11901 smDeviceHandle, 11902 smScsiRequest, 11903 satIOContext); 11904 11905 11906 SM_DBG5(("smsatSendDiagnostic: return Table 28 case 1\n")); 11907 return (status); 11908 case 2: 11909 pSatDevData->satBGPendingDiag = agTRUE; 11910 11911 tdsmIOCompletedCB( smRoot, 11912 smIORequest, 11913 smIOSuccess, 11914 SCSI_STAT_GOOD, 11915 agNULL, 11916 satIOContext->interruptContext ); 11917 11918 11919 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */ 11920 fis->h.fisType = 0x27; /* Reg host to device */ 11921 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11922 fis->h.command = SAT_SMART; /* 0x40 */ 11923 fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA */ 11924 fis->d.lbaLow = 0x02; /* FIS LBA (7 :0 ) */ 11925 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 11926 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 11927 fis->d.lbaLowExp = 0; 11928 fis->d.lbaMidExp = 0; 11929 fis->d.lbaHighExp = 0; 11930 fis->d.featuresExp = 0; 11931 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 11932 fis->d.sectorCountExp = 0; 11933 fis->d.reserved4 = 0; 11934 fis->d.device = 0; /* FIS DEV is discared in SATA */ 11935 fis->d.control = 0; /* FIS HOB bit clear */ 11936 fis->d.reserved5 = 0; 11937 11938 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 11939 11940 /* Initialize CB for SATA completion. 11941 */ 11942 satIOContext->satCompleteCB = &smsatSendDiagnosticCB; 11943 11944 /* 11945 * Prepare SGL and send FIS to LL layer. 11946 */ 11947 satIOContext->reqType = agRequestType; /* Save it */ 11948 11949 status = smsataLLIOStart( smRoot, 11950 smIORequest, 11951 smDeviceHandle, 11952 smScsiRequest, 11953 satIOContext); 11954 11955 11956 SM_DBG5(("smsatSendDiagnostic: return Table 28 case 2\n")); 11957 return (status); 11958 case 4: 11959 11960 if (parmLen != 0) 11961 { 11962 /* check condition */ 11963 smsatSetSensePayload( pSense, 11964 SCSI_SNSKEY_ILLEGAL_REQUEST, 11965 0, 11966 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 11967 satIOContext); 11968 11969 /*smEnqueueIO(smRoot, satIOContext);*/ 11970 11971 tdsmIOCompletedCB( smRoot, 11972 smIORequest, 11973 smIOSuccess, 11974 SCSI_STAT_CHECK_CONDITION, 11975 satIOContext->pSmSenseData, 11976 satIOContext->interruptContext ); 11977 11978 SM_DBG1(("smsatSendDiagnostic: case 4, non zero ParmLen %d!!!\n", parmLen)); 11979 return SM_RC_SUCCESS; 11980 } 11981 if (pSatDevData->satBGPendingDiag == agTRUE) 11982 { 11983 /* sends SMART EXECUTE OFF-LINE IMMEDIATE abort */ 11984 fis->h.fisType = 0x27; /* Reg host to device */ 11985 fis->h.c_pmPort = 0x80; /* C Bit is set */ 11986 fis->h.command = SAT_SMART; /* 0x40 */ 11987 fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA */ 11988 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */ 11989 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 11990 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 11991 11992 fis->d.lbaLowExp = 0; 11993 fis->d.lbaMidExp = 0; 11994 fis->d.lbaHighExp = 0; 11995 fis->d.featuresExp = 0; 11996 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 11997 fis->d.sectorCountExp = 0; 11998 fis->d.reserved4 = 0; 11999 fis->d.device = 0; /* FIS DEV is discared in SATA */ 12000 fis->d.control = 0; /* FIS HOB bit clear */ 12001 fis->d.reserved5 = 0; 12002 12003 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12004 12005 /* Initialize CB for SATA completion. 12006 */ 12007 satIOContext->satCompleteCB = &smsatSendDiagnosticCB; 12008 12009 /* 12010 * Prepare SGL and send FIS to LL layer. 12011 */ 12012 satIOContext->reqType = agRequestType; /* Save it */ 12013 12014 status = smsataLLIOStart( smRoot, 12015 smIORequest, 12016 smDeviceHandle, 12017 smScsiRequest, 12018 satIOContext); 12019 12020 12021 SM_DBG5(("smsatSendDiagnostic: send SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE case 3\n")); 12022 SM_DBG5(("smsatSendDiagnostic: Table 28 case 4\n")); 12023 return (status); 12024 } 12025 else 12026 { 12027 /* check condition */ 12028 smsatSetSensePayload( pSense, 12029 SCSI_SNSKEY_ILLEGAL_REQUEST, 12030 0, 12031 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12032 satIOContext); 12033 12034 /*smEnqueueIO(smRoot, satIOContext);*/ 12035 12036 tdsmIOCompletedCB( smRoot, 12037 smIORequest, 12038 smIOSuccess, 12039 SCSI_STAT_CHECK_CONDITION, 12040 satIOContext->pSmSenseData, 12041 satIOContext->interruptContext ); 12042 12043 SM_DBG1(("smsatSendDiagnostic: case 4, no pending diagnostic in background!!!\n")); 12044 SM_DBG5(("smsatSendDiagnostic: Table 28 case 4\n")); 12045 return SM_RC_SUCCESS; 12046 } 12047 break; 12048 case 5: 12049 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */ 12050 fis->h.fisType = 0x27; /* Reg host to device */ 12051 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12052 fis->h.command = SAT_SMART; /* 0x40 */ 12053 fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA */ 12054 fis->d.lbaLow = 0x81; /* FIS LBA (7 :0 ) */ 12055 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 12056 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 12057 fis->d.lbaLowExp = 0; 12058 fis->d.lbaMidExp = 0; 12059 fis->d.lbaHighExp = 0; 12060 fis->d.featuresExp = 0; 12061 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 12062 fis->d.sectorCountExp = 0; 12063 fis->d.reserved4 = 0; 12064 fis->d.device = 0; /* FIS DEV is discared in SATA */ 12065 fis->d.control = 0; /* FIS HOB bit clear */ 12066 fis->d.reserved5 = 0; 12067 12068 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12069 12070 /* Initialize CB for SATA completion. 12071 */ 12072 satIOContext->satCompleteCB = &smsatSendDiagnosticCB; 12073 12074 /* 12075 * Prepare SGL and send FIS to LL layer. 12076 */ 12077 satIOContext->reqType = agRequestType; /* Save it */ 12078 12079 status = smsataLLIOStart( smRoot, 12080 smIORequest, 12081 smDeviceHandle, 12082 smScsiRequest, 12083 satIOContext); 12084 12085 12086 SM_DBG5(("smsatSendDiagnostic: return Table 28 case 5\n")); 12087 return (status); 12088 case 6: 12089 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */ 12090 fis->h.fisType = 0x27; /* Reg host to device */ 12091 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12092 fis->h.command = SAT_SMART; /* 0x40 */ 12093 fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA */ 12094 fis->d.lbaLow = 0x82; /* FIS LBA (7 :0 ) */ 12095 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 12096 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 12097 fis->d.lbaLowExp = 0; 12098 fis->d.lbaMidExp = 0; 12099 fis->d.lbaHighExp = 0; 12100 fis->d.featuresExp = 0; 12101 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 12102 fis->d.sectorCountExp = 0; 12103 fis->d.reserved4 = 0; 12104 fis->d.device = 0; /* FIS DEV is discared in SATA */ 12105 fis->d.control = 0; /* FIS HOB bit clear */ 12106 fis->d.reserved5 = 0; 12107 12108 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12109 12110 /* Initialize CB for SATA completion. 12111 */ 12112 satIOContext->satCompleteCB = &smsatSendDiagnosticCB; 12113 12114 /* 12115 * Prepare SGL and send FIS to LL layer. 12116 */ 12117 satIOContext->reqType = agRequestType; /* Save it */ 12118 12119 status = smsataLLIOStart( smRoot, 12120 smIORequest, 12121 smDeviceHandle, 12122 smScsiRequest, 12123 satIOContext); 12124 12125 12126 SM_DBG5(("smsatSendDiagnostic: return Table 28 case 6\n")); 12127 return (status); 12128 case 0: 12129 case 3: /* fall through */ 12130 case 7: /* fall through */ 12131 default: 12132 break; 12133 }/* switch */ 12134 12135 /* returns the results of default self-testing, which is good */ 12136 /*smEnqueueIO(smRoot, satIOContext);*/ 12137 12138 tdsmIOCompletedCB( smRoot, 12139 smIORequest, 12140 smIOSuccess, 12141 SCSI_STAT_GOOD, 12142 agNULL, 12143 satIOContext->interruptContext ); 12144 12145 SM_DBG5(("smsatSendDiagnostic: return Table 28 case 0,3,7 and default\n")); 12146 return SM_RC_SUCCESS; 12147 } 12148 12149 12150 /*smEnqueueIO(smRoot, satIOContext);*/ 12151 12152 tdsmIOCompletedCB( smRoot, 12153 smIORequest, 12154 smIOSuccess, 12155 SCSI_STAT_GOOD, 12156 agNULL, 12157 satIOContext->interruptContext ); 12158 12159 12160 SM_DBG5(("smsatSendDiagnostic: return last\n")); 12161 return SM_RC_SUCCESS; 12162 12163 } 12164 12165 osGLOBAL bit32 12166 smsatStartStopUnit( 12167 smRoot_t *smRoot, 12168 smIORequest_t *smIORequest, 12169 smDeviceHandle_t *smDeviceHandle, 12170 smScsiInitiatorRequest_t *smScsiRequest, 12171 smSatIOContext_t *satIOContext 12172 ) 12173 { 12174 bit32 status; 12175 bit32 agRequestType; 12176 smDeviceData_t *pSatDevData; 12177 smScsiRspSense_t *pSense; 12178 smIniScsiCmnd_t *scsiCmnd; 12179 agsaFisRegHostToDevice_t *fis; 12180 12181 pSense = satIOContext->pSense; 12182 pSatDevData = satIOContext->pSatDevData; 12183 scsiCmnd = &smScsiRequest->scsiCmnd; 12184 fis = satIOContext->pFis; 12185 12186 SM_DBG5(("smsatStartStopUnit: start\n")); 12187 12188 /* checking CONTROL */ 12189 /* NACA == 1 or LINK == 1*/ 12190 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 12191 { 12192 smsatSetSensePayload( pSense, 12193 SCSI_SNSKEY_ILLEGAL_REQUEST, 12194 0, 12195 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12196 satIOContext); 12197 12198 /*smEnqueueIO(smRoot, satIOContext);*/ 12199 12200 tdsmIOCompletedCB( smRoot, 12201 smIORequest, 12202 smIOSuccess, 12203 SCSI_STAT_CHECK_CONDITION, 12204 satIOContext->pSmSenseData, 12205 satIOContext->interruptContext ); 12206 12207 SM_DBG1(("smsatStartStopUnit: return control!!!\n")); 12208 return SM_RC_SUCCESS; 12209 } 12210 12211 /* Spec p55, Table 48 checking START and LOEJ bit */ 12212 /* case 1 */ 12213 if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) 12214 { 12215 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) ) 12216 { 12217 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/ 12218 /*smEnqueueIO(smRoot, satIOContext);*/ 12219 12220 tdsmIOCompletedCB( smRoot, 12221 smIORequest, 12222 smIOSuccess, 12223 SCSI_STAT_GOOD, 12224 agNULL, 12225 satIOContext->interruptContext ); 12226 SM_DBG5(("smsatStartStopUnit: return table48 case 1-1\n")); 12227 return SM_RC_SUCCESS; 12228 } 12229 /* sends FLUSH CACHE or FLUSH CACHE EXT */ 12230 if (pSatDevData->sat48BitSupport == agTRUE) 12231 { 12232 /* FLUSH CACHE EXT */ 12233 fis->h.fisType = 0x27; /* Reg host to device */ 12234 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12235 12236 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */ 12237 fis->h.features = 0; /* FIS reserve */ 12238 fis->d.featuresExp = 0; /* FIS reserve */ 12239 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 12240 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 12241 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 12242 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 12243 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 12244 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 12245 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 12246 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 12247 fis->d.device = 0; /* FIS DEV is discared in SATA */ 12248 fis->d.control = 0; /* FIS HOB bit clear */ 12249 fis->d.reserved4 = 0; 12250 fis->d.reserved5 = 0; 12251 12252 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12253 } 12254 else 12255 { 12256 /* FLUSH CACHE */ 12257 fis->h.fisType = 0x27; /* Reg host to device */ 12258 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12259 12260 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */ 12261 fis->h.features = 0; /* FIS features NA */ 12262 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 12263 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 12264 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 12265 fis->d.lbaLowExp = 0; 12266 fis->d.lbaMidExp = 0; 12267 fis->d.lbaHighExp = 0; 12268 fis->d.featuresExp = 0; 12269 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 12270 fis->d.sectorCountExp = 0; 12271 fis->d.device = 0; /* FIS DEV is discared in SATA */ 12272 fis->d.control = 0; /* FIS HOB bit clear */ 12273 fis->d.reserved4 = 0; 12274 fis->d.reserved5 = 0; 12275 12276 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12277 } 12278 12279 /* Initialize CB for SATA completion. 12280 */ 12281 satIOContext->satCompleteCB = &smsatStartStopUnitCB; 12282 12283 /* 12284 * Prepare SGL and send FIS to LL layer. 12285 */ 12286 satIOContext->reqType = agRequestType; /* Save it */ 12287 12288 status = smsataLLIOStart( smRoot, 12289 smIORequest, 12290 smDeviceHandle, 12291 smScsiRequest, 12292 satIOContext); 12293 12294 12295 SM_DBG5(("smsatStartStopUnit: return table48 case 1\n")); 12296 return (status); 12297 } 12298 /* case 2 */ 12299 else if ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) 12300 { 12301 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/ 12302 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) ) 12303 { 12304 /*smEnqueueIO(smRoot, satIOContext);*/ 12305 12306 tdsmIOCompletedCB( smRoot, 12307 smIORequest, 12308 smIOSuccess, 12309 SCSI_STAT_GOOD, 12310 agNULL, 12311 satIOContext->interruptContext ); 12312 12313 SM_DBG5(("smsatStartStopUnit: return table48 case 2 1\n")); 12314 return SM_RC_SUCCESS; 12315 } 12316 /* 12317 sends READ_VERIFY_SECTORS(_EXT) 12318 sector count 1, any LBA between zero to Maximum 12319 */ 12320 if (pSatDevData->sat48BitSupport == agTRUE) 12321 { 12322 /* READ VERIFY SECTOR(S) EXT*/ 12323 fis->h.fisType = 0x27; /* Reg host to device */ 12324 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12325 12326 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 12327 fis->h.features = 0; /* FIS reserve */ 12328 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */ 12329 fis->d.lbaMid = 0x00; /* FIS LBA (15:8 ) */ 12330 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */ 12331 fis->d.lbaLowExp = 0x00; /* FIS LBA (31:24) */ 12332 fis->d.lbaMidExp = 0x00; /* FIS LBA (39:32) */ 12333 fis->d.lbaHighExp = 0x00; /* FIS LBA (47:40) */ 12334 fis->d.featuresExp = 0; /* FIS reserve */ 12335 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 12336 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 12337 fis->d.reserved4 = 0; 12338 fis->d.device = 0x40; /* 01000000 */ 12339 fis->d.control = 0; /* FIS HOB bit clear */ 12340 fis->d.reserved5 = 0; 12341 12342 } 12343 else 12344 { 12345 /* READ VERIFY SECTOR(S)*/ 12346 fis->h.fisType = 0x27; /* Reg host to device */ 12347 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12348 12349 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 12350 fis->h.features = 0; /* FIS features NA */ 12351 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */ 12352 fis->d.lbaMid = 0x00; /* FIS LBA (15:8 ) */ 12353 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */ 12354 fis->d.lbaLowExp = 0; 12355 fis->d.lbaMidExp = 0; 12356 fis->d.lbaHighExp = 0; 12357 fis->d.featuresExp = 0; 12358 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 12359 fis->d.sectorCountExp = 0; 12360 fis->d.reserved4 = 0; 12361 fis->d.device = 0x40; /* 01000000 */ 12362 fis->d.control = 0; /* FIS HOB bit clear */ 12363 fis->d.reserved5 = 0; 12364 12365 } 12366 12367 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12368 12369 /* Initialize CB for SATA completion. 12370 */ 12371 satIOContext->satCompleteCB = &smsatStartStopUnitCB; 12372 12373 /* 12374 * Prepare SGL and send FIS to LL layer. 12375 */ 12376 satIOContext->reqType = agRequestType; /* Save it */ 12377 12378 status = smsataLLIOStart( smRoot, 12379 smIORequest, 12380 smDeviceHandle, 12381 smScsiRequest, 12382 satIOContext); 12383 12384 SM_DBG5(("smsatStartStopUnit: return table48 case 2 2\n")); 12385 return status; 12386 } 12387 /* case 3 */ 12388 else if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) 12389 { 12390 if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled) 12391 { 12392 /* support for removal media */ 12393 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/ 12394 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) ) 12395 { 12396 /*smEnqueueIO(smRoot, satIOContext);*/ 12397 12398 tdsmIOCompletedCB( smRoot, 12399 smIORequest, 12400 smIOSuccess, 12401 SCSI_STAT_GOOD, 12402 agNULL, 12403 satIOContext->interruptContext ); 12404 12405 SM_DBG5(("smsatStartStopUnit: return table48 case 3 1\n")); 12406 return SM_RC_SUCCESS; 12407 } 12408 /* 12409 sends MEDIA EJECT 12410 */ 12411 /* Media Eject fis */ 12412 fis->h.fisType = 0x27; /* Reg host to device */ 12413 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12414 12415 fis->h.command = SAT_MEDIA_EJECT; /* 0xED */ 12416 fis->h.features = 0; /* FIS features NA */ 12417 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 12418 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 12419 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 12420 fis->d.lbaLowExp = 0; 12421 fis->d.lbaMidExp = 0; 12422 fis->d.lbaHighExp = 0; 12423 fis->d.featuresExp = 0; 12424 /* sector count zero */ 12425 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 12426 fis->d.sectorCountExp = 0; 12427 fis->d.device = 0; /* FIS DEV is discared in SATA */ 12428 fis->d.control = 0; /* FIS HOB bit clear */ 12429 fis->d.reserved4 = 0; 12430 fis->d.reserved5 = 0; 12431 12432 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 12433 12434 /* Initialize CB for SATA completion. 12435 */ 12436 satIOContext->satCompleteCB = &smsatStartStopUnitCB; 12437 12438 /* 12439 * Prepare SGL and send FIS to LL layer. 12440 */ 12441 satIOContext->reqType = agRequestType; /* Save it */ 12442 12443 status = smsataLLIOStart( smRoot, 12444 smIORequest, 12445 smDeviceHandle, 12446 smScsiRequest, 12447 satIOContext); 12448 12449 return status; 12450 } 12451 else 12452 { 12453 /* no support for removal media */ 12454 smsatSetSensePayload( pSense, 12455 SCSI_SNSKEY_ILLEGAL_REQUEST, 12456 0, 12457 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12458 satIOContext); 12459 12460 /*smEnqueueIO(smRoot, satIOContext);*/ 12461 12462 tdsmIOCompletedCB( smRoot, 12463 smIORequest, 12464 smIOSuccess, 12465 SCSI_STAT_CHECK_CONDITION, 12466 satIOContext->pSmSenseData, 12467 satIOContext->interruptContext ); 12468 12469 SM_DBG5(("smsatStartStopUnit: return Table 29 case 3 2\n")); 12470 return SM_RC_SUCCESS; 12471 } 12472 12473 } 12474 /* case 4 */ 12475 else /* ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) */ 12476 { 12477 smsatSetSensePayload( pSense, 12478 SCSI_SNSKEY_ILLEGAL_REQUEST, 12479 0, 12480 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12481 satIOContext); 12482 12483 /*smEnqueueIO(smRoot, satIOContext);*/ 12484 12485 tdsmIOCompletedCB( smRoot, 12486 smIORequest, 12487 smIOSuccess, 12488 SCSI_STAT_CHECK_CONDITION, 12489 satIOContext->pSmSenseData, 12490 satIOContext->interruptContext ); 12491 12492 SM_DBG5(("smsatStartStopUnit: return Table 29 case 4\n")); 12493 return SM_RC_SUCCESS; 12494 } 12495 } 12496 12497 osGLOBAL bit32 12498 smsatWriteSame10( 12499 smRoot_t *smRoot, 12500 smIORequest_t *smIORequest, 12501 smDeviceHandle_t *smDeviceHandle, 12502 smScsiInitiatorRequest_t *smScsiRequest, 12503 smSatIOContext_t *satIOContext 12504 ) 12505 { 12506 12507 bit32 status; 12508 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 12509 smDeviceData_t *pSatDevData; 12510 smScsiRspSense_t *pSense; 12511 smIniScsiCmnd_t *scsiCmnd; 12512 agsaFisRegHostToDevice_t *fis; 12513 bit32 lba = 0; 12514 bit32 tl = 0; 12515 12516 pSense = satIOContext->pSense; 12517 pSatDevData = satIOContext->pSatDevData; 12518 scsiCmnd = &smScsiRequest->scsiCmnd; 12519 fis = satIOContext->pFis; 12520 12521 SM_DBG5(("smsatWriteSame10: start\n")); 12522 12523 /* checking CONTROL */ 12524 /* NACA == 1 or LINK == 1*/ 12525 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 12526 { 12527 smsatSetSensePayload( pSense, 12528 SCSI_SNSKEY_ILLEGAL_REQUEST, 12529 0, 12530 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12531 satIOContext); 12532 12533 /*smEnqueueIO(smRoot, satIOContext);*/ 12534 12535 tdsmIOCompletedCB( smRoot, 12536 smIORequest, 12537 smIOSuccess, 12538 SCSI_STAT_CHECK_CONDITION, 12539 satIOContext->pSmSenseData, 12540 satIOContext->interruptContext ); 12541 12542 SM_DBG1(("smsatWriteSame10: return control!!!\n")); 12543 return SM_RC_SUCCESS; 12544 } 12545 12546 12547 /* checking LBDATA and PBDATA */ 12548 /* case 1 */ 12549 if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) && 12550 !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) 12551 { 12552 SM_DBG5(("smsatWriteSame10: case 1\n")); 12553 /* spec 9.26.2, Table 62, p64, case 1*/ 12554 /* 12555 normal case 12556 just like write in 9.17.1 12557 */ 12558 12559 if ( pSatDevData->sat48BitSupport != agTRUE ) 12560 { 12561 /* 12562 writeSame10 but no support for 48 bit addressing 12563 -> problem in transfer length. Therefore, return check condition 12564 */ 12565 smsatSetSensePayload( pSense, 12566 SCSI_SNSKEY_ILLEGAL_REQUEST, 12567 0, 12568 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12569 satIOContext); 12570 12571 /*smEnqueueIO(smRoot, satIOContext);*/ 12572 12573 tdsmIOCompletedCB( smRoot, 12574 smIORequest, 12575 smIOSuccess, 12576 SCSI_STAT_CHECK_CONDITION, 12577 satIOContext->pSmSenseData, 12578 satIOContext->interruptContext ); 12579 12580 SM_DBG1(("smsatWriteSame10: return internal checking!!!\n")); 12581 return SM_RC_SUCCESS; 12582 } 12583 12584 /* cdb10; computing LBA and transfer length */ 12585 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 12586 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 12587 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 12588 12589 12590 /* Table 34, 9.1, p 46 */ 12591 /* 12592 note: As of 2/10/2006, no support for DMA QUEUED 12593 */ 12594 12595 /* 12596 Table 34, 9.1, p 46, b (footnote) 12597 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 12598 return check condition 12599 */ 12600 if (pSatDevData->satNCQ != agTRUE && 12601 pSatDevData->sat48BitSupport != agTRUE 12602 ) 12603 { 12604 if (lba > SAT_TR_LBA_LIMIT - 1) /* SAT_TR_LBA_LIMIT is 2^28, 0x10000000 */ 12605 { 12606 smsatSetSensePayload( pSense, 12607 SCSI_SNSKEY_ILLEGAL_REQUEST, 12608 0, 12609 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 12610 satIOContext); 12611 12612 /*smEnqueueIO(smRoot, satIOContext);*/ 12613 12614 tdsmIOCompletedCB( smRoot, 12615 smIORequest, 12616 smIOSuccess, 12617 SCSI_STAT_CHECK_CONDITION, 12618 satIOContext->pSmSenseData, 12619 satIOContext->interruptContext ); 12620 12621 SM_DBG1(("smsatWriteSame10: return LBA out of range!!!\n")); 12622 return SM_RC_SUCCESS; 12623 } 12624 } 12625 12626 12627 if (lba + tl <= SAT_TR_LBA_LIMIT) 12628 { 12629 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 12630 { 12631 /* case 2 */ 12632 /* WRITE DMA */ 12633 /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */ 12634 SM_DBG1(("smsatWriteSame10: case 1-2 !!! error due to writesame10!!!\n")); 12635 smsatSetSensePayload( pSense, 12636 SCSI_SNSKEY_ILLEGAL_REQUEST, 12637 0, 12638 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12639 satIOContext); 12640 12641 /*smEnqueueIO(smRoot, satIOContext);*/ 12642 12643 tdsmIOCompletedCB( smRoot, 12644 smIORequest, 12645 smIOSuccess, 12646 SCSI_STAT_CHECK_CONDITION, 12647 satIOContext->pSmSenseData, 12648 satIOContext->interruptContext ); 12649 return SM_RC_SUCCESS; 12650 } 12651 else 12652 { 12653 /* case 1 */ 12654 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 12655 /* WRITE SECTORS is chosen for easier implemetation */ 12656 /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */ 12657 SM_DBG1(("smsatWriteSame10: case 1-1 !!! error due to writesame10!!!\n")); 12658 smsatSetSensePayload( pSense, 12659 SCSI_SNSKEY_ILLEGAL_REQUEST, 12660 0, 12661 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12662 satIOContext); 12663 12664 /*smEnqueueIO(smRoot, satIOContext);*/ 12665 12666 tdsmIOCompletedCB( smRoot, 12667 smIORequest, 12668 smIOSuccess, 12669 SCSI_STAT_CHECK_CONDITION, 12670 satIOContext->pSmSenseData, 12671 satIOContext->interruptContext ); 12672 return SM_RC_SUCCESS; 12673 } 12674 } /* end of case 1 and 2 */ 12675 12676 /* case 3 and 4 */ 12677 if (pSatDevData->sat48BitSupport == agTRUE) 12678 { 12679 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 12680 { 12681 /* case 3 */ 12682 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 12683 /* WRITE DMA EXT is chosen since WRITE SAME does not have FUA bit */ 12684 SM_DBG5(("smsatWriteSame10: case 1-3\n")); 12685 fis->h.fisType = 0x27; /* Reg host to device */ 12686 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12687 12688 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 12689 12690 fis->h.features = 0; /* FIS reserve */ 12691 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 12692 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 12693 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 12694 fis->d.device = 0x40; /* FIS LBA mode set */ 12695 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 12696 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 12697 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 12698 fis->d.featuresExp = 0; /* FIS reserve */ 12699 if (tl == 0) 12700 { 12701 /* error check 12702 ATA spec, p125, 6.17.29 12703 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF 12704 and allowed value is 0x0FFFFFFF - 1 12705 */ 12706 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF) 12707 { 12708 SM_DBG1(("smsatWriteSame10: case 3 !!! warning can't fit sectors!!!\n")); 12709 smsatSetSensePayload( pSense, 12710 SCSI_SNSKEY_ILLEGAL_REQUEST, 12711 0, 12712 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12713 satIOContext); 12714 12715 /*smEnqueueIO(smRoot, satIOContext);*/ 12716 12717 tdsmIOCompletedCB( smRoot, 12718 smIORequest, 12719 smIOSuccess, 12720 SCSI_STAT_CHECK_CONDITION, 12721 satIOContext->pSmSenseData, 12722 satIOContext->interruptContext ); 12723 return SM_RC_SUCCESS; 12724 } 12725 } 12726 /* one sector at a time */ 12727 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 12728 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 12729 fis->d.reserved4 = 0; 12730 fis->d.control = 0; /* FIS HOB bit clear */ 12731 fis->d.reserved5 = 0; 12732 12733 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 12734 } 12735 else 12736 { 12737 /* case 4 */ 12738 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 12739 /* WRITE SECTORS EXT is chosen for easier implemetation */ 12740 SM_DBG5(("smsatWriteSame10: case 1-4\n")); 12741 fis->h.fisType = 0x27; /* Reg host to device */ 12742 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12743 12744 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 12745 fis->h.features = 0; /* FIS reserve */ 12746 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 12747 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 12748 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 12749 fis->d.device = 0x40; /* FIS LBA mode set */ 12750 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 12751 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 12752 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 12753 fis->d.featuresExp = 0; /* FIS reserve */ 12754 if (tl == 0) 12755 { 12756 /* error check 12757 ATA spec, p125, 6.17.29 12758 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF 12759 and allowed value is 0x0FFFFFFF - 1 12760 */ 12761 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF) 12762 { 12763 SM_DBG1(("smsatWriteSame10: case 4 !!! warning can't fit sectors!!!\n")); 12764 smsatSetSensePayload( pSense, 12765 SCSI_SNSKEY_ILLEGAL_REQUEST, 12766 0, 12767 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12768 satIOContext); 12769 12770 /*smEnqueueIO(smRoot, satIOContext);*/ 12771 12772 tdsmIOCompletedCB( smRoot, 12773 smIORequest, 12774 smIOSuccess, 12775 SCSI_STAT_CHECK_CONDITION, 12776 satIOContext->pSmSenseData, 12777 satIOContext->interruptContext ); 12778 return SM_RC_SUCCESS; 12779 } 12780 } 12781 /* one sector at a time */ 12782 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 12783 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 12784 fis->d.reserved4 = 0; 12785 fis->d.control = 0; /* FIS HOB bit clear */ 12786 fis->d.reserved5 = 0; 12787 12788 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 12789 } 12790 } 12791 12792 /* case 5 */ 12793 if (pSatDevData->satNCQ == agTRUE) 12794 { 12795 /* WRITE FPDMA QUEUED */ 12796 if (pSatDevData->sat48BitSupport != agTRUE) 12797 { 12798 SM_DBG1(("smsatWriteSame10: case 1-5 !!! error NCQ but 28 bit address support!!!\n")); 12799 smsatSetSensePayload( pSense, 12800 SCSI_SNSKEY_ILLEGAL_REQUEST, 12801 0, 12802 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12803 satIOContext); 12804 12805 /*smEnqueueIO(smRoot, satIOContext);*/ 12806 12807 tdsmIOCompletedCB( smRoot, 12808 smIORequest, 12809 smIOSuccess, 12810 SCSI_STAT_CHECK_CONDITION, 12811 satIOContext->pSmSenseData, 12812 satIOContext->interruptContext ); 12813 return SM_RC_SUCCESS; 12814 } 12815 SM_DBG5(("smsatWriteSame10: case 1-5\n")); 12816 12817 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 12818 12819 fis->h.fisType = 0x27; /* Reg host to device */ 12820 fis->h.c_pmPort = 0x80; /* C Bit is set */ 12821 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 12822 12823 if (tl == 0) 12824 { 12825 /* error check 12826 ATA spec, p125, 6.17.29 12827 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF 12828 and allowed value is 0x0FFFFFFF - 1 12829 */ 12830 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF) 12831 { 12832 SM_DBG1(("smsatWriteSame10: case 4 !!! warning can't fit sectors!!!\n")); 12833 smsatSetSensePayload( pSense, 12834 SCSI_SNSKEY_ILLEGAL_REQUEST, 12835 0, 12836 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12837 satIOContext); 12838 12839 /*smEnqueueIO(smRoot, satIOContext);*/ 12840 12841 tdsmIOCompletedCB( smRoot, 12842 smIORequest, 12843 smIOSuccess, 12844 SCSI_STAT_CHECK_CONDITION, 12845 satIOContext->pSmSenseData, 12846 satIOContext->interruptContext ); 12847 return SM_RC_SUCCESS; 12848 } 12849 } 12850 /* one sector at a time */ 12851 fis->h.features = 1; /* FIS sector count (7:0) */ 12852 fis->d.featuresExp = 0; /* FIS sector count (15:8) */ 12853 12854 12855 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 12856 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 12857 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 12858 12859 /* NO FUA bit in the WRITE SAME 10 */ 12860 fis->d.device = 0x40; /* FIS FUA clear */ 12861 12862 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 12863 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 12864 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 12865 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 12866 fis->d.sectorCountExp = 0; 12867 fis->d.reserved4 = 0; 12868 fis->d.control = 0; /* FIS HOB bit clear */ 12869 fis->d.reserved5 = 0; 12870 12871 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 12872 } 12873 /* Initialize CB for SATA completion. 12874 */ 12875 satIOContext->satCompleteCB = &smsatWriteSame10CB; 12876 12877 /* 12878 * Prepare SGL and send FIS to LL layer. 12879 */ 12880 satIOContext->reqType = agRequestType; /* Save it */ 12881 12882 status = smsataLLIOStart( smRoot, 12883 smIORequest, 12884 smDeviceHandle, 12885 smScsiRequest, 12886 satIOContext); 12887 return (status); 12888 12889 12890 } /* end of case 1 */ 12891 else if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) && 12892 (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) 12893 { 12894 /* spec 9.26.2, Table 62, p64, case 2*/ 12895 smsatSetSensePayload( pSense, 12896 SCSI_SNSKEY_ILLEGAL_REQUEST, 12897 0, 12898 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12899 satIOContext); 12900 12901 /*smEnqueueIO(smRoot, satIOContext);*/ 12902 12903 tdsmIOCompletedCB( smRoot, 12904 smIORequest, 12905 smIOSuccess, 12906 SCSI_STAT_CHECK_CONDITION, 12907 satIOContext->pSmSenseData, 12908 satIOContext->interruptContext ); 12909 12910 SM_DBG5(("smsatWriteSame10: return Table 62 case 2\n")); 12911 return SM_RC_SUCCESS; 12912 } 12913 else if ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) && 12914 !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) 12915 { 12916 SM_DBG5(("smsatWriteSame10: Table 62 case 3\n")); 12917 12918 } 12919 else /* ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) && 12920 (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) */ 12921 { 12922 12923 /* spec 9.26.2, Table 62, p64, case 4*/ 12924 smsatSetSensePayload( pSense, 12925 SCSI_SNSKEY_ILLEGAL_REQUEST, 12926 0, 12927 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 12928 satIOContext); 12929 12930 /*smEnqueueIO(smRoot, satIOContext);*/ 12931 12932 tdsmIOCompletedCB( smRoot, 12933 smIORequest, 12934 smIOSuccess, 12935 SCSI_STAT_CHECK_CONDITION, 12936 satIOContext->pSmSenseData, 12937 satIOContext->interruptContext ); 12938 12939 SM_DBG5(("smsatWriteSame10: return Table 62 case 4\n")); 12940 return SM_RC_SUCCESS; 12941 } 12942 12943 12944 return SM_RC_SUCCESS; 12945 } 12946 12947 osGLOBAL bit32 12948 smsatWriteSame16( 12949 smRoot_t *smRoot, 12950 smIORequest_t *smIORequest, 12951 smDeviceHandle_t *smDeviceHandle, 12952 smScsiInitiatorRequest_t *smScsiRequest, 12953 smSatIOContext_t *satIOContext 12954 ) 12955 { 12956 smScsiRspSense_t *pSense; 12957 12958 pSense = satIOContext->pSense; 12959 12960 SM_DBG5(("smsatWriteSame16: start\n")); 12961 12962 12963 smsatSetSensePayload( pSense, 12964 SCSI_SNSKEY_NO_SENSE, 12965 0, 12966 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 12967 satIOContext); 12968 12969 /*smEnqueueIO(smRoot, satIOContext);*/ 12970 12971 tdsmIOCompletedCB( smRoot, 12972 smIORequest, /* == &satIntIo->satOrgSmIORequest */ 12973 smIOSuccess, 12974 SCSI_STAT_CHECK_CONDITION, 12975 satIOContext->pSmSenseData, 12976 satIOContext->interruptContext ); 12977 SM_DBG1(("smsatWriteSame16: return internal checking!!!\n")); 12978 return SM_RC_SUCCESS; 12979 } 12980 12981 osGLOBAL bit32 12982 smsatLogSense( 12983 smRoot_t *smRoot, 12984 smIORequest_t *smIORequest, 12985 smDeviceHandle_t *smDeviceHandle, 12986 smScsiInitiatorRequest_t *smScsiRequest, 12987 smSatIOContext_t *satIOContext 12988 ) 12989 { 12990 bit32 status; 12991 bit32 agRequestType; 12992 smDeviceData_t *pSatDevData; 12993 smScsiRspSense_t *pSense; 12994 smIniScsiCmnd_t *scsiCmnd; 12995 agsaFisRegHostToDevice_t *fis; 12996 bit8 *pLogPage; /* Log Page data buffer */ 12997 bit32 flag = 0; 12998 bit16 AllocLen = 0; /* allocation length */ 12999 bit8 AllLogPages[8]; 13000 bit16 lenRead = 0; 13001 13002 pSense = satIOContext->pSense; 13003 pSatDevData = satIOContext->pSatDevData; 13004 scsiCmnd = &smScsiRequest->scsiCmnd; 13005 fis = satIOContext->pFis; 13006 pLogPage = (bit8 *) smScsiRequest->sglVirtualAddr; 13007 13008 SM_DBG5(("smsatLogSense: start\n")); 13009 13010 sm_memset(&AllLogPages, 0, 8); 13011 /* checking CONTROL */ 13012 /* NACA == 1 or LINK == 1*/ 13013 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 13014 { 13015 smsatSetSensePayload( pSense, 13016 SCSI_SNSKEY_ILLEGAL_REQUEST, 13017 0, 13018 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13019 satIOContext); 13020 13021 /*smEnqueueIO(smRoot, satIOContext);*/ 13022 13023 tdsmIOCompletedCB( smRoot, 13024 smIORequest, 13025 smIOSuccess, 13026 SCSI_STAT_CHECK_CONDITION, 13027 satIOContext->pSmSenseData, 13028 satIOContext->interruptContext ); 13029 13030 SM_DBG1(("smsatLogSense: return control!!!\n")); 13031 return SM_RC_SUCCESS; 13032 } 13033 13034 13035 AllocLen = ((scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]); 13036 AllocLen = MIN(AllocLen, scsiCmnd->expDataLength); 13037 13038 /* checking PC (Page Control) */ 13039 /* nothing */ 13040 13041 /* special cases */ 13042 if (AllocLen == 4) 13043 { 13044 SM_DBG1(("smsatLogSense: AllocLen is 4!!!\n")); 13045 switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK) 13046 { 13047 case LOGSENSE_SUPPORTED_LOG_PAGES: 13048 SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n")); 13049 13050 if (pSatDevData->satSMARTFeatureSet == agTRUE) 13051 { 13052 /* add informational exception log */ 13053 flag = 1; 13054 if (pSatDevData->satSMARTSelfTest == agTRUE) 13055 { 13056 /* add Self-Test results log page */ 13057 flag = 2; 13058 } 13059 } 13060 else 13061 { 13062 /* only supported, no informational exception log, no Self-Test results log page */ 13063 flag = 0; 13064 } 13065 lenRead = 4; 13066 AllLogPages[0] = LOGSENSE_SUPPORTED_LOG_PAGES; /* page code */ 13067 AllLogPages[1] = 0; /* reserved */ 13068 switch (flag) 13069 { 13070 case 0: 13071 /* only supported */ 13072 AllLogPages[2] = 0; /* page length */ 13073 AllLogPages[3] = 1; /* page length */ 13074 break; 13075 case 1: 13076 /* supported and informational exception log */ 13077 AllLogPages[2] = 0; /* page length */ 13078 AllLogPages[3] = 2; /* page length */ 13079 break; 13080 case 2: 13081 /* supported and informational exception log */ 13082 AllLogPages[2] = 0; /* page length */ 13083 AllLogPages[3] = 3; /* page length */ 13084 break; 13085 default: 13086 SM_DBG1(("smsatLogSense: error unallowed flag value %d!!!\n", flag)); 13087 break; 13088 } 13089 sm_memcpy(pLogPage, &AllLogPages, lenRead); 13090 break; 13091 case LOGSENSE_SELFTEST_RESULTS_PAGE: 13092 SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n")); 13093 lenRead = 4; 13094 AllLogPages[0] = LOGSENSE_SELFTEST_RESULTS_PAGE; /* page code */ 13095 AllLogPages[1] = 0; /* reserved */ 13096 /* page length = SELFTEST_RESULTS_LOG_PAGE_LENGTH - 1 - 3 = 400 = 0x190 */ 13097 AllLogPages[2] = 0x01; 13098 AllLogPages[3] = 0x90; /* page length */ 13099 sm_memcpy(pLogPage, &AllLogPages, lenRead); 13100 13101 break; 13102 case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE: 13103 SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n")); 13104 lenRead = 4; 13105 AllLogPages[0] = LOGSENSE_INFORMATION_EXCEPTIONS_PAGE; /* page code */ 13106 AllLogPages[1] = 0; /* reserved */ 13107 AllLogPages[2] = 0; /* page length */ 13108 AllLogPages[3] = INFORMATION_EXCEPTIONS_LOG_PAGE_LENGTH - 1 - 3; /* page length */ 13109 sm_memcpy(pLogPage, &AllLogPages, lenRead); 13110 break; 13111 default: 13112 SM_DBG1(("smsatLogSense: default Page Code 0x%x!!!\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)); 13113 smsatSetSensePayload( pSense, 13114 SCSI_SNSKEY_ILLEGAL_REQUEST, 13115 0, 13116 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13117 satIOContext); 13118 13119 /*smEnqueueIO(smRoot, satIOContext);*/ 13120 13121 tdsmIOCompletedCB( smRoot, 13122 smIORequest, 13123 smIOSuccess, 13124 SCSI_STAT_CHECK_CONDITION, 13125 satIOContext->pSmSenseData, 13126 satIOContext->interruptContext ); 13127 return SM_RC_SUCCESS; 13128 } 13129 /*smEnqueueIO(smRoot, satIOContext);*/ 13130 13131 tdsmIOCompletedCB( smRoot, 13132 smIORequest, 13133 smIOSuccess, 13134 SCSI_STAT_GOOD, 13135 agNULL, 13136 satIOContext->interruptContext); 13137 return SM_RC_SUCCESS; 13138 13139 } /* if */ 13140 13141 /* SAT rev8 Table 11 p30*/ 13142 /* checking Page Code */ 13143 switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK) 13144 { 13145 case LOGSENSE_SUPPORTED_LOG_PAGES: 13146 SM_DBG5(("smsatLogSense: case 1\n")); 13147 13148 if (pSatDevData->satSMARTFeatureSet == agTRUE) 13149 { 13150 /* add informational exception log */ 13151 flag = 1; 13152 if (pSatDevData->satSMARTSelfTest == agTRUE) 13153 { 13154 /* add Self-Test results log page */ 13155 flag = 2; 13156 } 13157 } 13158 else 13159 { 13160 /* only supported, no informational exception log, no Self-Test results log page */ 13161 flag = 0; 13162 } 13163 AllLogPages[0] = 0; /* page code */ 13164 AllLogPages[1] = 0; /* reserved */ 13165 switch (flag) 13166 { 13167 case 0: 13168 /* only supported */ 13169 AllLogPages[2] = 0; /* page length */ 13170 AllLogPages[3] = 1; /* page length */ 13171 AllLogPages[4] = 0x00; /* supported page list */ 13172 lenRead = (bit8)(MIN(AllocLen, 5)); 13173 break; 13174 case 1: 13175 /* supported and informational exception log */ 13176 AllLogPages[2] = 0; /* page length */ 13177 AllLogPages[3] = 2; /* page length */ 13178 AllLogPages[4] = 0x00; /* supported page list */ 13179 AllLogPages[5] = 0x10; /* supported page list */ 13180 lenRead = (bit8)(MIN(AllocLen, 6)); 13181 break; 13182 case 2: 13183 /* supported and informational exception log */ 13184 AllLogPages[2] = 0; /* page length */ 13185 AllLogPages[3] = 3; /* page length */ 13186 AllLogPages[4] = 0x00; /* supported page list */ 13187 AllLogPages[5] = 0x10; /* supported page list */ 13188 AllLogPages[6] = 0x2F; /* supported page list */ 13189 lenRead = (bit8)(MIN(AllocLen, 7)); 13190 break; 13191 default: 13192 SM_DBG1(("smsatLogSense: error unallowed flag value %d!!!\n", flag)); 13193 break; 13194 } 13195 13196 sm_memcpy(pLogPage, &AllLogPages, lenRead); 13197 /* comparing allocation length to Log Page byte size */ 13198 /* SPC-4, 4.3.4.6, p28 */ 13199 if (AllocLen > lenRead ) 13200 { 13201 SM_DBG1(("smsatLogSense: reporting underrun lenRead=0x%x AllocLen=0x%x!!!\n", lenRead, AllocLen)); 13202 /*smEnqueueIO(smRoot, satIOContext);*/ 13203 13204 tdsmIOCompletedCB( smRoot, 13205 smIORequest, 13206 smIOUnderRun, 13207 AllocLen - lenRead, 13208 agNULL, 13209 satIOContext->interruptContext ); 13210 } 13211 else 13212 { 13213 /*smEnqueueIO(smRoot, satIOContext);*/ 13214 tdsmIOCompletedCB( smRoot, 13215 smIORequest, 13216 smIOSuccess, 13217 SCSI_STAT_GOOD, 13218 agNULL, 13219 satIOContext->interruptContext); 13220 } 13221 break; 13222 case LOGSENSE_SELFTEST_RESULTS_PAGE: 13223 SM_DBG5(("smsatLogSense: case 2\n")); 13224 /* checking SMART self-test */ 13225 if (pSatDevData->satSMARTSelfTest == agFALSE) 13226 { 13227 SM_DBG5(("smsatLogSense: case 2 no SMART Self Test\n")); 13228 smsatSetSensePayload( pSense, 13229 SCSI_SNSKEY_ILLEGAL_REQUEST, 13230 0, 13231 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13232 satIOContext); 13233 13234 /*smEnqueueIO(smRoot, satIOContext);*/ 13235 13236 tdsmIOCompletedCB( smRoot, 13237 smIORequest, 13238 smIOSuccess, 13239 SCSI_STAT_CHECK_CONDITION, 13240 satIOContext->pSmSenseData, 13241 satIOContext->interruptContext ); 13242 } 13243 else 13244 { 13245 /* if satSMARTEnabled is false, send SMART_ENABLE_OPERATIONS */ 13246 if (pSatDevData->satSMARTEnabled == agFALSE) 13247 { 13248 SM_DBG5(("smsatLogSense: case 2 calling satSMARTEnable\n")); 13249 status = smsatLogSenseAllocate(smRoot, 13250 smIORequest, 13251 smDeviceHandle, 13252 smScsiRequest, 13253 satIOContext, 13254 0, 13255 LOG_SENSE_0 13256 ); 13257 13258 return status; 13259 13260 } 13261 else 13262 { 13263 /* SAT Rev 8, 10.2.4 p74 */ 13264 if ( pSatDevData->sat48BitSupport == agTRUE ) 13265 { 13266 SM_DBG5(("smsatLogSense: case 2-1 sends READ LOG EXT\n")); 13267 status = smsatLogSenseAllocate(smRoot, 13268 smIORequest, 13269 smDeviceHandle, 13270 smScsiRequest, 13271 satIOContext, 13272 512, 13273 LOG_SENSE_1 13274 ); 13275 13276 return status; 13277 } 13278 else 13279 { 13280 SM_DBG5(("smsatLogSense: case 2-2 sends SMART READ LOG\n")); 13281 status = smsatLogSenseAllocate(smRoot, 13282 smIORequest, 13283 smDeviceHandle, 13284 smScsiRequest, 13285 satIOContext, 13286 512, 13287 LOG_SENSE_2 13288 ); 13289 13290 return status; 13291 } 13292 } 13293 } 13294 break; 13295 case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE: 13296 SM_DBG5(("smsatLogSense: case 3\n")); 13297 /* checking SMART feature set */ 13298 if (pSatDevData->satSMARTFeatureSet == agFALSE) 13299 { 13300 smsatSetSensePayload( pSense, 13301 SCSI_SNSKEY_ILLEGAL_REQUEST, 13302 0, 13303 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13304 satIOContext); 13305 13306 /*smEnqueueIO(smRoot, satIOContext);*/ 13307 13308 tdsmIOCompletedCB( smRoot, 13309 smIORequest, 13310 smIOSuccess, 13311 SCSI_STAT_CHECK_CONDITION, 13312 satIOContext->pSmSenseData, 13313 satIOContext->interruptContext ); 13314 } 13315 else 13316 { 13317 /* checking SMART feature enabled */ 13318 if (pSatDevData->satSMARTEnabled == agFALSE) 13319 { 13320 smsatSetSensePayload( pSense, 13321 SCSI_SNSKEY_ABORTED_COMMAND, 13322 0, 13323 SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED, 13324 satIOContext); 13325 13326 /*smEnqueueIO(smRoot, satIOContext);*/ 13327 13328 tdsmIOCompletedCB( smRoot, 13329 smIORequest, 13330 smIOSuccess, 13331 SCSI_STAT_CHECK_CONDITION, 13332 satIOContext->pSmSenseData, 13333 satIOContext->interruptContext ); 13334 } 13335 else 13336 { 13337 /* SAT Rev 8, 10.2.3 p72 */ 13338 SM_DBG5(("smsatLogSense: case 3 sends SMART RETURN STATUS\n")); 13339 13340 /* sends SMART RETURN STATUS */ 13341 fis->h.fisType = 0x27; /* Reg host to device */ 13342 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13343 13344 fis->h.command = SAT_SMART; /* 0xB0 */ 13345 fis->h.features = SAT_SMART_RETURN_STATUS;/* FIS features */ 13346 fis->d.featuresExp = 0; /* FIS reserve */ 13347 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 13348 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 13349 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 13350 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 13351 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */ 13352 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 13353 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */ 13354 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 13355 fis->d.device = 0; /* FIS DEV is discared in SATA */ 13356 fis->d.control = 0; /* FIS HOB bit clear */ 13357 fis->d.reserved4 = 0; 13358 fis->d.reserved5 = 0; 13359 13360 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 13361 /* Initialize CB for SATA completion. 13362 */ 13363 satIOContext->satCompleteCB = &smsatLogSenseCB; 13364 13365 /* 13366 * Prepare SGL and send FIS to LL layer. 13367 */ 13368 satIOContext->reqType = agRequestType; /* Save it */ 13369 13370 status = smsataLLIOStart( smRoot, 13371 smIORequest, 13372 smDeviceHandle, 13373 smScsiRequest, 13374 satIOContext); 13375 13376 13377 return status; 13378 } 13379 } 13380 break; 13381 default: 13382 SM_DBG1(("smsatLogSense: default Page Code 0x%x!!!\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)); 13383 smsatSetSensePayload( pSense, 13384 SCSI_SNSKEY_ILLEGAL_REQUEST, 13385 0, 13386 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13387 satIOContext); 13388 13389 /*smEnqueueIO(smRoot, satIOContext);*/ 13390 13391 tdsmIOCompletedCB( smRoot, 13392 smIORequest, 13393 smIOSuccess, 13394 SCSI_STAT_CHECK_CONDITION, 13395 satIOContext->pSmSenseData, 13396 satIOContext->interruptContext ); 13397 13398 break; 13399 } /* end switch */ 13400 13401 return SM_RC_SUCCESS; 13402 } 13403 13404 osGLOBAL bit32 13405 smsatLogSenseAllocate( 13406 smRoot_t *smRoot, 13407 smIORequest_t *smIORequest, 13408 smDeviceHandle_t *smDeviceHandle, 13409 smScsiInitiatorRequest_t *smSCSIRequest, 13410 smSatIOContext_t *satIOContext, 13411 bit32 payloadSize, 13412 bit32 flag 13413 ) 13414 { 13415 smDeviceData_t *pSatDevData; 13416 smIORequestBody_t *smIORequestBody; 13417 smSatInternalIo_t *satIntIo = agNULL; 13418 smSatIOContext_t *satIOContext2; 13419 bit32 status; 13420 13421 SM_DBG5(("smsatLogSenseAllocate: start\n")); 13422 13423 pSatDevData = satIOContext->pSatDevData; 13424 13425 /* create internal satIOContext */ 13426 satIntIo = smsatAllocIntIoResource( smRoot, 13427 smIORequest, /* original request */ 13428 pSatDevData, 13429 payloadSize, 13430 satIntIo); 13431 13432 if (satIntIo == agNULL) 13433 { 13434 /*smEnqueueIO(smRoot, satIOContext);*/ 13435 13436 tdsmIOCompletedCB( smRoot, 13437 smIORequest, 13438 smIOFailed, 13439 smDetailOtherError, 13440 agNULL, 13441 satIOContext->interruptContext ); 13442 13443 SM_DBG1(("smsatLogSenseAllocate: fail in allocation!!!\n")); 13444 return SM_RC_SUCCESS; 13445 } /* end of memory allocation failure */ 13446 13447 satIntIo->satOrgSmIORequest = smIORequest; 13448 smIORequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody; 13449 satIOContext2 = &(smIORequestBody->transport.SATA.satIOContext); 13450 13451 satIOContext2->pSatDevData = pSatDevData; 13452 satIOContext2->pFis = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev); 13453 satIOContext2->pScsiCmnd = &(satIntIo->satIntSmScsiXchg.scsiCmnd); 13454 satIOContext2->pSense = &(smIORequestBody->transport.SATA.sensePayload); 13455 satIOContext2->pSmSenseData = &(smIORequestBody->transport.SATA.smSenseData); 13456 satIOContext2->pSmSenseData->senseData = satIOContext2->pSense; 13457 satIOContext2->smRequestBody = satIntIo->satIntRequestBody; 13458 satIOContext2->interruptContext = satIOContext->interruptContext; 13459 satIOContext2->satIntIoContext = satIntIo; 13460 satIOContext2->psmDeviceHandle = smDeviceHandle; 13461 satIOContext2->satOrgIOContext = satIOContext; 13462 13463 if (flag == LOG_SENSE_0) 13464 { 13465 /* SAT_SMART_ENABLE_OPERATIONS */ 13466 status = smsatSMARTEnable( smRoot, 13467 &(satIntIo->satIntSmIORequest), 13468 smDeviceHandle, 13469 &(satIntIo->satIntSmScsiXchg), 13470 satIOContext2); 13471 } 13472 else if (flag == LOG_SENSE_1) 13473 { 13474 /* SAT_READ_LOG_EXT */ 13475 status = smsatLogSense_2( smRoot, 13476 &(satIntIo->satIntSmIORequest), 13477 smDeviceHandle, 13478 &(satIntIo->satIntSmScsiXchg), 13479 satIOContext2); 13480 } 13481 else 13482 { 13483 /* SAT_SMART_READ_LOG */ 13484 /* SAT_READ_LOG_EXT */ 13485 status = smsatLogSense_3( smRoot, 13486 &(satIntIo->satIntSmIORequest), 13487 smDeviceHandle, 13488 &(satIntIo->satIntSmScsiXchg), 13489 satIOContext2); 13490 13491 } 13492 if (status != SM_RC_SUCCESS) 13493 { 13494 smsatFreeIntIoResource( smRoot, 13495 pSatDevData, 13496 satIntIo); 13497 13498 /*smEnqueueIO(smRoot, satIOContext);*/ 13499 13500 tdsmIOCompletedCB( smRoot, 13501 smIORequest, 13502 smIOFailed, 13503 smDetailOtherError, 13504 agNULL, 13505 satIOContext->interruptContext ); 13506 return SM_RC_SUCCESS; 13507 } 13508 13509 13510 return SM_RC_SUCCESS; 13511 } 13512 13513 osGLOBAL bit32 13514 smsatSMARTEnable( 13515 smRoot_t *smRoot, 13516 smIORequest_t *smIORequest, 13517 smDeviceHandle_t *smDeviceHandle, 13518 smScsiInitiatorRequest_t *smScsiRequest, 13519 smSatIOContext_t *satIOContext 13520 ) 13521 { 13522 bit32 status; 13523 bit32 agRequestType; 13524 agsaFisRegHostToDevice_t *fis; 13525 13526 fis = satIOContext->pFis; 13527 SM_DBG5(("smsatSMARTEnable: start\n")); 13528 /* 13529 * Send the SAT_SMART_ENABLE_OPERATIONS command. 13530 */ 13531 fis->h.fisType = 0x27; /* Reg host to device */ 13532 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13533 fis->h.command = SAT_SMART; /* 0xB0 */ 13534 fis->h.features = SAT_SMART_ENABLE_OPERATIONS; 13535 fis->d.lbaLow = 0; 13536 fis->d.lbaMid = 0x4F; 13537 fis->d.lbaHigh = 0xC2; 13538 fis->d.device = 0; 13539 fis->d.lbaLowExp = 0; 13540 fis->d.lbaMidExp = 0; 13541 fis->d.lbaHighExp = 0; 13542 fis->d.featuresExp = 0; 13543 fis->d.sectorCount = 0; 13544 fis->d.sectorCountExp = 0; 13545 fis->d.reserved4 = 0; 13546 fis->d.control = 0; /* FIS HOB bit clear */ 13547 fis->d.reserved5 = 0; 13548 13549 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 13550 13551 /* Initialize CB for SATA completion. 13552 */ 13553 satIOContext->satCompleteCB = &smsatSMARTEnableCB; 13554 13555 /* 13556 * Prepare SGL and send FIS to LL layer. 13557 */ 13558 satIOContext->reqType = agRequestType; /* Save it */ 13559 13560 status = smsataLLIOStart( smRoot, 13561 smIORequest, 13562 smDeviceHandle, 13563 smScsiRequest, 13564 satIOContext); 13565 13566 13567 return status; 13568 } 13569 13570 osGLOBAL bit32 13571 smsatLogSense_2( 13572 smRoot_t *smRoot, 13573 smIORequest_t *smIORequest, 13574 smDeviceHandle_t *smDeviceHandle, 13575 smScsiInitiatorRequest_t *smScsiRequest, 13576 smSatIOContext_t *satIOContext 13577 ) 13578 { 13579 bit32 status; 13580 bit32 agRequestType; 13581 agsaFisRegHostToDevice_t *fis; 13582 13583 fis = satIOContext->pFis; 13584 SM_DBG5(("smsatLogSense_2: start\n")); 13585 13586 /* sends READ LOG EXT */ 13587 fis->h.fisType = 0x27; /* Reg host to device */ 13588 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13589 13590 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */ 13591 fis->h.features = 0; /* FIS reserve */ 13592 fis->d.lbaLow = 0x07; /* 0x07 */ 13593 fis->d.lbaMid = 0; /* */ 13594 fis->d.lbaHigh = 0; /* */ 13595 fis->d.device = 0; /* */ 13596 fis->d.lbaLowExp = 0; /* */ 13597 fis->d.lbaMidExp = 0; /* */ 13598 fis->d.lbaHighExp = 0; /* */ 13599 fis->d.featuresExp = 0; /* FIS reserve */ 13600 fis->d.sectorCount = 0x01; /* 1 sector counts */ 13601 fis->d.sectorCountExp = 0x00; /* 1 sector counts */ 13602 fis->d.reserved4 = 0; 13603 fis->d.control = 0; /* FIS HOB bit clear */ 13604 fis->d.reserved5 = 0; 13605 13606 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 13607 13608 /* Initialize CB for SATA completion. 13609 */ 13610 satIOContext->satCompleteCB = &smsatLogSenseCB; 13611 13612 /* 13613 * Prepare SGL and send FIS to LL layer. 13614 */ 13615 satIOContext->reqType = agRequestType; /* Save it */ 13616 13617 status = smsataLLIOStart( smRoot, 13618 smIORequest, 13619 smDeviceHandle, 13620 smScsiRequest, 13621 satIOContext); 13622 return status; 13623 } 13624 13625 osGLOBAL bit32 13626 smsatLogSense_3( 13627 smRoot_t *smRoot, 13628 smIORequest_t *smIORequest, 13629 smDeviceHandle_t *smDeviceHandle, 13630 smScsiInitiatorRequest_t *smScsiRequest, 13631 smSatIOContext_t *satIOContext 13632 ) 13633 { 13634 bit32 status; 13635 bit32 agRequestType; 13636 agsaFisRegHostToDevice_t *fis; 13637 13638 fis = satIOContext->pFis; 13639 SM_DBG5(("smsatLogSense_3: start\n")); 13640 /* sends READ LOG EXT */ 13641 fis->h.fisType = 0x27; /* Reg host to device */ 13642 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13643 fis->h.command = SAT_SMART; /* 0x2F */ 13644 fis->h.features = SAT_SMART_READ_LOG; /* 0xd5 */ 13645 fis->d.lbaLow = 0x06; /* 0x06 */ 13646 fis->d.lbaMid = 0x4F; /* 0x4f */ 13647 fis->d.lbaHigh = 0xC2; /* 0xc2 */ 13648 fis->d.device = 0; /* */ 13649 fis->d.lbaLowExp = 0; /* */ 13650 fis->d.lbaMidExp = 0; /* */ 13651 fis->d.lbaHighExp = 0; /* */ 13652 fis->d.featuresExp = 0; /* FIS reserve */ 13653 fis->d.sectorCount = 0x01; /* 1 sector counts */ 13654 fis->d.sectorCountExp = 0x00; /* 1 sector counts */ 13655 fis->d.reserved4 = 0; 13656 fis->d.control = 0; /* FIS HOB bit clear */ 13657 fis->d.reserved5 = 0; 13658 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 13659 /* Initialize CB for SATA completion. 13660 */ 13661 satIOContext->satCompleteCB = &smsatLogSenseCB; 13662 /* 13663 * Prepare SGL and send FIS to LL layer. 13664 */ 13665 satIOContext->reqType = agRequestType; /* Save it */ 13666 status = smsataLLIOStart( smRoot, 13667 smIORequest, 13668 smDeviceHandle, 13669 smScsiRequest, 13670 satIOContext); 13671 return status; 13672 } 13673 13674 13675 osGLOBAL bit32 13676 smsatModeSelect6( 13677 smRoot_t *smRoot, 13678 smIORequest_t *smIORequest, 13679 smDeviceHandle_t *smDeviceHandle, 13680 smScsiInitiatorRequest_t *smScsiRequest, 13681 smSatIOContext_t *satIOContext 13682 ) 13683 { 13684 bit32 status; 13685 bit32 agRequestType; 13686 smDeviceData_t *pSatDevData; 13687 smScsiRspSense_t *pSense; 13688 smIniScsiCmnd_t *scsiCmnd; 13689 agsaFisRegHostToDevice_t *fis; 13690 bit8 *pLogPage; /* Log Page data buffer */ 13691 bit32 StartingIndex = 0; 13692 bit8 PageCode = 0; 13693 bit32 chkCnd = agFALSE; 13694 bit32 parameterListLen = 0; 13695 13696 pSense = satIOContext->pSense; 13697 pSatDevData = satIOContext->pSatDevData; 13698 scsiCmnd = &smScsiRequest->scsiCmnd; 13699 fis = satIOContext->pFis; 13700 pLogPage = (bit8 *) smScsiRequest->sglVirtualAddr; 13701 13702 SM_DBG5(("smsatModeSelect6: start\n")); 13703 13704 /* checking CONTROL */ 13705 /* NACA == 1 or LINK == 1*/ 13706 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 13707 { 13708 smsatSetSensePayload( pSense, 13709 SCSI_SNSKEY_ILLEGAL_REQUEST, 13710 0, 13711 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13712 satIOContext); 13713 13714 /*smEnqueueIO(smRoot, satIOContext);*/ 13715 13716 tdsmIOCompletedCB( smRoot, 13717 smIORequest, 13718 smIOSuccess, 13719 SCSI_STAT_CHECK_CONDITION, 13720 satIOContext->pSmSenseData, 13721 satIOContext->interruptContext ); 13722 13723 SM_DBG1(("smsatModeSelect6: return control!!!\n")); 13724 return SM_RC_SUCCESS; 13725 } 13726 13727 /* checking PF bit */ 13728 if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT6_PF_MASK)) 13729 { 13730 smsatSetSensePayload( pSense, 13731 SCSI_SNSKEY_ILLEGAL_REQUEST, 13732 0, 13733 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13734 satIOContext); 13735 13736 /*smEnqueueIO(smRoot, satIOContext);*/ 13737 13738 tdsmIOCompletedCB( smRoot, 13739 smIORequest, 13740 smIOSuccess, 13741 SCSI_STAT_CHECK_CONDITION, 13742 satIOContext->pSmSenseData, 13743 satIOContext->interruptContext ); 13744 13745 SM_DBG1(("smsatModeSelect6: PF bit check!!!\n")); 13746 return SM_RC_SUCCESS; 13747 } 13748 13749 parameterListLen = scsiCmnd->cdb[4]; 13750 parameterListLen = MIN(parameterListLen, scsiCmnd->expDataLength); 13751 if ((0 == parameterListLen) || (agNULL == pLogPage)) 13752 { 13753 tdsmIOCompletedCB( smRoot, 13754 smIORequest, 13755 smIOSuccess, 13756 SCSI_STAT_GOOD, 13757 agNULL, 13758 satIOContext->interruptContext); 13759 return SM_RC_SUCCESS; 13760 } 13761 13762 /* checking Block Descriptor Length on Mode parameter header(6)*/ 13763 if (pLogPage[3] == 8) 13764 { 13765 /* mode parameter block descriptor exists */ 13766 PageCode = (bit8)(pLogPage[12] & 0x3F); /* page code and index is 4 + 8 */ 13767 StartingIndex = 12; 13768 } 13769 else if (pLogPage[3] == 0) 13770 { 13771 /* mode parameter block descriptor does not exist */ 13772 PageCode = (bit8)(pLogPage[4] & 0x3F); /* page code and index is 4 + 0 */ 13773 StartingIndex = 4; 13774 /*smEnqueueIO(smRoot, satIOContext);*/ 13775 13776 tdsmIOCompletedCB( smRoot, 13777 smIORequest, 13778 smIOSuccess, 13779 SCSI_STAT_GOOD, 13780 agNULL, 13781 satIOContext->interruptContext); 13782 return SM_RC_SUCCESS; 13783 } 13784 else 13785 { 13786 SM_DBG1(("smsatModeSelect6: return mode parameter block descriptor 0x%x!!!\n", pLogPage[3])); 13787 13788 smsatSetSensePayload( pSense, 13789 SCSI_SNSKEY_NO_SENSE, 13790 0, 13791 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 13792 satIOContext); 13793 13794 /*smEnqueueIO(smRoot, satIOContext);*/ 13795 13796 tdsmIOCompletedCB( smRoot, 13797 smIORequest, 13798 smIOSuccess, 13799 SCSI_STAT_CHECK_CONDITION, 13800 satIOContext->pSmSenseData, 13801 satIOContext->interruptContext ); 13802 return SM_RC_SUCCESS; 13803 } 13804 13805 13806 13807 switch (PageCode) /* page code */ 13808 { 13809 case MODESELECT_CONTROL_PAGE: 13810 SM_DBG1(("smsatModeSelect6: Control mode page!!!\n")); 13811 13812 if ( pLogPage[StartingIndex+1] != 0x0A || 13813 pLogPage[StartingIndex+2] != 0x02 || 13814 (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) || 13815 (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) || 13816 (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */ 13817 (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */ 13818 (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */ 13819 13820 (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */ 13821 (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */ 13822 (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */ 13823 (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */ 13824 13825 pLogPage[StartingIndex+8] != 0xFF || 13826 pLogPage[StartingIndex+9] != 0xFF || 13827 pLogPage[StartingIndex+10] != 0x00 || 13828 pLogPage[StartingIndex+11] != 0x00 13829 ) 13830 { 13831 chkCnd = agTRUE; 13832 } 13833 if (chkCnd == agTRUE) 13834 { 13835 smsatSetSensePayload( pSense, 13836 SCSI_SNSKEY_ILLEGAL_REQUEST, 13837 0, 13838 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 13839 satIOContext); 13840 13841 /*smEnqueueIO(smRoot, satIOContext);*/ 13842 13843 tdsmIOCompletedCB( smRoot, 13844 smIORequest, 13845 smIOSuccess, 13846 SCSI_STAT_CHECK_CONDITION, 13847 satIOContext->pSmSenseData, 13848 satIOContext->interruptContext ); 13849 13850 SM_DBG1(("smsatModeSelect6: unexpected values!!!\n")); 13851 } 13852 else 13853 { 13854 /*smEnqueueIO(smRoot, satIOContext);*/ 13855 13856 tdsmIOCompletedCB( smRoot, 13857 smIORequest, 13858 smIOSuccess, 13859 SCSI_STAT_GOOD, 13860 agNULL, 13861 satIOContext->interruptContext); 13862 } 13863 return SM_RC_SUCCESS; 13864 break; 13865 case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE: 13866 SM_DBG1(("smsatModeSelect6: Read-Write Error Recovery mode page!!!\n")); 13867 13868 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_AWRE_MASK) || 13869 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_RC_MASK) || 13870 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_EER_MASK) || 13871 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PER_MASK) || 13872 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DTE_MASK) || 13873 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DCR_MASK) || 13874 (pLogPage[StartingIndex + 10]) || 13875 (pLogPage[StartingIndex + 11]) 13876 ) 13877 { 13878 SM_DBG5(("smsatModeSelect6: return check condition\n")); 13879 13880 smsatSetSensePayload( pSense, 13881 SCSI_SNSKEY_ILLEGAL_REQUEST, 13882 0, 13883 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 13884 satIOContext); 13885 13886 /*smEnqueueIO(smRoot, satIOContext);*/ 13887 13888 tdsmIOCompletedCB( smRoot, 13889 smIORequest, 13890 smIOSuccess, 13891 SCSI_STAT_CHECK_CONDITION, 13892 satIOContext->pSmSenseData, 13893 satIOContext->interruptContext ); 13894 return SM_RC_SUCCESS; 13895 } 13896 else 13897 { 13898 SM_DBG5(("smsatModeSelect6: return GOOD \n")); 13899 /*smEnqueueIO(smRoot, satIOContext);*/ 13900 13901 tdsmIOCompletedCB( smRoot, 13902 smIORequest, 13903 smIOSuccess, 13904 SCSI_STAT_GOOD, 13905 agNULL, 13906 satIOContext->interruptContext); 13907 return SM_RC_SUCCESS; 13908 } 13909 13910 break; 13911 case MODESELECT_CACHING: 13912 /* SAT rev8 Table67, p69*/ 13913 SM_DBG5(("smsatModeSelect6: Caching mode page\n")); 13914 if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */ 13915 (pLogPage[StartingIndex + 3]) || 13916 (pLogPage[StartingIndex + 4]) || 13917 (pLogPage[StartingIndex + 5]) || 13918 (pLogPage[StartingIndex + 6]) || 13919 (pLogPage[StartingIndex + 7]) || 13920 (pLogPage[StartingIndex + 8]) || 13921 (pLogPage[StartingIndex + 9]) || 13922 (pLogPage[StartingIndex + 10]) || 13923 (pLogPage[StartingIndex + 11]) || 13924 13925 (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */ 13926 (pLogPage[StartingIndex + 13]) || 13927 (pLogPage[StartingIndex + 14]) || 13928 (pLogPage[StartingIndex + 15]) 13929 ) 13930 { 13931 SM_DBG1(("smsatModeSelect6: return check condition!!!\n")); 13932 13933 smsatSetSensePayload( pSense, 13934 SCSI_SNSKEY_ILLEGAL_REQUEST, 13935 0, 13936 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 13937 satIOContext); 13938 13939 /*smEnqueueIO(smRoot, satIOContext);*/ 13940 13941 tdsmIOCompletedCB( smRoot, 13942 smIORequest, 13943 smIOSuccess, 13944 SCSI_STAT_CHECK_CONDITION, 13945 satIOContext->pSmSenseData, 13946 satIOContext->interruptContext ); 13947 return SM_RC_SUCCESS; 13948 13949 } 13950 else 13951 { 13952 /* sends ATA SET FEATURES based on WCE bit */ 13953 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_WCE_MASK) ) 13954 { 13955 SM_DBG5(("smsatModeSelect6: disable write cache\n")); 13956 /* sends SET FEATURES */ 13957 fis->h.fisType = 0x27; /* Reg host to device */ 13958 fis->h.c_pmPort = 0x80; /* C Bit is set */ 13959 13960 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 13961 fis->h.features = 0x82; /* disable write cache */ 13962 fis->d.lbaLow = 0; /* */ 13963 fis->d.lbaMid = 0; /* */ 13964 fis->d.lbaHigh = 0; /* */ 13965 fis->d.device = 0; /* */ 13966 fis->d.lbaLowExp = 0; /* */ 13967 fis->d.lbaMidExp = 0; /* */ 13968 fis->d.lbaHighExp = 0; /* */ 13969 fis->d.featuresExp = 0; /* */ 13970 fis->d.sectorCount = 0; /* */ 13971 fis->d.sectorCountExp = 0; /* */ 13972 fis->d.reserved4 = 0; 13973 fis->d.control = 0; /* FIS HOB bit clear */ 13974 fis->d.reserved5 = 0; 13975 13976 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 13977 13978 /* Initialize CB for SATA completion. 13979 */ 13980 satIOContext->satCompleteCB = &smsatModeSelect6n10CB; 13981 13982 /* 13983 * Prepare SGL and send FIS to LL layer. 13984 */ 13985 satIOContext->reqType = agRequestType; /* Save it */ 13986 13987 status = smsataLLIOStart( smRoot, 13988 smIORequest, 13989 smDeviceHandle, 13990 smScsiRequest, 13991 satIOContext); 13992 return status; 13993 } 13994 else 13995 { 13996 SM_DBG5(("smsatModeSelect6: enable write cache\n")); 13997 /* sends SET FEATURES */ 13998 fis->h.fisType = 0x27; /* Reg host to device */ 13999 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14000 14001 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 14002 fis->h.features = 0x02; /* enable write cache */ 14003 fis->d.lbaLow = 0; /* */ 14004 fis->d.lbaMid = 0; /* */ 14005 fis->d.lbaHigh = 0; /* */ 14006 fis->d.device = 0; /* */ 14007 fis->d.lbaLowExp = 0; /* */ 14008 fis->d.lbaMidExp = 0; /* */ 14009 fis->d.lbaHighExp = 0; /* */ 14010 fis->d.featuresExp = 0; /* */ 14011 fis->d.sectorCount = 0; /* */ 14012 fis->d.sectorCountExp = 0; /* */ 14013 fis->d.reserved4 = 0; 14014 fis->d.control = 0; /* FIS HOB bit clear */ 14015 fis->d.reserved5 = 0; 14016 14017 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14018 14019 /* Initialize CB for SATA completion. 14020 */ 14021 satIOContext->satCompleteCB = &smsatModeSelect6n10CB; 14022 14023 /* 14024 * Prepare SGL and send FIS to LL layer. 14025 */ 14026 satIOContext->reqType = agRequestType; /* Save it */ 14027 14028 status = smsataLLIOStart( smRoot, 14029 smIORequest, 14030 smDeviceHandle, 14031 smScsiRequest, 14032 satIOContext); 14033 return status; 14034 14035 } 14036 } 14037 break; 14038 case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE: 14039 SM_DBG5(("smsatModeSelect6: Informational Exception Control mode page\n")); 14040 14041 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PERF_MASK) || 14042 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_TEST_MASK) 14043 ) 14044 { 14045 SM_DBG1(("smsatModeSelect6: return check condition!!! \n")); 14046 14047 smsatSetSensePayload( pSense, 14048 SCSI_SNSKEY_ILLEGAL_REQUEST, 14049 0, 14050 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 14051 satIOContext); 14052 14053 /*smEnqueueIO(smRoot, satIOContext);*/ 14054 14055 tdsmIOCompletedCB( smRoot, 14056 smIORequest, 14057 smIOSuccess, 14058 SCSI_STAT_CHECK_CONDITION, 14059 satIOContext->pSmSenseData, 14060 satIOContext->interruptContext ); 14061 return SM_RC_SUCCESS; 14062 } 14063 else 14064 { 14065 /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */ 14066 if ( !(pLogPage[StartingIndex + 2] & 0x08) ) 14067 { 14068 SM_DBG5(("smsatModeSelect6: enable information exceptions reporting\n")); 14069 /* sends SMART ENABLE OPERATIONS */ 14070 fis->h.fisType = 0x27; /* Reg host to device */ 14071 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14072 14073 fis->h.command = SAT_SMART; /* 0xB0 */ 14074 fis->h.features = SAT_SMART_ENABLE_OPERATIONS; /* enable */ 14075 fis->d.lbaLow = 0; /* */ 14076 fis->d.lbaMid = 0x4F; /* 0x4F */ 14077 fis->d.lbaHigh = 0xC2; /* 0xC2 */ 14078 fis->d.device = 0; /* */ 14079 fis->d.lbaLowExp = 0; /* */ 14080 fis->d.lbaMidExp = 0; /* */ 14081 fis->d.lbaHighExp = 0; /* */ 14082 fis->d.featuresExp = 0; /* */ 14083 fis->d.sectorCount = 0; /* */ 14084 fis->d.sectorCountExp = 0; /* */ 14085 fis->d.reserved4 = 0; 14086 fis->d.control = 0; /* FIS HOB bit clear */ 14087 fis->d.reserved5 = 0; 14088 14089 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14090 14091 /* Initialize CB for SATA completion. 14092 */ 14093 satIOContext->satCompleteCB = &smsatModeSelect6n10CB; 14094 14095 /* 14096 * Prepare SGL and send FIS to LL layer. 14097 */ 14098 satIOContext->reqType = agRequestType; /* Save it */ 14099 14100 status = smsataLLIOStart( smRoot, 14101 smIORequest, 14102 smDeviceHandle, 14103 smScsiRequest, 14104 satIOContext); 14105 return status; 14106 } 14107 else 14108 { 14109 SM_DBG5(("smsatModeSelect6: disable information exceptions reporting\n")); 14110 /* sends SMART DISABLE OPERATIONS */ 14111 fis->h.fisType = 0x27; /* Reg host to device */ 14112 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14113 14114 fis->h.command = SAT_SMART; /* 0xB0 */ 14115 fis->h.features = SAT_SMART_DISABLE_OPERATIONS; /* disable */ 14116 fis->d.lbaLow = 0; /* */ 14117 fis->d.lbaMid = 0x4F; /* 0x4F */ 14118 fis->d.lbaHigh = 0xC2; /* 0xC2 */ 14119 fis->d.device = 0; /* */ 14120 fis->d.lbaLowExp = 0; /* */ 14121 fis->d.lbaMidExp = 0; /* */ 14122 fis->d.lbaHighExp = 0; /* */ 14123 fis->d.featuresExp = 0; /* */ 14124 fis->d.sectorCount = 0; /* */ 14125 fis->d.sectorCountExp = 0; /* */ 14126 fis->d.reserved4 = 0; 14127 fis->d.control = 0; /* FIS HOB bit clear */ 14128 fis->d.reserved5 = 0; 14129 14130 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14131 14132 /* Initialize CB for SATA completion. 14133 */ 14134 satIOContext->satCompleteCB = &smsatModeSelect6n10CB; 14135 14136 /* 14137 * Prepare SGL and send FIS to LL layer. 14138 */ 14139 satIOContext->reqType = agRequestType; /* Save it */ 14140 14141 status = smsataLLIOStart( smRoot, 14142 smIORequest, 14143 smDeviceHandle, 14144 smScsiRequest, 14145 satIOContext); 14146 return status; 14147 14148 } 14149 } 14150 break; 14151 default: 14152 SM_DBG1(("smsatModeSelect6: Error unknown page code 0x%x!!!\n", pLogPage[12])); 14153 smsatSetSensePayload( pSense, 14154 SCSI_SNSKEY_NO_SENSE, 14155 0, 14156 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 14157 satIOContext); 14158 14159 /*smEnqueueIO(smRoot, satIOContext);*/ 14160 14161 tdsmIOCompletedCB( smRoot, 14162 smIORequest, 14163 smIOSuccess, 14164 SCSI_STAT_CHECK_CONDITION, 14165 satIOContext->pSmSenseData, 14166 satIOContext->interruptContext ); 14167 return SM_RC_SUCCESS; 14168 } 14169 } 14170 14171 14172 osGLOBAL bit32 14173 smsatModeSelect10( 14174 smRoot_t *smRoot, 14175 smIORequest_t *smIORequest, 14176 smDeviceHandle_t *smDeviceHandle, 14177 smScsiInitiatorRequest_t *smScsiRequest, 14178 smSatIOContext_t *satIOContext 14179 ) 14180 { 14181 bit32 status; 14182 bit32 agRequestType; 14183 smDeviceData_t *pSatDevData; 14184 smScsiRspSense_t *pSense; 14185 smIniScsiCmnd_t *scsiCmnd; 14186 agsaFisRegHostToDevice_t *fis; 14187 bit8 *pLogPage; /* Log Page data buffer */ 14188 bit16 BlkDescLen = 0; /* Block Descriptor Length */ 14189 bit32 StartingIndex = 0; 14190 bit8 PageCode = 0; 14191 bit32 chkCnd = agFALSE; 14192 bit32 parameterListLen = 0; 14193 14194 pSense = satIOContext->pSense; 14195 pSatDevData = satIOContext->pSatDevData; 14196 scsiCmnd = &smScsiRequest->scsiCmnd; 14197 fis = satIOContext->pFis; 14198 pLogPage = (bit8 *) smScsiRequest->sglVirtualAddr; 14199 14200 SM_DBG5(("smsatModeSelect10: start\n")); 14201 14202 /* checking CONTROL */ 14203 /* NACA == 1 or LINK == 1*/ 14204 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 14205 { 14206 smsatSetSensePayload( pSense, 14207 SCSI_SNSKEY_ILLEGAL_REQUEST, 14208 0, 14209 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 14210 satIOContext); 14211 14212 /*smEnqueueIO(smRoot, satIOContext);*/ 14213 14214 tdsmIOCompletedCB( smRoot, 14215 smIORequest, 14216 smIOSuccess, 14217 SCSI_STAT_CHECK_CONDITION, 14218 satIOContext->pSmSenseData, 14219 satIOContext->interruptContext ); 14220 14221 SM_DBG1(("smsatModeSelect10: return control!!!\n")); 14222 return SM_RC_SUCCESS; 14223 } 14224 14225 /* checking PF bit */ 14226 if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT10_PF_MASK)) 14227 { 14228 smsatSetSensePayload( pSense, 14229 SCSI_SNSKEY_ILLEGAL_REQUEST, 14230 0, 14231 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 14232 satIOContext); 14233 14234 /*smEnqueueIO(smRoot, satIOContext);*/ 14235 14236 tdsmIOCompletedCB( smRoot, 14237 smIORequest, 14238 smIOSuccess, 14239 SCSI_STAT_CHECK_CONDITION, 14240 satIOContext->pSmSenseData, 14241 satIOContext->interruptContext ); 14242 14243 SM_DBG1(("smsatModeSelect10: PF bit check!!!\n")); 14244 return SM_RC_SUCCESS; 14245 } 14246 14247 parameterListLen = ((scsiCmnd->cdb[7]) << 8) + scsiCmnd->cdb[8]; 14248 parameterListLen = MIN(parameterListLen, scsiCmnd->expDataLength); 14249 if ((0 == parameterListLen) || (agNULL == pLogPage)) 14250 { 14251 tdsmIOCompletedCB( smRoot, 14252 smIORequest, 14253 smIOSuccess, 14254 SCSI_STAT_GOOD, 14255 agNULL, 14256 satIOContext->interruptContext); 14257 return SM_RC_SUCCESS; 14258 } 14259 14260 BlkDescLen = (bit8)((pLogPage[6] << 8) + pLogPage[7]); 14261 14262 /* checking Block Descriptor Length on Mode parameter header(10) and LONGLBA bit*/ 14263 if ( (BlkDescLen == 8) && !(pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) ) 14264 { 14265 /* mode parameter block descriptor exists and length is 8 byte */ 14266 PageCode = (bit8)(pLogPage[16] & 0x3F); /* page code and index is 8 + 8 */ 14267 StartingIndex = 16; 14268 } 14269 else if ( (BlkDescLen == 16) && (pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) ) 14270 { 14271 /* mode parameter block descriptor exists and length is 16 byte */ 14272 PageCode = (bit8)(pLogPage[24] & 0x3F); /* page code and index is 8 + 16 */ 14273 StartingIndex = 24; 14274 } 14275 else if (BlkDescLen == 0) 14276 { 14277 PageCode = (bit8)(pLogPage[8] & 0x3F); /* page code and index is 8 + 0 */ 14278 StartingIndex = 8; 14279 /*smEnqueueIO(smRoot, satIOContext);*/ 14280 14281 tdsmIOCompletedCB( smRoot, 14282 smIORequest, 14283 smIOSuccess, 14284 SCSI_STAT_GOOD, 14285 agNULL, 14286 satIOContext->interruptContext); 14287 return SM_RC_SUCCESS; 14288 } 14289 else 14290 { 14291 SM_DBG1(("smsatModeSelect10: return mode parameter block descriptor 0x%x!!!\n", BlkDescLen)); 14292 /* no more than one mode parameter block descriptor shall be supported */ 14293 smsatSetSensePayload( pSense, 14294 SCSI_SNSKEY_NO_SENSE, 14295 0, 14296 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 14297 satIOContext); 14298 14299 /*smEnqueueIO(smRoot, satIOContext);*/ 14300 14301 tdsmIOCompletedCB( smRoot, 14302 smIORequest, 14303 smIOSuccess, 14304 SCSI_STAT_CHECK_CONDITION, 14305 satIOContext->pSmSenseData, 14306 satIOContext->interruptContext ); 14307 return SM_RC_SUCCESS; 14308 } 14309 /* 14310 for debugging only 14311 */ 14312 if (StartingIndex == 8) 14313 { 14314 smhexdump("startingindex 8", (bit8 *)pLogPage, 8); 14315 } 14316 else if(StartingIndex == 16) 14317 { 14318 if (PageCode == MODESELECT_CACHING) 14319 { 14320 smhexdump("startingindex 16", (bit8 *)pLogPage, 16+20); 14321 } 14322 else 14323 { 14324 smhexdump("startingindex 16", (bit8 *)pLogPage, 16+12); 14325 } 14326 } 14327 else 14328 { 14329 if (PageCode == MODESELECT_CACHING) 14330 { 14331 smhexdump("startingindex 24", (bit8 *)pLogPage, 24+20); 14332 } 14333 else 14334 { 14335 smhexdump("startingindex 24", (bit8 *)pLogPage, 24+12); 14336 } 14337 } 14338 switch (PageCode) /* page code */ 14339 { 14340 case MODESELECT_CONTROL_PAGE: 14341 SM_DBG5(("smsatModeSelect10: Control mode page\n")); 14342 /* 14343 compare pLogPage to expected value (SAT Table 65, p67) 14344 If not match, return check condition 14345 */ 14346 if ( pLogPage[StartingIndex+1] != 0x0A || 14347 pLogPage[StartingIndex+2] != 0x02 || 14348 (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) || 14349 (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) || 14350 (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */ 14351 (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */ 14352 (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */ 14353 14354 (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */ 14355 (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */ 14356 (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */ 14357 (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */ 14358 14359 pLogPage[StartingIndex+8] != 0xFF || 14360 pLogPage[StartingIndex+9] != 0xFF || 14361 pLogPage[StartingIndex+10] != 0x00 || 14362 pLogPage[StartingIndex+11] != 0x00 14363 ) 14364 { 14365 chkCnd = agTRUE; 14366 } 14367 if (chkCnd == agTRUE) 14368 { 14369 smsatSetSensePayload( pSense, 14370 SCSI_SNSKEY_ILLEGAL_REQUEST, 14371 0, 14372 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 14373 satIOContext); 14374 14375 /*smEnqueueIO(smRoot, satIOContext);*/ 14376 14377 tdsmIOCompletedCB( smRoot, 14378 smIORequest, 14379 smIOSuccess, 14380 SCSI_STAT_CHECK_CONDITION, 14381 satIOContext->pSmSenseData, 14382 satIOContext->interruptContext ); 14383 14384 SM_DBG1(("smsatModeSelect10: unexpected values!!!\n")); 14385 } 14386 else 14387 { 14388 /*smEnqueueIO(smRoot, satIOContext);*/ 14389 14390 tdsmIOCompletedCB( smRoot, 14391 smIORequest, 14392 smIOSuccess, 14393 SCSI_STAT_GOOD, 14394 agNULL, 14395 satIOContext->interruptContext); 14396 } 14397 return SM_RC_SUCCESS; 14398 break; 14399 case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE: 14400 SM_DBG5(("smsatModeSelect10: Read-Write Error Recovery mode page\n")); 14401 14402 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_AWRE_MASK) || 14403 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_RC_MASK) || 14404 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_EER_MASK) || 14405 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PER_MASK) || 14406 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DTE_MASK) || 14407 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DCR_MASK) || 14408 (pLogPage[StartingIndex + 10]) || 14409 (pLogPage[StartingIndex + 11]) 14410 ) 14411 { 14412 SM_DBG1(("smsatModeSelect10: return check condition!!!\n")); 14413 14414 smsatSetSensePayload( pSense, 14415 SCSI_SNSKEY_ILLEGAL_REQUEST, 14416 0, 14417 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 14418 satIOContext); 14419 14420 /*smEnqueueIO(smRoot, satIOContext);*/ 14421 14422 tdsmIOCompletedCB( smRoot, 14423 smIORequest, 14424 smIOSuccess, 14425 SCSI_STAT_CHECK_CONDITION, 14426 satIOContext->pSmSenseData, 14427 satIOContext->interruptContext ); 14428 return SM_RC_SUCCESS; 14429 } 14430 else 14431 { 14432 SM_DBG2(("smsatModeSelect10: return GOOD \n")); 14433 /*smEnqueueIO(smRoot, satIOContext);*/ 14434 14435 tdsmIOCompletedCB( smRoot, 14436 smIORequest, 14437 smIOSuccess, 14438 SCSI_STAT_GOOD, 14439 agNULL, 14440 satIOContext->interruptContext); 14441 return SM_RC_SUCCESS; 14442 } 14443 14444 break; 14445 case MODESELECT_CACHING: 14446 /* SAT rev8 Table67, p69*/ 14447 SM_DBG5(("smsatModeSelect10: Caching mode page\n")); 14448 if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */ 14449 (pLogPage[StartingIndex + 3]) || 14450 (pLogPage[StartingIndex + 4]) || 14451 (pLogPage[StartingIndex + 5]) || 14452 (pLogPage[StartingIndex + 6]) || 14453 (pLogPage[StartingIndex + 7]) || 14454 (pLogPage[StartingIndex + 8]) || 14455 (pLogPage[StartingIndex + 9]) || 14456 (pLogPage[StartingIndex + 10]) || 14457 (pLogPage[StartingIndex + 11]) || 14458 14459 (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */ 14460 (pLogPage[StartingIndex + 13]) || 14461 (pLogPage[StartingIndex + 14]) || 14462 (pLogPage[StartingIndex + 15]) 14463 ) 14464 { 14465 SM_DBG1(("smsatModeSelect10: return check condition!!!\n")); 14466 14467 smsatSetSensePayload( pSense, 14468 SCSI_SNSKEY_ILLEGAL_REQUEST, 14469 0, 14470 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 14471 satIOContext); 14472 14473 /*smEnqueueIO(smRoot, satIOContext);*/ 14474 14475 tdsmIOCompletedCB( smRoot, 14476 smIORequest, 14477 smIOSuccess, 14478 SCSI_STAT_CHECK_CONDITION, 14479 satIOContext->pSmSenseData, 14480 satIOContext->interruptContext ); 14481 return SM_RC_SUCCESS; 14482 14483 } 14484 else 14485 { 14486 /* sends ATA SET FEATURES based on WCE bit */ 14487 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_WCE_MASK) ) 14488 { 14489 SM_DBG5(("smsatModeSelect10: disable write cache\n")); 14490 /* sends SET FEATURES */ 14491 fis->h.fisType = 0x27; /* Reg host to device */ 14492 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14493 14494 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 14495 fis->h.features = 0x82; /* disable write cache */ 14496 fis->d.lbaLow = 0; /* */ 14497 fis->d.lbaMid = 0; /* */ 14498 fis->d.lbaHigh = 0; /* */ 14499 fis->d.device = 0; /* */ 14500 fis->d.lbaLowExp = 0; /* */ 14501 fis->d.lbaMidExp = 0; /* */ 14502 fis->d.lbaHighExp = 0; /* */ 14503 fis->d.featuresExp = 0; /* */ 14504 fis->d.sectorCount = 0; /* */ 14505 fis->d.sectorCountExp = 0; /* */ 14506 fis->d.reserved4 = 0; 14507 fis->d.control = 0; /* FIS HOB bit clear */ 14508 fis->d.reserved5 = 0; 14509 14510 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14511 14512 /* Initialize CB for SATA completion. 14513 */ 14514 satIOContext->satCompleteCB = &smsatModeSelect6n10CB; 14515 14516 /* 14517 * Prepare SGL and send FIS to LL layer. 14518 */ 14519 satIOContext->reqType = agRequestType; /* Save it */ 14520 14521 status = smsataLLIOStart( smRoot, 14522 smIORequest, 14523 smDeviceHandle, 14524 smScsiRequest, 14525 satIOContext); 14526 return status; 14527 } 14528 else 14529 { 14530 SM_DBG5(("smsatModeSelect10: enable write cache\n")); 14531 /* sends SET FEATURES */ 14532 fis->h.fisType = 0x27; /* Reg host to device */ 14533 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14534 14535 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 14536 fis->h.features = 0x02; /* enable write cache */ 14537 fis->d.lbaLow = 0; /* */ 14538 fis->d.lbaMid = 0; /* */ 14539 fis->d.lbaHigh = 0; /* */ 14540 fis->d.device = 0; /* */ 14541 fis->d.lbaLowExp = 0; /* */ 14542 fis->d.lbaMidExp = 0; /* */ 14543 fis->d.lbaHighExp = 0; /* */ 14544 fis->d.featuresExp = 0; /* */ 14545 fis->d.sectorCount = 0; /* */ 14546 fis->d.sectorCountExp = 0; /* */ 14547 fis->d.reserved4 = 0; 14548 fis->d.control = 0; /* FIS HOB bit clear */ 14549 fis->d.reserved5 = 0; 14550 14551 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14552 14553 /* Initialize CB for SATA completion. 14554 */ 14555 satIOContext->satCompleteCB = &smsatModeSelect6n10CB; 14556 14557 /* 14558 * Prepare SGL and send FIS to LL layer. 14559 */ 14560 satIOContext->reqType = agRequestType; /* Save it */ 14561 14562 status = smsataLLIOStart( smRoot, 14563 smIORequest, 14564 smDeviceHandle, 14565 smScsiRequest, 14566 satIOContext); 14567 return status; 14568 14569 } 14570 } 14571 break; 14572 case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE: 14573 SM_DBG5(("smsatModeSelect10: Informational Exception Control mode page\n")); 14574 14575 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PERF_MASK) || 14576 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_TEST_MASK) 14577 ) 14578 { 14579 SM_DBG1(("smsatModeSelect10: return check condition!!!\n")); 14580 14581 smsatSetSensePayload( pSense, 14582 SCSI_SNSKEY_ILLEGAL_REQUEST, 14583 0, 14584 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST, 14585 satIOContext); 14586 14587 /*smEnqueueIO(smRoot, satIOContext);*/ 14588 14589 tdsmIOCompletedCB( smRoot, 14590 smIORequest, 14591 smIOSuccess, 14592 SCSI_STAT_CHECK_CONDITION, 14593 satIOContext->pSmSenseData, 14594 satIOContext->interruptContext ); 14595 return SM_RC_SUCCESS; 14596 } 14597 else 14598 { 14599 /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */ 14600 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DEXCPT_MASK) ) 14601 { 14602 SM_DBG5(("smsatModeSelect10: enable information exceptions reporting\n")); 14603 /* sends SMART ENABLE OPERATIONS */ 14604 fis->h.fisType = 0x27; /* Reg host to device */ 14605 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14606 14607 fis->h.command = SAT_SMART; /* 0xB0 */ 14608 fis->h.features = SAT_SMART_ENABLE_OPERATIONS; /* enable */ 14609 fis->d.lbaLow = 0; /* */ 14610 fis->d.lbaMid = 0x4F; /* 0x4F */ 14611 fis->d.lbaHigh = 0xC2; /* 0xC2 */ 14612 fis->d.device = 0; /* */ 14613 fis->d.lbaLowExp = 0; /* */ 14614 fis->d.lbaMidExp = 0; /* */ 14615 fis->d.lbaHighExp = 0; /* */ 14616 fis->d.featuresExp = 0; /* */ 14617 fis->d.sectorCount = 0; /* */ 14618 fis->d.sectorCountExp = 0; /* */ 14619 fis->d.reserved4 = 0; 14620 fis->d.control = 0; /* FIS HOB bit clear */ 14621 fis->d.reserved5 = 0; 14622 14623 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14624 14625 /* Initialize CB for SATA completion. 14626 */ 14627 satIOContext->satCompleteCB = &smsatModeSelect6n10CB; 14628 14629 /* 14630 * Prepare SGL and send FIS to LL layer. 14631 */ 14632 satIOContext->reqType = agRequestType; /* Save it */ 14633 14634 status = smsataLLIOStart( smRoot, 14635 smIORequest, 14636 smDeviceHandle, 14637 smScsiRequest, 14638 satIOContext); 14639 return status; 14640 } 14641 else 14642 { 14643 SM_DBG5(("smsatModeSelect10: disable information exceptions reporting\n")); 14644 /* sends SMART DISABLE OPERATIONS */ 14645 fis->h.fisType = 0x27; /* Reg host to device */ 14646 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14647 14648 fis->h.command = SAT_SMART; /* 0xB0 */ 14649 fis->h.features = SAT_SMART_DISABLE_OPERATIONS; /* disable */ 14650 fis->d.lbaLow = 0; /* */ 14651 fis->d.lbaMid = 0x4F; /* 0x4F */ 14652 fis->d.lbaHigh = 0xC2; /* 0xC2 */ 14653 fis->d.device = 0; /* */ 14654 fis->d.lbaLowExp = 0; /* */ 14655 fis->d.lbaMidExp = 0; /* */ 14656 fis->d.lbaHighExp = 0; /* */ 14657 fis->d.featuresExp = 0; /* */ 14658 fis->d.sectorCount = 0; /* */ 14659 fis->d.sectorCountExp = 0; /* */ 14660 fis->d.reserved4 = 0; 14661 fis->d.control = 0; /* FIS HOB bit clear */ 14662 fis->d.reserved5 = 0; 14663 14664 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14665 14666 /* Initialize CB for SATA completion. 14667 */ 14668 satIOContext->satCompleteCB = &smsatModeSelect6n10CB; 14669 14670 /* 14671 * Prepare SGL and send FIS to LL layer. 14672 */ 14673 satIOContext->reqType = agRequestType; /* Save it */ 14674 14675 status = smsataLLIOStart( smRoot, 14676 smIORequest, 14677 smDeviceHandle, 14678 smScsiRequest, 14679 satIOContext); 14680 return status; 14681 14682 } 14683 } 14684 break; 14685 default: 14686 SM_DBG1(("smsatModeSelect10: Error unknown page code 0x%x!!!\n", pLogPage[12])); 14687 smsatSetSensePayload( pSense, 14688 SCSI_SNSKEY_NO_SENSE, 14689 0, 14690 SCSI_SNSCODE_NO_ADDITIONAL_INFO, 14691 satIOContext); 14692 14693 /*smEnqueueIO(smRoot, satIOContext);*/ 14694 14695 tdsmIOCompletedCB( smRoot, 14696 smIORequest, 14697 smIOSuccess, 14698 SCSI_STAT_CHECK_CONDITION, 14699 satIOContext->pSmSenseData, 14700 satIOContext->interruptContext ); 14701 return SM_RC_SUCCESS; 14702 } 14703 } 14704 14705 osGLOBAL bit32 14706 smsatSynchronizeCache10( 14707 smRoot_t *smRoot, 14708 smIORequest_t *smIORequest, 14709 smDeviceHandle_t *smDeviceHandle, 14710 smScsiInitiatorRequest_t *smScsiRequest, 14711 smSatIOContext_t *satIOContext 14712 ) 14713 { 14714 bit32 status; 14715 bit32 agRequestType; 14716 smDeviceData_t *pSatDevData; 14717 smScsiRspSense_t *pSense; 14718 smIniScsiCmnd_t *scsiCmnd; 14719 agsaFisRegHostToDevice_t *fis; 14720 14721 pSense = satIOContext->pSense; 14722 pSatDevData = satIOContext->pSatDevData; 14723 scsiCmnd = &smScsiRequest->scsiCmnd; 14724 fis = satIOContext->pFis; 14725 14726 SM_DBG5(("smsatSynchronizeCache10: start\n")); 14727 14728 /* checking CONTROL */ 14729 /* NACA == 1 or LINK == 1*/ 14730 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 14731 { 14732 smsatSetSensePayload( pSense, 14733 SCSI_SNSKEY_ILLEGAL_REQUEST, 14734 0, 14735 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 14736 satIOContext); 14737 14738 /*smEnqueueIO(smRoot, satIOContext);*/ 14739 14740 tdsmIOCompletedCB( smRoot, 14741 smIORequest, 14742 smIOSuccess, 14743 SCSI_STAT_CHECK_CONDITION, 14744 satIOContext->pSmSenseData, 14745 satIOContext->interruptContext ); 14746 14747 SM_DBG1(("smsatSynchronizeCache10: return control!!!\n")); 14748 return SM_RC_SUCCESS; 14749 } 14750 14751 /* checking IMMED bit */ 14752 if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK) 14753 { 14754 SM_DBG1(("smsatSynchronizeCache10: GOOD status due to IMMED bit!!!\n")); 14755 14756 /* return GOOD status first here */ 14757 tdsmIOCompletedCB( smRoot, 14758 smIORequest, 14759 smIOSuccess, 14760 SCSI_STAT_GOOD, 14761 agNULL, 14762 satIOContext->interruptContext); 14763 } 14764 14765 /* sends FLUSH CACHE or FLUSH CACHE EXT */ 14766 if (pSatDevData->sat48BitSupport == agTRUE) 14767 { 14768 SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE EXT\n")); 14769 /* FLUSH CACHE EXT */ 14770 fis->h.fisType = 0x27; /* Reg host to device */ 14771 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14772 14773 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */ 14774 fis->h.features = 0; /* FIS reserve */ 14775 fis->d.featuresExp = 0; /* FIS reserve */ 14776 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 14777 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 14778 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 14779 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 14780 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 14781 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14782 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 14783 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14784 fis->d.device = 0; /* FIS DEV is discared in SATA */ 14785 fis->d.control = 0; /* FIS HOB bit clear */ 14786 fis->d.reserved4 = 0; 14787 fis->d.reserved5 = 0; 14788 14789 } 14790 else 14791 { 14792 SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE\n")); 14793 /* FLUSH CACHE */ 14794 fis->h.fisType = 0x27; /* Reg host to device */ 14795 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14796 14797 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */ 14798 fis->h.features = 0; /* FIS features NA */ 14799 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 14800 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 14801 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 14802 fis->d.lbaLowExp = 0; 14803 fis->d.lbaMidExp = 0; 14804 fis->d.lbaHighExp = 0; 14805 fis->d.featuresExp = 0; 14806 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 14807 fis->d.sectorCountExp = 0; 14808 fis->d.device = 0; /* FIS DEV is discared in SATA */ 14809 fis->d.control = 0; /* FIS HOB bit clear */ 14810 fis->d.reserved4 = 0; 14811 fis->d.reserved5 = 0; 14812 14813 } 14814 14815 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14816 14817 /* Initialize CB for SATA completion. 14818 */ 14819 satIOContext->satCompleteCB = &smsatSynchronizeCache10n16CB; 14820 14821 /* 14822 * Prepare SGL and send FIS to LL layer. 14823 */ 14824 satIOContext->reqType = agRequestType; /* Save it */ 14825 14826 status = smsataLLIOStart( smRoot, 14827 smIORequest, 14828 smDeviceHandle, 14829 smScsiRequest, 14830 satIOContext); 14831 14832 14833 return (status); 14834 } 14835 14836 osGLOBAL bit32 14837 smsatSynchronizeCache16( 14838 smRoot_t *smRoot, 14839 smIORequest_t *smIORequest, 14840 smDeviceHandle_t *smDeviceHandle, 14841 smScsiInitiatorRequest_t *smScsiRequest, 14842 smSatIOContext_t *satIOContext 14843 ) 14844 { 14845 bit32 status; 14846 bit32 agRequestType; 14847 smDeviceData_t *pSatDevData; 14848 smScsiRspSense_t *pSense; 14849 smIniScsiCmnd_t *scsiCmnd; 14850 agsaFisRegHostToDevice_t *fis; 14851 14852 pSense = satIOContext->pSense; 14853 pSatDevData = satIOContext->pSatDevData; 14854 scsiCmnd = &smScsiRequest->scsiCmnd; 14855 fis = satIOContext->pFis; 14856 14857 SM_DBG5(("smsatSynchronizeCache10: start\n")); 14858 14859 /* checking CONTROL */ 14860 /* NACA == 1 or LINK == 1*/ 14861 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 14862 { 14863 smsatSetSensePayload( pSense, 14864 SCSI_SNSKEY_ILLEGAL_REQUEST, 14865 0, 14866 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 14867 satIOContext); 14868 14869 /*smEnqueueIO(smRoot, satIOContext);*/ 14870 14871 tdsmIOCompletedCB( smRoot, 14872 smIORequest, 14873 smIOSuccess, 14874 SCSI_STAT_CHECK_CONDITION, 14875 satIOContext->pSmSenseData, 14876 satIOContext->interruptContext ); 14877 14878 SM_DBG1(("smsatSynchronizeCache10: return control!!!\n")); 14879 return SM_RC_SUCCESS; 14880 } 14881 14882 14883 /* checking IMMED bit */ 14884 if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK) 14885 { 14886 SM_DBG1(("smsatSynchronizeCache10: GOOD status due to IMMED bit!!!\n")); 14887 14888 /* return GOOD status first here */ 14889 tdsmIOCompletedCB( smRoot, 14890 smIORequest, 14891 smIOSuccess, 14892 SCSI_STAT_GOOD, 14893 agNULL, 14894 satIOContext->interruptContext); 14895 } 14896 14897 /* sends FLUSH CACHE or FLUSH CACHE EXT */ 14898 if (pSatDevData->sat48BitSupport == agTRUE) 14899 { 14900 SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE EXT\n")); 14901 /* FLUSH CACHE EXT */ 14902 fis->h.fisType = 0x27; /* Reg host to device */ 14903 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14904 14905 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */ 14906 fis->h.features = 0; /* FIS reserve */ 14907 fis->d.featuresExp = 0; /* FIS reserve */ 14908 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 14909 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 14910 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 14911 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 14912 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 14913 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 14914 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 14915 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 14916 fis->d.device = 0; /* FIS DEV is discared in SATA */ 14917 fis->d.control = 0; /* FIS HOB bit clear */ 14918 fis->d.reserved4 = 0; 14919 fis->d.reserved5 = 0; 14920 14921 } 14922 else 14923 { 14924 SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE\n")); 14925 /* FLUSH CACHE */ 14926 fis->h.fisType = 0x27; /* Reg host to device */ 14927 fis->h.c_pmPort = 0x80; /* C Bit is set */ 14928 14929 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */ 14930 fis->h.features = 0; /* FIS features NA */ 14931 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 14932 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 14933 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 14934 fis->d.lbaLowExp = 0; 14935 fis->d.lbaMidExp = 0; 14936 fis->d.lbaHighExp = 0; 14937 fis->d.featuresExp = 0; 14938 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 14939 fis->d.sectorCountExp = 0; 14940 fis->d.device = 0; /* FIS DEV is discared in SATA */ 14941 fis->d.control = 0; /* FIS HOB bit clear */ 14942 fis->d.reserved4 = 0; 14943 fis->d.reserved5 = 0; 14944 14945 } 14946 14947 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 14948 14949 /* Initialize CB for SATA completion. 14950 */ 14951 satIOContext->satCompleteCB = &smsatSynchronizeCache10n16CB; 14952 14953 /* 14954 * Prepare SGL and send FIS to LL layer. 14955 */ 14956 satIOContext->reqType = agRequestType; /* Save it */ 14957 14958 status = smsataLLIOStart( smRoot, 14959 smIORequest, 14960 smDeviceHandle, 14961 smScsiRequest, 14962 satIOContext); 14963 14964 14965 return (status); 14966 } 14967 14968 osGLOBAL bit32 14969 smsatWriteAndVerify10( 14970 smRoot_t *smRoot, 14971 smIORequest_t *smIORequest, 14972 smDeviceHandle_t *smDeviceHandle, 14973 smScsiInitiatorRequest_t *smScsiRequest, 14974 smSatIOContext_t *satIOContext 14975 ) 14976 { 14977 /* 14978 combination of write10 and verify10 14979 */ 14980 14981 bit32 status; 14982 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 14983 smDeviceData_t *pSatDevData; 14984 smScsiRspSense_t *pSense; 14985 smIniScsiCmnd_t *scsiCmnd; 14986 agsaFisRegHostToDevice_t *fis; 14987 bit32 lba = 0; 14988 bit32 tl = 0; 14989 bit32 LoopNum = 1; 14990 bit8 LBA[8]; 14991 bit8 TL[8]; 14992 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 14993 14994 pSense = satIOContext->pSense; 14995 pSatDevData = satIOContext->pSatDevData; 14996 scsiCmnd = &smScsiRequest->scsiCmnd; 14997 fis = satIOContext->pFis; 14998 14999 SM_DBG5(("smsatWriteAndVerify10: start\n")); 15000 15001 /* checking BYTCHK bit */ 15002 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK) 15003 { 15004 smsatSetSensePayload( pSense, 15005 SCSI_SNSKEY_ILLEGAL_REQUEST, 15006 0, 15007 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15008 satIOContext); 15009 15010 /*smEnqueueIO(smRoot, satIOContext);*/ 15011 15012 tdsmIOCompletedCB( smRoot, 15013 smIORequest, 15014 smIOSuccess, 15015 SCSI_STAT_CHECK_CONDITION, 15016 satIOContext->pSmSenseData, 15017 satIOContext->interruptContext ); 15018 15019 SM_DBG1(("smsatWriteAndVerify10: BYTCHK bit checking!!!\n")); 15020 return SM_RC_SUCCESS; 15021 } 15022 15023 15024 /* checking CONTROL */ 15025 /* NACA == 1 or LINK == 1*/ 15026 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 15027 { 15028 smsatSetSensePayload( pSense, 15029 SCSI_SNSKEY_ILLEGAL_REQUEST, 15030 0, 15031 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15032 satIOContext); 15033 15034 /*smEnqueueIO(smRoot, satIOContext);*/ 15035 15036 tdsmIOCompletedCB( smRoot, 15037 smIORequest, 15038 smIOSuccess, 15039 SCSI_STAT_CHECK_CONDITION, 15040 satIOContext->pSmSenseData, 15041 satIOContext->interruptContext ); 15042 15043 SM_DBG1(("smsatWriteAndVerify10: return control!!!\n")); 15044 return SM_RC_SUCCESS; 15045 } 15046 15047 sm_memset(LBA, 0, sizeof(LBA)); 15048 sm_memset(TL, 0, sizeof(TL)); 15049 15050 /* do not use memcpy due to indexing in LBA and TL */ 15051 LBA[0] = 0; /* MSB */ 15052 LBA[1] = 0; 15053 LBA[2] = 0; 15054 LBA[3] = 0; 15055 LBA[4] = scsiCmnd->cdb[2]; 15056 LBA[5] = scsiCmnd->cdb[3]; 15057 LBA[6] = scsiCmnd->cdb[4]; 15058 LBA[7] = scsiCmnd->cdb[5]; /* LSB */ 15059 15060 TL[0] = 0; 15061 TL[1] = 0; 15062 TL[2] = 0; 15063 TL[3] = 0; 15064 TL[4] = 0; 15065 TL[5] = 0; 15066 TL[6] = scsiCmnd->cdb[7]; 15067 TL[7] = scsiCmnd->cdb[8]; /* LSB */ 15068 15069 15070 /* cbd10; computing LBA and transfer length */ 15071 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 15072 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 15073 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 15074 15075 15076 /* Table 34, 9.1, p 46 */ 15077 /* 15078 note: As of 2/10/2006, no support for DMA QUEUED 15079 */ 15080 15081 /* 15082 Table 34, 9.1, p 46, b 15083 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 15084 return check condition 15085 */ 15086 if (pSatDevData->satNCQ != agTRUE && 15087 pSatDevData->sat48BitSupport != agTRUE 15088 ) 15089 { 15090 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 15091 if (AllChk) 15092 { 15093 SM_DBG1(("smsatWriteAndVerify10: return LBA out of range!!!\n")); 15094 smsatSetSensePayload( pSense, 15095 SCSI_SNSKEY_ILLEGAL_REQUEST, 15096 0, 15097 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 15098 satIOContext); 15099 15100 /*smEnqueueIO(smRoot, satIOContext);*/ 15101 15102 tdsmIOCompletedCB( smRoot, 15103 smIORequest, 15104 smIOSuccess, 15105 SCSI_STAT_CHECK_CONDITION, 15106 satIOContext->pSmSenseData, 15107 satIOContext->interruptContext ); 15108 15109 return SM_RC_SUCCESS; 15110 } 15111 } 15112 else 15113 { 15114 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 15115 if (AllChk) 15116 { 15117 SM_DBG1(("smsatWriteAndVerify10: return LBA out of range, EXT!!!\n")); 15118 smsatSetSensePayload( pSense, 15119 SCSI_SNSKEY_ILLEGAL_REQUEST, 15120 0, 15121 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 15122 satIOContext); 15123 15124 /*smEnqueueIO(smRoot, satIOContext);*/ 15125 15126 tdsmIOCompletedCB( smRoot, 15127 smIORequest, 15128 smIOSuccess, 15129 SCSI_STAT_CHECK_CONDITION, 15130 satIOContext->pSmSenseData, 15131 satIOContext->interruptContext ); 15132 15133 return SM_RC_SUCCESS; 15134 } 15135 } 15136 15137 15138 /* case 1 and 2 */ 15139 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 15140 { 15141 /* case 2 */ 15142 /* WRITE DMA*/ 15143 /* can't fit the transfer length */ 15144 SM_DBG5(("smsatWriteAndVerify10: case 2\n")); 15145 fis->h.fisType = 0x27; /* Reg host to device */ 15146 fis->h.c_pmPort = 0x80; /* C bit is set */ 15147 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 15148 fis->h.features = 0; /* FIS reserve */ 15149 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15150 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15151 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15152 15153 /* FIS LBA mode set LBA (27:24) */ 15154 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 15155 15156 fis->d.lbaLowExp = 0; 15157 fis->d.lbaMidExp = 0; 15158 fis->d.lbaHighExp = 0; 15159 fis->d.featuresExp = 0; 15160 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 15161 fis->d.sectorCountExp = 0; 15162 fis->d.reserved4 = 0; 15163 fis->d.control = 0; /* FIS HOB bit clear */ 15164 fis->d.reserved5 = 0; 15165 15166 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 15167 satIOContext->ATACmd = SAT_WRITE_DMA; 15168 } 15169 else 15170 { 15171 /* case 1 */ 15172 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 15173 /* WRITE SECTORS for easier implemetation */ 15174 /* can't fit the transfer length */ 15175 SM_DBG5(("smsatWriteAndVerify10: case 1\n")); 15176 fis->h.fisType = 0x27; /* Reg host to device */ 15177 fis->h.c_pmPort = 0x80; /* C bit is set */ 15178 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 15179 fis->h.features = 0; /* FIS reserve */ 15180 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15181 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15182 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15183 15184 /* FIS LBA mode set LBA (27:24) */ 15185 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 15186 15187 fis->d.lbaLowExp = 0; 15188 fis->d.lbaMidExp = 0; 15189 fis->d.lbaHighExp = 0; 15190 fis->d.featuresExp = 0; 15191 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 15192 fis->d.sectorCountExp = 0; 15193 fis->d.reserved4 = 0; 15194 fis->d.control = 0; /* FIS HOB bit clear */ 15195 fis->d.reserved5 = 0; 15196 15197 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 15198 satIOContext->ATACmd = SAT_WRITE_SECTORS; 15199 15200 } 15201 15202 /* case 3 and 4 */ 15203 if (pSatDevData->sat48BitSupport == agTRUE) 15204 { 15205 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 15206 { 15207 /* case 3 */ 15208 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 15209 SM_DBG5(("smsatWriteAndVerify10: case 3\n")); 15210 fis->h.fisType = 0x27; /* Reg host to device */ 15211 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15212 15213 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 15214 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 15215 15216 fis->h.features = 0; /* FIS reserve */ 15217 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15218 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15219 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15220 fis->d.device = 0x40; /* FIS LBA mode set */ 15221 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 15222 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 15223 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 15224 fis->d.featuresExp = 0; /* FIS reserve */ 15225 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 15226 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 15227 fis->d.reserved4 = 0; 15228 fis->d.control = 0; /* FIS HOB bit clear */ 15229 fis->d.reserved5 = 0; 15230 15231 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 15232 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 15233 } 15234 else 15235 { 15236 /* case 4 */ 15237 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 15238 /* WRITE SECTORS EXT for easier implemetation */ 15239 SM_DBG5(("smsatWriteAndVerify10: case 4\n")); 15240 fis->h.fisType = 0x27; /* Reg host to device */ 15241 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15242 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 15243 15244 fis->h.features = 0; /* FIS reserve */ 15245 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15246 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15247 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15248 fis->d.device = 0x40; /* FIS LBA mode set */ 15249 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 15250 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 15251 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 15252 fis->d.featuresExp = 0; /* FIS reserve */ 15253 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 15254 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 15255 fis->d.reserved4 = 0; 15256 fis->d.control = 0; /* FIS HOB bit clear */ 15257 fis->d.reserved5 = 0; 15258 15259 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 15260 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 15261 } 15262 } 15263 /* case 5 */ 15264 if (pSatDevData->satNCQ == agTRUE) 15265 { 15266 /* WRITE FPDMA QUEUED */ 15267 if (pSatDevData->sat48BitSupport != agTRUE) 15268 { 15269 SM_DBG1(("smsatWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support!!!\n")); 15270 smsatSetSensePayload( pSense, 15271 SCSI_SNSKEY_ILLEGAL_REQUEST, 15272 0, 15273 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15274 satIOContext); 15275 15276 /*smEnqueueIO(smRoot, satIOContext);*/ 15277 15278 tdsmIOCompletedCB( smRoot, 15279 smIORequest, 15280 smIOSuccess, 15281 SCSI_STAT_CHECK_CONDITION, 15282 satIOContext->pSmSenseData, 15283 satIOContext->interruptContext ); 15284 return SM_RC_SUCCESS; 15285 } 15286 SM_DBG5(("smsatWriteAndVerify10: case 5\n")); 15287 15288 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 15289 15290 fis->h.fisType = 0x27; /* Reg host to device */ 15291 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15292 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 15293 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 15294 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15295 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15296 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15297 15298 /* Check FUA bit */ 15299 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK) 15300 fis->d.device = 0xC0; /* FIS FUA set */ 15301 else 15302 fis->d.device = 0x40; /* FIS FUA clear */ 15303 15304 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 15305 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 15306 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 15307 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 15308 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 15309 fis->d.sectorCountExp = 0; 15310 fis->d.reserved4 = 0; 15311 fis->d.control = 0; /* FIS HOB bit clear */ 15312 fis->d.reserved5 = 0; 15313 15314 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 15315 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 15316 } 15317 15318 satIOContext->currentLBA = lba; 15319 satIOContext->OrgTL = tl; 15320 15321 /* 15322 computing number of loop and remainder for tl 15323 0xFF in case not ext 15324 0xFFFF in case EXT 15325 */ 15326 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 15327 { 15328 LoopNum = smsatComputeLoopNum(tl, 0xFF); 15329 } 15330 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 15331 fis->h.command == SAT_WRITE_DMA_EXT || 15332 fis->h.command == SAT_WRITE_DMA_FUA_EXT 15333 ) 15334 { 15335 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 15336 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 15337 } 15338 else 15339 { 15340 /* SAT_WRITE_FPDMA_QUEUED */ 15341 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 15342 } 15343 15344 satIOContext->LoopNum = LoopNum; 15345 15346 15347 if (LoopNum == 1) 15348 { 15349 SM_DBG5(("smsatWriteAndVerify10: NON CHAINED data\n")); 15350 /* Initialize CB for SATA completion. 15351 */ 15352 satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB; 15353 } 15354 else 15355 { 15356 SM_DBG1(("smsatWriteAndVerify10: CHAINED data!!!\n")); 15357 /* re-setting tl */ 15358 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 15359 { 15360 fis->d.sectorCount = 0xFF; 15361 } 15362 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 15363 fis->h.command == SAT_WRITE_DMA_EXT || 15364 fis->h.command == SAT_WRITE_DMA_FUA_EXT 15365 ) 15366 { 15367 fis->d.sectorCount = 0xFF; 15368 fis->d.sectorCountExp = 0xFF; 15369 } 15370 else 15371 { 15372 /* SAT_WRITE_FPDMA_QUEUED */ 15373 fis->h.features = 0xFF; 15374 fis->d.featuresExp = 0xFF; 15375 } 15376 15377 /* Initialize CB for SATA completion. 15378 */ 15379 satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB; 15380 } 15381 15382 15383 /* 15384 * Prepare SGL and send FIS to LL layer. 15385 */ 15386 satIOContext->reqType = agRequestType; /* Save it */ 15387 15388 status = smsataLLIOStart( smRoot, 15389 smIORequest, 15390 smDeviceHandle, 15391 smScsiRequest, 15392 satIOContext); 15393 return (status); 15394 15395 } 15396 15397 osGLOBAL bit32 15398 smsatWriteAndVerify12( 15399 smRoot_t *smRoot, 15400 smIORequest_t *smIORequest, 15401 smDeviceHandle_t *smDeviceHandle, 15402 smScsiInitiatorRequest_t *smScsiRequest, 15403 smSatIOContext_t *satIOContext 15404 ) 15405 { 15406 /* 15407 combination of write12 and verify12 15408 temp: since write12 is not support (due to internal checking), no support 15409 */ 15410 bit32 status; 15411 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 15412 smDeviceData_t *pSatDevData; 15413 smScsiRspSense_t *pSense; 15414 smIniScsiCmnd_t *scsiCmnd; 15415 agsaFisRegHostToDevice_t *fis; 15416 bit32 lba = 0; 15417 bit32 tl = 0; 15418 bit32 LoopNum = 1; 15419 bit8 LBA[8]; 15420 bit8 TL[8]; 15421 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 15422 15423 pSense = satIOContext->pSense; 15424 pSatDevData = satIOContext->pSatDevData; 15425 scsiCmnd = &smScsiRequest->scsiCmnd; 15426 fis = satIOContext->pFis; 15427 15428 SM_DBG5(("smsatWriteAndVerify12: start\n")); 15429 15430 /* checking BYTCHK bit */ 15431 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK) 15432 { 15433 smsatSetSensePayload( pSense, 15434 SCSI_SNSKEY_ILLEGAL_REQUEST, 15435 0, 15436 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15437 satIOContext); 15438 15439 /*smEnqueueIO(smRoot, satIOContext);*/ 15440 15441 tdsmIOCompletedCB( smRoot, 15442 smIORequest, 15443 smIOSuccess, 15444 SCSI_STAT_CHECK_CONDITION, 15445 satIOContext->pSmSenseData, 15446 satIOContext->interruptContext ); 15447 15448 SM_DBG1(("smsatWriteAndVerify12: BYTCHK bit checking!!!\n")); 15449 return SM_RC_SUCCESS; 15450 } 15451 15452 /* checking CONTROL */ 15453 /* NACA == 1 or LINK == 1*/ 15454 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) ) 15455 { 15456 smsatSetSensePayload( pSense, 15457 SCSI_SNSKEY_ILLEGAL_REQUEST, 15458 0, 15459 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15460 satIOContext); 15461 15462 /*smEnqueueIO(smRoot, satIOContext);*/ 15463 15464 tdsmIOCompletedCB( smRoot, 15465 smIORequest, 15466 smIOSuccess, 15467 SCSI_STAT_CHECK_CONDITION, 15468 satIOContext->pSmSenseData, 15469 satIOContext->interruptContext ); 15470 15471 SM_DBG1(("smsatWriteAndVerify12: return control!!!\n")); 15472 return SM_RC_SUCCESS; 15473 } 15474 15475 sm_memset(LBA, 0, sizeof(LBA)); 15476 sm_memset(TL, 0, sizeof(TL)); 15477 15478 /* do not use memcpy due to indexing in LBA and TL */ 15479 LBA[0] = 0; /* MSB */ 15480 LBA[1] = 0; 15481 LBA[2] = 0; 15482 LBA[3] = 0; 15483 LBA[4] = scsiCmnd->cdb[2]; 15484 LBA[5] = scsiCmnd->cdb[3]; 15485 LBA[6] = scsiCmnd->cdb[4]; 15486 LBA[7] = scsiCmnd->cdb[5]; /* LSB */ 15487 15488 TL[0] = 0; /* MSB */ 15489 TL[1] = 0; 15490 TL[2] = 0; 15491 TL[3] = 0; 15492 TL[4] = scsiCmnd->cdb[6]; 15493 TL[5] = scsiCmnd->cdb[7]; 15494 TL[6] = scsiCmnd->cdb[8]; 15495 TL[7] = scsiCmnd->cdb[9]; /* LSB */ 15496 15497 15498 lba = smsatComputeCDB12LBA(satIOContext); 15499 tl = smsatComputeCDB12TL(satIOContext); 15500 15501 15502 /* Table 34, 9.1, p 46 */ 15503 /* 15504 note: As of 2/10/2006, no support for DMA QUEUED 15505 */ 15506 15507 /* 15508 Table 34, 9.1, p 46, b 15509 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 15510 return check condition 15511 */ 15512 if (pSatDevData->satNCQ != agTRUE && 15513 pSatDevData->sat48BitSupport != agTRUE 15514 ) 15515 { 15516 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 15517 if (AllChk) 15518 { 15519 15520 /*smEnqueueIO(smRoot, satIOContext);*/ 15521 15522 15523 SM_DBG1(("smsatWriteAndVerify12: return LBA out of range, not EXT!!!\n")); 15524 15525 smsatSetSensePayload( pSense, 15526 SCSI_SNSKEY_ILLEGAL_REQUEST, 15527 0, 15528 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 15529 satIOContext); 15530 15531 /*smEnqueueIO(smRoot, satIOContext);*/ 15532 15533 tdsmIOCompletedCB( smRoot, 15534 smIORequest, 15535 smIOSuccess, 15536 SCSI_STAT_CHECK_CONDITION, 15537 satIOContext->pSmSenseData, 15538 satIOContext->interruptContext ); 15539 15540 return SM_RC_SUCCESS; 15541 } 15542 } 15543 else 15544 { 15545 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 15546 if (AllChk) 15547 { 15548 SM_DBG1(("smsatWriteAndVerify12: return LBA out of range, EXT!!!\n")); 15549 smsatSetSensePayload( pSense, 15550 SCSI_SNSKEY_ILLEGAL_REQUEST, 15551 0, 15552 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 15553 satIOContext); 15554 tdsmIOCompletedCB( smRoot, 15555 smIORequest, 15556 smIOSuccess, 15557 SCSI_STAT_CHECK_CONDITION, 15558 satIOContext->pSmSenseData, 15559 satIOContext->interruptContext ); 15560 return SM_RC_SUCCESS; 15561 } 15562 } 15563 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 15564 { 15565 /* case 2 */ 15566 /* WRITE DMA*/ 15567 /* In case that we can't fit the transfer length, we loop */ 15568 SM_DBG5(("smsatWriteAndVerify12: case 2\n")); 15569 fis->h.fisType = 0x27; /* Reg host to device */ 15570 fis->h.c_pmPort = 0x80; /* C bit is set */ 15571 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 15572 fis->h.features = 0; /* FIS reserve */ 15573 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15574 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15575 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15576 15577 /* FIS LBA mode set LBA (27:24) */ 15578 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 15579 15580 fis->d.lbaLowExp = 0; 15581 fis->d.lbaMidExp = 0; 15582 fis->d.lbaHighExp = 0; 15583 fis->d.featuresExp = 0; 15584 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 15585 fis->d.sectorCountExp = 0; 15586 fis->d.reserved4 = 0; 15587 fis->d.control = 0; /* FIS HOB bit clear */ 15588 fis->d.reserved5 = 0; 15589 15590 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 15591 satIOContext->ATACmd = SAT_WRITE_DMA; 15592 } 15593 else 15594 { 15595 /* case 1 */ 15596 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 15597 /* WRITE SECTORS for easier implemetation */ 15598 /* In case that we can't fit the transfer length, we loop */ 15599 SM_DBG5(("smsatWriteAndVerify12: case 1\n")); 15600 fis->h.fisType = 0x27; /* Reg host to device */ 15601 fis->h.c_pmPort = 0x80; /* C bit is set */ 15602 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 15603 fis->h.features = 0; /* FIS reserve */ 15604 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15605 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15606 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15607 15608 /* FIS LBA mode set LBA (27:24) */ 15609 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 15610 15611 fis->d.lbaLowExp = 0; 15612 fis->d.lbaMidExp = 0; 15613 fis->d.lbaHighExp = 0; 15614 fis->d.featuresExp = 0; 15615 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 15616 fis->d.sectorCountExp = 0; 15617 fis->d.reserved4 = 0; 15618 fis->d.control = 0; /* FIS HOB bit clear */ 15619 fis->d.reserved5 = 0; 15620 15621 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 15622 satIOContext->ATACmd = SAT_WRITE_SECTORS; 15623 } 15624 15625 /* case 3 and 4 */ 15626 if (pSatDevData->sat48BitSupport == agTRUE) 15627 { 15628 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 15629 { 15630 /* case 3 */ 15631 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 15632 SM_DBG5(("smsatWriteAndVerify12: case 3\n")); 15633 fis->h.fisType = 0x27; /* Reg host to device */ 15634 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15635 15636 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 15637 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 15638 15639 fis->h.features = 0; /* FIS reserve */ 15640 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15641 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15642 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15643 fis->d.device = 0x40; /* FIS LBA mode set */ 15644 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 15645 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 15646 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 15647 fis->d.featuresExp = 0; /* FIS reserve */ 15648 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 15649 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 15650 fis->d.reserved4 = 0; 15651 fis->d.control = 0; /* FIS HOB bit clear */ 15652 fis->d.reserved5 = 0; 15653 15654 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 15655 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 15656 } 15657 else 15658 { 15659 /* case 4 */ 15660 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 15661 /* WRITE SECTORS EXT for easier implemetation */ 15662 SM_DBG5(("smsatWriteAndVerify12: case 4\n")); 15663 fis->h.fisType = 0x27; /* Reg host to device */ 15664 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15665 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 15666 15667 fis->h.features = 0; /* FIS reserve */ 15668 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15669 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15670 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15671 fis->d.device = 0x40; /* FIS LBA mode set */ 15672 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 15673 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 15674 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 15675 fis->d.featuresExp = 0; /* FIS reserve */ 15676 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 15677 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 15678 fis->d.reserved4 = 0; 15679 fis->d.control = 0; /* FIS HOB bit clear */ 15680 fis->d.reserved5 = 0; 15681 15682 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 15683 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 15684 } 15685 } 15686 15687 /* case 5 */ 15688 if (pSatDevData->satNCQ == agTRUE) 15689 { 15690 /* WRITE FPDMA QUEUED */ 15691 if (pSatDevData->sat48BitSupport != agTRUE) 15692 { 15693 SM_DBG1(("smsatWriteAndVerify12: case 5 !!! error NCQ but 28 bit address support!!!\n")); 15694 smsatSetSensePayload( pSense, 15695 SCSI_SNSKEY_ILLEGAL_REQUEST, 15696 0, 15697 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15698 satIOContext); 15699 15700 /*smEnqueueIO(smRoot, satIOContext);*/ 15701 15702 tdsmIOCompletedCB( smRoot, 15703 smIORequest, 15704 smIOSuccess, 15705 SCSI_STAT_CHECK_CONDITION, 15706 satIOContext->pSmSenseData, 15707 satIOContext->interruptContext ); 15708 return SM_RC_SUCCESS; 15709 } 15710 SM_DBG6(("smsatWriteAndVerify12: case 5\n")); 15711 15712 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 15713 15714 fis->h.fisType = 0x27; /* Reg host to device */ 15715 fis->h.c_pmPort = 0x80; /* C Bit is set */ 15716 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 15717 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */ 15718 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 15719 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 15720 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 15721 15722 /* Check FUA bit */ 15723 if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK) 15724 fis->d.device = 0xC0; /* FIS FUA set */ 15725 else 15726 fis->d.device = 0x40; /* FIS FUA clear */ 15727 15728 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 15729 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 15730 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 15731 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */ 15732 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 15733 fis->d.sectorCountExp = 0; 15734 fis->d.reserved4 = 0; 15735 fis->d.control = 0; /* FIS HOB bit clear */ 15736 fis->d.reserved5 = 0; 15737 15738 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 15739 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 15740 } 15741 15742 satIOContext->currentLBA = lba; 15743 // satIOContext->OrgLBA = lba; 15744 satIOContext->OrgTL = tl; 15745 15746 /* 15747 computing number of loop and remainder for tl 15748 0xFF in case not ext 15749 0xFFFF in case EXT 15750 */ 15751 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 15752 { 15753 LoopNum = smsatComputeLoopNum(tl, 0xFF); 15754 } 15755 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 15756 fis->h.command == SAT_WRITE_DMA_EXT || 15757 fis->h.command == SAT_WRITE_DMA_FUA_EXT 15758 ) 15759 { 15760 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 15761 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 15762 } 15763 else 15764 { 15765 /* SAT_WRITE_FPDMA_QUEUEDK */ 15766 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 15767 } 15768 15769 satIOContext->LoopNum = LoopNum; 15770 satIOContext->LoopNum2 = LoopNum; 15771 15772 15773 if (LoopNum == 1) 15774 { 15775 SM_DBG5(("smsatWriteAndVerify12: NON CHAINED data\n")); 15776 /* Initialize CB for SATA completion. 15777 */ 15778 satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB; 15779 } 15780 else 15781 { 15782 SM_DBG1(("smsatWriteAndVerify12: CHAINED data!!!\n")); 15783 /* re-setting tl */ 15784 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 15785 { 15786 fis->d.sectorCount = 0xFF; 15787 } 15788 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 15789 fis->h.command == SAT_WRITE_DMA_EXT || 15790 fis->h.command == SAT_WRITE_DMA_FUA_EXT 15791 ) 15792 { 15793 fis->d.sectorCount = 0xFF; 15794 fis->d.sectorCountExp = 0xFF; 15795 } 15796 else 15797 { 15798 /* SAT_WRITE_FPDMA_QUEUED */ 15799 fis->h.features = 0xFF; 15800 fis->d.featuresExp = 0xFF; 15801 } 15802 15803 /* Initialize CB for SATA completion. 15804 */ 15805 satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB; 15806 } 15807 15808 15809 /* 15810 * Prepare SGL and send FIS to LL layer. 15811 */ 15812 satIOContext->reqType = agRequestType; /* Save it */ 15813 15814 status = smsataLLIOStart( smRoot, 15815 smIORequest, 15816 smDeviceHandle, 15817 smScsiRequest, 15818 satIOContext); 15819 return (status); 15820 } 15821 15822 osGLOBAL bit32 15823 smsatWriteAndVerify16( 15824 smRoot_t *smRoot, 15825 smIORequest_t *smIORequest, 15826 smDeviceHandle_t *smDeviceHandle, 15827 smScsiInitiatorRequest_t *smScsiRequest, 15828 smSatIOContext_t *satIOContext 15829 ) 15830 { 15831 /* 15832 combination of write16 and verify16 15833 since write16 has 8 bytes LBA -> problem ATA LBA(upto 6 bytes), no support 15834 */ 15835 bit32 status; 15836 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 15837 smDeviceData_t *pSatDevData; 15838 smScsiRspSense_t *pSense; 15839 smIniScsiCmnd_t *scsiCmnd; 15840 agsaFisRegHostToDevice_t *fis; 15841 bit32 lba = 0; 15842 bit32 tl = 0; 15843 bit32 LoopNum = 1; 15844 bit8 LBA[8]; 15845 bit8 TL[8]; 15846 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */ 15847 15848 pSense = satIOContext->pSense; 15849 pSatDevData = satIOContext->pSatDevData; 15850 scsiCmnd = &smScsiRequest->scsiCmnd; 15851 fis = satIOContext->pFis; 15852 15853 SM_DBG5(("smsatWriteAndVerify16: start\n")); 15854 15855 /* checking BYTCHK bit */ 15856 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK) 15857 { 15858 smsatSetSensePayload( pSense, 15859 SCSI_SNSKEY_ILLEGAL_REQUEST, 15860 0, 15861 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15862 satIOContext); 15863 15864 /*smEnqueueIO(smRoot, satIOContext);*/ 15865 15866 tdsmIOCompletedCB( smRoot, 15867 smIORequest, 15868 smIOSuccess, 15869 SCSI_STAT_CHECK_CONDITION, 15870 satIOContext->pSmSenseData, 15871 satIOContext->interruptContext ); 15872 15873 SM_DBG1(("smsatWriteAndVerify16: BYTCHK bit checking!!!\n")); 15874 return SM_RC_SUCCESS; 15875 } 15876 15877 15878 /* checking CONTROL */ 15879 /* NACA == 1 or LINK == 1*/ 15880 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) ) 15881 { 15882 smsatSetSensePayload( pSense, 15883 SCSI_SNSKEY_ILLEGAL_REQUEST, 15884 0, 15885 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 15886 satIOContext); 15887 15888 /*smEnqueueIO(smRoot, satIOContext);*/ 15889 15890 tdsmIOCompletedCB( smRoot, 15891 smIORequest, 15892 smIOSuccess, 15893 SCSI_STAT_CHECK_CONDITION, 15894 satIOContext->pSmSenseData, 15895 satIOContext->interruptContext ); 15896 15897 SM_DBG1(("smsatWriteAndVerify16: return control!!!\n")); 15898 return SM_RC_SUCCESS; 15899 } 15900 15901 sm_memset(LBA, 0, sizeof(LBA)); 15902 sm_memset(TL, 0, sizeof(TL)); 15903 15904 15905 /* do not use memcpy due to indexing in LBA and TL */ 15906 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 15907 LBA[1] = scsiCmnd->cdb[3]; 15908 LBA[2] = scsiCmnd->cdb[4]; 15909 LBA[3] = scsiCmnd->cdb[5]; 15910 LBA[4] = scsiCmnd->cdb[6]; 15911 LBA[5] = scsiCmnd->cdb[7]; 15912 LBA[6] = scsiCmnd->cdb[8]; 15913 LBA[7] = scsiCmnd->cdb[9]; /* LSB */ 15914 15915 TL[0] = 0; 15916 TL[1] = 0; 15917 TL[2] = 0; 15918 TL[3] = 0; 15919 TL[4] = scsiCmnd->cdb[10]; /* MSB */ 15920 TL[5] = scsiCmnd->cdb[11]; 15921 TL[6] = scsiCmnd->cdb[12]; 15922 TL[7] = scsiCmnd->cdb[13]; /* LSB */ 15923 15924 15925 15926 lba = smsatComputeCDB16LBA(satIOContext); 15927 tl = smsatComputeCDB16TL(satIOContext); 15928 15929 15930 /* Table 34, 9.1, p 46 */ 15931 /* 15932 note: As of 2/10/2006, no support for DMA QUEUED 15933 */ 15934 15935 /* 15936 Table 34, 9.1, p 46, b 15937 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1), 15938 return check condition 15939 */ 15940 if (pSatDevData->satNCQ != agTRUE && 15941 pSatDevData->sat48BitSupport != agTRUE 15942 ) 15943 { 15944 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData); 15945 if (AllChk) 15946 { 15947 SM_DBG1(("smsatWriteAndVerify16: return LBA out of range, not EXT!!!\n")); 15948 smsatSetSensePayload( pSense, 15949 SCSI_SNSKEY_ILLEGAL_REQUEST, 15950 0, 15951 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 15952 satIOContext); 15953 15954 /*smEnqueueIO(smRoot, satIOContext);*/ 15955 15956 tdsmIOCompletedCB( smRoot, 15957 smIORequest, 15958 smIOSuccess, 15959 SCSI_STAT_CHECK_CONDITION, 15960 satIOContext->pSmSenseData, 15961 satIOContext->interruptContext ); 15962 15963 return SM_RC_SUCCESS; 15964 } 15965 } 15966 else 15967 { 15968 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData); 15969 if (AllChk) 15970 { 15971 SM_DBG1(("smsatWriteAndVerify16: return LBA out of range, EXT!!!\n")); 15972 smsatSetSensePayload( pSense, 15973 SCSI_SNSKEY_ILLEGAL_REQUEST, 15974 0, 15975 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 15976 satIOContext); 15977 15978 /*smEnqueueIO(smRoot, satIOContext);*/ 15979 15980 tdsmIOCompletedCB( smRoot, 15981 smIORequest, 15982 smIOSuccess, 15983 SCSI_STAT_CHECK_CONDITION, 15984 satIOContext->pSmSenseData, 15985 satIOContext->interruptContext ); 15986 15987 return SM_RC_SUCCESS; 15988 } 15989 } 15990 15991 15992 /* case 1 and 2 */ 15993 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 15994 { 15995 /* case 2 */ 15996 /* WRITE DMA*/ 15997 /* In case that we can't fit the transfer length, we loop */ 15998 SM_DBG5(("smsatWriteAndVerify16: case 2\n")); 15999 fis->h.fisType = 0x27; /* Reg host to device */ 16000 fis->h.c_pmPort = 0x80; /* C bit is set */ 16001 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 16002 fis->h.features = 0; /* FIS reserve */ 16003 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 16004 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 16005 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 16006 16007 /* FIS LBA mode set LBA (27:24) */ 16008 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); 16009 16010 fis->d.lbaLowExp = 0; 16011 fis->d.lbaMidExp = 0; 16012 fis->d.lbaHighExp = 0; 16013 fis->d.featuresExp = 0; 16014 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 16015 fis->d.sectorCountExp = 0; 16016 fis->d.reserved4 = 0; 16017 fis->d.control = 0; /* FIS HOB bit clear */ 16018 fis->d.reserved5 = 0; 16019 16020 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 16021 satIOContext->ATACmd = SAT_WRITE_DMA; 16022 } 16023 else 16024 { 16025 /* case 1 */ 16026 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 16027 /* WRITE SECTORS for easier implemetation */ 16028 /* In case that we can't fit the transfer length, we loop */ 16029 SM_DBG5(("smsatWriteAndVerify16: case 1\n")); 16030 fis->h.fisType = 0x27; /* Reg host to device */ 16031 fis->h.c_pmPort = 0x80; /* C bit is set */ 16032 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 16033 fis->h.features = 0; /* FIS reserve */ 16034 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 16035 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 16036 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 16037 16038 /* FIS LBA mode set LBA (27:24) */ 16039 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); 16040 16041 fis->d.lbaLowExp = 0; 16042 fis->d.lbaMidExp = 0; 16043 fis->d.lbaHighExp = 0; 16044 fis->d.featuresExp = 0; 16045 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 16046 fis->d.sectorCountExp = 0; 16047 fis->d.reserved4 = 0; 16048 fis->d.control = 0; /* FIS HOB bit clear */ 16049 fis->d.reserved5 = 0; 16050 16051 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 16052 satIOContext->ATACmd = SAT_WRITE_SECTORS; 16053 } 16054 16055 /* case 3 and 4 */ 16056 if (pSatDevData->sat48BitSupport == agTRUE) 16057 { 16058 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 16059 { 16060 /* case 3 */ 16061 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 16062 SM_DBG5(("smsatWriteAndVerify16: case 3\n")); 16063 fis->h.fisType = 0x27; /* Reg host to device */ 16064 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16065 16066 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 16067 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 16068 16069 fis->h.features = 0; /* FIS reserve */ 16070 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 16071 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 16072 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 16073 fis->d.device = 0x40; /* FIS LBA mode set */ 16074 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 16075 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 16076 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 16077 fis->d.featuresExp = 0; /* FIS reserve */ 16078 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 16079 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 16080 fis->d.reserved4 = 0; 16081 fis->d.control = 0; /* FIS HOB bit clear */ 16082 fis->d.reserved5 = 0; 16083 16084 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 16085 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 16086 } 16087 else 16088 { 16089 /* case 4 */ 16090 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 16091 /* WRITE SECTORS EXT for easier implemetation */ 16092 SM_DBG5(("smsatWriteAndVerify16: case 4\n")); 16093 fis->h.fisType = 0x27; /* Reg host to device */ 16094 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16095 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 16096 16097 fis->h.features = 0; /* FIS reserve */ 16098 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 16099 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 16100 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 16101 fis->d.device = 0x40; /* FIS LBA mode set */ 16102 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 16103 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 16104 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 16105 fis->d.featuresExp = 0; /* FIS reserve */ 16106 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 16107 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 16108 fis->d.reserved4 = 0; 16109 fis->d.control = 0; /* FIS HOB bit clear */ 16110 fis->d.reserved5 = 0; 16111 16112 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 16113 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 16114 } 16115 } 16116 16117 /* case 5 */ 16118 if (pSatDevData->satNCQ == agTRUE) 16119 { 16120 /* WRITE FPDMA QUEUED */ 16121 if (pSatDevData->sat48BitSupport != agTRUE) 16122 { 16123 SM_DBG1(("smsatWriteAndVerify16: case 5 !!! error NCQ but 28 bit address support!!!\n")); 16124 smsatSetSensePayload( pSense, 16125 SCSI_SNSKEY_ILLEGAL_REQUEST, 16126 0, 16127 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16128 satIOContext); 16129 16130 /*smEnqueueIO(smRoot, satIOContext);*/ 16131 16132 tdsmIOCompletedCB( smRoot, 16133 smIORequest, 16134 smIOSuccess, 16135 SCSI_STAT_CHECK_CONDITION, 16136 satIOContext->pSmSenseData, 16137 satIOContext->interruptContext ); 16138 return SM_RC_SUCCESS; 16139 } 16140 SM_DBG6(("smsatWriteAndVerify16: case 5\n")); 16141 16142 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 16143 16144 fis->h.fisType = 0x27; /* Reg host to device */ 16145 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16146 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 16147 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */ 16148 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */ 16149 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */ 16150 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */ 16151 16152 /* Check FUA bit */ 16153 if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK) 16154 fis->d.device = 0xC0; /* FIS FUA set */ 16155 else 16156 fis->d.device = 0x40; /* FIS FUA clear */ 16157 16158 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */ 16159 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */ 16160 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */ 16161 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */ 16162 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 16163 fis->d.sectorCountExp = 0; 16164 fis->d.reserved4 = 0; 16165 fis->d.control = 0; /* FIS HOB bit clear */ 16166 fis->d.reserved5 = 0; 16167 16168 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 16169 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 16170 } 16171 16172 satIOContext->currentLBA = lba; 16173 satIOContext->OrgTL = tl; 16174 16175 /* 16176 computing number of loop and remainder for tl 16177 0xFF in case not ext 16178 0xFFFF in case EXT 16179 */ 16180 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 16181 { 16182 LoopNum = smsatComputeLoopNum(tl, 0xFF); 16183 } 16184 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 16185 fis->h.command == SAT_WRITE_DMA_EXT || 16186 fis->h.command == SAT_WRITE_DMA_FUA_EXT 16187 ) 16188 { 16189 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 16190 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 16191 } 16192 else 16193 { 16194 /* SAT_WRITE_FPDMA_QUEUEDK */ 16195 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 16196 } 16197 16198 satIOContext->LoopNum = LoopNum; 16199 16200 16201 if (LoopNum == 1) 16202 { 16203 SM_DBG5(("smsatWriteAndVerify16: NON CHAINED data\n")); 16204 /* Initialize CB for SATA completion. 16205 */ 16206 satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB; 16207 } 16208 else 16209 { 16210 SM_DBG1(("smsatWriteAndVerify16: CHAINED data!!!\n")); 16211 /* re-setting tl */ 16212 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA) 16213 { 16214 fis->d.sectorCount = 0xFF; 16215 } 16216 else if (fis->h.command == SAT_WRITE_SECTORS_EXT || 16217 fis->h.command == SAT_WRITE_DMA_EXT || 16218 fis->h.command == SAT_WRITE_DMA_FUA_EXT 16219 ) 16220 { 16221 fis->d.sectorCount = 0xFF; 16222 fis->d.sectorCountExp = 0xFF; 16223 } 16224 else 16225 { 16226 /* SAT_WRITE_FPDMA_QUEUED */ 16227 fis->h.features = 0xFF; 16228 fis->d.featuresExp = 0xFF; 16229 } 16230 16231 /* Initialize CB for SATA completion. 16232 */ 16233 satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB; 16234 } 16235 16236 16237 /* 16238 * Prepare SGL and send FIS to LL layer. 16239 */ 16240 satIOContext->reqType = agRequestType; /* Save it */ 16241 16242 status = smsataLLIOStart( smRoot, 16243 smIORequest, 16244 smDeviceHandle, 16245 smScsiRequest, 16246 satIOContext); 16247 return (status); 16248 } 16249 16250 osGLOBAL bit32 16251 smsatReadMediaSerialNumber( 16252 smRoot_t *smRoot, 16253 smIORequest_t *smIORequest, 16254 smDeviceHandle_t *smDeviceHandle, 16255 smScsiInitiatorRequest_t *smScsiRequest, 16256 smSatIOContext_t *satIOContext 16257 ) 16258 { 16259 bit32 status; 16260 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 16261 smDeviceData_t *pSatDevData; 16262 smScsiRspSense_t *pSense; 16263 smIniScsiCmnd_t *scsiCmnd; 16264 agsaFisRegHostToDevice_t *fis; 16265 agsaSATAIdentifyData_t *pSATAIdData; 16266 bit8 *pSerialNumber; 16267 bit8 MediaSerialNumber[64] = {0}; 16268 bit32 allocationLen = 0; 16269 16270 pSense = satIOContext->pSense; 16271 pSatDevData = satIOContext->pSatDevData; 16272 scsiCmnd = &smScsiRequest->scsiCmnd; 16273 fis = satIOContext->pFis; 16274 pSATAIdData = &(pSatDevData->satIdentifyData); 16275 pSerialNumber = (bit8 *) smScsiRequest->sglVirtualAddr; 16276 16277 SM_DBG5(("smsatReadMediaSerialNumber: start\n")); 16278 16279 /* checking CONTROL */ 16280 /* NACA == 1 or LINK == 1*/ 16281 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) ) 16282 { 16283 smsatSetSensePayload( pSense, 16284 SCSI_SNSKEY_ILLEGAL_REQUEST, 16285 0, 16286 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16287 satIOContext); 16288 16289 /*smEnqueueIO(smRoot, satIOContext);*/ 16290 16291 tdsmIOCompletedCB( smRoot, 16292 smIORequest, 16293 smIOSuccess, 16294 SCSI_STAT_CHECK_CONDITION, 16295 satIOContext->pSmSenseData, 16296 satIOContext->interruptContext ); 16297 16298 SM_DBG1(("smsatReadMediaSerialNumber: return control!!!\n")); 16299 return SM_RC_SUCCESS; 16300 } 16301 16302 allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) | 16303 (((bit32)scsiCmnd->cdb[7]) << 16) | 16304 (((bit32)scsiCmnd->cdb[8]) << 8 ) | 16305 (((bit32)scsiCmnd->cdb[9])); 16306 allocationLen = MIN(allocationLen, scsiCmnd->expDataLength); 16307 if (allocationLen == 4) 16308 { 16309 if (pSATAIdData->commandSetFeatureDefault & 0x4) 16310 { 16311 SM_DBG1(("smsatReadMediaSerialNumber: Media serial number returning only length!!!\n")); 16312 /* SPC-3 6.16 p192; filling in length */ 16313 MediaSerialNumber[0] = 0; 16314 MediaSerialNumber[1] = 0; 16315 MediaSerialNumber[2] = 0; 16316 MediaSerialNumber[3] = 0x3C; 16317 } 16318 else 16319 { 16320 /* 1 sector - 4 = 512 - 4 to avoid underflow; 0x1fc*/ 16321 MediaSerialNumber[0] = 0; 16322 MediaSerialNumber[1] = 0; 16323 MediaSerialNumber[2] = 0x1; 16324 MediaSerialNumber[3] = 0xfc; 16325 } 16326 16327 sm_memcpy(pSerialNumber, MediaSerialNumber, 4); 16328 /*smEnqueueIO(smRoot, satIOContext);*/ 16329 16330 tdsmIOCompletedCB( smRoot, 16331 smIORequest, 16332 smIOSuccess, 16333 SCSI_STAT_GOOD, 16334 agNULL, 16335 satIOContext->interruptContext); 16336 16337 return SM_RC_SUCCESS; 16338 } 16339 16340 if ( pSatDevData->IDDeviceValid == agTRUE) 16341 { 16342 if (pSATAIdData->commandSetFeatureDefault & 0x4) 16343 { 16344 /* word87 bit2 Media serial number is valid */ 16345 /* read word 176 to 205; length is 2*30 = 60 = 0x3C*/ 16346 #ifdef LOG_ENABLE 16347 smhexdump("ID smsatReadMediaSerialNumber", (bit8*)pSATAIdData->currentMediaSerialNumber, 2*30); 16348 #endif 16349 /* SPC-3 6.16 p192; filling in length */ 16350 MediaSerialNumber[0] = 0; 16351 MediaSerialNumber[1] = 0; 16352 MediaSerialNumber[2] = 0; 16353 MediaSerialNumber[3] = 0x3C; 16354 sm_memcpy(&MediaSerialNumber[4], (void *)pSATAIdData->currentMediaSerialNumber, 60); 16355 #ifdef LOG_ENABLE 16356 smhexdump("smsatReadMediaSerialNumber", (bit8*)MediaSerialNumber, 2*30 + 4); 16357 #endif 16358 sm_memcpy(pSerialNumber, MediaSerialNumber, MIN(allocationLen, 64)); 16359 /*smEnqueueIO(smRoot, satIOContext);*/ 16360 16361 tdsmIOCompletedCB( smRoot, 16362 smIORequest, 16363 smIOSuccess, 16364 SCSI_STAT_GOOD, 16365 agNULL, 16366 satIOContext->interruptContext); 16367 return SM_RC_SUCCESS; 16368 16369 16370 } 16371 else 16372 { 16373 /* word87 bit2 Media serial number is NOT valid */ 16374 SM_DBG1(("smsatReadMediaSerialNumber: Media serial number is NOT valid!!!\n")); 16375 16376 if (pSatDevData->sat48BitSupport == agTRUE) 16377 { 16378 /* READ VERIFY SECTORS EXT */ 16379 fis->h.fisType = 0x27; /* Reg host to device */ 16380 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16381 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 16382 16383 fis->h.features = 0; /* FIS reserve */ 16384 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 16385 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 16386 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 16387 fis->d.device = 0x40; /* FIS LBA mode set */ 16388 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 16389 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 16390 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 16391 fis->d.featuresExp = 0; /* FIS reserve */ 16392 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 16393 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 16394 fis->d.reserved4 = 0; 16395 fis->d.control = 0; /* FIS HOB bit clear */ 16396 fis->d.reserved5 = 0; 16397 16398 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 16399 } 16400 else 16401 { 16402 /* READ VERIFY SECTORS */ 16403 fis->h.fisType = 0x27; /* Reg host to device */ 16404 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16405 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 16406 fis->h.features = 0; /* FIS reserve */ 16407 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 16408 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 16409 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 16410 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */ 16411 fis->d.lbaLowExp = 0; 16412 fis->d.lbaMidExp = 0; 16413 fis->d.lbaHighExp = 0; 16414 fis->d.featuresExp = 0; 16415 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 16416 fis->d.sectorCountExp = 0; 16417 fis->d.reserved4 = 0; 16418 fis->d.control = 0; /* FIS HOB bit clear */ 16419 fis->d.reserved5 = 0; 16420 16421 16422 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 16423 } 16424 satIOContext->satCompleteCB = &smsatReadMediaSerialNumberCB; 16425 satIOContext->reqType = agRequestType; /* Save it */ 16426 status = smsataLLIOStart( smRoot, 16427 smIORequest, 16428 smDeviceHandle, 16429 smScsiRequest, 16430 satIOContext); 16431 16432 return status; 16433 } 16434 } 16435 else 16436 { 16437 16438 tdsmIOCompletedCB( smRoot, 16439 smIORequest, 16440 smIOFailed, 16441 smDetailOtherError, 16442 agNULL, 16443 satIOContext->interruptContext); 16444 16445 return SM_RC_SUCCESS; 16446 16447 } 16448 } 16449 16450 osGLOBAL bit32 16451 smsatReadBuffer( 16452 smRoot_t *smRoot, 16453 smIORequest_t *smIORequest, 16454 smDeviceHandle_t *smDeviceHandle, 16455 smScsiInitiatorRequest_t *smScsiRequest, 16456 smSatIOContext_t *satIOContext 16457 ) 16458 { 16459 bit32 status = SM_RC_SUCCESS; 16460 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 16461 smScsiRspSense_t *pSense; 16462 smIniScsiCmnd_t *scsiCmnd; 16463 agsaFisRegHostToDevice_t *fis; 16464 bit32 bufferOffset; 16465 bit32 tl; 16466 bit8 mode; 16467 bit8 bufferID; 16468 bit8 *pBuff; 16469 16470 pSense = satIOContext->pSense; 16471 scsiCmnd = &smScsiRequest->scsiCmnd; 16472 fis = satIOContext->pFis; 16473 pBuff = (bit8 *) smScsiRequest->sglVirtualAddr; 16474 16475 SM_DBG5(("smsatReadBuffer: start\n")); 16476 16477 /* checking CONTROL */ 16478 /* NACA == 1 or LINK == 1*/ 16479 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 16480 { 16481 smsatSetSensePayload( pSense, 16482 SCSI_SNSKEY_ILLEGAL_REQUEST, 16483 0, 16484 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16485 satIOContext); 16486 16487 /*smEnqueueIO(smRoot, satIOContext);*/ 16488 16489 tdsmIOCompletedCB( smRoot, 16490 smIORequest, 16491 smIOSuccess, 16492 SCSI_STAT_CHECK_CONDITION, 16493 satIOContext->pSmSenseData, 16494 satIOContext->interruptContext ); 16495 16496 SM_DBG1(("smsatReadBuffer: return control!!!\n")); 16497 return SM_RC_SUCCESS; 16498 } 16499 16500 bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 16501 tl = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 16502 16503 mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK); 16504 bufferID = scsiCmnd->cdb[2]; 16505 16506 if (mode == READ_BUFFER_DATA_MODE) /* 2 */ 16507 { 16508 if (bufferID == 0 && bufferOffset == 0 && tl == 512) 16509 { 16510 /* send ATA READ BUFFER */ 16511 fis->h.fisType = 0x27; /* Reg host to device */ 16512 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16513 fis->h.command = SAT_READ_BUFFER; /* 0xE4 */ 16514 fis->h.features = 0; /* FIS reserve */ 16515 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 16516 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 16517 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 16518 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */ 16519 fis->d.lbaLowExp = 0; 16520 fis->d.lbaMidExp = 0; 16521 fis->d.lbaHighExp = 0; 16522 fis->d.featuresExp = 0; 16523 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 16524 fis->d.sectorCountExp = 0; 16525 fis->d.reserved4 = 0; 16526 fis->d.control = 0; /* FIS HOB bit clear */ 16527 fis->d.reserved5 = 0; 16528 16529 16530 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 16531 16532 satIOContext->satCompleteCB = &smsatReadBufferCB; 16533 16534 satIOContext->reqType = agRequestType; /* Save it */ 16535 16536 status = smsataLLIOStart( smRoot, 16537 smIORequest, 16538 smDeviceHandle, 16539 smScsiRequest, 16540 satIOContext); 16541 return status; 16542 } 16543 16544 if (bufferID == 0 && bufferOffset == 0 && tl != 512) 16545 { 16546 smsatSetSensePayload( pSense, 16547 SCSI_SNSKEY_ILLEGAL_REQUEST, 16548 0, 16549 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16550 satIOContext); 16551 16552 /*smEnqueueIO(smRoot, satIOContext);*/ 16553 16554 tdsmIOCompletedCB( smRoot, 16555 smIORequest, 16556 smIOSuccess, 16557 SCSI_STAT_CHECK_CONDITION, 16558 satIOContext->pSmSenseData, 16559 satIOContext->interruptContext ); 16560 16561 SM_DBG1(("smsatReadBuffer: allocation length is not 512; it is %d!!!\n", tl)); 16562 return SM_RC_SUCCESS; 16563 } 16564 16565 if (bufferID == 0 && bufferOffset != 0) 16566 { 16567 smsatSetSensePayload( pSense, 16568 SCSI_SNSKEY_ILLEGAL_REQUEST, 16569 0, 16570 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16571 satIOContext); 16572 16573 /*smEnqueueIO(smRoot, satIOContext);*/ 16574 16575 tdsmIOCompletedCB( smRoot, 16576 smIORequest, 16577 smIOSuccess, 16578 SCSI_STAT_CHECK_CONDITION, 16579 satIOContext->pSmSenseData, 16580 satIOContext->interruptContext ); 16581 16582 SM_DBG1(("smsatReadBuffer: buffer offset is not 0; it is %d!!!\n", bufferOffset)); 16583 return SM_RC_SUCCESS; 16584 } 16585 /* all other cases unsupported */ 16586 SM_DBG1(("smsatReadBuffer: unsupported case 1!!!\n")); 16587 smsatSetSensePayload( pSense, 16588 SCSI_SNSKEY_ILLEGAL_REQUEST, 16589 0, 16590 SCSI_SNSCODE_INVALID_COMMAND, 16591 satIOContext); 16592 16593 /*smEnqueueIO(smRoot, satIOContext);*/ 16594 16595 tdsmIOCompletedCB( smRoot, 16596 smIORequest, 16597 smIOSuccess, 16598 SCSI_STAT_CHECK_CONDITION, 16599 satIOContext->pSmSenseData, 16600 satIOContext->interruptContext ); 16601 16602 return SM_RC_SUCCESS; 16603 16604 } 16605 else if (mode == READ_BUFFER_DESCRIPTOR_MODE) /* 3 */ 16606 { 16607 if (tl < READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN) /* 4 */ 16608 { 16609 smsatSetSensePayload( pSense, 16610 SCSI_SNSKEY_ILLEGAL_REQUEST, 16611 0, 16612 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16613 satIOContext); 16614 16615 /*smEnqueueIO(smRoot, satIOContext);*/ 16616 16617 tdsmIOCompletedCB( smRoot, 16618 smIORequest, 16619 smIOSuccess, 16620 SCSI_STAT_CHECK_CONDITION, 16621 satIOContext->pSmSenseData, 16622 satIOContext->interruptContext ); 16623 16624 SM_DBG1(("smsatReadBuffer: tl < 4; tl is %d!!!\n", tl)); 16625 return SM_RC_SUCCESS; 16626 } 16627 if (bufferID == 0) 16628 { 16629 /* SPC-4, 6.15.5, p189; SAT-2 Rev00, 8.7.2.3, p41*/ 16630 pBuff[0] = 0xFF; 16631 pBuff[1] = 0x00; 16632 pBuff[2] = 0x02; 16633 pBuff[3] = 0x00; 16634 if (READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN < tl) 16635 { 16636 /* underrrun */ 16637 SM_DBG1(("smsatReadBuffer: underrun tl %d data %d!!!\n", tl, READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN)); 16638 /*smEnqueueIO(smRoot, satIOContext);*/ 16639 16640 tdsmIOCompletedCB( smRoot, 16641 smIORequest, 16642 smIOUnderRun, 16643 tl - READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN, 16644 agNULL, 16645 satIOContext->interruptContext ); 16646 16647 return SM_RC_SUCCESS; 16648 } 16649 else 16650 { 16651 /*smEnqueueIO(smRoot, satIOContext);*/ 16652 16653 tdsmIOCompletedCB( smRoot, 16654 smIORequest, 16655 smIOSuccess, 16656 SCSI_STAT_GOOD, 16657 agNULL, 16658 satIOContext->interruptContext); 16659 return SM_RC_SUCCESS; 16660 } 16661 } 16662 else 16663 { 16664 /* We don't support other than bufferID 0 */ 16665 smsatSetSensePayload( pSense, 16666 SCSI_SNSKEY_ILLEGAL_REQUEST, 16667 0, 16668 SCSI_SNSCODE_INVALID_COMMAND, 16669 satIOContext); 16670 16671 /*smEnqueueIO(smRoot, satIOContext);*/ 16672 16673 tdsmIOCompletedCB( smRoot, 16674 smIORequest, 16675 smIOSuccess, 16676 SCSI_STAT_CHECK_CONDITION, 16677 satIOContext->pSmSenseData, 16678 satIOContext->interruptContext ); 16679 16680 return SM_RC_SUCCESS; 16681 } 16682 } 16683 else 16684 { 16685 /* We don't support any other mode */ 16686 SM_DBG1(("smsatReadBuffer: unsupported mode %d!!!\n", mode)); 16687 smsatSetSensePayload( pSense, 16688 SCSI_SNSKEY_ILLEGAL_REQUEST, 16689 0, 16690 SCSI_SNSCODE_INVALID_COMMAND, 16691 satIOContext); 16692 16693 /*smEnqueueIO(smRoot, satIOContext);*/ 16694 16695 tdsmIOCompletedCB( smRoot, 16696 smIORequest, 16697 smIOSuccess, 16698 SCSI_STAT_CHECK_CONDITION, 16699 satIOContext->pSmSenseData, 16700 satIOContext->interruptContext ); 16701 16702 return SM_RC_SUCCESS; 16703 } 16704 } 16705 16706 osGLOBAL bit32 16707 smsatWriteBuffer( 16708 smRoot_t *smRoot, 16709 smIORequest_t *smIORequest, 16710 smDeviceHandle_t *smDeviceHandle, 16711 smScsiInitiatorRequest_t *smScsiRequest, 16712 smSatIOContext_t *satIOContext 16713 ) 16714 { 16715 #ifdef NOT_YET 16716 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 16717 #endif 16718 smScsiRspSense_t *pSense; 16719 smIniScsiCmnd_t *scsiCmnd; 16720 #ifdef NOT_YET 16721 agsaFisRegHostToDevice_t *fis; 16722 #endif 16723 bit32 bufferOffset; 16724 bit32 parmLen; 16725 bit8 mode; 16726 bit8 bufferID; 16727 bit8 *pBuff; 16728 16729 pSense = satIOContext->pSense; 16730 scsiCmnd = &smScsiRequest->scsiCmnd; 16731 #ifdef NOT_YET 16732 fis = satIOContext->pFis; 16733 #endif 16734 pBuff = (bit8 *) smScsiRequest->sglVirtualAddr; 16735 16736 SM_DBG5(("smsatWriteBuffer: start\n")); 16737 16738 /* checking CONTROL */ 16739 /* NACA == 1 or LINK == 1*/ 16740 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) ) 16741 { 16742 smsatSetSensePayload( pSense, 16743 SCSI_SNSKEY_ILLEGAL_REQUEST, 16744 0, 16745 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16746 satIOContext); 16747 16748 /*smEnqueueIO(smRoot, satIOContext);*/ 16749 16750 tdsmIOCompletedCB( smRoot, 16751 smIORequest, 16752 smIOSuccess, 16753 SCSI_STAT_CHECK_CONDITION, 16754 satIOContext->pSmSenseData, 16755 satIOContext->interruptContext ); 16756 16757 SM_DBG1(("smsatWriteBuffer: return control!!!\n")); 16758 return SM_RC_SUCCESS; 16759 } 16760 16761 bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 16762 parmLen = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 16763 16764 mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK); 16765 bufferID = scsiCmnd->cdb[2]; 16766 16767 /* for debugging only */ 16768 smhexdump("smsatWriteBuffer pBuff", (bit8 *)pBuff, 24); 16769 16770 if (mode == WRITE_BUFFER_DATA_MODE) /* 2 */ 16771 { 16772 if (bufferID == 0 && bufferOffset == 0 && parmLen == 512) 16773 { 16774 SM_DBG1(("smsatWriteBuffer: sending ATA WRITE BUFFER!!!\n")); 16775 /* send ATA WRITE BUFFER */ 16776 #ifdef NOT_YET 16777 fis->h.fisType = 0x27; /* Reg host to device */ 16778 fis->h.c_pmPort = 0x80; /* C Bit is set */ 16779 fis->h.command = SAT_WRITE_BUFFER; /* 0xE8 */ 16780 fis->h.features = 0; /* FIS reserve */ 16781 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 16782 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 16783 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 16784 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */ 16785 fis->d.lbaLowExp = 0; 16786 fis->d.lbaMidExp = 0; 16787 fis->d.lbaHighExp = 0; 16788 fis->d.featuresExp = 0; 16789 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 16790 fis->d.sectorCountExp = 0; 16791 fis->d.reserved4 = 0; 16792 fis->d.control = 0; /* FIS HOB bit clear */ 16793 fis->d.reserved5 = 0; 16794 16795 16796 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 16797 16798 satIOContext->satCompleteCB = &smsatWriteBufferCB; 16799 16800 satIOContext->reqType = agRequestType; /* Save it */ 16801 16802 status = smsataLLIOStart( smRoot, 16803 smIORequest, 16804 smDeviceHandle, 16805 smScsiRequest, 16806 satIOContext); 16807 return status; 16808 #endif 16809 /* temp */ 16810 /*smEnqueueIO(smRoot, satIOContext);*/ 16811 16812 tdsmIOCompletedCB( smRoot, 16813 smIORequest, 16814 smIOSuccess, 16815 SCSI_STAT_GOOD, 16816 agNULL, 16817 satIOContext->interruptContext); 16818 return SM_RC_SUCCESS; 16819 } 16820 if ( (bufferID == 0 && bufferOffset != 0) || 16821 (bufferID == 0 && parmLen != 512) 16822 ) 16823 { 16824 smsatSetSensePayload( pSense, 16825 SCSI_SNSKEY_ILLEGAL_REQUEST, 16826 0, 16827 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16828 satIOContext); 16829 16830 /*smEnqueueIO(smRoot, satIOContext);*/ 16831 16832 tdsmIOCompletedCB( smRoot, 16833 smIORequest, 16834 smIOSuccess, 16835 SCSI_STAT_CHECK_CONDITION, 16836 satIOContext->pSmSenseData, 16837 satIOContext->interruptContext ); 16838 16839 SM_DBG1(("smsatWriteBuffer: wrong buffer offset %d or parameter length parmLen %d!!!\n", bufferOffset, parmLen)); 16840 return SM_RC_SUCCESS; 16841 } 16842 16843 /* all other cases unsupported */ 16844 SM_DBG1(("smsatWriteBuffer: unsupported case 1!!!\n")); 16845 smsatSetSensePayload( pSense, 16846 SCSI_SNSKEY_ILLEGAL_REQUEST, 16847 0, 16848 SCSI_SNSCODE_INVALID_COMMAND, 16849 satIOContext); 16850 16851 /*smEnqueueIO(smRoot, satIOContext);*/ 16852 16853 tdsmIOCompletedCB( smRoot, 16854 smIORequest, 16855 smIOSuccess, 16856 SCSI_STAT_CHECK_CONDITION, 16857 satIOContext->pSmSenseData, 16858 satIOContext->interruptContext ); 16859 16860 return SM_RC_SUCCESS; 16861 16862 } 16863 else if (mode == WRITE_BUFFER_DL_MICROCODE_SAVE_MODE) /* 5 */ 16864 { 16865 /* temporary */ 16866 SM_DBG1(("smsatWriteBuffer: not yet supported mode %d!!!\n", mode)); 16867 smsatSetSensePayload( pSense, 16868 SCSI_SNSKEY_ILLEGAL_REQUEST, 16869 0, 16870 SCSI_SNSCODE_INVALID_COMMAND, 16871 satIOContext); 16872 16873 16874 tdsmIOCompletedCB( smRoot, 16875 smIORequest, 16876 smIOSuccess, 16877 SCSI_STAT_CHECK_CONDITION, 16878 satIOContext->pSmSenseData, 16879 satIOContext->interruptContext ); 16880 16881 return SM_RC_SUCCESS; 16882 } 16883 else 16884 { 16885 /* We don't support any other mode */ 16886 SM_DBG1(("smsatWriteBuffer: unsupported mode %d!!!\n", mode)); 16887 smsatSetSensePayload( pSense, 16888 SCSI_SNSKEY_ILLEGAL_REQUEST, 16889 0, 16890 SCSI_SNSCODE_INVALID_COMMAND, 16891 satIOContext); 16892 16893 /*smEnqueueIO(smRoot, satIOContext);*/ 16894 16895 tdsmIOCompletedCB( smRoot, 16896 smIORequest, 16897 smIOSuccess, 16898 SCSI_STAT_CHECK_CONDITION, 16899 satIOContext->pSmSenseData, 16900 satIOContext->interruptContext ); 16901 16902 return SM_RC_SUCCESS; 16903 } 16904 16905 } 16906 16907 osGLOBAL bit32 16908 smsatReassignBlocks( 16909 smRoot_t *smRoot, 16910 smIORequest_t *smIORequest, 16911 smDeviceHandle_t *smDeviceHandle, 16912 smScsiInitiatorRequest_t *smScsiRequest, 16913 smSatIOContext_t *satIOContext 16914 ) 16915 { 16916 /* 16917 assumes all LBA fits in ATA command; no boundary condition is checked here yet 16918 */ 16919 bit32 status; 16920 bit32 agRequestType; 16921 smDeviceData_t *pSatDevData; 16922 smScsiRspSense_t *pSense; 16923 smIniScsiCmnd_t *scsiCmnd; 16924 agsaFisRegHostToDevice_t *fis; 16925 bit8 *pParmList; /* Log Page data buffer */ 16926 bit8 LongLBA; 16927 bit8 LongList; 16928 bit32 defectListLen; 16929 bit8 LBA[8]; 16930 bit32 startingIndex; 16931 16932 pSense = satIOContext->pSense; 16933 pSatDevData = satIOContext->pSatDevData; 16934 scsiCmnd = &smScsiRequest->scsiCmnd; 16935 fis = satIOContext->pFis; 16936 pParmList = (bit8 *) smScsiRequest->sglVirtualAddr; 16937 16938 SM_DBG5(("smsatReassignBlocks: start\n")); 16939 16940 /* checking CONTROL */ 16941 /* NACA == 1 or LINK == 1*/ 16942 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) ) 16943 { 16944 smsatSetSensePayload( pSense, 16945 SCSI_SNSKEY_ILLEGAL_REQUEST, 16946 0, 16947 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 16948 satIOContext); 16949 16950 /*smEnqueueIO(smRoot, satIOContext);*/ 16951 16952 tdsmIOCompletedCB( smRoot, 16953 smIORequest, 16954 smIOSuccess, 16955 SCSI_STAT_CHECK_CONDITION, 16956 satIOContext->pSmSenseData, 16957 satIOContext->interruptContext ); 16958 16959 SM_DBG1(("smsatReassignBlocks: return control!!!\n")); 16960 return SM_RC_SUCCESS; 16961 } 16962 16963 sm_memset(satIOContext->LBA, 0, 8); 16964 satIOContext->ParmIndex = 0; 16965 satIOContext->ParmLen = 0; 16966 16967 LongList = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLIST_MASK); 16968 LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK); 16969 sm_memset(LBA, 0, sizeof(LBA)); 16970 16971 if (LongList == 0) 16972 { 16973 defectListLen = (pParmList[2] << 8) + pParmList[3]; 16974 } 16975 else 16976 { 16977 defectListLen = (pParmList[0] << (8*3)) + (pParmList[1] << (8*2)) 16978 + (pParmList[2] << 8) + pParmList[3]; 16979 } 16980 /* SBC 5.16.2, p61*/ 16981 satIOContext->ParmLen = defectListLen + 4 /* header size */; 16982 16983 startingIndex = 4; 16984 16985 if (LongLBA == 0) 16986 { 16987 LBA[4] = pParmList[startingIndex]; /* MSB */ 16988 LBA[5] = pParmList[startingIndex+1]; 16989 LBA[6] = pParmList[startingIndex+2]; 16990 LBA[7] = pParmList[startingIndex+3]; /* LSB */ 16991 startingIndex = startingIndex + 4; 16992 } 16993 else 16994 { 16995 LBA[0] = pParmList[startingIndex]; /* MSB */ 16996 LBA[1] = pParmList[startingIndex+1]; 16997 LBA[2] = pParmList[startingIndex+2]; 16998 LBA[3] = pParmList[startingIndex+3]; 16999 LBA[4] = pParmList[startingIndex+4]; 17000 LBA[5] = pParmList[startingIndex+5]; 17001 LBA[6] = pParmList[startingIndex+6]; 17002 LBA[7] = pParmList[startingIndex+7]; /* LSB */ 17003 startingIndex = startingIndex + 8; 17004 } 17005 17006 smhexdump("smsatReassignBlocks Parameter list", (bit8 *)pParmList, 4 + defectListLen); 17007 17008 if (pSatDevData->sat48BitSupport == agTRUE) 17009 { 17010 /* sends READ VERIFY SECTOR(S) EXT*/ 17011 fis->h.fisType = 0x27; /* Reg host to device */ 17012 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17013 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 17014 fis->h.features = 0; /* FIS reserve */ 17015 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 17016 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 17017 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 17018 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */ 17019 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */ 17020 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */ 17021 fis->d.featuresExp = 0; /* FIS reserve */ 17022 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 17023 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 17024 fis->d.reserved4 = 0; 17025 fis->d.device = 0x40; /* 01000000 */ 17026 fis->d.control = 0; /* FIS HOB bit clear */ 17027 fis->d.reserved5 = 0; 17028 } 17029 else 17030 { 17031 /* READ VERIFY SECTOR(S)*/ 17032 fis->h.fisType = 0x27; /* Reg host to device */ 17033 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17034 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 17035 fis->h.features = 0; /* FIS features NA */ 17036 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 17037 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 17038 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 17039 fis->d.lbaLowExp = 0; 17040 fis->d.lbaMidExp = 0; 17041 fis->d.lbaHighExp = 0; 17042 fis->d.featuresExp = 0; 17043 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 17044 fis->d.sectorCountExp = 0; 17045 fis->d.reserved4 = 0; 17046 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF)); 17047 /* DEV and LBA 27:24 */ 17048 fis->d.control = 0; /* FIS HOB bit clear */ 17049 fis->d.reserved5 = 0; 17050 } 17051 17052 sm_memcpy(satIOContext->LBA, LBA, 8); 17053 satIOContext->ParmIndex = startingIndex; 17054 17055 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 17056 17057 /* Initialize CB for SATA completion. 17058 */ 17059 satIOContext->satCompleteCB = &smsatReassignBlocksCB; 17060 17061 /* 17062 * Prepare SGL and send FIS to LL layer. 17063 */ 17064 satIOContext->reqType = agRequestType; /* Save it */ 17065 17066 status = smsataLLIOStart( smRoot, 17067 smIORequest, 17068 smDeviceHandle, 17069 smScsiRequest, 17070 satIOContext); 17071 17072 return status; 17073 } 17074 17075 osGLOBAL bit32 17076 smsatRead_1( 17077 smRoot_t *smRoot, 17078 smIORequest_t *smIORequest, 17079 smDeviceHandle_t *smDeviceHandle, 17080 smScsiInitiatorRequest_t *smScsiRequest, 17081 smSatIOContext_t *satIOContext 17082 ) 17083 { 17084 /* 17085 Assumption: error check on lba and tl has been done in satRead*() 17086 lba = lba + tl; 17087 */ 17088 bit32 status; 17089 smSatIOContext_t *satOrgIOContext = agNULL; 17090 smIniScsiCmnd_t *scsiCmnd; 17091 agsaFisRegHostToDevice_t *fis; 17092 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 17093 bit32 lba = 0; 17094 bit32 DenomTL = 0xFF; 17095 bit32 Remainder = 0; 17096 bit8 LBA[4]; /* 0 MSB, 3 LSB */ 17097 17098 SM_DBG2(("smsatRead_1: start\n")); 17099 17100 fis = satIOContext->pFis; 17101 satOrgIOContext = satIOContext->satOrgIOContext; 17102 scsiCmnd = satOrgIOContext->pScsiCmnd; 17103 17104 sm_memset(LBA,0, sizeof(LBA)); 17105 17106 switch (satOrgIOContext->ATACmd) 17107 { 17108 case SAT_READ_DMA: 17109 DenomTL = 0x100; 17110 break; 17111 case SAT_READ_SECTORS: 17112 DenomTL = 0x100; 17113 break; 17114 case SAT_READ_DMA_EXT: 17115 DenomTL = 0xFFFF; 17116 break; 17117 case SAT_READ_SECTORS_EXT: 17118 DenomTL = 0xFFFF; 17119 break; 17120 case SAT_READ_FPDMA_QUEUED: 17121 DenomTL = 0xFFFF; 17122 break; 17123 default: 17124 SM_DBG1(("smsatRead_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd)); 17125 return SM_RC_FAILURE; 17126 break; 17127 } 17128 17129 Remainder = satOrgIOContext->OrgTL % DenomTL; 17130 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL; 17131 lba = satOrgIOContext->currentLBA; 17132 17133 LBA[0] = (bit8)((lba & 0xFF000000) >> (8 * 3)); 17134 LBA[1] = (bit8)((lba & 0xFF0000) >> (8 * 2)); 17135 LBA[2] = (bit8)((lba & 0xFF00) >> 8); 17136 LBA[3] = (bit8)(lba & 0xFF); 17137 17138 switch (satOrgIOContext->ATACmd) 17139 { 17140 case SAT_READ_DMA: 17141 fis->h.fisType = 0x27; /* Reg host to device */ 17142 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17143 fis->h.command = SAT_READ_DMA; /* 0xC8 */ 17144 fis->h.features = 0; /* FIS reserve */ 17145 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 17146 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 17147 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 17148 fis->d.device = 17149 (bit8)((0x4 << 4) | (LBA[0] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 17150 fis->d.lbaLowExp = 0; 17151 fis->d.lbaMidExp = 0; 17152 fis->d.lbaHighExp = 0; 17153 fis->d.featuresExp = 0; 17154 17155 if (satOrgIOContext->LoopNum == 1) 17156 { 17157 /* last loop */ 17158 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 17159 } 17160 else 17161 { 17162 fis->d.sectorCount = 0x0; /* FIS sector count (7:0) */ 17163 } 17164 17165 fis->d.sectorCountExp = 0; 17166 fis->d.reserved4 = 0; 17167 fis->d.control = 0; /* FIS HOB bit clear */ 17168 fis->d.reserved5 = 0; 17169 17170 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 17171 17172 break; 17173 case SAT_READ_SECTORS: 17174 fis->h.fisType = 0x27; /* Reg host to device */ 17175 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17176 fis->h.command = SAT_READ_SECTORS; /* 0x20 */ 17177 fis->h.features = 0; /* FIS reserve */ 17178 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 17179 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 17180 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 17181 fis->d.device = 17182 (bit8)((0x4 << 4) | (LBA[0] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */ 17183 fis->d.lbaLowExp = 0; 17184 fis->d.lbaMidExp = 0; 17185 fis->d.lbaHighExp = 0; 17186 fis->d.featuresExp = 0; 17187 if (satOrgIOContext->LoopNum == 1) 17188 { 17189 /* last loop */ 17190 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 17191 } 17192 else 17193 { 17194 fis->d.sectorCount = 0x0; /* FIS sector count (7:0) */ 17195 } 17196 fis->d.sectorCountExp = 0; 17197 fis->d.reserved4 = 0; 17198 fis->d.control = 0; /* FIS HOB bit clear */ 17199 fis->d.reserved5 = 0; 17200 17201 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 17202 17203 break; 17204 case SAT_READ_DMA_EXT: 17205 fis->h.fisType = 0x27; /* Reg host to device */ 17206 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17207 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */ 17208 fis->h.features = 0; /* FIS reserve */ 17209 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 17210 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 17211 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 17212 fis->d.device = 0x40; /* FIS LBA mode set */ 17213 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 17214 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 17215 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 17216 fis->d.featuresExp = 0; /* FIS reserve */ 17217 if (satOrgIOContext->LoopNum == 1) 17218 { 17219 /* last loop */ 17220 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 17221 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 17222 17223 } 17224 else 17225 { 17226 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 17227 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 17228 } 17229 fis->d.reserved4 = 0; 17230 fis->d.control = 0; /* FIS HOB bit clear */ 17231 fis->d.reserved5 = 0; 17232 17233 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ; 17234 17235 break; 17236 case SAT_READ_SECTORS_EXT: 17237 fis->h.fisType = 0x27; /* Reg host to device */ 17238 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17239 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */ 17240 fis->h.features = 0; /* FIS reserve */ 17241 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 17242 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 17243 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 17244 fis->d.device = 0x40; /* FIS LBA mode set */ 17245 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 17246 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 17247 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 17248 fis->d.featuresExp = 0; /* FIS reserve */ 17249 if (satOrgIOContext->LoopNum == 1) 17250 { 17251 /* last loop */ 17252 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 17253 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 17254 } 17255 else 17256 { 17257 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 17258 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 17259 } 17260 fis->d.reserved4 = 0; 17261 fis->d.control = 0; /* FIS HOB bit clear */ 17262 fis->d.reserved5 = 0; 17263 17264 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 17265 break; 17266 case SAT_READ_FPDMA_QUEUED: 17267 fis->h.fisType = 0x27; /* Reg host to device */ 17268 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17269 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */ 17270 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 17271 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 17272 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 17273 17274 /* Check FUA bit */ 17275 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK) 17276 fis->d.device = 0xC0; /* FIS FUA set */ 17277 else 17278 fis->d.device = 0x40; /* FIS FUA clear */ 17279 17280 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 17281 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 17282 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 17283 if (satOrgIOContext->LoopNum == 1) 17284 { 17285 /* last loop */ 17286 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 17287 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 17288 } 17289 else 17290 { 17291 fis->h.features = 0xFF; /* FIS sector count (7:0) */ 17292 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */ 17293 } 17294 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 17295 fis->d.sectorCountExp = 0; 17296 fis->d.reserved4 = 0; 17297 fis->d.control = 0; /* FIS HOB bit clear */ 17298 fis->d.reserved5 = 0; 17299 17300 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ; 17301 break; 17302 default: 17303 SM_DBG1(("smsatRead_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd)); 17304 return SM_RC_FAILURE; 17305 break; 17306 } 17307 17308 /* Initialize CB for SATA completion. 17309 */ 17310 /* chained data */ 17311 satIOContext->satCompleteCB = &smsatChainedDataIOCB; 17312 17313 if (satOrgIOContext->ATACmd == SAT_READ_DMA || satOrgIOContext->ATACmd == SAT_READ_SECTORS) 17314 { 17315 smsatSplitSGL(smRoot, 17316 smIORequest, 17317 smDeviceHandle, 17318 (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg, 17319 satOrgIOContext, 17320 NON_BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0x100 * 0x200*/ 17321 (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE, 17322 agFALSE); 17323 } 17324 else 17325 { 17326 smsatSplitSGL(smRoot, 17327 smIORequest, 17328 smDeviceHandle, 17329 (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg, 17330 satOrgIOContext, 17331 BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0xFFFF * 0x200*/ 17332 (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE, 17333 agFALSE); 17334 } 17335 17336 /* 17337 * Prepare SGL and send FIS to LL layer. 17338 */ 17339 satIOContext->reqType = agRequestType; /* Save it */ 17340 17341 status = smsataLLIOStart( smRoot, 17342 smIORequest, 17343 smDeviceHandle, 17344 (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg, //smScsiRequest, 17345 satIOContext); 17346 17347 SM_DBG5(("smsatRead_1: return\n")); 17348 return (status); 17349 } 17350 17351 osGLOBAL bit32 17352 smsatWrite_1( 17353 smRoot_t *smRoot, 17354 smIORequest_t *smIORequest, 17355 smDeviceHandle_t *smDeviceHandle, 17356 smScsiInitiatorRequest_t *smScsiRequest, 17357 smSatIOContext_t *satIOContext 17358 ) 17359 { 17360 /* 17361 Assumption: error check on lba and tl has been done in satWrite*() 17362 lba = lba + tl; 17363 */ 17364 bit32 status; 17365 smSatIOContext_t *satOrgIOContext = agNULL; 17366 smIniScsiCmnd_t *scsiCmnd; 17367 agsaFisRegHostToDevice_t *fis; 17368 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 17369 bit32 lba = 0; 17370 bit32 DenomTL = 0xFF; 17371 bit32 Remainder = 0; 17372 bit8 LBA[4]; /* 0 MSB, 3 LSB */ 17373 17374 SM_DBG2(("smsatWrite_1: start\n")); 17375 17376 fis = satIOContext->pFis; 17377 satOrgIOContext = satIOContext->satOrgIOContext; 17378 scsiCmnd = satOrgIOContext->pScsiCmnd; 17379 17380 sm_memset(LBA,0, sizeof(LBA)); 17381 17382 switch (satOrgIOContext->ATACmd) 17383 { 17384 case SAT_WRITE_DMA: 17385 DenomTL = 0x100; 17386 break; 17387 case SAT_WRITE_SECTORS: 17388 DenomTL = 0x100; 17389 break; 17390 case SAT_WRITE_DMA_EXT: 17391 DenomTL = 0xFFFF; 17392 break; 17393 case SAT_WRITE_DMA_FUA_EXT: 17394 DenomTL = 0xFFFF; 17395 break; 17396 case SAT_WRITE_SECTORS_EXT: 17397 DenomTL = 0xFFFF; 17398 break; 17399 case SAT_WRITE_FPDMA_QUEUED: 17400 DenomTL = 0xFFFF; 17401 break; 17402 default: 17403 SM_DBG1(("smsatWrite_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd)); 17404 return SM_RC_FAILURE; 17405 break; 17406 } 17407 17408 Remainder = satOrgIOContext->OrgTL % DenomTL; 17409 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL; 17410 lba = satOrgIOContext->currentLBA; 17411 17412 17413 LBA[0] = (bit8)((lba & 0xFF000000) >> (8 * 3)); 17414 LBA[1] = (bit8)((lba & 0xFF0000) >> (8 * 2)); 17415 LBA[2] = (bit8)((lba & 0xFF00) >> 8); 17416 LBA[3] = (bit8)(lba & 0xFF); 17417 17418 switch (satOrgIOContext->ATACmd) 17419 { 17420 case SAT_WRITE_DMA: 17421 fis->h.fisType = 0x27; /* Reg host to device */ 17422 fis->h.c_pmPort = 0x80; /* C bit is set */ 17423 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 17424 fis->h.features = 0; /* FIS reserve */ 17425 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 17426 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 17427 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 17428 17429 /* FIS LBA mode set LBA (27:24) */ 17430 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 17431 17432 fis->d.lbaLowExp = 0; 17433 fis->d.lbaMidExp = 0; 17434 fis->d.lbaHighExp = 0; 17435 fis->d.featuresExp = 0; 17436 if (satOrgIOContext->LoopNum == 1) 17437 { 17438 /* last loop */ 17439 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 17440 } 17441 else 17442 { 17443 fis->d.sectorCount = 0x0; /* FIS sector count (7:0) */ 17444 } 17445 fis->d.sectorCountExp = 0; 17446 fis->d.reserved4 = 0; 17447 fis->d.control = 0; /* FIS HOB bit clear */ 17448 fis->d.reserved5 = 0; 17449 17450 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 17451 17452 break; 17453 case SAT_WRITE_SECTORS: 17454 fis->h.fisType = 0x27; /* Reg host to device */ 17455 fis->h.c_pmPort = 0x80; /* C bit is set */ 17456 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 17457 fis->h.features = 0; /* FIS reserve */ 17458 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 17459 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 17460 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 17461 17462 /* FIS LBA mode set LBA (27:24) */ 17463 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 17464 17465 fis->d.lbaLowExp = 0; 17466 fis->d.lbaMidExp = 0; 17467 fis->d.lbaHighExp = 0; 17468 fis->d.featuresExp = 0; 17469 if (satOrgIOContext->LoopNum == 1) 17470 { 17471 /* last loop */ 17472 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 17473 } 17474 else 17475 { 17476 fis->d.sectorCount = 0x0; /* FIS sector count (7:0) */ 17477 } 17478 fis->d.sectorCountExp = 0; 17479 fis->d.reserved4 = 0; 17480 fis->d.control = 0; /* FIS HOB bit clear */ 17481 fis->d.reserved5 = 0; 17482 17483 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 17484 17485 break; 17486 case SAT_WRITE_DMA_EXT: 17487 fis->h.fisType = 0x27; /* Reg host to device */ 17488 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17489 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x3D */ 17490 fis->h.features = 0; /* FIS reserve */ 17491 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 17492 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 17493 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 17494 fis->d.device = 0x40; /* FIS LBA mode set */ 17495 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 17496 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 17497 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 17498 fis->d.featuresExp = 0; /* FIS reserve */ 17499 if (satOrgIOContext->LoopNum == 1) 17500 { 17501 /* last loop */ 17502 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 17503 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 17504 } 17505 else 17506 { 17507 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 17508 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 17509 } 17510 fis->d.reserved4 = 0; 17511 fis->d.control = 0; /* FIS HOB bit clear */ 17512 fis->d.reserved5 = 0; 17513 17514 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 17515 17516 break; 17517 case SAT_WRITE_SECTORS_EXT: 17518 fis->h.fisType = 0x27; /* Reg host to device */ 17519 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17520 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 17521 17522 fis->h.features = 0; /* FIS reserve */ 17523 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 17524 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 17525 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 17526 fis->d.device = 0x40; /* FIS LBA mode set */ 17527 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 17528 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 17529 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 17530 fis->d.featuresExp = 0; /* FIS reserve */ 17531 if (satOrgIOContext->LoopNum == 1) 17532 { 17533 /* last loop */ 17534 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 17535 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 17536 } 17537 else 17538 { 17539 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 17540 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 17541 } 17542 fis->d.reserved4 = 0; 17543 fis->d.control = 0; /* FIS HOB bit clear */ 17544 fis->d.reserved5 = 0; 17545 17546 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 17547 17548 break; 17549 case SAT_WRITE_FPDMA_QUEUED: 17550 fis->h.fisType = 0x27; /* Reg host to device */ 17551 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17552 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 17553 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 17554 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 17555 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 17556 17557 /* Check FUA bit */ 17558 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK) 17559 fis->d.device = 0xC0; /* FIS FUA set */ 17560 else 17561 fis->d.device = 0x40; /* FIS FUA clear */ 17562 17563 fis->d.lbaLowExp = LBA[0];; /* FIS LBA (31:24) */ 17564 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 17565 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 17566 if (satOrgIOContext->LoopNum == 1) 17567 { 17568 /* last loop */ 17569 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 17570 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 17571 } 17572 else 17573 { 17574 fis->h.features = 0xFF; /* FIS sector count (7:0) */ 17575 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */ 17576 } 17577 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 17578 fis->d.sectorCountExp = 0; 17579 fis->d.reserved4 = 0; 17580 fis->d.control = 0; /* FIS HOB bit clear */ 17581 fis->d.reserved5 = 0; 17582 17583 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 17584 break; 17585 17586 default: 17587 SM_DBG1(("smsatWrite_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd)); 17588 return SM_RC_FAILURE; 17589 break; 17590 } 17591 17592 /* Initialize CB for SATA completion. 17593 */ 17594 /* chained data */ 17595 satIOContext->satCompleteCB = &smsatChainedDataIOCB; 17596 17597 if (satOrgIOContext->ATACmd == SAT_WRITE_DMA || satOrgIOContext->ATACmd == SAT_WRITE_SECTORS) 17598 { 17599 smsatSplitSGL(smRoot, 17600 smIORequest, 17601 smDeviceHandle, 17602 (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg, 17603 satOrgIOContext, 17604 NON_BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0x100 * 0x200*/ 17605 (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE, 17606 agFALSE); 17607 } 17608 else 17609 { 17610 smsatSplitSGL(smRoot, 17611 smIORequest, 17612 smDeviceHandle, 17613 (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg, 17614 satOrgIOContext, 17615 BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0xFFFF * 0x200*/ 17616 (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE, 17617 agFALSE); 17618 } 17619 17620 /* 17621 * Prepare SGL and send FIS to LL layer. 17622 */ 17623 satIOContext->reqType = agRequestType; /* Save it */ 17624 17625 status = smsataLLIOStart( smRoot, 17626 smIORequest, 17627 smDeviceHandle, 17628 (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg, //smScsiRequest, 17629 satIOContext); 17630 17631 SM_DBG5(("smsatWrite_1: return\n")); 17632 return (status); 17633 } 17634 17635 osGLOBAL bit32 17636 smsatPassthrough( 17637 smRoot_t *smRoot, 17638 smIORequest_t *smIORequest, 17639 smDeviceHandle_t *smDeviceHandle, 17640 smScsiInitiatorRequest_t *smScsiRequest, 17641 smSatIOContext_t *satIOContext 17642 ) 17643 { 17644 smScsiRspSense_t *pSense; 17645 smIniScsiCmnd_t *scsiCmnd; 17646 smDeviceData_t *pSatDevData; 17647 agsaFisRegHostToDevice_t *fis; 17648 bit32 status; 17649 bit32 agRequestType; 17650 smAtaPassThroughHdr_t ataPassThroughHdr; 17651 17652 17653 pSense = satIOContext->pSense; 17654 scsiCmnd = &smScsiRequest->scsiCmnd; 17655 pSatDevData = satIOContext->pSatDevData; 17656 fis = satIOContext->pFis; 17657 17658 SM_DBG1(("smsatPassthrough: START!!!\n")); 17659 17660 osti_memset(&ataPassThroughHdr, 0 , sizeof(smAtaPassThroughHdr_t)); 17661 17662 ataPassThroughHdr.opc = scsiCmnd->cdb[0]; 17663 ataPassThroughHdr.mulCount = scsiCmnd->cdb[1] >> 5; 17664 ataPassThroughHdr.proto = (scsiCmnd->cdb[1] >> 1) & 0x0F; 17665 ataPassThroughHdr.extend = scsiCmnd->cdb[1] & 1; 17666 ataPassThroughHdr.offline = scsiCmnd->cdb[2] >> 6; 17667 ataPassThroughHdr.ckCond = (scsiCmnd->cdb[2] >> 5) & 1; 17668 ataPassThroughHdr.tType = (scsiCmnd->cdb[2] >> 4) & 1; 17669 ataPassThroughHdr.tDir = (scsiCmnd->cdb[2] >> 3) & 1; 17670 ataPassThroughHdr.byteBlock = (scsiCmnd->cdb[2] >> 2) & 1; 17671 ataPassThroughHdr.tlength = scsiCmnd->cdb[2] & 0x3; 17672 17673 switch(ataPassThroughHdr.proto) 17674 { 17675 case 0: 17676 case 9: 17677 agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET; //Device Reset 17678 break; 17679 case 1: 17680 agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT; //Software reset 17681 break; 17682 case 3: 17683 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; //Non Data mode 17684 break; 17685 case 4: 17686 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; //IO_Data_In mode 17687 break; 17688 case 5: 17689 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; //PIO_Data_out 17690 break; 17691 case 6: 17692 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; //DMA READ and WRITE 17693 break; 17694 case 8: 17695 agRequestType = AGSA_SATA_ATAP_EXECDEVDIAG; //device diagnostic 17696 break; 17697 case 12: 17698 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; //FPDMA Read and Write 17699 break; 17700 default: 17701 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; //Default Non Data Mode 17702 break; 17703 } 17704 17705 17706 if((ataPassThroughHdr.tlength == 0) && (agRequestType != AGSA_SATA_PROTOCOL_NON_DATA)) 17707 { 17708 SM_DBG1(("smsatPassthrough SCSI_SNSCODE_INVALID_FIELD_IN_CDB\n")); 17709 17710 smsatSetSensePayload( pSense, 17711 SCSI_SNSKEY_ILLEGAL_REQUEST, 17712 0, 17713 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 17714 satIOContext); 17715 17716 tdsmIOCompletedCB( smRoot, 17717 smIORequest, 17718 smIOSuccess, 17719 SCSI_STAT_CHECK_CONDITION, 17720 satIOContext->pSmSenseData, 17721 satIOContext->interruptContext ); 17722 17723 return SM_RC_SUCCESS; 17724 } 17725 17726 if(scsiCmnd->cdb[0] == 0xA1) 17727 { 17728 SM_DBG1(("smsatPassthrough A1h: COMMAND: %x FEATURE: %x \n",scsiCmnd->cdb[9],scsiCmnd->cdb[3])); 17729 17730 fis->h.fisType = 0x27; /* Reg host to device */ 17731 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17732 fis->h.features = scsiCmnd->cdb[3]; 17733 fis->d.sectorCount = scsiCmnd->cdb[4]; /* 0x01 FIS sector count (7:0) */ 17734 fis->d.lbaLow = scsiCmnd->cdb[5]; /* Reading LBA FIS LBA (7 :0 ) */ 17735 fis->d.lbaMid = scsiCmnd->cdb[6]; 17736 fis->d.lbaHigh = scsiCmnd->cdb[7]; 17737 fis->d.device = scsiCmnd->cdb[8]; 17738 fis->h.command = scsiCmnd->cdb[9]; 17739 fis->d.featuresExp = 0; 17740 fis->d.sectorCountExp = 0; 17741 fis->d.lbaLowExp = 0; 17742 fis->d.lbaMidExp = 0; 17743 fis->d.lbaHighExp = 0; 17744 fis->d.reserved4 = 0; 17745 fis->d.control = 0; /* FIS HOB bit clear */ 17746 fis->d.reserved5 = 0; 17747 17748 /* Initialize CB for SATA completion*/ 17749 satIOContext->satCompleteCB = &smsatPassthroughCB; 17750 17751 /* 17752 * Prepare SGL and send FIS to LL layer. 17753 */ 17754 17755 satIOContext->reqType = agRequestType; 17756 status = smsataLLIOStart( smRoot, 17757 smIORequest, 17758 smDeviceHandle, 17759 smScsiRequest, 17760 satIOContext); 17761 return status; 17762 17763 } 17764 else if(scsiCmnd->cdb[0] == 0x85) 17765 { 17766 SM_DBG1(("smsatPassthrough 85h: COMMAND: %x FEATURE: %x \n",scsiCmnd->cdb[14],scsiCmnd->cdb[4])); 17767 17768 fis->h.fisType = 0x27; /* Reg host to device */ 17769 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17770 17771 if(1 == ataPassThroughHdr.extend) 17772 { 17773 fis->d.featuresExp = scsiCmnd->cdb[3]; 17774 fis->d.sectorCountExp = scsiCmnd->cdb[5]; 17775 fis->d.lbaMidExp = scsiCmnd->cdb[9]; 17776 fis->d.lbaHighExp = scsiCmnd->cdb[11]; 17777 fis->d.lbaLowExp = scsiCmnd->cdb[7]; 17778 } 17779 fis->h.features = scsiCmnd->cdb[4]; 17780 fis->d.sectorCount = scsiCmnd->cdb[6]; 17781 fis->d.lbaLow = scsiCmnd->cdb[8]; 17782 fis->d.lbaMid = scsiCmnd->cdb[10]; 17783 fis->d.lbaHigh = scsiCmnd->cdb[12]; 17784 fis->d.device = scsiCmnd->cdb[13]; 17785 fis->h.command = scsiCmnd->cdb[14]; 17786 fis->d.reserved4 = 0; 17787 fis->d.control = 0; 17788 fis->d.reserved5 = 0; 17789 17790 17791 /* Initialize CB for SATA completion. 17792 */ 17793 17794 satIOContext->satCompleteCB = &smsatPassthroughCB; 17795 17796 /* 17797 * Prepare SGL and send FIS to LL layer. 17798 */ 17799 satIOContext->reqType = agRequestType; 17800 status = smsataLLIOStart( smRoot, 17801 smIORequest, 17802 smDeviceHandle, 17803 smScsiRequest, 17804 satIOContext); 17805 return status; 17806 17807 } 17808 else 17809 { 17810 SM_DBG1(("smsatPassthrough : INVALD PASSTHROUGH!!!\n")); 17811 smsatSetSensePayload( pSense, 17812 SCSI_SNSKEY_ILLEGAL_REQUEST, 17813 0, 17814 SCSI_SNSCODE_INVALID_FIELD_IN_CDB, 17815 satIOContext); 17816 tdsmIOCompletedCB( smRoot, 17817 smIORequest, 17818 smIOSuccess, 17819 SCSI_STAT_CHECK_CONDITION, 17820 satIOContext->pSmSenseData, 17821 satIOContext->interruptContext ); 17822 17823 SM_DBG1(("smsatPassthrough : return control!!!\n")); 17824 17825 return SM_RC_SUCCESS; 17826 } 17827 } 17828 17829 osGLOBAL bit32 17830 smsatNonChainedWriteNVerify_Verify( 17831 smRoot_t *smRoot, 17832 smIORequest_t *smIORequest, 17833 smDeviceHandle_t *smDeviceHandle, 17834 smScsiInitiatorRequest_t *smScsiRequest, 17835 smSatIOContext_t *satIOContext 17836 ) 17837 { 17838 bit32 status; 17839 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 17840 smDeviceData_t *pSatDevData; 17841 smIniScsiCmnd_t *scsiCmnd; 17842 agsaFisRegHostToDevice_t *fis; 17843 17844 pSatDevData = satIOContext->pSatDevData; 17845 scsiCmnd = &smScsiRequest->scsiCmnd; 17846 fis = satIOContext->pFis; 17847 SM_DBG5(("smsatNonChainedWriteNVerify_Verify: start\n")); 17848 if (pSatDevData->sat48BitSupport == agTRUE) 17849 { 17850 fis->h.fisType = 0x27; /* Reg host to device */ 17851 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17852 17853 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 17854 fis->h.features = 0; /* FIS reserve */ 17855 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 17856 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 17857 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 17858 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 17859 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 17860 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 17861 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 17862 fis->d.featuresExp = 0; /* FIS reserve */ 17863 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 17864 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 17865 17866 fis->d.reserved4 = 0; 17867 fis->d.control = 0; /* FIS HOB bit clear */ 17868 fis->d.reserved5 = 0; 17869 17870 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 17871 17872 /* Initialize CB for SATA completion. 17873 */ 17874 satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB; 17875 17876 /* 17877 * Prepare SGL and send FIS to LL layer. 17878 */ 17879 satIOContext->reqType = agRequestType; /* Save it */ 17880 17881 status = smsataLLIOStart( smRoot, 17882 smIORequest, 17883 smDeviceHandle, 17884 smScsiRequest, 17885 satIOContext); 17886 17887 17888 SM_DBG1(("smsatNonChainedWriteNVerify_Verify: return status %d!!!\n", status)); 17889 return (status); 17890 } 17891 else 17892 { 17893 /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */ 17894 SM_DBG1(("smsatNonChainedWriteNVerify_Verify: can't fit in SAT_READ_VERIFY_SECTORS!!!\n")); 17895 return SM_RC_FAILURE; 17896 } 17897 } 17898 17899 osGLOBAL bit32 17900 smsatChainedWriteNVerify_Start_Verify( 17901 smRoot_t *smRoot, 17902 smIORequest_t *smIORequest, 17903 smDeviceHandle_t *smDeviceHandle, 17904 smScsiInitiatorRequest_t *smScsiRequest, 17905 smSatIOContext_t *satIOContext 17906 ) 17907 { 17908 /* 17909 deal with transfer length; others have been handled previously at this point; 17910 no LBA check; no range check; 17911 */ 17912 bit32 status; 17913 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 17914 smDeviceData_t *pSatDevData; 17915 smIniScsiCmnd_t *scsiCmnd; 17916 agsaFisRegHostToDevice_t *fis; 17917 bit32 lba = 0; 17918 bit32 tl = 0; 17919 bit32 LoopNum = 1; 17920 bit8 LBA[4]; 17921 bit8 TL[4]; 17922 17923 pSatDevData = satIOContext->pSatDevData; 17924 scsiCmnd = &smScsiRequest->scsiCmnd; 17925 fis = satIOContext->pFis; 17926 17927 SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: start\n")); 17928 sm_memset(LBA, 0, sizeof(LBA)); 17929 sm_memset(TL, 0, sizeof(TL)); 17930 /* do not use memcpy due to indexing in LBA and TL */ 17931 LBA[0] = scsiCmnd->cdb[2]; /* MSB */ 17932 LBA[1] = scsiCmnd->cdb[3]; 17933 LBA[2] = scsiCmnd->cdb[4]; 17934 LBA[3] = scsiCmnd->cdb[5]; /* LSB */ 17935 TL[0] = scsiCmnd->cdb[6]; /* MSB */ 17936 TL[1] = scsiCmnd->cdb[7]; 17937 TL[2] = scsiCmnd->cdb[7]; 17938 TL[3] = scsiCmnd->cdb[8]; /* LSB */ 17939 lba = smsatComputeCDB12LBA(satIOContext); 17940 tl = smsatComputeCDB12TL(satIOContext); 17941 if (pSatDevData->sat48BitSupport == agTRUE) 17942 { 17943 SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS_EXT\n")); 17944 fis->h.fisType = 0x27; /* Reg host to device */ 17945 fis->h.c_pmPort = 0x80; /* C Bit is set */ 17946 17947 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 17948 fis->h.features = 0; /* FIS reserve */ 17949 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 17950 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 17951 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 17952 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 17953 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */ 17954 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 17955 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 17956 fis->d.featuresExp = 0; /* FIS reserve */ 17957 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 17958 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */ 17959 17960 fis->d.reserved4 = 0; 17961 fis->d.control = 0; /* FIS HOB bit clear */ 17962 fis->d.reserved5 = 0; 17963 17964 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 17965 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT; 17966 } 17967 else 17968 { 17969 SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS\n")); 17970 fis->h.fisType = 0x27; /* Reg host to device */ 17971 fis->h.c_pmPort = 0x80; /* C bit is set */ 17972 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 17973 fis->h.features = 0; /* FIS reserve */ 17974 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */ 17975 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */ 17976 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */ 17977 /* FIS LBA mode set LBA (27:24) */ 17978 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); 17979 fis->d.lbaLowExp = 0; 17980 fis->d.lbaMidExp = 0; 17981 fis->d.lbaHighExp = 0; 17982 fis->d.featuresExp = 0; 17983 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */ 17984 fis->d.sectorCountExp = 0; 17985 fis->d.reserved4 = 0; 17986 fis->d.control = 0; /* FIS HOB bit clear */ 17987 fis->d.reserved5 = 0; 17988 17989 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 17990 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS; 17991 17992 } 17993 17994 satIOContext->currentLBA = lba; 17995 satIOContext->OrgTL = tl; 17996 17997 /* 17998 computing number of loop and remainder for tl 17999 0xFF in case not ext 18000 0xFFFF in case EXT 18001 */ 18002 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 18003 { 18004 LoopNum = smsatComputeLoopNum(tl, 0xFF); 18005 } 18006 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 18007 { 18008 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */ 18009 LoopNum = smsatComputeLoopNum(tl, 0xFFFF); 18010 } 18011 else 18012 { 18013 SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: error case 1!!!\n")); 18014 LoopNum = 1; 18015 } 18016 18017 satIOContext->LoopNum = LoopNum; 18018 18019 if (LoopNum == 1) 18020 { 18021 SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: NON CHAINED data\n")); 18022 /* Initialize CB for SATA completion. 18023 */ 18024 satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB; 18025 } 18026 else 18027 { 18028 SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: CHAINED data!!!\n")); 18029 /* re-setting tl */ 18030 if (fis->h.command == SAT_READ_VERIFY_SECTORS) 18031 { 18032 fis->d.sectorCount = 0xFF; 18033 } 18034 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT) 18035 { 18036 fis->d.sectorCount = 0xFF; 18037 fis->d.sectorCountExp = 0xFF; 18038 } 18039 else 18040 { 18041 SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: error case 2!!!\n")); 18042 } 18043 18044 /* Initialize CB for SATA completion. 18045 */ 18046 satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB; 18047 } 18048 18049 18050 /* 18051 * Prepare SGL and send FIS to LL layer. 18052 */ 18053 satIOContext->reqType = agRequestType; /* Save it */ 18054 18055 status = smsataLLIOStart( smRoot, 18056 smIORequest, 18057 smDeviceHandle, 18058 smScsiRequest, 18059 satIOContext); 18060 return (status); 18061 18062 18063 } 18064 18065 osGLOBAL bit32 18066 smsatChainedWriteNVerify_Write( 18067 smRoot_t *smRoot, 18068 smIORequest_t *smIORequest, 18069 smDeviceHandle_t *smDeviceHandle, 18070 smScsiInitiatorRequest_t *smScsiRequest, 18071 smSatIOContext_t *satIOContext 18072 ) 18073 { 18074 /* 18075 Assumption: error check on lba and tl has been done in satWrite*() 18076 lba = lba + tl; 18077 */ 18078 bit32 status; 18079 smSatIOContext_t *satOrgIOContext = agNULL; 18080 smIniScsiCmnd_t *scsiCmnd; 18081 agsaFisRegHostToDevice_t *fis; 18082 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 18083 bit32 lba = 0; 18084 bit32 DenomTL = 0xFF; 18085 bit32 Remainder = 0; 18086 bit8 LBA[4]; /* 0 MSB, 3 LSB */ 18087 18088 SM_DBG1(("smsatChainedWriteNVerify_Write: start\n")); 18089 18090 fis = satIOContext->pFis; 18091 satOrgIOContext = satIOContext->satOrgIOContext; 18092 scsiCmnd = satOrgIOContext->pScsiCmnd; 18093 18094 18095 sm_memset(LBA,0, sizeof(LBA)); 18096 18097 switch (satOrgIOContext->ATACmd) 18098 { 18099 case SAT_WRITE_DMA: 18100 DenomTL = 0xFF; 18101 break; 18102 case SAT_WRITE_SECTORS: 18103 DenomTL = 0xFF; 18104 break; 18105 case SAT_WRITE_DMA_EXT: 18106 DenomTL = 0xFFFF; 18107 break; 18108 case SAT_WRITE_DMA_FUA_EXT: 18109 DenomTL = 0xFFFF; 18110 break; 18111 case SAT_WRITE_SECTORS_EXT: 18112 DenomTL = 0xFFFF; 18113 break; 18114 case SAT_WRITE_FPDMA_QUEUED: 18115 DenomTL = 0xFFFF; 18116 break; 18117 default: 18118 SM_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd)); 18119 return SM_RC_FAILURE; 18120 break; 18121 } 18122 18123 Remainder = satOrgIOContext->OrgTL % DenomTL; 18124 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL; 18125 lba = satOrgIOContext->currentLBA; 18126 18127 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */ 18128 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2)); 18129 LBA[2] = (bit8)((lba & 0xF0) >> 8); 18130 LBA[3] = (bit8)(lba & 0xF); /* LSB */ 18131 18132 switch (satOrgIOContext->ATACmd) 18133 { 18134 case SAT_WRITE_DMA: 18135 fis->h.fisType = 0x27; /* Reg host to device */ 18136 fis->h.c_pmPort = 0x80; /* C bit is set */ 18137 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 18138 fis->h.features = 0; /* FIS reserve */ 18139 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 18140 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 18141 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 18142 18143 /* FIS LBA mode set LBA (27:24) */ 18144 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 18145 18146 fis->d.lbaLowExp = 0; 18147 fis->d.lbaMidExp = 0; 18148 fis->d.lbaHighExp = 0; 18149 fis->d.featuresExp = 0; 18150 if (satOrgIOContext->LoopNum == 1) 18151 { 18152 /* last loop */ 18153 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 18154 } 18155 else 18156 { 18157 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 18158 } 18159 fis->d.sectorCountExp = 0; 18160 fis->d.reserved4 = 0; 18161 fis->d.control = 0; /* FIS HOB bit clear */ 18162 fis->d.reserved5 = 0; 18163 18164 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 18165 18166 break; 18167 case SAT_WRITE_SECTORS: 18168 fis->h.fisType = 0x27; /* Reg host to device */ 18169 fis->h.c_pmPort = 0x80; /* C bit is set */ 18170 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 18171 fis->h.features = 0; /* FIS reserve */ 18172 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 18173 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 18174 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 18175 18176 /* FIS LBA mode set LBA (27:24) */ 18177 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 18178 18179 fis->d.lbaLowExp = 0; 18180 fis->d.lbaMidExp = 0; 18181 fis->d.lbaHighExp = 0; 18182 fis->d.featuresExp = 0; 18183 if (satOrgIOContext->LoopNum == 1) 18184 { 18185 /* last loop */ 18186 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 18187 } 18188 else 18189 { 18190 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 18191 } 18192 fis->d.sectorCountExp = 0; 18193 fis->d.reserved4 = 0; 18194 fis->d.control = 0; /* FIS HOB bit clear */ 18195 fis->d.reserved5 = 0; 18196 18197 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 18198 18199 break; 18200 case SAT_WRITE_DMA_EXT: 18201 fis->h.fisType = 0x27; /* Reg host to device */ 18202 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18203 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x3D */ 18204 fis->h.features = 0; /* FIS reserve */ 18205 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 18206 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 18207 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 18208 fis->d.device = 0x40; /* FIS LBA mode set */ 18209 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 18210 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 18211 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 18212 fis->d.featuresExp = 0; /* FIS reserve */ 18213 if (satOrgIOContext->LoopNum == 1) 18214 { 18215 /* last loop */ 18216 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 18217 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 18218 } 18219 else 18220 { 18221 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 18222 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 18223 } 18224 fis->d.reserved4 = 0; 18225 fis->d.control = 0; /* FIS HOB bit clear */ 18226 fis->d.reserved5 = 0; 18227 18228 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 18229 18230 break; 18231 case SAT_WRITE_SECTORS_EXT: 18232 fis->h.fisType = 0x27; /* Reg host to device */ 18233 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18234 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 18235 18236 fis->h.features = 0; /* FIS reserve */ 18237 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 18238 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 18239 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 18240 fis->d.device = 0x40; /* FIS LBA mode set */ 18241 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 18242 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 18243 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 18244 fis->d.featuresExp = 0; /* FIS reserve */ 18245 if (satOrgIOContext->LoopNum == 1) 18246 { 18247 /* last loop */ 18248 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 18249 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 18250 } 18251 else 18252 { 18253 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 18254 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 18255 } 18256 fis->d.reserved4 = 0; 18257 fis->d.control = 0; /* FIS HOB bit clear */ 18258 fis->d.reserved5 = 0; 18259 18260 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 18261 18262 break; 18263 case SAT_WRITE_FPDMA_QUEUED: 18264 fis->h.fisType = 0x27; /* Reg host to device */ 18265 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18266 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 18267 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 18268 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 18269 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 18270 18271 /* Check FUA bit */ 18272 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK) 18273 fis->d.device = 0xC0; /* FIS FUA set */ 18274 else 18275 fis->d.device = 0x40; /* FIS FUA clear */ 18276 18277 fis->d.lbaLowExp = LBA[0];; /* FIS LBA (31:24) */ 18278 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 18279 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 18280 if (satOrgIOContext->LoopNum == 1) 18281 { 18282 /* last loop */ 18283 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 18284 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 18285 } 18286 else 18287 { 18288 fis->h.features = 0xFF; /* FIS sector count (7:0) */ 18289 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */ 18290 } 18291 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 18292 fis->d.sectorCountExp = 0; 18293 fis->d.reserved4 = 0; 18294 fis->d.control = 0; /* FIS HOB bit clear */ 18295 fis->d.reserved5 = 0; 18296 18297 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 18298 break; 18299 18300 default: 18301 SM_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd)); 18302 return SM_RC_FAILURE; 18303 break; 18304 } 18305 18306 /* Initialize CB for SATA completion. 18307 */ 18308 /* chained data */ 18309 satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB; 18310 18311 18312 /* 18313 * Prepare SGL and send FIS to LL layer. 18314 */ 18315 satIOContext->reqType = agRequestType; /* Save it */ 18316 18317 status = smsataLLIOStart( smRoot, 18318 smIORequest, 18319 smDeviceHandle, 18320 smScsiRequest, 18321 satIOContext); 18322 18323 SM_DBG5(("satChainedWriteNVerify_Write: return\n")); 18324 return (status); 18325 } 18326 18327 osGLOBAL bit32 18328 smsatChainedWriteNVerify_Verify( 18329 smRoot_t *smRoot, 18330 smIORequest_t *smIORequest, 18331 smDeviceHandle_t *smDeviceHandle, 18332 smScsiInitiatorRequest_t *smScsiRequest, 18333 smSatIOContext_t *satIOContext 18334 ) 18335 { 18336 bit32 status; 18337 smSatIOContext_t *satOrgIOContext = agNULL; 18338 agsaFisRegHostToDevice_t *fis; 18339 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 18340 bit32 lba = 0; 18341 bit32 DenomTL = 0xFF; 18342 bit32 Remainder = 0; 18343 bit8 LBA[4]; /* 0 MSB, 3 LSB */ 18344 18345 SM_DBG2(("smsatChainedWriteNVerify_Verify: start\n")); 18346 fis = satIOContext->pFis; 18347 satOrgIOContext = satIOContext->satOrgIOContext; 18348 sm_memset(LBA,0, sizeof(LBA)); 18349 switch (satOrgIOContext->ATACmd) 18350 { 18351 case SAT_READ_VERIFY_SECTORS: 18352 DenomTL = 0xFF; 18353 break; 18354 case SAT_READ_VERIFY_SECTORS_EXT: 18355 DenomTL = 0xFFFF; 18356 break; 18357 default: 18358 SM_DBG1(("smsatChainedWriteNVerify_Verify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd)); 18359 return SM_RC_FAILURE; 18360 break; 18361 } 18362 18363 Remainder = satOrgIOContext->OrgTL % DenomTL; 18364 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL; 18365 lba = satOrgIOContext->currentLBA; 18366 18367 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */ 18368 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2)); 18369 LBA[2] = (bit8)((lba & 0xF0) >> 8); 18370 LBA[3] = (bit8)(lba & 0xF); /* LSB */ 18371 18372 switch (satOrgIOContext->ATACmd) 18373 { 18374 case SAT_READ_VERIFY_SECTORS: 18375 fis->h.fisType = 0x27; /* Reg host to device */ 18376 fis->h.c_pmPort = 0x80; /* C bit is set */ 18377 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 18378 fis->h.features = 0; /* FIS reserve */ 18379 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 18380 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 18381 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 18382 18383 /* FIS LBA mode set LBA (27:24) */ 18384 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 18385 18386 fis->d.lbaLowExp = 0; 18387 fis->d.lbaMidExp = 0; 18388 fis->d.lbaHighExp = 0; 18389 fis->d.featuresExp = 0; 18390 if (satOrgIOContext->LoopNum == 1) 18391 { 18392 /* last loop */ 18393 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 18394 } 18395 else 18396 { 18397 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 18398 } 18399 fis->d.sectorCountExp = 0; 18400 fis->d.reserved4 = 0; 18401 fis->d.control = 0; /* FIS HOB bit clear */ 18402 fis->d.reserved5 = 0; 18403 18404 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 18405 18406 break; 18407 case SAT_READ_VERIFY_SECTORS_EXT: 18408 fis->h.fisType = 0x27; /* Reg host to device */ 18409 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18410 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT; /* 0x42 */ 18411 fis->h.features = 0; /* FIS reserve */ 18412 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 18413 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 18414 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 18415 fis->d.device = 0x40; /* FIS LBA mode set */ 18416 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 18417 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 18418 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 18419 fis->d.featuresExp = 0; /* FIS reserve */ 18420 if (satOrgIOContext->LoopNum == 1) 18421 { 18422 /* last loop */ 18423 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 18424 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 18425 } 18426 else 18427 { 18428 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 18429 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 18430 } 18431 fis->d.reserved4 = 0; 18432 fis->d.control = 0; /* FIS HOB bit clear */ 18433 fis->d.reserved5 = 0; 18434 18435 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 18436 18437 break; 18438 18439 default: 18440 SM_DBG1(("smsatChainedWriteNVerify_Verify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd)); 18441 return SM_RC_FAILURE; 18442 break; 18443 } 18444 18445 /* Initialize CB for SATA completion. 18446 */ 18447 /* chained data */ 18448 satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB; 18449 18450 18451 /* 18452 * Prepare SGL and send FIS to LL layer. 18453 */ 18454 satIOContext->reqType = agRequestType; /* Save it */ 18455 18456 status = smsataLLIOStart( smRoot, 18457 smIORequest, 18458 smDeviceHandle, 18459 smScsiRequest, 18460 satIOContext); 18461 18462 SM_DBG5(("smsatChainedWriteNVerify_Verify: return\n")); 18463 return (status); 18464 } 18465 18466 osGLOBAL bit32 18467 smsatChainedVerify( 18468 smRoot_t *smRoot, 18469 smIORequest_t *smIORequest, 18470 smDeviceHandle_t *smDeviceHandle, 18471 smScsiInitiatorRequest_t *smScsiRequest, 18472 smSatIOContext_t *satIOContext 18473 ) 18474 { 18475 bit32 status; 18476 smSatIOContext_t *satOrgIOContext = agNULL; 18477 agsaFisRegHostToDevice_t *fis; 18478 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 18479 bit32 lba = 0; 18480 bit32 DenomTL = 0xFF; 18481 bit32 Remainder = 0; 18482 bit8 LBA[4]; /* 0 MSB, 3 LSB */ 18483 18484 SM_DBG2(("smsatChainedVerify: start\n")); 18485 fis = satIOContext->pFis; 18486 satOrgIOContext = satIOContext->satOrgIOContext; 18487 sm_memset(LBA,0, sizeof(LBA)); 18488 switch (satOrgIOContext->ATACmd) 18489 { 18490 case SAT_READ_VERIFY_SECTORS: 18491 DenomTL = 0xFF; 18492 break; 18493 case SAT_READ_VERIFY_SECTORS_EXT: 18494 DenomTL = 0xFFFF; 18495 break; 18496 default: 18497 SM_DBG1(("satChainedVerify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd)); 18498 return tiError; 18499 break; 18500 } 18501 18502 Remainder = satOrgIOContext->OrgTL % DenomTL; 18503 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL; 18504 lba = satOrgIOContext->currentLBA; 18505 18506 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */ 18507 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2)); 18508 LBA[2] = (bit8)((lba & 0xF0) >> 8); 18509 LBA[3] = (bit8)(lba & 0xF); /* LSB */ 18510 18511 switch (satOrgIOContext->ATACmd) 18512 { 18513 case SAT_READ_VERIFY_SECTORS: 18514 fis->h.fisType = 0x27; /* Reg host to device */ 18515 fis->h.c_pmPort = 0x80; /* C bit is set */ 18516 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */ 18517 fis->h.features = 0; /* FIS reserve */ 18518 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 18519 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 18520 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 18521 18522 /* FIS LBA mode set LBA (27:24) */ 18523 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF)); 18524 18525 fis->d.lbaLowExp = 0; 18526 fis->d.lbaMidExp = 0; 18527 fis->d.lbaHighExp = 0; 18528 fis->d.featuresExp = 0; 18529 if (satOrgIOContext->LoopNum == 1) 18530 { 18531 /* last loop */ 18532 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */ 18533 } 18534 else 18535 { 18536 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 18537 } 18538 fis->d.sectorCountExp = 0; 18539 fis->d.reserved4 = 0; 18540 fis->d.control = 0; /* FIS HOB bit clear */ 18541 fis->d.reserved5 = 0; 18542 18543 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 18544 18545 break; 18546 case SAT_READ_VERIFY_SECTORS_EXT: 18547 fis->h.fisType = 0x27; /* Reg host to device */ 18548 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18549 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT; /* 0x42 */ 18550 fis->h.features = 0; /* FIS reserve */ 18551 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */ 18552 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */ 18553 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */ 18554 fis->d.device = 0x40; /* FIS LBA mode set */ 18555 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */ 18556 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 18557 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 18558 fis->d.featuresExp = 0; /* FIS reserve */ 18559 if (satOrgIOContext->LoopNum == 1) 18560 { 18561 /* last loop */ 18562 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */ 18563 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */ 18564 } 18565 else 18566 { 18567 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */ 18568 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */ 18569 } 18570 fis->d.reserved4 = 0; 18571 fis->d.control = 0; /* FIS HOB bit clear */ 18572 fis->d.reserved5 = 0; 18573 18574 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 18575 18576 break; 18577 18578 default: 18579 SM_DBG1(("satChainedVerify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd)); 18580 return tiError; 18581 break; 18582 } 18583 18584 /* Initialize CB for SATA completion. 18585 */ 18586 /* chained data */ 18587 satIOContext->satCompleteCB = &smsatChainedVerifyCB; 18588 18589 18590 /* 18591 * Prepare SGL and send FIS to LL layer. 18592 */ 18593 satIOContext->reqType = agRequestType; /* Save it */ 18594 18595 status = smsataLLIOStart( smRoot, 18596 smIORequest, 18597 smDeviceHandle, 18598 smScsiRequest, 18599 satIOContext); 18600 18601 SM_DBG5(("satChainedVerify: return\n")); 18602 return (status); 18603 } 18604 18605 osGLOBAL bit32 18606 smsatWriteSame10_1( 18607 smRoot_t *smRoot, 18608 smIORequest_t *smIORequest, 18609 smDeviceHandle_t *smDeviceHandle, 18610 smScsiInitiatorRequest_t *smScsiRequest, 18611 smSatIOContext_t *satIOContext, 18612 bit32 lba 18613 ) 18614 { 18615 /* 18616 sends SAT_WRITE_DMA_EXT 18617 */ 18618 18619 bit32 status; 18620 bit32 agRequestType; 18621 agsaFisRegHostToDevice_t *fis; 18622 bit8 lba1, lba2 ,lba3, lba4; 18623 18624 SM_DBG5(("smsatWriteSame10_1: start\n")); 18625 fis = satIOContext->pFis; 18626 /* MSB */ 18627 lba1 = (bit8)((lba & 0xFF000000) >> (8*3)); 18628 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2)); 18629 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1)); 18630 /* LSB */ 18631 lba4 = (bit8)(lba & 0x000000FF); 18632 /* SAT_WRITE_DMA_EXT */ 18633 fis->h.fisType = 0x27; /* Reg host to device */ 18634 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18635 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 18636 fis->h.features = 0; /* FIS reserve */ 18637 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */ 18638 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */ 18639 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */ 18640 fis->d.device = 0x40; /* FIS LBA mode set */ 18641 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */ 18642 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 18643 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 18644 fis->d.featuresExp = 0; /* FIS reserve */ 18645 /* one sector at a time */ 18646 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 18647 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 18648 fis->d.reserved4 = 0; 18649 fis->d.control = 0; /* FIS HOB bit clear */ 18650 fis->d.reserved5 = 0; 18651 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 18652 /* Initialize CB for SATA completion. 18653 */ 18654 satIOContext->satCompleteCB = &smsatWriteSame10CB; 18655 /* 18656 * Prepare SGL and send FIS to LL layer. 18657 */ 18658 satIOContext->reqType = agRequestType; /* Save it */ 18659 status = smsataLLIOStart( smRoot, 18660 smIORequest, 18661 smDeviceHandle, 18662 smScsiRequest, 18663 satIOContext); 18664 SM_DBG5(("smsatWriteSame10_1 return status %d\n", status)); 18665 return status; 18666 } 18667 18668 18669 osGLOBAL bit32 18670 smsatWriteSame10_2( 18671 smRoot_t *smRoot, 18672 smIORequest_t *smIORequest, 18673 smDeviceHandle_t *smDeviceHandle, 18674 smScsiInitiatorRequest_t *smScsiRequest, 18675 smSatIOContext_t *satIOContext, 18676 bit32 lba 18677 ) 18678 { 18679 /* 18680 sends SAT_WRITE_SECTORS_EXT 18681 */ 18682 18683 bit32 status; 18684 bit32 agRequestType; 18685 agsaFisRegHostToDevice_t *fis; 18686 bit8 lba1, lba2 ,lba3, lba4; 18687 18688 SM_DBG5(("smsatWriteSame10_2: start\n")); 18689 fis = satIOContext->pFis; 18690 /* MSB */ 18691 lba1 = (bit8)((lba & 0xFF000000) >> (8*3)); 18692 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2)); 18693 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1)); 18694 /* LSB */ 18695 lba4 = (bit8)(lba & 0x000000FF); 18696 /* SAT_WRITE_SECTORS_EXT */ 18697 fis->h.fisType = 0x27; /* Reg host to device */ 18698 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18699 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 18700 fis->h.features = 0; /* FIS reserve */ 18701 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */ 18702 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */ 18703 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */ 18704 fis->d.device = 0x40; /* FIS LBA mode set */ 18705 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */ 18706 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 18707 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 18708 fis->d.featuresExp = 0; /* FIS reserve */ 18709 /* one sector at a time */ 18710 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 18711 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 18712 fis->d.reserved4 = 0; 18713 fis->d.control = 0; /* FIS HOB bit clear */ 18714 fis->d.reserved5 = 0; 18715 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 18716 /* Initialize CB for SATA completion. 18717 */ 18718 satIOContext->satCompleteCB = &smsatWriteSame10CB; 18719 /* 18720 * Prepare SGL and send FIS to LL layer. 18721 */ 18722 satIOContext->reqType = agRequestType; /* Save it */ 18723 status = smsataLLIOStart( smRoot, 18724 smIORequest, 18725 smDeviceHandle, 18726 smScsiRequest, 18727 satIOContext); 18728 SM_DBG5(("smsatWriteSame10_2 return status %d\n", status)); 18729 return status; 18730 } 18731 18732 18733 osGLOBAL bit32 18734 smsatWriteSame10_3( 18735 smRoot_t *smRoot, 18736 smIORequest_t *smIORequest, 18737 smDeviceHandle_t *smDeviceHandle, 18738 smScsiInitiatorRequest_t *smScsiRequest, 18739 smSatIOContext_t *satIOContext, 18740 bit32 lba 18741 ) 18742 { 18743 /* 18744 sends SAT_WRITE_FPDMA_QUEUED 18745 */ 18746 18747 bit32 status; 18748 bit32 agRequestType; 18749 agsaFisRegHostToDevice_t *fis; 18750 bit8 lba1, lba2 ,lba3, lba4; 18751 18752 SM_DBG5(("smsatWriteSame10_3: start\n")); 18753 fis = satIOContext->pFis; 18754 /* MSB */ 18755 lba1 = (bit8)((lba & 0xFF000000) >> (8*3)); 18756 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2)); 18757 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1)); 18758 /* LSB */ 18759 lba4 = (bit8)(lba & 0x000000FF); 18760 18761 /* SAT_WRITE_FPDMA_QUEUED */ 18762 fis->h.fisType = 0x27; /* Reg host to device */ 18763 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18764 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 18765 18766 18767 /* one sector at a time */ 18768 fis->h.features = 1; /* FIS sector count (7:0) */ 18769 fis->d.featuresExp = 0; /* FIS sector count (15:8) */ 18770 18771 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */ 18772 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */ 18773 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */ 18774 /* NO FUA bit in the WRITE SAME 10 */ 18775 fis->d.device = 0x40; /* FIS FUA clear */ 18776 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */ 18777 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 18778 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 18779 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 18780 fis->d.sectorCountExp = 0; 18781 fis->d.reserved4 = 0; 18782 fis->d.control = 0; /* FIS HOB bit clear */ 18783 fis->d.reserved5 = 0; 18784 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 18785 18786 /* Initialize CB for SATA completion. 18787 */ 18788 satIOContext->satCompleteCB = &smsatWriteSame10CB; 18789 /* 18790 * Prepare SGL and send FIS to LL layer. 18791 */ 18792 satIOContext->reqType = agRequestType; /* Save it */ 18793 status = smsataLLIOStart( smRoot, 18794 smIORequest, 18795 smDeviceHandle, 18796 smScsiRequest, 18797 satIOContext); 18798 18799 SM_DBG5(("smsatWriteSame10_3 return status %d\n", status)); 18800 return status; 18801 } 18802 18803 osGLOBAL bit32 18804 smsatStartStopUnit_1( 18805 smRoot_t *smRoot, 18806 smIORequest_t *smIORequest, 18807 smDeviceHandle_t *smDeviceHandle, 18808 smScsiInitiatorRequest_t *smScsiRequest, 18809 smSatIOContext_t *satIOContext 18810 ) 18811 { 18812 /* 18813 SAT Rev 8, Table 48, 9.11.3 p55 18814 sends STANDBY 18815 */ 18816 bit32 status; 18817 bit32 agRequestType; 18818 agsaFisRegHostToDevice_t *fis; 18819 18820 SM_DBG5(("smsatStartStopUnit_1: start\n")); 18821 fis = satIOContext->pFis; 18822 /* STANDBY */ 18823 fis->h.fisType = 0x27; /* Reg host to device */ 18824 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18825 fis->h.command = SAT_STANDBY; /* 0xE2 */ 18826 fis->h.features = 0; /* FIS features NA */ 18827 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 18828 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 18829 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 18830 fis->d.lbaLowExp = 0; 18831 fis->d.lbaMidExp = 0; 18832 fis->d.lbaHighExp = 0; 18833 fis->d.featuresExp = 0; 18834 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 18835 fis->d.sectorCountExp = 0; 18836 fis->d.reserved4 = 0; 18837 fis->d.device = 0; /* 0 */ 18838 fis->d.control = 0; /* FIS HOB bit clear */ 18839 fis->d.reserved5 = 0; 18840 18841 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 18842 18843 /* Initialize CB for SATA completion. 18844 */ 18845 satIOContext->satCompleteCB = &smsatStartStopUnitCB; 18846 18847 /* 18848 * Prepare SGL and send FIS to LL layer. 18849 */ 18850 satIOContext->reqType = agRequestType; /* Save it */ 18851 18852 status = smsataLLIOStart( smRoot, 18853 smIORequest, 18854 smDeviceHandle, 18855 smScsiRequest, 18856 satIOContext); 18857 18858 SM_DBG5(("smsatStartStopUnit_1 return status %d\n", status)); 18859 return status; 18860 } 18861 18862 osGLOBAL bit32 18863 smsatSendDiagnostic_1( 18864 smRoot_t *smRoot, 18865 smIORequest_t *smIORequest, 18866 smDeviceHandle_t *smDeviceHandle, 18867 smScsiInitiatorRequest_t *smScsiRequest, 18868 smSatIOContext_t *satIOContext 18869 ) 18870 { 18871 /* 18872 SAT Rev9, Table29, p41 18873 send 2nd SAT_READ_VERIFY_SECTORS(_EXT) 18874 */ 18875 bit32 status; 18876 bit32 agRequestType; 18877 smDeviceData_t *pSatDevData; 18878 agsaFisRegHostToDevice_t *fis; 18879 18880 SM_DBG5(("smsatSendDiagnostic_1: start\n")); 18881 pSatDevData = satIOContext->pSatDevData; 18882 fis = satIOContext->pFis; 18883 /* 18884 sector count 1, LBA MAX 18885 */ 18886 if (pSatDevData->sat48BitSupport == agTRUE) 18887 { 18888 /* sends READ VERIFY SECTOR(S) EXT*/ 18889 fis->h.fisType = 0x27; /* Reg host to device */ 18890 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18891 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 18892 fis->h.features = 0; /* FIS reserve */ 18893 fis->d.lbaLow = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */ 18894 fis->d.lbaMid = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */ 18895 fis->d.lbaHigh = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */ 18896 fis->d.lbaLowExp = pSatDevData->satMaxLBA[4]; /* FIS LBA (31:24) */ 18897 fis->d.lbaMidExp = pSatDevData->satMaxLBA[3]; /* FIS LBA (39:32) */ 18898 fis->d.lbaHighExp = pSatDevData->satMaxLBA[2]; /* FIS LBA (47:40) */ 18899 fis->d.featuresExp = 0; /* FIS reserve */ 18900 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 18901 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 18902 fis->d.reserved4 = 0; 18903 fis->d.device = 0x40; /* 01000000 */ 18904 fis->d.control = 0; /* FIS HOB bit clear */ 18905 fis->d.reserved5 = 0; 18906 18907 } 18908 else 18909 { 18910 /* READ VERIFY SECTOR(S)*/ 18911 fis->h.fisType = 0x27; /* Reg host to device */ 18912 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18913 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 18914 fis->h.features = 0; /* FIS features NA */ 18915 fis->d.lbaLow = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */ 18916 fis->d.lbaMid = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */ 18917 fis->d.lbaHigh = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */ 18918 fis->d.lbaLowExp = 0; 18919 fis->d.lbaMidExp = 0; 18920 fis->d.lbaHighExp = 0; 18921 fis->d.featuresExp = 0; 18922 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 18923 fis->d.sectorCountExp = 0; 18924 fis->d.reserved4 = 0; 18925 fis->d.device = (bit8)((0x4 << 4) | (pSatDevData->satMaxLBA[4] & 0xF)); 18926 /* DEV and LBA 27:24 */ 18927 fis->d.control = 0; /* FIS HOB bit clear */ 18928 fis->d.reserved5 = 0; 18929 18930 } 18931 18932 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 18933 18934 /* Initialize CB for SATA completion. 18935 */ 18936 satIOContext->satCompleteCB = &smsatSendDiagnosticCB; 18937 18938 /* 18939 * Prepare SGL and send FIS to LL layer. 18940 */ 18941 satIOContext->reqType = agRequestType; /* Save it */ 18942 18943 status = smsataLLIOStart( smRoot, 18944 smIORequest, 18945 smDeviceHandle, 18946 smScsiRequest, 18947 satIOContext); 18948 18949 18950 return status; 18951 } 18952 18953 osGLOBAL bit32 18954 smsatSendDiagnostic_2( 18955 smRoot_t *smRoot, 18956 smIORequest_t *smIORequest, 18957 smDeviceHandle_t *smDeviceHandle, 18958 smScsiInitiatorRequest_t *smScsiRequest, 18959 smSatIOContext_t *satIOContext 18960 ) 18961 { 18962 /* 18963 SAT Rev9, Table29, p41 18964 send 3rd SAT_READ_VERIFY_SECTORS(_EXT) 18965 */ 18966 bit32 status; 18967 bit32 agRequestType; 18968 smDeviceData_t *pSatDevData; 18969 agsaFisRegHostToDevice_t *fis; 18970 18971 SM_DBG5(("smsatSendDiagnostic_2: start\n")); 18972 18973 pSatDevData = satIOContext->pSatDevData; 18974 fis = satIOContext->pFis; 18975 /* 18976 sector count 1, LBA Random 18977 */ 18978 if (pSatDevData->sat48BitSupport == agTRUE) 18979 { 18980 /* sends READ VERIFY SECTOR(S) EXT*/ 18981 fis->h.fisType = 0x27; /* Reg host to device */ 18982 fis->h.c_pmPort = 0x80; /* C Bit is set */ 18983 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 18984 fis->h.features = 0; /* FIS reserve */ 18985 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */ 18986 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 18987 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 18988 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */ 18989 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */ 18990 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */ 18991 fis->d.featuresExp = 0; /* FIS reserve */ 18992 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 18993 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 18994 fis->d.reserved4 = 0; 18995 fis->d.device = 0x40; /* 01000000 */ 18996 fis->d.control = 0; /* FIS HOB bit clear */ 18997 fis->d.reserved5 = 0; 18998 18999 } 19000 else 19001 { 19002 /* READ VERIFY SECTOR(S)*/ 19003 fis->h.fisType = 0x27; /* Reg host to device */ 19004 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19005 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 19006 fis->h.features = 0; /* FIS features NA */ 19007 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */ 19008 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 19009 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 19010 fis->d.lbaLowExp = 0; 19011 fis->d.lbaMidExp = 0; 19012 fis->d.lbaHighExp = 0; 19013 fis->d.featuresExp = 0; 19014 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 19015 fis->d.sectorCountExp = 0; 19016 fis->d.reserved4 = 0; 19017 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */ 19018 fis->d.control = 0; /* FIS HOB bit clear */ 19019 fis->d.reserved5 = 0; 19020 19021 } 19022 19023 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 19024 19025 /* Initialize CB for SATA completion. 19026 */ 19027 satIOContext->satCompleteCB = &smsatSendDiagnosticCB; 19028 19029 /* 19030 * Prepare SGL and send FIS to LL layer. 19031 */ 19032 satIOContext->reqType = agRequestType; /* Save it */ 19033 19034 status = smsataLLIOStart( smRoot, 19035 smIORequest, 19036 smDeviceHandle, 19037 smScsiRequest, 19038 satIOContext); 19039 19040 19041 return status; 19042 } 19043 19044 osGLOBAL bit32 19045 smsatModeSelect6n10_1( 19046 smRoot_t *smRoot, 19047 smIORequest_t *smIORequest, 19048 smDeviceHandle_t *smDeviceHandle, 19049 smScsiInitiatorRequest_t *smScsiRequest, 19050 smSatIOContext_t *satIOContext 19051 ) 19052 { 19053 /* sends either ATA SET FEATURES based on DRA bit */ 19054 bit32 status; 19055 bit32 agRequestType; 19056 agsaFisRegHostToDevice_t *fis; 19057 bit8 *pLogPage; /* Log Page data buffer */ 19058 bit32 StartingIndex = 0; 19059 19060 fis = satIOContext->pFis; 19061 pLogPage = (bit8 *) smScsiRequest->sglVirtualAddr; 19062 SM_DBG5(("smsatModeSelect6n10_1: start\n")); 19063 19064 if (pLogPage[3] == 8) 19065 { 19066 /* mode parameter block descriptor exists */ 19067 StartingIndex = 12; 19068 } 19069 else 19070 { 19071 /* mode parameter block descriptor does not exist */ 19072 StartingIndex = 4; 19073 } 19074 19075 /* sends ATA SET FEATURES based on DRA bit */ 19076 if ( !(pLogPage[StartingIndex + 12] & SCSI_MODE_SELECT6_DRA_MASK) ) 19077 { 19078 SM_DBG5(("smsatModeSelect6n10_1: enable read look-ahead feature\n")); 19079 /* sends SET FEATURES */ 19080 fis->h.fisType = 0x27; /* Reg host to device */ 19081 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19082 19083 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 19084 fis->h.features = 0xAA; /* enable read look-ahead */ 19085 fis->d.lbaLow = 0; /* */ 19086 fis->d.lbaMid = 0; /* */ 19087 fis->d.lbaHigh = 0; /* */ 19088 fis->d.device = 0; /* */ 19089 fis->d.lbaLowExp = 0; /* */ 19090 fis->d.lbaMidExp = 0; /* */ 19091 fis->d.lbaHighExp = 0; /* */ 19092 fis->d.featuresExp = 0; /* */ 19093 fis->d.sectorCount = 0; /* */ 19094 fis->d.sectorCountExp = 0; /* */ 19095 fis->d.reserved4 = 0; 19096 fis->d.control = 0; /* FIS HOB bit clear */ 19097 fis->d.reserved5 = 0; 19098 19099 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 19100 19101 /* Initialize CB for SATA completion. 19102 */ 19103 satIOContext->satCompleteCB = &smsatModeSelect6n10CB; 19104 19105 /* 19106 * Prepare SGL and send FIS to LL layer. 19107 */ 19108 satIOContext->reqType = agRequestType; /* Save it */ 19109 19110 status = smsataLLIOStart( smRoot, 19111 smIORequest, 19112 smDeviceHandle, 19113 smScsiRequest, 19114 satIOContext); 19115 return status; 19116 } 19117 else 19118 { 19119 SM_DBG5(("smsatModeSelect6n10_1: disable read look-ahead feature\n")); 19120 /* sends SET FEATURES */ 19121 fis->h.fisType = 0x27; /* Reg host to device */ 19122 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19123 19124 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 19125 fis->h.features = 0x55; /* disable read look-ahead */ 19126 fis->d.lbaLow = 0; /* */ 19127 fis->d.lbaMid = 0; /* */ 19128 fis->d.lbaHigh = 0; /* */ 19129 fis->d.device = 0; /* */ 19130 fis->d.lbaLowExp = 0; /* */ 19131 fis->d.lbaMidExp = 0; /* */ 19132 fis->d.lbaHighExp = 0; /* */ 19133 fis->d.featuresExp = 0; /* */ 19134 fis->d.sectorCount = 0; /* */ 19135 fis->d.sectorCountExp = 0; /* */ 19136 fis->d.reserved4 = 0; 19137 fis->d.control = 0; /* FIS HOB bit clear */ 19138 fis->d.reserved5 = 0; 19139 19140 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 19141 19142 /* Initialize CB for SATA completion. 19143 */ 19144 satIOContext->satCompleteCB = &smsatModeSelect6n10CB; 19145 19146 /* 19147 * Prepare SGL and send FIS to LL layer. 19148 */ 19149 satIOContext->reqType = agRequestType; /* Save it */ 19150 19151 status = smsataLLIOStart( smRoot, 19152 smIORequest, 19153 smDeviceHandle, 19154 smScsiRequest, 19155 satIOContext); 19156 return status; 19157 } 19158 } 19159 19160 19161 osGLOBAL bit32 19162 smsatLogSense_1( 19163 smRoot_t *smRoot, 19164 smIORequest_t *smIORequest, 19165 smDeviceHandle_t *smDeviceHandle, 19166 smScsiInitiatorRequest_t *smScsiRequest, 19167 smSatIOContext_t *satIOContext 19168 ) 19169 { 19170 bit32 status; 19171 bit32 agRequestType; 19172 smDeviceData_t *pSatDevData; 19173 agsaFisRegHostToDevice_t *fis; 19174 19175 pSatDevData = satIOContext->pSatDevData; 19176 fis = satIOContext->pFis; 19177 19178 SM_DBG5(("smsatLogSense_1: start\n")); 19179 19180 /* SAT Rev 8, 10.2.4 p74 */ 19181 if ( pSatDevData->sat48BitSupport == agTRUE ) 19182 { 19183 SM_DBG5(("smsatLogSense_1: case 2-1 sends READ LOG EXT\n")); 19184 /* sends READ LOG EXT */ 19185 fis->h.fisType = 0x27; /* Reg host to device */ 19186 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19187 19188 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */ 19189 fis->h.features = 0; /* FIS reserve */ 19190 fis->d.lbaLow = 0x07; /* 0x07 */ 19191 fis->d.lbaMid = 0; /* */ 19192 fis->d.lbaHigh = 0; /* */ 19193 fis->d.device = 0; /* */ 19194 fis->d.lbaLowExp = 0; /* */ 19195 fis->d.lbaMidExp = 0; /* */ 19196 fis->d.lbaHighExp = 0; /* */ 19197 fis->d.featuresExp = 0; /* FIS reserve */ 19198 fis->d.sectorCount = 0x01; /* 1 sector counts */ 19199 fis->d.sectorCountExp = 0x00; /* 1 sector counts */ 19200 fis->d.reserved4 = 0; 19201 fis->d.control = 0; /* FIS HOB bit clear */ 19202 fis->d.reserved5 = 0; 19203 19204 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 19205 19206 /* Initialize CB for SATA completion. 19207 */ 19208 satIOContext->satCompleteCB = &smsatLogSenseCB; 19209 19210 /* 19211 * Prepare SGL and send FIS to LL layer. 19212 */ 19213 satIOContext->reqType = agRequestType; /* Save it */ 19214 19215 status = smsataLLIOStart( smRoot, 19216 smIORequest, 19217 smDeviceHandle, 19218 smScsiRequest, 19219 satIOContext); 19220 return status; 19221 19222 } 19223 else 19224 { 19225 SM_DBG5(("smsatLogSense_1: case 2-2 sends SMART READ LOG\n")); 19226 /* sends SMART READ LOG */ 19227 fis->h.fisType = 0x27; /* Reg host to device */ 19228 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19229 19230 fis->h.command = SAT_SMART; /* 0x2F */ 19231 fis->h.features = SAT_SMART_READ_LOG; /* 0xd5 */ 19232 fis->d.lbaLow = 0x06; /* 0x06 */ 19233 fis->d.lbaMid = 0x00; /* 0x4f */ 19234 fis->d.lbaHigh = 0x00; /* 0xc2 */ 19235 fis->d.device = 0; /* */ 19236 fis->d.lbaLowExp = 0; /* */ 19237 fis->d.lbaMidExp = 0; /* */ 19238 fis->d.lbaHighExp = 0; /* */ 19239 fis->d.featuresExp = 0; /* FIS reserve */ 19240 fis->d.sectorCount = 0x01; /* */ 19241 fis->d.sectorCountExp = 0x00; /* */ 19242 fis->d.reserved4 = 0; 19243 fis->d.control = 0; /* FIS HOB bit clear */ 19244 fis->d.reserved5 = 0; 19245 19246 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 19247 19248 /* Initialize CB for SATA completion. 19249 */ 19250 satIOContext->satCompleteCB = &smsatLogSenseCB; 19251 19252 /* 19253 * Prepare SGL and send FIS to LL layer. 19254 */ 19255 satIOContext->reqType = agRequestType; /* Save it */ 19256 19257 status = smsataLLIOStart( smRoot, 19258 smIORequest, 19259 smDeviceHandle, 19260 smScsiRequest, 19261 satIOContext); 19262 return status; 19263 19264 } 19265 } 19266 19267 osGLOBAL bit32 19268 smsatReassignBlocks_2( 19269 smRoot_t *smRoot, 19270 smIORequest_t *smIORequest, 19271 smDeviceHandle_t *smDeviceHandle, 19272 smScsiInitiatorRequest_t *smScsiRequest, 19273 smSatIOContext_t *satIOContext, 19274 bit8 *LBA 19275 ) 19276 { 19277 /* 19278 assumes all LBA fits in ATA command; no boundary condition is checked here yet 19279 tiScsiRequest is TD generated for writing 19280 */ 19281 bit32 status; 19282 bit32 agRequestType; 19283 smDeviceData_t *pSatDevData; 19284 smScsiRspSense_t *pSense; 19285 agsaFisRegHostToDevice_t *fis; 19286 19287 pSense = satIOContext->pSense; 19288 pSatDevData = satIOContext->pSatDevData; 19289 fis = satIOContext->pFis; 19290 SM_DBG5(("smsatReassignBlocks_2: start\n")); 19291 19292 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 19293 { 19294 /* case 2 */ 19295 /* WRITE DMA*/ 19296 /* can't fit the transfer length */ 19297 SM_DBG5(("smsatReassignBlocks_2: case 2\n")); 19298 fis->h.fisType = 0x27; /* Reg host to device */ 19299 fis->h.c_pmPort = 0x80; /* C bit is set */ 19300 fis->h.command = SAT_WRITE_DMA; /* 0xCA */ 19301 fis->h.features = 0; /* FIS reserve */ 19302 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 19303 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 19304 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 19305 19306 /* FIS LBA mode set LBA (27:24) */ 19307 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF)); 19308 19309 fis->d.lbaLowExp = 0; 19310 fis->d.lbaMidExp = 0; 19311 fis->d.lbaHighExp = 0; 19312 fis->d.featuresExp = 0; 19313 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 19314 fis->d.sectorCountExp = 0; 19315 fis->d.reserved4 = 0; 19316 fis->d.control = 0; /* FIS HOB bit clear */ 19317 fis->d.reserved5 = 0; 19318 19319 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 19320 satIOContext->ATACmd = SAT_WRITE_DMA; 19321 } 19322 else 19323 { 19324 /* case 1 */ 19325 /* WRITE MULTIPLE or WRITE SECTOR(S) */ 19326 /* WRITE SECTORS for easier implemetation */ 19327 /* can't fit the transfer length */ 19328 SM_DBG5(("smsatReassignBlocks_2: case 1\n")); 19329 fis->h.fisType = 0x27; /* Reg host to device */ 19330 fis->h.c_pmPort = 0x80; /* C bit is set */ 19331 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */ 19332 fis->h.features = 0; /* FIS reserve */ 19333 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 19334 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 19335 fis->d.lbaHigh = LBA[7]; /* FIS LBA (23:16) */ 19336 19337 /* FIS LBA mode set LBA (27:24) */ 19338 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF)); 19339 19340 fis->d.lbaLowExp = 0; 19341 fis->d.lbaMidExp = 0; 19342 fis->d.lbaHighExp = 0; 19343 fis->d.featuresExp = 0; 19344 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 19345 fis->d.sectorCountExp = 0; 19346 fis->d.reserved4 = 0; 19347 fis->d.control = 0; /* FIS HOB bit clear */ 19348 fis->d.reserved5 = 0; 19349 19350 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 19351 satIOContext->ATACmd = SAT_WRITE_SECTORS; 19352 } 19353 19354 /* case 3 and 4 */ 19355 if (pSatDevData->sat48BitSupport == agTRUE) 19356 { 19357 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE) 19358 { 19359 /* case 3 */ 19360 /* WRITE DMA EXT or WRITE DMA FUA EXT */ 19361 SM_DBG5(("smsatReassignBlocks_2: case 3\n")); 19362 fis->h.fisType = 0x27; /* Reg host to device */ 19363 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19364 19365 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */ 19366 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */ 19367 satIOContext->ATACmd = SAT_WRITE_DMA_EXT; 19368 19369 fis->h.features = 0; /* FIS reserve */ 19370 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 19371 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 19372 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 19373 fis->d.device = 0x40; /* FIS LBA mode set */ 19374 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */ 19375 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */ 19376 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */ 19377 fis->d.featuresExp = 0; /* FIS reserve */ 19378 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 19379 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 19380 fis->d.reserved4 = 0; 19381 fis->d.control = 0; /* FIS HOB bit clear */ 19382 fis->d.reserved5 = 0; 19383 19384 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; 19385 } 19386 else 19387 { 19388 /* case 4 */ 19389 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */ 19390 /* WRITE SECTORS EXT for easier implemetation */ 19391 SM_DBG5(("smsatReassignBlocks_2: case 4\n")); 19392 fis->h.fisType = 0x27; /* Reg host to device */ 19393 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19394 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */ 19395 19396 fis->h.features = 0; /* FIS reserve */ 19397 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 19398 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 19399 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 19400 fis->d.device = 0x40; /* FIS LBA mode set */ 19401 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */ 19402 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */ 19403 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */ 19404 fis->d.featuresExp = 0; /* FIS reserve */ 19405 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 19406 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 19407 fis->d.reserved4 = 0; 19408 fis->d.control = 0; /* FIS HOB bit clear */ 19409 fis->d.reserved5 = 0; 19410 19411 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; 19412 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT; 19413 } 19414 } 19415 /* case 5 */ 19416 if (pSatDevData->satNCQ == agTRUE) 19417 { 19418 /* WRITE FPDMA QUEUED */ 19419 if (pSatDevData->sat48BitSupport != agTRUE) 19420 { 19421 SM_DBG5(("smsatReassignBlocks_2: case 5 !!! error NCQ but 28 bit address support \n")); 19422 smsatSetSensePayload( pSense, 19423 SCSI_SNSKEY_HARDWARE_ERROR, 19424 0, 19425 SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED, 19426 satIOContext); 19427 19428 /*smEnqueueIO(smRoot, satIOContext);*/ 19429 19430 tdsmIOCompletedCB( smRoot, 19431 smIORequest, 19432 smIOSuccess, 19433 SCSI_STAT_CHECK_CONDITION, 19434 satIOContext->pSmSenseData, 19435 satIOContext->interruptContext ); 19436 return SM_RC_SUCCESS; 19437 } 19438 SM_DBG6(("satWrite10: case 5\n")); 19439 19440 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */ 19441 19442 fis->h.fisType = 0x27; /* Reg host to device */ 19443 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19444 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */ 19445 fis->h.features = 1; /* FIS sector count (7:0) */ 19446 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 19447 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 19448 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 19449 19450 /* Check FUA bit */ 19451 fis->d.device = 0x40; /* FIS FUA clear */ 19452 19453 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */ 19454 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */ 19455 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */ 19456 fis->d.featuresExp = 0; /* FIS sector count (15:8) */ 19457 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */ 19458 fis->d.sectorCountExp = 0; 19459 fis->d.reserved4 = 0; 19460 fis->d.control = 0; /* FIS HOB bit clear */ 19461 fis->d.reserved5 = 0; 19462 19463 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; 19464 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED; 19465 } 19466 19467 satIOContext->satCompleteCB = &smsatReassignBlocksCB; 19468 19469 /* 19470 * Prepare SGL and send FIS to LL layer. 19471 */ 19472 satIOContext->reqType = agRequestType; /* Save it */ 19473 19474 status = smsataLLIOStart( smRoot, 19475 smIORequest, 19476 smDeviceHandle, 19477 /* not the original, should be the TD generated one */ 19478 smScsiRequest, 19479 satIOContext); 19480 return (status); 19481 } 19482 19483 osGLOBAL bit32 19484 smsatReassignBlocks_1( 19485 smRoot_t *smRoot, 19486 smIORequest_t *smIORequest, 19487 smDeviceHandle_t *smDeviceHandle, 19488 smScsiInitiatorRequest_t *smScsiRequest, 19489 smSatIOContext_t *satIOContext, 19490 smSatIOContext_t *satOrgIOContext 19491 ) 19492 { 19493 /* 19494 assumes all LBA fits in ATA command; no boundary condition is checked here yet 19495 tiScsiRequest is OS generated; needs for accessing parameter list 19496 */ 19497 bit32 agRequestType; 19498 smDeviceData_t *pSatDevData; 19499 smIniScsiCmnd_t *scsiCmnd; 19500 agsaFisRegHostToDevice_t *fis; 19501 bit8 *pParmList; /* Log Page data buffer */ 19502 bit8 LongLBA; 19503 bit8 LBA[8]; 19504 bit32 startingIndex; 19505 19506 pSatDevData = satIOContext->pSatDevData; 19507 scsiCmnd = &smScsiRequest->scsiCmnd; 19508 fis = satIOContext->pFis; 19509 pParmList = (bit8 *) smScsiRequest->sglVirtualAddr; 19510 SM_DBG5(("smsatReassignBlocks_1: start\n")); 19511 LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK); 19512 sm_memset(LBA, 0, sizeof(LBA)); 19513 startingIndex = satOrgIOContext->ParmIndex; 19514 if (LongLBA == 0) 19515 { 19516 LBA[4] = pParmList[startingIndex]; 19517 LBA[5] = pParmList[startingIndex+1]; 19518 LBA[6] = pParmList[startingIndex+2]; 19519 LBA[7] = pParmList[startingIndex+3]; 19520 startingIndex = startingIndex + 4; 19521 } 19522 else 19523 { 19524 LBA[0] = pParmList[startingIndex]; 19525 LBA[1] = pParmList[startingIndex+1]; 19526 LBA[2] = pParmList[startingIndex+2]; 19527 LBA[3] = pParmList[startingIndex+3]; 19528 LBA[4] = pParmList[startingIndex+4]; 19529 LBA[5] = pParmList[startingIndex+5]; 19530 LBA[6] = pParmList[startingIndex+6]; 19531 LBA[7] = pParmList[startingIndex+7]; 19532 startingIndex = startingIndex + 8; 19533 } 19534 19535 if (pSatDevData->sat48BitSupport == agTRUE) 19536 { 19537 /* sends READ VERIFY SECTOR(S) EXT*/ 19538 fis->h.fisType = 0x27; /* Reg host to device */ 19539 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19540 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */ 19541 fis->h.features = 0; /* FIS reserve */ 19542 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 19543 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 19544 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 19545 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */ 19546 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */ 19547 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */ 19548 fis->d.featuresExp = 0; /* FIS reserve */ 19549 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 19550 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */ 19551 fis->d.reserved4 = 0; 19552 fis->d.device = 0x40; /* 01000000 */ 19553 fis->d.control = 0; /* FIS HOB bit clear */ 19554 fis->d.reserved5 = 0; 19555 } 19556 else 19557 { 19558 /* READ VERIFY SECTOR(S)*/ 19559 fis->h.fisType = 0x27; /* Reg host to device */ 19560 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19561 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */ 19562 fis->h.features = 0; /* FIS features NA */ 19563 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */ 19564 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */ 19565 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */ 19566 fis->d.lbaLowExp = 0; 19567 fis->d.lbaMidExp = 0; 19568 fis->d.lbaHighExp = 0; 19569 fis->d.featuresExp = 0; 19570 fis->d.sectorCount = 1; /* FIS sector count (7:0) */ 19571 fis->d.sectorCountExp = 0; 19572 fis->d.reserved4 = 0; 19573 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF)); 19574 /* DEV and LBA 27:24 */ 19575 fis->d.control = 0; /* FIS HOB bit clear */ 19576 fis->d.reserved5 = 0; 19577 } 19578 19579 sm_memcpy(satOrgIOContext->LBA, LBA, 8); 19580 satOrgIOContext->ParmIndex = startingIndex; 19581 19582 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 19583 19584 /* Initialize CB for SATA completion. 19585 */ 19586 satIOContext->satCompleteCB = &smsatReassignBlocksCB; 19587 19588 /* 19589 * Prepare SGL and send FIS to LL layer. 19590 */ 19591 satIOContext->reqType = agRequestType; /* Save it */ 19592 19593 smsataLLIOStart( smRoot, 19594 smIORequest, 19595 smDeviceHandle, 19596 smScsiRequest, 19597 satIOContext); 19598 19599 return SM_RC_SUCCESS; 19600 } 19601 19602 osGLOBAL bit32 19603 smsatSendReadLogExt( 19604 smRoot_t *smRoot, 19605 smIORequest_t *smIORequest, 19606 smDeviceHandle_t *smDeviceHandle, 19607 smScsiInitiatorRequest_t *smScsiRequest, 19608 smSatIOContext_t *satIOContext 19609 ) 19610 { 19611 bit32 status; 19612 bit32 agRequestType; 19613 agsaFisRegHostToDevice_t *fis; 19614 19615 fis = satIOContext->pFis; 19616 SM_DBG1(("smsatSendReadLogExt: start\n")); 19617 fis->h.fisType = 0x27; /* Reg host to device */ 19618 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19619 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */ 19620 fis->h.features = 0; /* FIS reserve */ 19621 fis->d.lbaLow = 0x10; /* Page number */ 19622 fis->d.lbaMid = 0; /* */ 19623 fis->d.lbaHigh = 0; /* */ 19624 fis->d.device = 0; /* DEV is ignored in SATA */ 19625 fis->d.lbaLowExp = 0; /* */ 19626 fis->d.lbaMidExp = 0; /* */ 19627 fis->d.lbaHighExp = 0; /* */ 19628 fis->d.featuresExp = 0; /* FIS reserve */ 19629 fis->d.sectorCount = 0x01; /* 1 sector counts*/ 19630 fis->d.sectorCountExp = 0x00; /* 1 sector counts */ 19631 fis->d.reserved4 = 0; 19632 fis->d.control = 0; /* FIS HOB bit clear */ 19633 fis->d.reserved5 = 0; 19634 19635 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; 19636 19637 /* Initialize CB for SATA completion. 19638 */ 19639 satIOContext->satCompleteCB = &smsatReadLogExtCB; 19640 19641 /* 19642 * Prepare SGL and send FIS to LL layer. 19643 */ 19644 satIOContext->reqType = agRequestType; /* Save it */ 19645 19646 status = smsataLLIOStart( smRoot, 19647 smIORequest, 19648 smDeviceHandle, 19649 smScsiRequest, 19650 satIOContext); 19651 19652 SM_DBG1(("smsatSendReadLogExt: end status %d!!!\n", status)); 19653 19654 return (status); 19655 } 19656 19657 osGLOBAL bit32 19658 smsatCheckPowerMode( 19659 smRoot_t *smRoot, 19660 smIORequest_t *smIORequest, 19661 smDeviceHandle_t *smDeviceHandle, 19662 smScsiInitiatorRequest_t *smScsiRequest, 19663 smSatIOContext_t *satIOContext 19664 ) 19665 { 19666 /* 19667 sends SAT_CHECK_POWER_MODE as a part of ABORT TASKMANGEMENT for NCQ commands 19668 internally generated - no directly corresponding scsi 19669 */ 19670 bit32 status; 19671 bit32 agRequestType; 19672 agsaFisRegHostToDevice_t *fis; 19673 19674 fis = satIOContext->pFis; 19675 SM_DBG1(("smsatCheckPowerMode: start\n")); 19676 /* 19677 * Send the ATA CHECK POWER MODE command. 19678 */ 19679 fis->h.fisType = 0x27; /* Reg host to device */ 19680 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19681 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */ 19682 fis->h.features = 0; 19683 fis->d.lbaLow = 0; 19684 fis->d.lbaMid = 0; 19685 fis->d.lbaHigh = 0; 19686 fis->d.device = 0; 19687 fis->d.lbaLowExp = 0; 19688 fis->d.lbaMidExp = 0; 19689 fis->d.lbaHighExp = 0; 19690 fis->d.featuresExp = 0; 19691 fis->d.sectorCount = 0; 19692 fis->d.sectorCountExp = 0; 19693 fis->d.reserved4 = 0; 19694 fis->d.control = 0; /* FIS HOB bit clear */ 19695 fis->d.reserved5 = 0; 19696 19697 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 19698 19699 /* Initialize CB for SATA completion. 19700 */ 19701 satIOContext->satCompleteCB = &smsatCheckPowerModeCB; 19702 19703 /* 19704 * Prepare SGL and send FIS to LL layer. 19705 */ 19706 satIOContext->reqType = agRequestType; /* Save it */ 19707 19708 status = smsataLLIOStart( smRoot, 19709 smIORequest, 19710 smDeviceHandle, 19711 smScsiRequest, 19712 satIOContext); 19713 19714 SM_DBG5(("smsatCheckPowerMode: return\n")); 19715 19716 return status; 19717 } 19718 19719 osGLOBAL bit32 19720 smsatResetDevice( 19721 smRoot_t *smRoot, 19722 smIORequest_t *smIORequest, 19723 smDeviceHandle_t *smDeviceHandle, 19724 smScsiInitiatorRequest_t *smScsiRequest, /* NULL */ 19725 smSatIOContext_t *satIOContext 19726 ) 19727 { 19728 bit32 status; 19729 bit32 agRequestType; 19730 agsaFisRegHostToDevice_t *fis; 19731 #ifdef TD_DEBUG_ENABLE 19732 smIORequestBody_t *smIORequestBody; 19733 smSatInternalIo_t *satIntIoContext; 19734 #endif 19735 19736 fis = satIOContext->pFis; 19737 SM_DBG1(("smsatResetDevice: start\n")); 19738 #ifdef TD_DEBUG_ENABLE 19739 satIntIoContext = satIOContext->satIntIoContext; 19740 smIORequestBody = satIntIoContext->satIntRequestBody; 19741 #endif 19742 SM_DBG5(("smsatResetDevice: satIOContext %p smIORequestBody %p\n", satIOContext, smIORequestBody)); 19743 /* any fis should work */ 19744 fis->h.fisType = 0x27; /* Reg host to device */ 19745 fis->h.c_pmPort = 0; /* C Bit is not set */ 19746 fis->h.command = 0; /* any command */ 19747 fis->h.features = 0; /* FIS reserve */ 19748 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 19749 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 19750 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 19751 fis->d.device = 0; /* FIS LBA mode */ 19752 fis->d.lbaLowExp = 0; 19753 fis->d.lbaMidExp = 0; 19754 fis->d.lbaHighExp = 0; 19755 fis->d.featuresExp = 0; 19756 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 19757 fis->d.sectorCountExp = 0; 19758 fis->d.reserved4 = 0; 19759 fis->d.control = 0x4; /* SRST bit is set */ 19760 fis->d.reserved5 = 0; 19761 19762 agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT; 19763 19764 /* Initialize CB for SATA completion. 19765 */ 19766 satIOContext->satCompleteCB = &smsatResetDeviceCB; 19767 19768 /* 19769 * Prepare SGL and send FIS to LL layer. 19770 */ 19771 satIOContext->reqType = agRequestType; /* Save it */ 19772 19773 #ifdef SM_INTERNAL_DEBUG 19774 smhexdump("smsatResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 19775 #ifdef TD_DEBUG_ENABLE 19776 smhexdump("smsatResetDevice LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t)); 19777 #endif 19778 #endif 19779 19780 status = smsataLLIOStart( smRoot, 19781 smIORequest, 19782 smDeviceHandle, 19783 smScsiRequest, 19784 satIOContext); 19785 19786 SM_DBG6(("smsatResetDevice: end status %d\n", status)); 19787 return status; 19788 } 19789 19790 osGLOBAL bit32 19791 smsatDeResetDevice( 19792 smRoot_t *smRoot, 19793 smIORequest_t *smIORequest, 19794 smDeviceHandle_t *smDeviceHandle, 19795 smScsiInitiatorRequest_t *smScsiRequest, 19796 smSatIOContext_t *satIOContext 19797 ) 19798 { 19799 bit32 status; 19800 bit32 agRequestType; 19801 agsaFisRegHostToDevice_t *fis; 19802 #ifdef TD_DEBUG_ENABLE 19803 smIORequestBody_t *smIORequestBody; 19804 smSatInternalIo_t *satIntIoContext; 19805 #endif 19806 19807 fis = satIOContext->pFis; 19808 SM_DBG1(("smsatDeResetDevice: start\n")); 19809 #ifdef TD_DEBUG_ENABLE 19810 satIntIoContext = satIOContext->satIntIoContext; 19811 smIORequestBody = satIntIoContext->satIntRequestBody; 19812 #endif 19813 SM_DBG5(("smsatDeResetDevice: satIOContext %p smIORequestBody %p\n", satIOContext, smIORequestBody)); 19814 /* any fis should work */ 19815 fis->h.fisType = 0x27; /* Reg host to device */ 19816 fis->h.c_pmPort = 0; /* C Bit is not set */ 19817 fis->h.command = 0; /* any command */ 19818 fis->h.features = 0; /* FIS reserve */ 19819 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */ 19820 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */ 19821 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */ 19822 fis->d.device = 0; /* FIS LBA mode */ 19823 fis->d.lbaLowExp = 0; 19824 fis->d.lbaMidExp = 0; 19825 fis->d.lbaHighExp = 0; 19826 fis->d.featuresExp = 0; 19827 fis->d.sectorCount = 0; /* FIS sector count (7:0) */ 19828 fis->d.sectorCountExp = 0; 19829 fis->d.reserved4 = 0; 19830 fis->d.control = 0; /* SRST bit is not set */ 19831 fis->d.reserved5 = 0; 19832 19833 agRequestType = AGSA_SATA_PROTOCOL_SRST_DEASSERT; 19834 19835 /* Initialize CB for SATA completion. 19836 */ 19837 satIOContext->satCompleteCB = &smsatDeResetDeviceCB; 19838 19839 /* 19840 * Prepare SGL and send FIS to LL layer. 19841 */ 19842 satIOContext->reqType = agRequestType; /* Save it */ 19843 19844 #ifdef SM_INTERNAL_DEBUG 19845 smhexdump("smsatDeResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t)); 19846 #ifdef TD_DEBUG_ENABLE 19847 smhexdump("smsatDeResetDevice LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t)); 19848 #endif 19849 #endif 19850 19851 status = smsataLLIOStart( smRoot, 19852 smIORequest, 19853 smDeviceHandle, 19854 smScsiRequest, 19855 satIOContext); 19856 19857 SM_DBG6(("smsatDeResetDevice: end status %d\n", status)); 19858 return status; 19859 } 19860 19861 /* set feature for auto activate */ 19862 osGLOBAL bit32 19863 smsatSetFeaturesAA( 19864 smRoot_t *smRoot, 19865 smIORequest_t *smIORequest, 19866 smDeviceHandle_t *smDeviceHandle, 19867 smScsiInitiatorRequest_t *smScsiRequest, 19868 smSatIOContext_t *satIOContext 19869 ) 19870 { 19871 bit32 status = SM_RC_FAILURE; 19872 bit32 agRequestType; 19873 agsaFisRegHostToDevice_t *fis; 19874 19875 fis = satIOContext->pFis; 19876 SM_DBG2(("smsatSetFeaturesAA: start\n")); 19877 /* 19878 * Send the Set Features command. 19879 * See SATA II 1.0a spec 19880 */ 19881 fis->h.fisType = 0x27; /* Reg host to device */ 19882 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19883 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 19884 fis->h.features = 0x10; /* enable SATA feature */ 19885 fis->d.lbaLow = 0; 19886 fis->d.lbaMid = 0; 19887 fis->d.lbaHigh = 0; 19888 fis->d.device = 0; 19889 fis->d.lbaLowExp = 0; 19890 fis->d.lbaMidExp = 0; 19891 fis->d.lbaHighExp = 0; 19892 fis->d.featuresExp = 0; 19893 fis->d.sectorCount = 0x02; /* DMA Setup FIS Auto-Activate */ 19894 fis->d.sectorCountExp = 0; 19895 fis->d.reserved4 = 0; 19896 fis->d.control = 0; /* FIS HOB bit clear */ 19897 fis->d.reserved5 = 0; 19898 19899 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 19900 19901 /* Initialize CB for SATA completion. 19902 */ 19903 satIOContext->satCompleteCB = &smsatSetFeaturesAACB; 19904 19905 /* 19906 * Prepare SGL and send FIS to LL layer. 19907 */ 19908 satIOContext->reqType = agRequestType; /* Save it */ 19909 19910 status = smsataLLIOStart( smRoot, 19911 smIORequest, 19912 smDeviceHandle, 19913 smScsiRequest, 19914 satIOContext); 19915 19916 /* debugging code */ 19917 if (smIORequest->tdData == smIORequest->smData) 19918 { 19919 SM_DBG1(("smsatSetFeaturesAA: incorrect smIORequest\n")); 19920 } 19921 SM_DBG2(("smsatSetFeatures: return\n")); 19922 return status; 19923 } 19924 19925 19926 /* set feature for DMA transfer mode*/ 19927 osGLOBAL bit32 19928 smsatSetFeaturesDMA( 19929 smRoot_t *smRoot, 19930 smIORequest_t *smIORequest, 19931 smDeviceHandle_t *smDeviceHandle, 19932 smScsiInitiatorRequest_t *smScsiRequest, 19933 smSatIOContext_t *satIOContext 19934 ) 19935 { 19936 bit32 status = SM_RC_FAILURE; 19937 bit32 agRequestType; 19938 smDeviceData_t *pSatDevData; 19939 agsaFisRegHostToDevice_t *fis; 19940 19941 pSatDevData = satIOContext->pSatDevData; 19942 fis = satIOContext->pFis; 19943 SM_DBG2(("smsatSetFeaturesDMA: start\n")); 19944 /* 19945 * Send the Set Features command. 19946 * See SATA II 1.0a spec 19947 */ 19948 fis->h.fisType = 0x27; /* Reg host to device */ 19949 fis->h.c_pmPort = 0x80; /* C Bit is set */ 19950 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 19951 fis->h.features = 0x03; /* enable ATA transfer mode */ 19952 fis->d.lbaLow = 0; 19953 fis->d.lbaMid = 0; 19954 fis->d.lbaHigh = 0; 19955 fis->d.device = 0; 19956 fis->d.lbaLowExp = 0; 19957 fis->d.lbaMidExp = 0; 19958 fis->d.lbaHighExp = 0; 19959 fis->d.featuresExp = 0; 19960 fis->d.sectorCount = 0x40 |(bit8)pSatDevData->satUltraDMAMode; /* enable Ultra DMA mode */ 19961 fis->d.sectorCountExp = 0; 19962 fis->d.reserved4 = 0; 19963 fis->d.control = 0; /* FIS HOB bit clear */ 19964 fis->d.reserved5 = 0; 19965 19966 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 19967 19968 /* Initialize CB for SATA completion. 19969 */ 19970 satIOContext->satCompleteCB = &smsatSetFeaturesDMACB; 19971 19972 /* 19973 * Prepare SGL and send FIS to LL layer. 19974 */ 19975 satIOContext->reqType = agRequestType; /* Save it */ 19976 19977 status = smsataLLIOStart( smRoot, 19978 smIORequest, 19979 smDeviceHandle, 19980 smScsiRequest, 19981 satIOContext); 19982 19983 /* debugging code */ 19984 if (smIORequest->tdData == smIORequest->smData) 19985 { 19986 SM_DBG1(("smsatSetFeaturesDMA: incorrect smIORequest\n")); 19987 } 19988 19989 SM_DBG2(("smsatSetFeaturesDMA: return\n")); 19990 19991 return status; 19992 } 19993 19994 /* set feature for Read Look Ahead*/ 19995 osGLOBAL bit32 19996 smsatSetFeaturesReadLookAhead( 19997 smRoot_t *smRoot, 19998 smIORequest_t *smIORequest, 19999 smDeviceHandle_t *smDeviceHandle, 20000 smScsiInitiatorRequest_t *smScsiRequest, 20001 smSatIOContext_t *satIOContext 20002 ) 20003 { 20004 bit32 status = SM_RC_FAILURE; 20005 bit32 agRequestType; 20006 agsaFisRegHostToDevice_t *fis; 20007 20008 fis = satIOContext->pFis; 20009 SM_DBG2(("smsatSetFeaturesReadLookAhead: start\n")); 20010 /* 20011 * Send the Set Features command. 20012 * See SATA II 1.0a spec 20013 */ 20014 fis->h.fisType = 0x27; /* Reg host to device */ 20015 fis->h.c_pmPort = 0x80; /* C Bit is set */ 20016 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 20017 fis->h.features = 0xAA; /* Enable read look-ahead feature */ 20018 fis->d.lbaLow = 0; 20019 fis->d.lbaMid = 0; 20020 fis->d.lbaHigh = 0; 20021 fis->d.device = 0; 20022 fis->d.lbaLowExp = 0; 20023 fis->d.lbaMidExp = 0; 20024 fis->d.lbaHighExp = 0; 20025 fis->d.featuresExp = 0; 20026 fis->d.sectorCount = 0; 20027 fis->d.sectorCountExp = 0; 20028 fis->d.reserved4 = 0; 20029 fis->d.control = 0; /* FIS HOB bit clear */ 20030 fis->d.reserved5 = 0; 20031 20032 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 20033 20034 /* Initialize CB for SATA completion. 20035 */ 20036 satIOContext->satCompleteCB = &smsatSetFeaturesReadLookAheadCB; 20037 20038 /* 20039 * Prepare SGL and send FIS to LL layer. 20040 */ 20041 satIOContext->reqType = agRequestType; /* Save it */ 20042 20043 status = smsataLLIOStart( smRoot, 20044 smIORequest, 20045 smDeviceHandle, 20046 smScsiRequest, 20047 satIOContext); 20048 20049 /* debugging code */ 20050 if (smIORequest->tdData == smIORequest->smData) 20051 { 20052 SM_DBG1(("smsatSetFeaturesReadLookAhead: incorrect smIORequest\n")); 20053 } 20054 20055 SM_DBG2(("smsatSetFeaturesReadLookAhead: return\n")); 20056 20057 return status; 20058 } 20059 20060 /* set feature for Volatile Write Cache*/ 20061 osGLOBAL bit32 20062 smsatSetFeaturesVolatileWriteCache( 20063 smRoot_t *smRoot, 20064 smIORequest_t *smIORequest, 20065 smDeviceHandle_t *smDeviceHandle, 20066 smScsiInitiatorRequest_t *smScsiRequest, 20067 smSatIOContext_t *satIOContext 20068 ) 20069 { 20070 bit32 status = SM_RC_FAILURE; 20071 bit32 agRequestType; 20072 agsaFisRegHostToDevice_t *fis; 20073 20074 fis = satIOContext->pFis; 20075 SM_DBG2(("smsatSetFeaturesVolatileWriteCache: start\n")); 20076 /* 20077 * Send the Set Features command. 20078 * See SATA II 1.0a spec 20079 */ 20080 fis->h.fisType = 0x27; /* Reg host to device */ 20081 fis->h.c_pmPort = 0x80; /* C Bit is set */ 20082 fis->h.command = SAT_SET_FEATURES; /* 0xEF */ 20083 fis->h.features = 0x02; /* Enable Volatile Write Cache feature */ 20084 fis->d.lbaLow = 0; 20085 fis->d.lbaMid = 0; 20086 fis->d.lbaHigh = 0; 20087 fis->d.device = 0; 20088 fis->d.lbaLowExp = 0; 20089 fis->d.lbaMidExp = 0; 20090 fis->d.lbaHighExp = 0; 20091 fis->d.featuresExp = 0; 20092 fis->d.sectorCount = 0; 20093 fis->d.sectorCountExp = 0; 20094 fis->d.reserved4 = 0; 20095 fis->d.control = 0; /* FIS HOB bit clear */ 20096 fis->d.reserved5 = 0; 20097 20098 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; 20099 20100 /* Initialize CB for SATA completion. 20101 */ 20102 satIOContext->satCompleteCB = &smsatSetFeaturesVolatileWriteCacheCB; 20103 /* 20104 * Prepare SGL and send FIS to LL layer. 20105 */ 20106 satIOContext->reqType = agRequestType; /* Save it */ 20107 20108 status = smsataLLIOStart( smRoot, 20109 smIORequest, 20110 smDeviceHandle, 20111 smScsiRequest, 20112 satIOContext); 20113 /* debugging code */ 20114 if (smIORequest->tdData == smIORequest->smData) 20115 { 20116 SM_DBG1(("smsatSetFeaturesVolatileWriteCache: incorrect smIORequest\n")); 20117 } 20118 SM_DBG2(("smsatSetFeaturesVolatileWriteCache: return\n")); 20119 20120 return status; 20121 } 20122 20123 20124 20125 /******************************** start of utils ***********************************************************/ 20126 osGLOBAL FORCEINLINE void 20127 smsatBitSet(smRoot_t *smRoot, bit8 *data, bit32 index) 20128 { 20129 data[index>>3] |= (1 << (index&7)); 20130 } 20131 20132 osGLOBAL FORCEINLINE void 20133 smsatBitClear(smRoot_t *smRoot, bit8 *data, bit32 index) 20134 { 20135 data[index>>3] &= ~(1 << (index&7)); 20136 } 20137 20138 osGLOBAL FORCEINLINE BOOLEAN 20139 smsatBitTest(smRoot_t *smRoot, bit8 *data, bit32 index) 20140 { 20141 return ( (BOOLEAN)((data[index>>3] & (1 << (index&7)) ) ? 1: 0)); 20142 } 20143 20144 20145 FORCEINLINE bit32 20146 smsatTagAlloc( 20147 smRoot_t *smRoot, 20148 smDeviceData_t *pSatDevData, 20149 bit8 *pTag 20150 ) 20151 { 20152 bit32 retCode = agFALSE; 20153 bit32 i; 20154 20155 tdsmSingleThreadedEnter(smRoot, SM_NCQ_TAG_LOCK); 20156 20157 #ifdef CCFLAG_OPTIMIZE_SAT_LOCK 20158 20159 if (tdsmBitScanForward(smRoot, &i, ~(pSatDevData->freeSATAFDMATagBitmap))) 20160 { 20161 smsatBitSet(smRoot, (bit8*)&pSatDevData->freeSATAFDMATagBitmap, i); 20162 *pTag = (bit8)i; 20163 retCode = agTRUE; 20164 } 20165 20166 #else 20167 20168 for ( i = 0; i < pSatDevData->satNCQMaxIO; i ++ ) 20169 { 20170 if ( 0 == smsatBitTest(smRoot, (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, i) ) 20171 { 20172 smsatBitSet(smRoot, (bit8*)&pSatDevData->freeSATAFDMATagBitmap, i); 20173 *pTag = (bit8) i; 20174 retCode = agTRUE; 20175 break; 20176 } 20177 } 20178 20179 #endif 20180 20181 tdsmSingleThreadedLeave(smRoot, SM_NCQ_TAG_LOCK); 20182 20183 return retCode; 20184 } 20185 20186 FORCEINLINE bit32 20187 smsatTagRelease( 20188 smRoot_t *smRoot, 20189 smDeviceData_t *pSatDevData, 20190 bit8 tag 20191 ) 20192 { 20193 bit32 retCode = agFALSE; 20194 20195 if ( tag < pSatDevData->satNCQMaxIO ) 20196 { 20197 tdsmSingleThreadedEnter(smRoot, SM_NCQ_TAG_LOCK); 20198 smsatBitClear(smRoot, (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, (bit32)tag); 20199 tdsmSingleThreadedLeave(smRoot, SM_NCQ_TAG_LOCK); 20200 /*tdsmInterlockedAnd(smRoot, (volatile LONG *)(&pSatDevData->freeSATAFDMATagBitmap), ~(1 << (tag&31)));*/ 20201 retCode = agTRUE; 20202 } 20203 else 20204 { 20205 SM_DBG1(("smsatTagRelease: tag %d >= satNCQMaxIO %d!!!!\n", tag, pSatDevData->satNCQMaxIO)); 20206 } 20207 return retCode; 20208 } 20209 20210 20211 20212 osGLOBAL bit32 20213 smsatComputeCDB10LBA(smSatIOContext_t *satIOContext) 20214 { 20215 smIniScsiCmnd_t *scsiCmnd; 20216 smScsiInitiatorRequest_t *smScsiRequest; 20217 bit32 lba = 0; 20218 20219 SM_DBG5(("smsatComputeCDB10LBA: start\n")); 20220 smScsiRequest = satIOContext->smScsiXchg; 20221 scsiCmnd = &(smScsiRequest->scsiCmnd); 20222 20223 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 20224 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 20225 20226 return lba; 20227 } 20228 20229 osGLOBAL bit32 20230 smsatComputeCDB10TL(smSatIOContext_t *satIOContext) 20231 { 20232 20233 smIniScsiCmnd_t *scsiCmnd; 20234 smScsiInitiatorRequest_t *smScsiRequest; 20235 bit32 tl = 0; 20236 20237 SM_DBG5(("smsatComputeCDB10TL: start\n")); 20238 smScsiRequest = satIOContext->smScsiXchg; 20239 scsiCmnd = &(smScsiRequest->scsiCmnd); 20240 20241 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]; 20242 return tl; 20243 } 20244 20245 osGLOBAL bit32 20246 smsatComputeCDB12LBA(smSatIOContext_t *satIOContext) 20247 { 20248 smIniScsiCmnd_t *scsiCmnd; 20249 smScsiInitiatorRequest_t *smScsiRequest; 20250 bit32 lba = 0; 20251 20252 SM_DBG5(("smsatComputeCDB12LBA: start\n")); 20253 smScsiRequest = satIOContext->smScsiXchg; 20254 scsiCmnd = &(smScsiRequest->scsiCmnd); 20255 20256 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2)) 20257 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5]; 20258 20259 return lba; 20260 } 20261 20262 osGLOBAL bit32 20263 smsatComputeCDB12TL(smSatIOContext_t *satIOContext) 20264 { 20265 20266 smIniScsiCmnd_t *scsiCmnd; 20267 smScsiInitiatorRequest_t *smScsiRequest; 20268 bit32 tl = 0; 20269 20270 SM_DBG5(("smsatComputeCDB12TL: start\n")); 20271 smScsiRequest = satIOContext->smScsiXchg; 20272 scsiCmnd = &(smScsiRequest->scsiCmnd); 20273 20274 tl = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2)) 20275 + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9]; 20276 return tl; 20277 } 20278 20279 /* 20280 CBD16 has bit64 LBA 20281 But it has to be less than (2^28 - 1) 20282 Therefore, use last four bytes to compute LBA is OK 20283 */ 20284 osGLOBAL bit32 20285 smsatComputeCDB16LBA(smSatIOContext_t *satIOContext) 20286 { 20287 smIniScsiCmnd_t *scsiCmnd; 20288 smScsiInitiatorRequest_t *smScsiRequest; 20289 bit32 lba = 0; 20290 20291 SM_DBG5(("smsatComputeCDB16LBA: start\n")); 20292 smScsiRequest = satIOContext->smScsiXchg; 20293 scsiCmnd = &(smScsiRequest->scsiCmnd); 20294 20295 lba = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2)) 20296 + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9]; 20297 20298 return lba; 20299 } 20300 20301 osGLOBAL bit32 20302 smsatComputeCDB16TL(smSatIOContext_t *satIOContext) 20303 { 20304 20305 smIniScsiCmnd_t *scsiCmnd; 20306 smScsiInitiatorRequest_t *smScsiRequest; 20307 bit32 tl = 0; 20308 20309 SM_DBG5(("smsatComputeCDB16TL: start\n")); 20310 smScsiRequest = satIOContext->smScsiXchg; 20311 scsiCmnd = &(smScsiRequest->scsiCmnd); 20312 20313 tl = (scsiCmnd->cdb[10] << (8*3)) + (scsiCmnd->cdb[11] << (8*2)) 20314 + (scsiCmnd->cdb[12] << 8) + scsiCmnd->cdb[13]; 20315 return tl; 20316 } 20317 20318 /* 20319 (tl, denom) 20320 tl can be upto bit32 because CDB16 has bit32 tl 20321 Therefore, fine 20322 either (tl, 0xFF) or (tl, 0xFFFF) 20323 */ 20324 osGLOBAL FORCEINLINE bit32 20325 smsatComputeLoopNum(bit32 a, bit32 b) 20326 { 20327 bit32 LoopNum = 0; 20328 20329 SM_DBG5(("smsatComputeLoopNum: start\n")); 20330 20331 if (a < b || a == 0) 20332 { 20333 LoopNum = 1; 20334 } 20335 else 20336 { 20337 if (a == b || a == 0) 20338 { 20339 LoopNum = a/b; 20340 } 20341 else 20342 { 20343 LoopNum = a/b + 1; 20344 } 20345 } 20346 20347 return LoopNum; 20348 } 20349 20350 /* 20351 Generic new function for checking 20352 LBA itself, LBA+TL < SAT_TR_LBA_LIMIT or SAT_EXT_TR_LBA_LIMIT 20353 and LBA+TL < Read Capacity Limit 20354 flag: false - not 48BitSupport; true - 48BitSupport 20355 returns TRUE when over the limit 20356 20357 */ 20358 osGLOBAL FORCEINLINE bit32 20359 smsatCheckLimit(bit8 *lba, bit8 *tl, int flag, smDeviceData_t *pSatDevData) 20360 { 20361 bit32 lbaCheck = agFALSE; 20362 int i; 20363 bit8 limit[8]; 20364 bit32 rangeCheck = agFALSE; 20365 bit16 ans[8]; // 0 MSB, 8 LSB 20366 bit8 final_ans[9]; // 0 MSB, 9 LSB 20367 bit8 Bit28max[8]; 20368 bit8 Bit48max[8]; 20369 bit32 ReadCapCheck = agFALSE; 20370 bit32 ret; 20371 20372 bit8 final_satMaxLBA[9]; 20373 bit8 oneTL[8]; 20374 bit8 temp_satMaxLBA[8]; // 0 MSB, 8 LSB 20375 /* 20376 check LBA 20377 */ 20378 if (flag == agFALSE) 20379 { 20380 /* limit is 0xF FF FF = 2^28 - 1 */ 20381 limit[0] = 0x0; /* MSB */ 20382 limit[1] = 0x0; 20383 limit[2] = 0x0; 20384 limit[3] = 0x0; 20385 limit[4] = 0xF; 20386 limit[5] = 0xFF; 20387 limit[6] = 0xFF; 20388 limit[7] = 0xFF; /* LSB */ 20389 } 20390 else 20391 { 20392 /* limit is 0xF FF FF = 2^48 - 1 */ 20393 limit[0] = 0x0; /* MSB */ 20394 limit[1] = 0x0; 20395 limit[2] = 0xFF; 20396 limit[3] = 0xFF; 20397 limit[4] = 0xFF; 20398 limit[5] = 0xFF; 20399 limit[6] = 0xFF; 20400 limit[7] = 0xFF; /* LSB */ 20401 } 20402 //compare lba to limit 20403 for(i=0;i<8;i++) 20404 { 20405 if (lba[i] > limit[i]) 20406 { 20407 SM_DBG1(("smsatCheckLimit: LBA check True at %d\n", i)); 20408 lbaCheck = agTRUE; 20409 break; 20410 } 20411 else if (lba[i] < limit[i]) 20412 { 20413 SM_DBG5(("smsatCheckLimit: LBA check False at %d\n", i)); 20414 lbaCheck = agFALSE; 20415 break; 20416 } 20417 else 20418 { 20419 continue; 20420 } 20421 } 20422 20423 if (lbaCheck == agTRUE) 20424 { 20425 SM_DBG1(("smsatCheckLimit: return LBA check True\n")); 20426 return agTRUE; 20427 } 20428 20429 /* 20430 check LBA+TL < SAT_TR_LBA_LIMIT or SAT_EXT_TR_LBA_LIMIT 20431 */ 20432 sm_memset(ans, 0, sizeof(ans)); 20433 sm_memset(final_ans, 0, sizeof(final_ans)); 20434 20435 // adding from LSB to MSB 20436 for(i=7;i>=0;i--) 20437 { 20438 ans[i] = (bit16)(lba[i] + tl[i]); 20439 if (i != 7) 20440 { 20441 ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8)); 20442 } 20443 } 20444 20445 /* 20446 filling in the final answer 20447 */ 20448 final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8)); 20449 20450 for(i=1;i<=8;i++) 20451 { 20452 final_ans[i] = (bit8)(ans[i-1] & 0xFF); 20453 } 20454 20455 20456 if (flag == agFALSE) 20457 { 20458 sm_memset(Bit28max, 0, sizeof(Bit28max)); 20459 Bit28max[4] = 0x10; // max =0x1000 0000 20460 20461 //compare final_ans to max 20462 if (final_ans[0] != 0 || final_ans[1] != 0 || final_ans[2] != 0 20463 || final_ans[3] != 0 || final_ans[4] != 0) 20464 { 20465 SM_DBG1(("smsatCheckLimit: before 28Bit addressing TRUE\n")); 20466 rangeCheck = agTRUE; 20467 } 20468 else 20469 { 20470 for(i=5;i<=8;i++) 20471 { 20472 if (final_ans[i] > Bit28max[i-1]) 20473 { 20474 SM_DBG1(("smsatCheckLimit: 28Bit addressing TRUE at %d\n", i)); 20475 rangeCheck = agTRUE; 20476 break; 20477 } 20478 else if (final_ans[i] < Bit28max[i-1]) 20479 { 20480 SM_DBG5(("smsatCheckLimit: 28Bit addressing FALSE at %d\n", i)); 20481 rangeCheck = agFALSE; 20482 break; 20483 } 20484 else 20485 { 20486 continue; 20487 } 20488 } 20489 } 20490 } 20491 else 20492 { 20493 sm_memset(Bit48max, 0, sizeof(Bit48max)); 20494 Bit48max[1] = 0x1; //max = 0x1 0000 0000 0000 20495 20496 //compare final_ans to max 20497 if (final_ans[0] != 0 || final_ans[1] != 0) 20498 { 20499 SM_DBG1(("smsatCheckLimit: before 48Bit addressing TRUE\n")); 20500 rangeCheck = agTRUE; 20501 } 20502 else 20503 { 20504 for(i=2;i<=8;i++) 20505 { 20506 if (final_ans[i] > Bit48max[i-1]) 20507 { 20508 SM_DBG1(("smsatCheckLimit: 48Bit addressing TRUE at %d\n", i)); 20509 rangeCheck = agTRUE; 20510 break; 20511 } 20512 else if (final_ans[i] < Bit48max[i-1]) 20513 { 20514 SM_DBG5(("smsatCheckLimit: 48Bit addressing FALSE at %d\n", i)); 20515 rangeCheck = agFALSE; 20516 break; 20517 } 20518 else 20519 { 20520 continue; 20521 } 20522 } 20523 } 20524 } 20525 if (rangeCheck == agTRUE) 20526 { 20527 SM_DBG1(("smsatCheckLimit: return rangeCheck True\n")); 20528 return agTRUE; 20529 } 20530 20531 /* 20532 LBA+TL < Read Capacity Limit 20533 */ 20534 sm_memset(temp_satMaxLBA, 0, sizeof(temp_satMaxLBA)); 20535 sm_memset(oneTL, 0, sizeof(oneTL)); 20536 sm_memset(final_satMaxLBA, 0, sizeof(final_satMaxLBA)); 20537 sm_memset(ans, 0, sizeof(ans)); 20538 20539 sm_memcpy(&temp_satMaxLBA, &pSatDevData->satMaxLBA, sizeof(temp_satMaxLBA)); 20540 oneTL[7] = 1; 20541 20542 // adding temp_satMaxLBA to oneTL 20543 for(i=7;i>=0;i--) 20544 { 20545 ans[i] = (bit16)(temp_satMaxLBA[i] + oneTL[i]); 20546 if (i != 7) 20547 { 20548 ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8)); 20549 } 20550 } 20551 20552 /* 20553 filling in the final answer 20554 */ 20555 final_satMaxLBA[0] = (bit8)(((ans[0] & 0xFF00) >> 8)); 20556 20557 for(i=1;i<=8;i++) 20558 { 20559 final_satMaxLBA[i] = (bit8)(ans[i-1] & 0xFF); 20560 } 20561 if ( pSatDevData->ReadCapacity == 10) 20562 { 20563 for (i=0;i<=8;i++) 20564 { 20565 if (final_ans[i] > final_satMaxLBA[i]) 20566 { 20567 SM_DBG1(("smsatCheckLimit: Read Capacity 10 TRUE at %d\n", i)); 20568 ReadCapCheck = agTRUE; 20569 break; 20570 } 20571 else if (final_ans[i] < final_satMaxLBA[i]) 20572 { 20573 SM_DBG5(("smsatCheckLimit: Read Capacity 10 FALSE at %d\n", i)); 20574 ReadCapCheck = agFALSE; 20575 break; 20576 } 20577 else 20578 { 20579 continue; 20580 } 20581 } 20582 if ( ReadCapCheck) 20583 { 20584 SM_DBG1(("smsatCheckLimit: after Read Capacity 10 TRUE\n")); 20585 } 20586 else 20587 { 20588 SM_DBG5(("smsatCheckLimit: after Read Capacity 10 FALSE\n")); 20589 } 20590 } 20591 else if ( pSatDevData->ReadCapacity == 16) 20592 { 20593 for (i=0;i<=8;i++) 20594 { 20595 if (final_ans[i] > final_satMaxLBA[i]) 20596 { 20597 SM_DBG1(("smsatCheckLimit: Read Capacity 16 TRUE at %d\n", i)); 20598 ReadCapCheck = agTRUE; 20599 break; 20600 } 20601 else if (final_ans[i] < final_satMaxLBA[i]) 20602 { 20603 SM_DBG5(("smsatCheckLimit: Read Capacity 16 FALSE at %d\n", i)); 20604 ReadCapCheck = agFALSE; 20605 break; 20606 } 20607 else 20608 { 20609 continue; 20610 } 20611 } 20612 if ( ReadCapCheck) 20613 { 20614 SM_DBG1(("smsatCheckLimit: after Read Capacity 16 TRUE\n")); 20615 } 20616 else 20617 { 20618 SM_DBG5(("smsatCheckLimit: after Read Capacity 16 FALSE\n")); 20619 } 20620 } 20621 else 20622 { 20623 SM_DBG5(("smsatCheckLimit: unknown pSatDevData->ReadCapacity %d\n", pSatDevData->ReadCapacity)); 20624 } 20625 20626 if (ReadCapCheck == agTRUE) 20627 { 20628 SM_DBG1(("smsatCheckLimit: return ReadCapCheck True\n")); 20629 return agTRUE; 20630 } 20631 20632 20633 ret = (lbaCheck | rangeCheck | ReadCapCheck); 20634 if (ret == agTRUE) 20635 { 20636 SM_DBG1(("smsatCheckLimit: final check TRUE\n")); 20637 } 20638 else 20639 { 20640 SM_DBG5(("smsatCheckLimit: final check FALSE\n")); 20641 } 20642 return ret; 20643 } 20644 20645 20646 20647 osGLOBAL void 20648 smsatPrintSgl( 20649 smRoot_t *smRoot, 20650 agsaEsgl_t *agEsgl, 20651 bit32 idx 20652 ) 20653 { 20654 bit32 i=0; 20655 #ifdef TD_DEBUG_ENABLE 20656 agsaSgl_t *agSgl; 20657 #endif 20658 20659 for (i=0;i<idx;i++) 20660 { 20661 #ifdef TD_DEBUG_ENABLE 20662 agSgl = &(agEsgl->descriptor[i]); 20663 #endif 20664 SM_DBG3(("smsatPrintSgl: agSgl %d upperAddr 0x%08x lowerAddr 0x%08x len 0x%08x ext 0x%08x\n", 20665 i, agSgl->sgUpper, agSgl->sgLower, agSgl->len, agSgl->extReserved)); 20666 } 20667 20668 return; 20669 } 20670 20671 20672 osGLOBAL void 20673 smsatSplitSGL( 20674 smRoot_t *smRoot, 20675 smIORequest_t *smIORequest, 20676 smDeviceHandle_t *smDeviceHandle, 20677 smScsiInitiatorRequest_t *smScsiRequest, 20678 smSatIOContext_t *satIOContext, 20679 bit32 split, /*in sector number, depeding on IO value */ 20680 bit32 tl, /* in sector number */ 20681 bit32 flag 20682 ) 20683 { 20684 agsaSgl_t *agSgl; 20685 agsaEsgl_t *agEsgl; 20686 bit32 i=0; 20687 smIniScsiCmnd_t *scsiCmnd; 20688 bit32 totalLen=0; /* in bytes */ 20689 bit32 splitLen=0; /* in bytes */ 20690 bit32 splitDiffByte = 0; /* in bytes */ 20691 bit32 splitDiffExtra = 0; /* in bytes */ 20692 bit32 splitIdx = 0; 20693 bit32 UpperAddr, LowerAddr; 20694 bit32 tmpLowerAddr; 20695 void *sglVirtualAddr; 20696 void *sglSplitVirtualAddr; 20697 20698 scsiCmnd = &smScsiRequest->scsiCmnd; 20699 SM_DBG3(("smsatSplitSGL: start\n")); 20700 20701 if (smScsiRequest->smSgl1.type == 0x80000000) /* esgl */ 20702 { 20703 if (flag == agFALSE) 20704 { 20705 SM_DBG3(("smsatSplitSGL: Not first time\n")); 20706 SM_DBG3(("smsatSplitSGL: UpperAddr 0x%08x LowerAddr 0x%08x\n", satIOContext->UpperAddr, satIOContext->LowerAddr)); 20707 SM_DBG3(("smsatSplitSGL: SplitIdx %d AdjustBytes 0x%08x\n", satIOContext->SplitIdx, satIOContext->AdjustBytes)); 20708 20709 sglVirtualAddr = smScsiRequest->sglVirtualAddr; 20710 20711 agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr; 20712 20713 sglSplitVirtualAddr = &(agEsgl->descriptor[satIOContext->SplitIdx]); 20714 20715 agEsgl = (agsaEsgl_t *)sglSplitVirtualAddr; 20716 20717 if (agEsgl == agNULL) 20718 { 20719 SM_DBG1(("smsatSplitSGL: error!\n")); 20720 return; 20721 } 20722 /* first sgl ajustment */ 20723 agSgl = &(agEsgl->descriptor[0]); 20724 agSgl->sgUpper = satIOContext->UpperAddr; 20725 agSgl->sgLower = satIOContext->LowerAddr; 20726 agSgl->len = satIOContext->AdjustBytes; 20727 sm_memcpy(sglVirtualAddr, sglSplitVirtualAddr, (satIOContext->EsglLen) * sizeof(agsaSgl_t)); 20728 agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr; 20729 smsatPrintSgl(smRoot, (agsaEsgl_t *)sglVirtualAddr, satIOContext->EsglLen); 20730 } 20731 else 20732 { 20733 /* first time */ 20734 SM_DBG3(("smsatSplitSGL: first time\n")); 20735 satIOContext->EsglLen = smScsiRequest->smSgl1.len; 20736 agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr; 20737 if (agEsgl == agNULL) 20738 { 20739 return; 20740 } 20741 smsatPrintSgl(smRoot, agEsgl, satIOContext->EsglLen); 20742 } 20743 20744 if (tl > split) 20745 { 20746 /* split */ 20747 SM_DBG3(("smsatSplitSGL: split case\n")); 20748 i = 0; 20749 while (1) 20750 { 20751 agSgl = &(agEsgl->descriptor[i]); 20752 splitLen = splitLen + agSgl->len; 20753 if (splitLen >= split) 20754 { 20755 splitDiffExtra = splitLen - split; 20756 splitDiffByte = agSgl->len - splitDiffExtra; 20757 splitIdx = i; 20758 break; 20759 } 20760 i++; 20761 } 20762 SM_DBG3(("smsatSplitSGL: splitIdx %d\n", splitIdx)); 20763 SM_DBG3(("smsatSplitSGL: splitDiffByte 0x%8x\n", splitDiffByte)); 20764 SM_DBG3(("smsatSplitSGL: splitDiffExtra 0x%8x \n", splitDiffExtra)); 20765 20766 20767 agSgl = &(agEsgl->descriptor[splitIdx]); 20768 UpperAddr = agSgl->sgUpper; 20769 LowerAddr = agSgl->sgLower; 20770 tmpLowerAddr = LowerAddr + splitDiffByte; 20771 if (tmpLowerAddr < LowerAddr) 20772 { 20773 UpperAddr = UpperAddr + 1; 20774 } 20775 SM_DBG3(("smsatSplitSGL: UpperAddr 0x%08x tmpLowerAddr 0x%08x\n", UpperAddr, tmpLowerAddr)); 20776 agSgl->len = splitDiffByte; 20777 /* Esgl len adjustment */ 20778 smScsiRequest->smSgl1.len = splitIdx; 20779 /* expected data lent adjustment */ 20780 scsiCmnd->expDataLength = 0x20000; 20781 /* remeber for the next round */ 20782 satIOContext->UpperAddr = UpperAddr; 20783 satIOContext->LowerAddr = tmpLowerAddr; 20784 satIOContext->SplitIdx = splitIdx; 20785 satIOContext->AdjustBytes = splitDiffExtra; 20786 satIOContext->EsglLen = satIOContext->EsglLen - smScsiRequest->smSgl1.len; 20787 satIOContext->OrgTL = satIOContext->OrgTL - 0x100; 20788 // smsatPrintSgl(smRoot, agEsgl, satIOContext->EsglLen); 20789 20790 } 20791 else 20792 { 20793 /* no split */ 20794 SM_DBG3(("smsatSplitSGL: no split case\n")); 20795 /* Esgl len adjustment */ 20796 smScsiRequest->smSgl1.len = satIOContext->EsglLen; 20797 for (i=0;i< smScsiRequest->smSgl1.len;i++) 20798 { 20799 agSgl = &(agEsgl->descriptor[i]); 20800 totalLen = totalLen + (agSgl->len); 20801 } 20802 /* expected data lent adjustment */ 20803 scsiCmnd->expDataLength = totalLen; 20804 // smsatPrintSgl(smRoot, agEsgl, satIOContext->EsglLen); 20805 } 20806 } 20807 else 20808 { 20809 SM_DBG1(("not exntened esgl\n")); 20810 20811 } 20812 20813 return; 20814 } 20815 20816 20817 /******************************** end of utils ***********************************************************/ 20818 20819 20820 20821