1 /* 2 * Copyright 2008-2021 Haiku, Inc. All rights reserved. 3 * Copyright 2007-2009, Marcus Overhagen. All rights reserved. 4 * Distributed under the terms of the MIT License. 5 * 6 * Authors: 7 * Axel Dörfler, axeld@pinc-software.de 8 * Michael Lotz, mmlr@mlotz.ch 9 * Alexander von Gluck IV, kallisti5@unixzen.com 10 * David Sebek, dasebek@gmail.com 11 */ 12 13 14 #include "ahci_port.h" 15 16 #include <new> 17 #include <stdio.h> 18 #include <string.h> 19 20 #include <ByteOrder.h> 21 #include <KernelExport.h> 22 23 #include <ATACommands.h> 24 #include <ATAInfoBlock.h> 25 #include <AutoDeleter.h> 26 27 #include "ahci_controller.h" 28 #include "ahci_tracing.h" 29 #include "sata_request.h" 30 #include "scsi_cmds.h" 31 #include "util.h" 32 33 34 //#define TRACE_AHCI 35 #ifdef TRACE_AHCI 36 # define TRACE(a...) dprintf("ahci: " a) 37 #else 38 # define TRACE(a...) 39 #endif 40 41 #define ERROR(a...) dprintf("ahci: " a) 42 //#define FLOW(a...) dprintf("ahci: " a) 43 //#define RWTRACE(a...) dprintf("ahci: " a) 44 #define FLOW(a...) 45 #define RWTRACE(a...) 46 47 48 #define INQUIRY_BASE_LENGTH 36 49 50 51 // DATA SET MANAGEMENT command limits 52 53 #define DSM_MAX_COUNT_48 UINT16_MAX 54 // max number of 512-byte blocks (48-bit command) 55 #define DSM_MAX_COUNT_28 UINT8_MAX 56 // max number of 512-byte blocks (28-bit command) 57 #define DSM_RANGE_BLOCK_ENTRIES 64 58 // max entries in a 512-byte block (512 / 8) 59 #define DSM_MAX_RANGE_VALUE UINT16_C(0xffff) 60 #define DSM_MAX_LBA_VALUE UINT64_C(0xffffffffffff) 61 62 63 AHCIPort::AHCIPort(AHCIController* controller, int index) 64 : 65 fController(controller), 66 fIndex(index), 67 fRegs(&controller->fRegs->port[index]), 68 fArea(-1), 69 fCommandsActive(0), 70 fRequestSem(-1), 71 fResponseSem(-1), 72 fDevicePresent(false), 73 fUse48BitCommands(false), 74 fSectorSize(0), 75 fSectorCount(0), 76 fIsATAPI(false), 77 fTestUnitReadyActive(false), 78 fPortReset(false), 79 fError(false), 80 fTrimSupported(false), 81 fTrimReturnsZeros(false), 82 fMaxTrimRangeBlocks(0) 83 { 84 B_INITIALIZE_SPINLOCK(&fSpinlock); 85 fRequestSem = create_sem(1, "ahci request"); 86 fResponseSem = create_sem(0, "ahci response"); 87 } 88 89 90 AHCIPort::~AHCIPort() 91 { 92 delete_sem(fRequestSem); 93 delete_sem(fResponseSem); 94 } 95 96 97 status_t 98 AHCIPort::Init1() 99 { 100 TRACE("AHCIPort::Init1 port %d\n", fIndex); 101 102 size_t size = sizeof(command_list_entry) * COMMAND_LIST_ENTRY_COUNT 103 + sizeof(fis) + sizeof(command_table) 104 + sizeof(prd) * PRD_TABLE_ENTRY_COUNT; 105 106 char* virtAddr; 107 phys_addr_t physAddr; 108 char name[32]; 109 snprintf(name, sizeof(name), "AHCI port %d", fIndex); 110 111 fArea = alloc_mem((void**)&virtAddr, &physAddr, size, 0, name); 112 if (fArea < B_OK) { 113 TRACE("failed allocating memory for port %d\n", fIndex); 114 return fArea; 115 } 116 memset(virtAddr, 0, size); 117 118 fCommandList = (command_list_entry*)virtAddr; 119 virtAddr += sizeof(command_list_entry) * COMMAND_LIST_ENTRY_COUNT; 120 fFIS = (fis*)virtAddr; 121 virtAddr += sizeof(fis); 122 fCommandTable = (command_table*)virtAddr; 123 virtAddr += sizeof(command_table); 124 fPRDTable = (prd*)virtAddr; 125 TRACE("PRD table is at %p\n", fPRDTable); 126 127 fRegs->clb = LO32(physAddr); 128 fRegs->clbu = HI32(physAddr); 129 physAddr += sizeof(command_list_entry) * COMMAND_LIST_ENTRY_COUNT; 130 fRegs->fb = LO32(physAddr); 131 fRegs->fbu = HI32(physAddr); 132 physAddr += sizeof(fis); 133 fCommandList[0].ctba = LO32(physAddr); 134 fCommandList[0].ctbau = HI32(physAddr); 135 // prdt follows after command table 136 137 // disable transitions to partial or slumber state 138 fRegs->sctl |= (SCTL_PORT_IPM_NOPART | SCTL_PORT_IPM_NOSLUM); 139 140 // clear IRQ status bits 141 fRegs->is = fRegs->is; 142 143 // clear error bits 144 _ClearErrorRegister(); 145 146 // power up device 147 fRegs->cmd |= PORT_CMD_POD; 148 149 // spin up device 150 fRegs->cmd |= PORT_CMD_SUD; 151 152 // activate link 153 fRegs->cmd = (fRegs->cmd & ~PORT_CMD_ICC_MASK) | PORT_CMD_ICC_ACTIVE; 154 155 // enable FIS receive (enabled when fb set, only to be disabled when unset) 156 fRegs->cmd |= PORT_CMD_FRE; 157 158 FlushPostedWrites(); 159 160 return B_OK; 161 } 162 163 164 // called with global interrupts enabled 165 status_t 166 AHCIPort::Init2() 167 { 168 TRACE("AHCIPort::Init2 port %d\n", fIndex); 169 170 // enable port 171 Enable(); 172 173 // enable interrupts 174 fRegs->ie = PORT_INT_MASK; 175 176 FlushPostedWrites(); 177 178 // reset port and probe info 179 ResetDevice(); 180 181 DumpHBAState(); 182 183 TRACE("%s: port %d, device %s\n", __func__, fIndex, 184 fDevicePresent ? "present" : "absent"); 185 186 return B_OK; 187 } 188 189 190 void 191 AHCIPort::Uninit() 192 { 193 TRACE("AHCIPort::Uninit port %d\n", fIndex); 194 195 // Spec v1.3.1, §10.3.2 - Shut down port before unsetting FRE 196 197 // shutdown the port 198 if (!Disable()) { 199 ERROR("%s: port %d error, unable to shutdown before FRE clear!\n", 200 __func__, fIndex); 201 return; 202 } 203 204 // Clear FRE and wait for completion 205 fRegs->cmd &= ~PORT_CMD_FRE; 206 if (wait_until_clear(&fRegs->cmd, PORT_CMD_FR, 500000) < B_OK) 207 ERROR("%s: port %d error FIS rx still running\n", __func__, fIndex); 208 209 // disable interrupts 210 fRegs->ie = 0; 211 212 // clear pending interrupts 213 fRegs->is = fRegs->is; 214 215 // invalidate DMA addresses 216 fRegs->clb = 0; 217 fRegs->clbu = 0; 218 fRegs->fb = 0; 219 fRegs->fbu = 0; 220 221 delete_area(fArea); 222 } 223 224 225 void 226 AHCIPort::ResetDevice() 227 { 228 // perform a hard reset 229 if (PortReset() != B_OK) { 230 ERROR("%s: port %d unable to hard reset device\n", __func__, fIndex); 231 return; 232 } 233 234 if (wait_until_set(&fRegs->ssts, SSTS_PORT_DET_NODEV, 100000) < B_OK) 235 TRACE("AHCIPort::ResetDevice port %d no device detected\n", fIndex); 236 237 _ClearErrorRegister(); 238 239 if (fRegs->ssts & SSTS_PORT_DET_NOPHY) { 240 if (wait_until_set(&fRegs->ssts, 0x3, 500000) < B_OK) { 241 TRACE("AHCIPort::ResetDevice port %d device present but no phy " 242 "communication\n", fIndex); 243 } 244 } 245 246 _ClearErrorRegister(); 247 } 248 249 250 status_t 251 AHCIPort::PortReset() 252 { 253 TRACE("AHCIPort::PortReset port %d\n", fIndex); 254 255 if (!Disable()) { 256 ERROR("%s: port %d unable to shutdown!\n", __func__, fIndex); 257 return B_ERROR; 258 } 259 260 _ClearErrorRegister(); 261 262 // Wait for BSY and DRQ to clear (idle port) 263 if (wait_until_clear(&fRegs->tfd, ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST, 264 1000000) < B_OK) { 265 // If we can't clear busy, do a full comreset 266 267 // Spec v1.3.1, §10.4.2 Port Reset 268 // Physical comm between HBA and port disabled. More Intrusive 269 ERROR("%s: port %d undergoing COMRESET\n", __func__, fIndex); 270 271 // Notice we're throwing out all other control flags. 272 fRegs->sctl = (SSTS_PORT_IPM_ACTIVE | SSTS_PORT_IPM_PARTIAL 273 | SCTL_PORT_DET_INIT); 274 FlushPostedWrites(); 275 spin(1100); 276 // You must wait 1ms at minimum 277 fRegs->sctl = (fRegs->sctl & ~HBA_PORT_DET_MASK) | SCTL_PORT_DET_NOINIT; 278 FlushPostedWrites(); 279 } 280 281 Enable(); 282 283 if (wait_until_set(&fRegs->ssts, SSTS_PORT_DET_PRESENT, 500000) < B_OK) { 284 TRACE("%s: port %d: no device detected\n", __func__, fIndex); 285 fDevicePresent = false; 286 return B_OK; 287 } 288 289 return Probe(); 290 } 291 292 293 status_t 294 AHCIPort::Probe() 295 { 296 if ((fRegs->tfd & 0xff) == 0xff) 297 snooze(200000); 298 299 if ((fRegs->tfd & 0xff) == 0xff) { 300 TRACE("%s: port %d: invalid task file status 0xff\n", __func__, 301 fIndex); 302 return B_ERROR; 303 } 304 305 if (!fTestUnitReadyActive) { 306 switch (fRegs->ssts & HBA_PORT_SPD_MASK) { 307 case 0x10: 308 ERROR("%s: port %d link speed 1.5Gb/s\n", __func__, fIndex); 309 break; 310 case 0x20: 311 ERROR("%s: port %d link speed 3.0Gb/s\n", __func__, fIndex); 312 break; 313 case 0x30: 314 ERROR("%s: port %d link speed 6.0Gb/s\n", __func__, fIndex); 315 break; 316 default: 317 ERROR("%s: port %d link speed unrestricted\n", __func__, fIndex); 318 break; 319 } 320 } 321 322 wait_until_clear(&fRegs->tfd, ATA_STATUS_BUSY, 31000000); 323 324 fDevicePresent = (fRegs->ssts & HBA_PORT_DET_MASK) == SSTS_PORT_DET_PRESENT; 325 fIsATAPI = fRegs->sig == SATA_SIG_ATAPI; 326 327 if (fIsATAPI) 328 fRegs->cmd |= PORT_CMD_ATAPI; 329 else 330 fRegs->cmd &= ~PORT_CMD_ATAPI; 331 FlushPostedWrites(); 332 333 TRACE("device signature 0x%08" B_PRIx32 " (%s)\n", fRegs->sig, 334 fRegs->sig == SATA_SIG_ATAPI ? "ATAPI" : fRegs->sig == SATA_SIG_ATA 335 ? "ATA" : "unknown"); 336 337 return B_OK; 338 } 339 340 341 void 342 AHCIPort::DumpD2HFis() 343 { 344 TRACE("D2H FIS:\n"); 345 TRACE(" DW0 %02x %02x %02x %02x\n", fFIS->rfis[3], fFIS->rfis[2], 346 fFIS->rfis[1], fFIS->rfis[0]); 347 TRACE(" DW1 %02x %02x %02x %02x\n", fFIS->rfis[7], fFIS->rfis[6], 348 fFIS->rfis[5], fFIS->rfis[4]); 349 TRACE(" DW2 %02x %02x %02x %02x\n", fFIS->rfis[11], fFIS->rfis[10], 350 fFIS->rfis[9], fFIS->rfis[8]); 351 TRACE(" DW3 %02x %02x %02x %02x\n", fFIS->rfis[15], fFIS->rfis[14], 352 fFIS->rfis[13], fFIS->rfis[12]); 353 TRACE(" DW4 %02x %02x %02x %02x\n", fFIS->rfis[19], fFIS->rfis[18], 354 fFIS->rfis[17], fFIS->rfis[16]); 355 } 356 357 358 void 359 AHCIPort::DumpHBAState() 360 { 361 TRACE("Port %d state:\n", fIndex); 362 TRACE(" ie 0x%08" B_PRIx32 "\n", fRegs->ie); 363 TRACE(" is 0x%08" B_PRIx32 "\n", fRegs->is); 364 TRACE(" cmd 0x%08" B_PRIx32 "\n", fRegs->cmd); 365 TRACE(" ssts 0x%08" B_PRIx32 "\n", fRegs->ssts); 366 TRACE(" sctl 0x%08" B_PRIx32 "\n", fRegs->sctl); 367 TRACE(" serr 0x%08" B_PRIx32 "\n", fRegs->serr); 368 TRACE(" sact 0x%08" B_PRIx32 "\n", fRegs->sact); 369 TRACE(" tfd 0x%08" B_PRIx32 "\n", fRegs->tfd); 370 } 371 372 373 void 374 AHCIPort::Interrupt() 375 { 376 uint32 is = fRegs->is; 377 fRegs->is = is; // clear interrupts 378 379 if (is & PORT_INT_ERROR) { 380 InterruptErrorHandler(is); 381 return; 382 } 383 384 uint32 ci = fRegs->ci; 385 386 RWTRACE("[%lld] %ld AHCIPort::Interrupt port %d, fCommandsActive 0x%08" 387 B_PRIx32 ", is 0x%08" B_PRIx32 ", ci 0x%08" B_PRIx32 "\n", 388 system_time(), find_thread(NULL), fIndex, fCommandsActive, is, ci); 389 390 acquire_spinlock(&fSpinlock); 391 if ((fCommandsActive & 1) && !(ci & 1)) { 392 fCommandsActive &= ~1; 393 release_sem_etc(fResponseSem, 1, B_DO_NOT_RESCHEDULE); 394 } 395 release_spinlock(&fSpinlock); 396 } 397 398 399 void 400 AHCIPort::InterruptErrorHandler(uint32 is) 401 { 402 TRACE("AHCIPort::InterruptErrorHandler port %d, fCommandsActive 0x%08" 403 B_PRIx32 ", is 0x%08" B_PRIx32 ", ci 0x%08" B_PRIx32 "\n", fIndex, 404 fCommandsActive, is, fRegs->ci); 405 TRACE("ssts 0x%08" B_PRIx32 "\n", fRegs->ssts); 406 TRACE("sctl 0x%08" B_PRIx32 "\n", fRegs->sctl); 407 TRACE("serr 0x%08" B_PRIx32 "\n", fRegs->serr); 408 TRACE("sact 0x%08" B_PRIx32 "\n", fRegs->sact); 409 410 // read and clear SError 411 _ClearErrorRegister(); 412 413 if (is & PORT_INT_TFE) { 414 TRACE("Task File Error\n"); 415 416 fPortReset = true; 417 fError = true; 418 } 419 if (is & PORT_INT_HBF) { 420 ERROR("Host Bus Fatal Error\n"); 421 fPortReset = true; 422 fError = true; 423 } 424 if (is & PORT_INT_HBD) { 425 ERROR("Host Bus Data Error\n"); 426 fPortReset = true; 427 fError = true; 428 } 429 if (is & PORT_INT_IF) { 430 ERROR("Interface Fatal Error\n"); 431 fPortReset = true; 432 fError = true; 433 } 434 if (is & PORT_INT_INF) { 435 TRACE("Interface Non Fatal Error\n"); 436 } 437 if (is & PORT_INT_OF) { 438 TRACE("Overflow\n"); 439 fPortReset = true; 440 fError = true; 441 } 442 if (is & PORT_INT_IPM) { 443 TRACE("Incorrect Port Multiplier Status\n"); 444 } 445 if (is & PORT_INT_PRC) { 446 TRACE("PhyReady Change\n"); 447 //fPortReset = true; 448 } 449 if (is & PORT_INT_PC) { 450 TRACE("Port Connect Change\n"); 451 // Unsolicited when we had a port connect change without us requesting 452 // Spec v1.3, §6.2.2.3 Recovery of Unsolicited COMINIT 453 454 // XXX: This shouldn't be needed here... but we can loop without it 455 //_ClearErrorRegister(); 456 } 457 if (is & PORT_INT_UF) { 458 TRACE("Unknown FIS\n"); 459 fPortReset = true; 460 } 461 462 if (fError) { 463 acquire_spinlock(&fSpinlock); 464 if ((fCommandsActive & 1)) { 465 fCommandsActive &= ~1; 466 release_sem_etc(fResponseSem, 1, B_DO_NOT_RESCHEDULE); 467 } 468 release_spinlock(&fSpinlock); 469 } 470 } 471 472 473 status_t 474 AHCIPort::FillPrdTable(volatile prd* prdTable, int* prdCount, int prdMax, 475 const void* data, size_t dataSize) 476 { 477 int maxEntries = prdMax + 1; 478 physical_entry entries[maxEntries]; 479 uint32 entriesUsed = maxEntries; 480 481 status_t status = get_memory_map_etc(B_CURRENT_TEAM, data, dataSize, 482 entries, &entriesUsed); 483 if (status != B_OK) { 484 ERROR("%s: get_memory_map() failed: %s\n", __func__, strerror(status)); 485 return B_ERROR; 486 } 487 488 return FillPrdTable(prdTable, prdCount, prdMax, entries, entriesUsed, 489 dataSize); 490 } 491 492 493 status_t 494 AHCIPort::FillPrdTable(volatile prd* prdTable, int* prdCount, int prdMax, 495 const physical_entry* sgTable, int sgCount, size_t dataSize) 496 { 497 *prdCount = 0; 498 while (sgCount > 0 && dataSize > 0) { 499 size_t size = min_c(sgTable->size, dataSize); 500 phys_addr_t address = sgTable->address; 501 T_PORT(AHCIPortPrdTable(fController, fIndex, address, size)); 502 FLOW("FillPrdTable: sg-entry addr %#" B_PRIxPHYSADDR ", size %lu\n", 503 address, size); 504 if (address & 1) { 505 ERROR("AHCIPort::FillPrdTable: data alignment error\n"); 506 return B_ERROR; 507 } 508 dataSize -= size; 509 while (size > 0) { 510 size_t bytes = min_c(size, PRD_MAX_DATA_LENGTH); 511 if (*prdCount == prdMax) { 512 ERROR("AHCIPort::FillPrdTable: prd table exhausted\n"); 513 return B_ERROR; 514 } 515 FLOW("FillPrdTable: prd-entry %u, addr %p, size %lu\n", 516 *prdCount, address, bytes); 517 518 prdTable->dba = LO32(address); 519 prdTable->dbau = HI32(address); 520 prdTable->res = 0; 521 prdTable->dbc = bytes - 1; 522 *prdCount += 1; 523 prdTable++; 524 address = address + bytes; 525 size -= bytes; 526 } 527 sgTable++; 528 sgCount--; 529 } 530 if (*prdCount == 0) { 531 ERROR("%s: count is 0\n", __func__); 532 return B_ERROR; 533 } 534 if (dataSize > 0) { 535 ERROR("AHCIPort::FillPrdTable: sg table %ld bytes too small\n", 536 dataSize); 537 return B_ERROR; 538 } 539 return B_OK; 540 } 541 542 543 void 544 AHCIPort::StartTransfer() 545 { 546 acquire_sem(fRequestSem); 547 } 548 549 550 status_t 551 AHCIPort::WaitForTransfer(int* tfd, bigtime_t timeout) 552 { 553 status_t result = acquire_sem_etc(fResponseSem, 1, B_RELATIVE_TIMEOUT, 554 timeout); 555 if (result < B_OK) { 556 cpu_status cpu = disable_interrupts(); 557 acquire_spinlock(&fSpinlock); 558 fCommandsActive &= ~1; 559 release_spinlock(&fSpinlock); 560 restore_interrupts(cpu); 561 562 result = B_TIMED_OUT; 563 } else if (fError) { 564 *tfd = fRegs->tfd; 565 result = B_ERROR; 566 fError = false; 567 } else { 568 *tfd = fRegs->tfd; 569 } 570 return result; 571 } 572 573 574 void 575 AHCIPort::FinishTransfer() 576 { 577 release_sem(fRequestSem); 578 } 579 580 581 void 582 AHCIPort::ScsiTestUnitReady(scsi_ccb* request) 583 { 584 TRACE("AHCIPort::ScsiTestUnitReady port %d\n", fIndex); 585 request->subsys_status = SCSI_REQ_CMP; 586 gSCSI->finished(request, 1); 587 } 588 589 590 void 591 AHCIPort::ScsiVPDInquiry(scsi_ccb* request, ata_device_infoblock* ataData) 592 { 593 TRACE("AHCIPort::ScsiVPDInquiry port %d\n", fIndex); 594 595 const scsi_cmd_inquiry* cmd = (const scsi_cmd_inquiry*)request->cdb; 596 597 size_t vpdDataLength = 0; 598 status_t transactionResult = B_ERROR; 599 600 switch (cmd->page_code) { 601 case SCSI_PAGE_SUPPORTED_VPD: 602 { 603 // supported pages should be in ascending numerical order 604 const uint8 supportedPages[] = { 605 SCSI_PAGE_SUPPORTED_VPD, 606 SCSI_PAGE_BLOCK_LIMITS, 607 SCSI_PAGE_LB_PROVISIONING 608 }; 609 610 const size_t bufferLength = sizeof(scsi_page_list) 611 + sizeof(supportedPages) - 1; 612 uint8 buffer[bufferLength]; 613 614 scsi_page_list* vpdPageData = (scsi_page_list*)buffer; 615 memset(vpdPageData, 0, bufferLength); 616 617 vpdPageData->page_code = cmd->page_code; 618 // Our supported pages 619 vpdPageData->page_length = sizeof(supportedPages); 620 memcpy(vpdPageData->pages, supportedPages, sizeof(supportedPages)); 621 622 uint8 allocationLength = cmd->allocation_length; 623 vpdDataLength = min_c(allocationLength, bufferLength); 624 625 transactionResult = sg_memcpy(request->sg_list, request->sg_count, 626 vpdPageData, vpdDataLength); 627 break; 628 } 629 case SCSI_PAGE_BLOCK_LIMITS: 630 { 631 scsi_page_block_limits vpdPageData; 632 memset(&vpdPageData, 0, sizeof(vpdPageData)); 633 634 vpdPageData.page_code = cmd->page_code; 635 vpdPageData.page_length 636 = B_HOST_TO_BENDIAN_INT16(sizeof(vpdPageData) - 4); 637 if (fTrimSupported) { 638 // We can handle anything as long as we have enough memory 639 // (UNMAP structure can realistically be max. 65528 bytes) 640 vpdPageData.max_unmap_lba_count 641 = B_HOST_TO_BENDIAN_INT32(UINT32_MAX); 642 vpdPageData.max_unmap_blk_count 643 = B_HOST_TO_BENDIAN_INT32(UINT32_MAX); 644 } 645 646 uint8 allocationLength = cmd->allocation_length; 647 vpdDataLength = min_c(allocationLength, sizeof(vpdPageData)); 648 649 transactionResult = sg_memcpy(request->sg_list, request->sg_count, 650 &vpdPageData, vpdDataLength); 651 break; 652 } 653 case SCSI_PAGE_LB_PROVISIONING: 654 { 655 scsi_page_lb_provisioning vpdPageData; 656 memset(&vpdPageData, 0, sizeof(vpdPageData)); 657 658 vpdPageData.page_code = cmd->page_code; 659 vpdPageData.page_length 660 = B_HOST_TO_BENDIAN_INT16(sizeof(vpdPageData) - 4); 661 vpdPageData.lbpu = fTrimSupported; 662 vpdPageData.lbprz = fTrimReturnsZeros; 663 664 uint8 allocationLength = cmd->allocation_length; 665 vpdDataLength = min_c(allocationLength, sizeof(vpdPageData)); 666 667 transactionResult = sg_memcpy(request->sg_list, request->sg_count, 668 &vpdPageData, vpdDataLength); 669 break; 670 } 671 case SCSI_PAGE_USN: 672 case SCSI_PAGE_BLOCK_DEVICE_CHARS: 673 case SCSI_PAGE_REFERRALS: 674 ERROR("VPD AHCI page %d not yet implemented!\n", 675 cmd->page_code); 676 //request->subsys_status = SCSI_REQ_CMP; 677 request->subsys_status = SCSI_REQ_ABORTED; 678 return; 679 default: 680 ERROR("unknown VPD page code!\n"); 681 request->subsys_status = SCSI_REQ_ABORTED; 682 return; 683 } 684 685 if (transactionResult < B_OK) { 686 request->subsys_status = SCSI_DATA_RUN_ERR; 687 } else { 688 request->subsys_status = SCSI_REQ_CMP; 689 request->data_resid = request->data_length 690 - vpdDataLength; 691 } 692 } 693 694 695 void 696 AHCIPort::ScsiInquiry(scsi_ccb* request) 697 { 698 TRACE("AHCIPort::ScsiInquiry port %d\n", fIndex); 699 700 const scsi_cmd_inquiry* cmd = (const scsi_cmd_inquiry*)request->cdb; 701 scsi_res_inquiry scsiData; 702 ata_device_infoblock ataData; 703 704 ASSERT(sizeof(ataData) == 512); 705 706 if (cmd->evpd) { 707 TRACE("VPD inquiry page 0x%X\n", cmd->page_code); 708 if (!request->data || request->data_length == 0) { 709 ERROR("invalid VPD request\n"); 710 request->subsys_status = SCSI_REQ_ABORTED; 711 gSCSI->finished(request, 1); 712 return; 713 } 714 } else if (cmd->page_code) { 715 // page_code without evpd is invalid per SCSI spec 716 ERROR("page code 0x%X on non-VPD request\n", cmd->page_code); 717 request->subsys_status = SCSI_REQ_ABORTED; 718 request->device_status = SCSI_STATUS_CHECK_CONDITION; 719 // TODO: Sense ILLEGAL REQUEST + INVALID FIELD IN CDB? 720 gSCSI->finished(request, 1); 721 return; 722 } else if (request->data_length < INQUIRY_BASE_LENGTH) { 723 ERROR("invalid request %" B_PRIu32 "\n", request->data_length); 724 request->subsys_status = SCSI_REQ_ABORTED; 725 gSCSI->finished(request, 1); 726 return; 727 } 728 729 memset(&ataData, 0, sizeof(ataData)); 730 731 sata_request sreq; 732 sreq.SetData(&ataData, sizeof(ataData)); 733 sreq.SetATACommand(fIsATAPI 734 ? ATA_COMMAND_IDENTIFY_PACKET_DEVICE : ATA_COMMAND_IDENTIFY_DEVICE); 735 ExecuteSataRequest(&sreq); 736 sreq.WaitForCompletion(); 737 738 if ((sreq.CompletionStatus() & ATA_STATUS_ERROR) != 0) { 739 ERROR("identify device failed\n"); 740 request->subsys_status = SCSI_REQ_CMP_ERR; 741 gSCSI->finished(request, 1); 742 return; 743 } 744 745 if (cmd->evpd) { 746 // Simulate SCSI VPD data. 747 ScsiVPDInquiry(request, &ataData); 748 gSCSI->finished(request, 1); 749 return; 750 } 751 752 /* 753 uint8* data = (uint8*)&ataData; 754 for (int i = 0; i < 512; i += 8) { 755 TRACE(" %02x %02x %02x %02x %02x %02x %02x %02x\n", data[i], data[i+1], 756 data[i+2], data[i+3], data[i+4], data[i+5], data[i+6], data[i+7]); 757 } 758 */ 759 760 memset(&scsiData, 0, sizeof(scsiData)); 761 762 scsiData.device_type = fIsATAPI 763 ? ataData.word_0.atapi.command_packet_set : scsi_dev_direct_access; 764 scsiData.device_qualifier = scsi_periph_qual_connected; 765 scsiData.device_type_modifier = 0; 766 scsiData.removable_medium = ataData.word_0.ata.removable_media_device; 767 scsiData.ansi_version = 5; 768 // Set the version to SPC-3 so that scsi_periph 769 // uses READ CAPACITY (16) and attempts to read VPD pages 770 scsiData.ecma_version = 0; 771 scsiData.iso_version = 0; 772 scsiData.response_data_format = 2; 773 scsiData.term_iop = false; 774 scsiData.additional_length = sizeof(scsi_res_inquiry) - 4; 775 scsiData.soft_reset = false; 776 scsiData.cmd_queue = false; 777 scsiData.linked = false; 778 scsiData.sync = false; 779 scsiData.write_bus16 = true; 780 scsiData.write_bus32 = false; 781 scsiData.relative_address = false; 782 783 if (!fIsATAPI) { 784 fSectorCount = ataData.SectorCount(fUse48BitCommands, true); 785 fSectorSize = ataData.SectorSize(); 786 fTrimSupported = ataData.data_set_management_support; 787 fTrimReturnsZeros = ataData.supports_read_zero_after_trim; 788 fMaxTrimRangeBlocks = B_LENDIAN_TO_HOST_INT16( 789 ataData.max_data_set_management_lba_range_blocks); 790 TRACE("lba %d, lba48 %d, fUse48BitCommands %d, sectors %" B_PRIu32 791 ", sectors48 %" B_PRIu64 ", size %" B_PRIu64 "\n", 792 ataData.dma_supported != 0, ataData.lba48_supported != 0, 793 fUse48BitCommands, ataData.lba_sector_count, 794 ataData.lba48_sector_count, fSectorCount * fSectorSize); 795 if (fTrimSupported) { 796 if (fMaxTrimRangeBlocks == 0) 797 fMaxTrimRangeBlocks = 1; 798 799 #ifdef TRACE_AHCI 800 bool deterministic = ataData.supports_deterministic_read_after_trim; 801 TRACE("trim supported, %" B_PRIu32 " ranges blocks, reads are " 802 "%sdeterministic%s.\n", fMaxTrimRangeBlocks, 803 deterministic ? "" : "non-", deterministic 804 ? (ataData.supports_read_zero_after_trim 805 ? ", zero" : ", undefined") : ""); 806 #endif 807 } 808 } 809 810 #if 0 811 if (fSectorCount < 0x0fffffff) { 812 TRACE("disabling 48 bit commands\n"); 813 fUse48BitCommands = 0; 814 } 815 #endif 816 817 char modelNumber[sizeof(ataData.model_number) + 1]; 818 char serialNumber[sizeof(ataData.serial_number) + 1]; 819 char firmwareRev[sizeof(ataData.firmware_revision) + 1]; 820 821 strlcpy(modelNumber, ataData.model_number, sizeof(modelNumber)); 822 strlcpy(serialNumber, ataData.serial_number, sizeof(serialNumber)); 823 strlcpy(firmwareRev, ataData.firmware_revision, sizeof(firmwareRev)); 824 825 swap_words(modelNumber, sizeof(modelNumber) - 1); 826 swap_words(serialNumber, sizeof(serialNumber) - 1); 827 swap_words(firmwareRev, sizeof(firmwareRev) - 1); 828 829 TRACE("model number: %s\n", modelNumber); 830 TRACE("serial number: %s\n", serialNumber); 831 TRACE("firmware rev.: %s\n", firmwareRev); 832 833 // There's not enough space to fit all of the data in. ATA has 40 bytes for 834 // the model number, 20 for the serial number and another 8 for the 835 // firmware revision. SCSI has room for 8 for vendor ident, 16 for product 836 // ident and another 4 for product revision. 837 size_t vendorLen = strcspn(modelNumber, " "); 838 if (vendorLen >= sizeof(scsiData.vendor_ident)) 839 vendorLen = strcspn(modelNumber, "-"); 840 if (vendorLen < sizeof(scsiData.vendor_ident)) { 841 // First we try to break things apart smartly. 842 snprintf(scsiData.vendor_ident, vendorLen + 1, "%s", modelNumber); 843 size_t modelRemain = (sizeof(modelNumber) - vendorLen); 844 if (modelRemain > sizeof(scsiData.product_ident)) 845 modelRemain = sizeof(scsiData.product_ident); 846 memcpy(scsiData.product_ident, modelNumber + (vendorLen + 1), 847 modelRemain); 848 } else { 849 // If we're unable to smartly break apart the vendor and model, just 850 // dumbly squeeze as much in as possible. 851 memcpy(scsiData.vendor_ident, modelNumber, sizeof(scsiData.vendor_ident)); 852 memcpy(scsiData.product_ident, modelNumber + 8, 853 sizeof(scsiData.product_ident)); 854 } 855 // Take the last 4 digits of the serial number as product rev 856 size_t serialLen = sizeof(scsiData.product_rev); 857 size_t serialOff = sizeof(serialNumber) - serialLen; 858 memcpy(scsiData.product_rev, serialNumber + serialOff, serialLen); 859 860 if (sg_memcpy(request->sg_list, request->sg_count, &scsiData, 861 sizeof(scsiData)) < B_OK) { 862 request->subsys_status = SCSI_DATA_RUN_ERR; 863 } else { 864 request->subsys_status = SCSI_REQ_CMP; 865 request->data_resid = request->data_length - sizeof(scsiData); 866 } 867 gSCSI->finished(request, 1); 868 } 869 870 871 void 872 AHCIPort::ScsiSynchronizeCache(scsi_ccb* request) 873 { 874 //TRACE("AHCIPort::ScsiSynchronizeCache port %d\n", fIndex); 875 876 sata_request* sreq = new(std::nothrow) sata_request(request); 877 if (sreq == NULL) { 878 ERROR("out of memory when allocating sync request\n"); 879 request->subsys_status = SCSI_REQ_ABORTED; 880 gSCSI->finished(request, 1); 881 return; 882 } 883 884 sreq->SetATACommand(fUse48BitCommands 885 ? ATA_COMMAND_FLUSH_CACHE_EXT : ATA_COMMAND_FLUSH_CACHE); 886 ExecuteSataRequest(sreq); 887 } 888 889 890 void 891 AHCIPort::ScsiReadCapacity(scsi_ccb* request) 892 { 893 TRACE("AHCIPort::ScsiReadCapacity port %d\n", fIndex); 894 895 const scsi_cmd_read_capacity* cmd 896 = (const scsi_cmd_read_capacity*)request->cdb; 897 scsi_res_read_capacity scsiData; 898 899 if (cmd->pmi || cmd->lba || request->data_length < sizeof(scsiData)) { 900 TRACE("invalid request\n"); 901 request->subsys_status = SCSI_REQ_ABORTED; 902 gSCSI->finished(request, 1); 903 return; 904 } 905 906 TRACE("SectorSize %" B_PRIu32 ", SectorCount 0x%" B_PRIx64 "\n", 907 fSectorSize, fSectorCount); 908 909 memset(&scsiData, 0, sizeof(scsiData)); 910 911 scsiData.block_size = B_HOST_TO_BENDIAN_INT32(fSectorSize); 912 913 if (fSectorCount <= 0xffffffff) 914 scsiData.lba = B_HOST_TO_BENDIAN_INT32(fSectorCount - 1); 915 else 916 scsiData.lba = 0xffffffff; 917 918 if (sg_memcpy(request->sg_list, request->sg_count, &scsiData, 919 sizeof(scsiData)) < B_OK) { 920 request->subsys_status = SCSI_DATA_RUN_ERR; 921 } else { 922 request->subsys_status = SCSI_REQ_CMP; 923 request->data_resid = request->data_length - sizeof(scsiData); 924 } 925 gSCSI->finished(request, 1); 926 } 927 928 929 void 930 AHCIPort::ScsiReadCapacity16(scsi_ccb* request) 931 { 932 TRACE("AHCIPort::ScsiReadCapacity16 port %d\n", fIndex); 933 934 const scsi_cmd_read_capacity_long* cmd 935 = (const scsi_cmd_read_capacity_long*)request->cdb; 936 scsi_res_read_capacity_long scsiData; 937 938 uint32 allocationLength = B_BENDIAN_TO_HOST_INT32(cmd->alloc_length); 939 size_t copySize = min_c(allocationLength, sizeof(scsiData)); 940 941 if (cmd->pmi || cmd->lba || request->data_length < copySize) { 942 TRACE("invalid request\n"); 943 request->subsys_status = SCSI_REQ_ABORTED; 944 gSCSI->finished(request, 1); 945 return; 946 } 947 948 TRACE("SectorSize %" B_PRIu32 ", SectorCount 0x%" B_PRIx64 "\n", 949 fSectorSize, fSectorCount); 950 951 memset(&scsiData, 0, sizeof(scsiData)); 952 953 scsiData.block_size = B_HOST_TO_BENDIAN_INT32(fSectorSize); 954 scsiData.lba = B_HOST_TO_BENDIAN_INT64(fSectorCount - 1); 955 scsiData.rc_basis = 0x01; 956 scsiData.lbpme = fTrimSupported; 957 scsiData.lbprz = fTrimReturnsZeros; 958 959 if (sg_memcpy(request->sg_list, request->sg_count, &scsiData, 960 copySize) < B_OK) { 961 request->subsys_status = SCSI_DATA_RUN_ERR; 962 } else { 963 request->subsys_status = SCSI_REQ_CMP; 964 request->data_resid = request->data_length - copySize; 965 } 966 gSCSI->finished(request, 1); 967 } 968 969 970 void 971 AHCIPort::ScsiReadWrite(scsi_ccb* request, uint64 lba, size_t sectorCount, 972 bool isWrite) 973 { 974 RWTRACE("[%lld] %ld ScsiReadWrite: position %llu, size %lu, isWrite %d\n", 975 system_time(), find_thread(NULL), lba * 512, sectorCount * 512, 976 isWrite); 977 978 #if 0 979 if (isWrite) { 980 TRACE("write request ignored\n"); 981 request->subsys_status = SCSI_REQ_CMP; 982 request->data_resid = 0; 983 gSCSI->finished(request, 1); 984 return; 985 } 986 #endif 987 988 ASSERT(request->data_length == sectorCount * 512); 989 sata_request* sreq = new(std::nothrow) sata_request(request); 990 if (sreq == NULL) { 991 TRACE("out of memory when allocating read/write request\n"); 992 request->subsys_status = SCSI_REQ_ABORTED; 993 gSCSI->finished(request, 1); 994 return; 995 } 996 997 if (fUse48BitCommands) { 998 if (sectorCount > 65536) { 999 panic("ahci: ScsiReadWrite length too large, %lu sectors", 1000 sectorCount); 1001 } 1002 if (lba > MAX_SECTOR_LBA_48) 1003 panic("achi: ScsiReadWrite position too large for 48-bit LBA\n"); 1004 sreq->SetATA48Command( 1005 isWrite ? ATA_COMMAND_WRITE_DMA_EXT : ATA_COMMAND_READ_DMA_EXT, 1006 lba, sectorCount); 1007 } else { 1008 if (sectorCount > 256) { 1009 panic("ahci: ScsiReadWrite length too large, %lu sectors", 1010 sectorCount); 1011 } 1012 if (lba > MAX_SECTOR_LBA_28) 1013 panic("achi: ScsiReadWrite position too large for normal LBA\n"); 1014 sreq->SetATA28Command(isWrite 1015 ? ATA_COMMAND_WRITE_DMA : ATA_COMMAND_READ_DMA, lba, sectorCount); 1016 } 1017 1018 ExecuteSataRequest(sreq, isWrite); 1019 } 1020 1021 1022 void 1023 AHCIPort::ScsiUnmap(scsi_ccb* request, scsi_unmap_parameter_list* unmapBlocks) 1024 { 1025 if (!fTrimSupported || fMaxTrimRangeBlocks == 0) { 1026 ERROR("TRIM error: Invalid TRIM support values detected\n"); 1027 return; 1028 } 1029 1030 // Determine how many blocks are supposed to be trimmed in total 1031 uint32 scsiRangeCount = (uint16)B_BENDIAN_TO_HOST_INT16( 1032 unmapBlocks->block_data_length) / sizeof(scsi_unmap_block_descriptor); 1033 1034 #ifdef DEBUG_TRIM 1035 dprintf("TRIM: AHCI: received a SCSI UNMAP command (blocks):\n"); 1036 for (uint32 i = 0; i < scsiRangeCount; i++) { 1037 dprintf("[%3" B_PRIu32 "] %" B_PRIu64 " : %" B_PRIu32 "\n", i, 1038 (uint64)B_BENDIAN_TO_HOST_INT64(unmapBlocks->blocks[i].lba), 1039 (uint32)B_BENDIAN_TO_HOST_INT32( 1040 unmapBlocks->blocks[i].block_count)); 1041 } 1042 #endif 1043 1044 if (scsiRangeCount == 0) { 1045 request->subsys_status = SCSI_REQ_CMP; 1046 request->data_resid = 0; 1047 request->device_status = SCSI_STATUS_GOOD; 1048 gSCSI->finished(request, 1); 1049 return; 1050 } 1051 1052 size_t lbaRangeCount = 0; 1053 for (uint32 i = 0; i < scsiRangeCount; i++) { 1054 uint32 range 1055 = B_BENDIAN_TO_HOST_INT32(unmapBlocks->blocks[i].block_count); 1056 lbaRangeCount += range / DSM_MAX_RANGE_VALUE; 1057 if (range % DSM_MAX_RANGE_VALUE != 0) 1058 lbaRangeCount++; 1059 } 1060 TRACE("Total number of ATA ranges: %" B_PRIuSIZE "\n", lbaRangeCount); 1061 1062 size_t lbaRangesAllocatedSize = lbaRangeCount * sizeof(uint64); 1063 // Request data is transferred in 512-byte blocks 1064 if (lbaRangesAllocatedSize % 512 != 0) { 1065 lbaRangesAllocatedSize += 512 - (lbaRangesAllocatedSize % 512); 1066 } 1067 // Apply reported device limits 1068 if (lbaRangesAllocatedSize > (size_t)fMaxTrimRangeBlocks * 512) { 1069 lbaRangesAllocatedSize = (size_t)fMaxTrimRangeBlocks * 512; 1070 } 1071 // Allocate a single buffer and re-use it between requests 1072 TRACE("Allocating a %" B_PRIuSIZE "-byte buffer for ATA request ranges\n", 1073 lbaRangesAllocatedSize); 1074 uint64* lbaRanges = (uint64*)malloc(lbaRangesAllocatedSize); 1075 if (lbaRanges == NULL) { 1076 ERROR("out of memory when allocating space for %" B_PRIuSIZE 1077 " unmap ranges\n", lbaRangesAllocatedSize / sizeof(uint64)); 1078 request->subsys_status = SCSI_REQ_ABORTED; 1079 gSCSI->finished(request, 1); 1080 return; 1081 } 1082 1083 MemoryDeleter deleter(lbaRanges); 1084 1085 memset(lbaRanges, 0, lbaRangesAllocatedSize); 1086 // Entries with range length of 0 will be ignored 1087 uint32 lbaIndex = 0; 1088 for (uint32 i = 0; i < scsiRangeCount; i++) { 1089 uint64 lba = B_BENDIAN_TO_HOST_INT64(unmapBlocks->blocks[i].lba); 1090 uint64 length = (uint32)B_BENDIAN_TO_HOST_INT32( 1091 unmapBlocks->blocks[i].block_count); 1092 1093 if (length == 0) 1094 continue; // Length of 0 would be ignored by the device anyway 1095 1096 if (lba > DSM_MAX_LBA_VALUE) { 1097 ERROR("LBA value is too large!" 1098 " This unmap range will be skipped.\n"); 1099 continue; 1100 } 1101 1102 // Split large ranges if needed. 1103 // Range length is limited by: 1104 // - max value of the range field (DSM_MAX_RANGE_VALUE) 1105 while (length > 0) { 1106 uint64 ataRange = min_c(length, DSM_MAX_RANGE_VALUE); 1107 lbaRanges[lbaIndex++] 1108 = B_HOST_TO_LENDIAN_INT64((ataRange << 48) | lba); 1109 1110 // Split into multiple requests if needed. 1111 // The number of entries in a request is limited by: 1112 // - the maximum number of 512-byte blocks reported by the device 1113 // - maximum possible value of the COUNT field 1114 // - the size of our buffer 1115 if (lbaIndex >= fMaxTrimRangeBlocks * DSM_RANGE_BLOCK_ENTRIES 1116 || (((lbaIndex + 1) * sizeof(uint64) + 511) / 512) 1117 > DSM_MAX_COUNT_48 1118 || lbaIndex >= lbaRangesAllocatedSize / sizeof(uint64) 1119 || (i == scsiRangeCount - 1 && length <= DSM_MAX_RANGE_VALUE)) 1120 { 1121 uint32 lbaRangeCount = lbaIndex; 1122 if (lbaRangeCount % DSM_RANGE_BLOCK_ENTRIES != 0) 1123 lbaRangeCount += DSM_RANGE_BLOCK_ENTRIES 1124 - (lbaRangeCount % DSM_RANGE_BLOCK_ENTRIES); 1125 uint32 lbaRangesSize = lbaRangeCount * sizeof(uint64); 1126 1127 #ifdef DEBUG_TRIM 1128 dprintf("TRIM: AHCI: sending a DATA SET MANAGEMENT command" 1129 " to the device (blocks):\n"); 1130 for (uint32 i = 0; i < lbaRangeCount; i++) { 1131 uint64 value = B_LENDIAN_TO_HOST_INT64(lbaRanges[i]); 1132 dprintf("[%3" B_PRIu32 "] %" B_PRIu64 " : %" B_PRIu64 "\n", i, 1133 value & (((uint64)1 << 48) - 1), value >> 48); 1134 } 1135 #endif 1136 1137 ASSERT(lbaRangesSize % 512 == 0); 1138 ASSERT(lbaRangesSize <= lbaRangesAllocatedSize); 1139 1140 sata_request sreq; 1141 sreq.SetATA48Command(ATA_COMMAND_DATA_SET_MANAGEMENT, 0, 1142 lbaRangesSize / 512); 1143 sreq.SetFeature(1); 1144 sreq.SetData(lbaRanges, lbaRangesSize); 1145 1146 ExecuteSataRequest(&sreq, true); 1147 sreq.WaitForCompletion(); 1148 1149 if ((sreq.CompletionStatus() & ATA_STATUS_ERROR) != 0) { 1150 ERROR("trim failed (%" B_PRIu32 1151 " ATA ranges)!\n", lbaRangeCount); 1152 request->subsys_status = SCSI_REQ_CMP_ERR; 1153 request->device_status = SCSI_STATUS_CHECK_CONDITION; 1154 gSCSI->finished(request, 1); 1155 return; 1156 } else 1157 request->subsys_status = SCSI_REQ_CMP; 1158 1159 lbaIndex = 0; 1160 memset(lbaRanges, 0, lbaRangesSize); 1161 } 1162 1163 length -= ataRange; 1164 lba += ataRange; 1165 } 1166 } 1167 1168 request->data_resid = 0; 1169 request->device_status = SCSI_STATUS_GOOD; 1170 gSCSI->finished(request, 1); 1171 } 1172 1173 1174 void 1175 AHCIPort::ExecuteSataRequest(sata_request* request, bool isWrite) 1176 { 1177 FLOW("ExecuteAtaRequest port %d\n", fIndex); 1178 1179 StartTransfer(); 1180 1181 int prdEntrys; 1182 1183 if (request->CCB() && request->CCB()->data_length) { 1184 FillPrdTable(fPRDTable, &prdEntrys, PRD_TABLE_ENTRY_COUNT, 1185 request->CCB()->sg_list, request->CCB()->sg_count, 1186 request->CCB()->data_length); 1187 } else if (request->Data() && request->Size()) { 1188 FillPrdTable(fPRDTable, &prdEntrys, PRD_TABLE_ENTRY_COUNT, 1189 request->Data(), request->Size()); 1190 } else 1191 prdEntrys = 0; 1192 1193 FLOW("prdEntrys %d\n", prdEntrys); 1194 1195 fCommandList->prdtl_flags_cfl = 0; 1196 fCommandList->cfl = 5; // 20 bytes, length in DWORDS 1197 memcpy((char*)fCommandTable->cfis, request->FIS(), 20); 1198 1199 // We some hide messages when the test unit ready active is clear 1200 // as empty removeable media resets constantly. 1201 fTestUnitReadyActive = request->IsTestUnitReady(); 1202 1203 if (request->IsATAPI()) { 1204 // ATAPI PACKET is a 12 or 16 byte SCSI command 1205 memset((char*)fCommandTable->acmd, 0, 32); 1206 memcpy((char*)fCommandTable->acmd, request->CCB()->cdb, 1207 request->CCB()->cdb_length); 1208 fCommandList->a = 1; 1209 } 1210 1211 if (isWrite) 1212 fCommandList->w = 1; 1213 fCommandList->prdtl = prdEntrys; 1214 fCommandList->prdbc = 0; 1215 1216 if (wait_until_clear(&fRegs->tfd, ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST, 1217 1000000) < B_OK) { 1218 ERROR("ExecuteAtaRequest port %d: device is busy\n", fIndex); 1219 PortReset(); 1220 FinishTransfer(); 1221 request->Abort(); 1222 return; 1223 } 1224 1225 cpu_status cpu = disable_interrupts(); 1226 acquire_spinlock(&fSpinlock); 1227 fCommandsActive |= 1; 1228 fRegs->ci = 1; 1229 FlushPostedWrites(); 1230 release_spinlock(&fSpinlock); 1231 restore_interrupts(cpu); 1232 1233 int tfd; 1234 status_t status = WaitForTransfer(&tfd, 20000000); 1235 1236 FLOW("Port %d sata request flow:\n", fIndex); 1237 FLOW(" tfd %#x\n", tfd); 1238 FLOW(" prdbc %ld\n", fCommandList->prdbc); 1239 FLOW(" ci 0x%08" B_PRIx32 "\n", fRegs->ci); 1240 FLOW(" is 0x%08" B_PRIx32 "\n", fRegs->is); 1241 FLOW(" serr 0x%08" B_PRIx32 "\n", fRegs->serr); 1242 1243 /* 1244 TRACE("ci 0x%08" B_PRIx32 "\n", fRegs->ci); 1245 TRACE("ie 0x%08" B_PRIx32 "\n", fRegs->ie); 1246 TRACE("is 0x%08" B_PRIx32 "\n", fRegs->is); 1247 TRACE("cmd 0x%08" B_PRIx32 "\n", fRegs->cmd); 1248 TRACE("ssts 0x%08" B_PRIx32 "\n", fRegs->ssts); 1249 TRACE("sctl 0x%08" B_PRIx32 "\n", fRegs->sctl); 1250 TRACE("serr 0x%08" B_PRIx32 "\n", fRegs->serr); 1251 TRACE("sact 0x%08" B_PRIx32 "\n", fRegs->sact); 1252 TRACE("tfd 0x%08" B_PRIx32 "\n", fRegs->tfd); 1253 */ 1254 1255 if (fPortReset || status == B_TIMED_OUT) { 1256 fPortReset = false; 1257 PortReset(); 1258 } 1259 1260 size_t bytesTransfered = fCommandList->prdbc; 1261 1262 FinishTransfer(); 1263 1264 if (status == B_TIMED_OUT) { 1265 ERROR("ExecuteAtaRequest port %d: device timeout\n", fIndex); 1266 request->Abort(); 1267 return; 1268 } 1269 1270 request->Finish(tfd, bytesTransfered); 1271 } 1272 1273 1274 void 1275 AHCIPort::ScsiExecuteRequest(scsi_ccb* request) 1276 { 1277 // TRACE("AHCIPort::ScsiExecuteRequest port %d, opcode 0x%02x, length %u\n", fIndex, request->cdb[0], request->cdb_length); 1278 1279 if (fIsATAPI) { 1280 bool isWrite = false; 1281 switch (request->flags & SCSI_DIR_MASK) { 1282 case SCSI_DIR_NONE: 1283 ASSERT(request->data_length == 0); 1284 break; 1285 case SCSI_DIR_IN: 1286 break; 1287 case SCSI_DIR_OUT: 1288 isWrite = true; 1289 ASSERT(request->data_length > 0); 1290 break; 1291 default: 1292 panic("CDB has invalid direction mask"); 1293 } 1294 1295 // TRACE("AHCIPort::ScsiExecuteRequest ATAPI: port %d, opcode 0x%02x, length %u\n", fIndex, request->cdb[0], request->cdb_length); 1296 1297 sata_request* sreq = new(std::nothrow) sata_request(request); 1298 if (sreq == NULL) { 1299 ERROR("out of memory when allocating atapi request\n"); 1300 request->subsys_status = SCSI_REQ_ABORTED; 1301 gSCSI->finished(request, 1); 1302 return; 1303 } 1304 1305 sreq->SetATAPICommand(request->data_length); 1306 // uint8* data = (uint8*) sreq->ccb()->cdb; 1307 // for (int i = 0; i < 16; i += 8) { 1308 // TRACE(" %02x %02x %02x %02x %02x %02x %02x %02x\n", data[i], data[i+1], data[i+2], data[i+3], data[i+4], data[i+5], data[i+6], data[i+7]); 1309 // } 1310 ExecuteSataRequest(sreq, isWrite); 1311 return; 1312 } 1313 1314 if (request->cdb[0] == SCSI_OP_REQUEST_SENSE) { 1315 panic("ahci: SCSI_OP_REQUEST_SENSE not yet supported\n"); 1316 return; 1317 } 1318 1319 if (!fDevicePresent) { 1320 TRACE("no device present on port %d\n", fIndex); 1321 request->subsys_status = SCSI_DEV_NOT_THERE; 1322 gSCSI->finished(request, 1); 1323 return; 1324 } 1325 1326 request->subsys_status = SCSI_REQ_CMP; 1327 1328 switch (request->cdb[0]) { 1329 case SCSI_OP_TEST_UNIT_READY: 1330 ScsiTestUnitReady(request); 1331 break; 1332 case SCSI_OP_INQUIRY: 1333 ScsiInquiry(request); 1334 break; 1335 case SCSI_OP_READ_CAPACITY: 1336 ScsiReadCapacity(request); 1337 break; 1338 case SCSI_OP_SERVICE_ACTION_IN: 1339 if ((request->cdb[1] & 0x1f) == SCSI_SAI_READ_CAPACITY_16) 1340 ScsiReadCapacity16(request); 1341 else { 1342 request->subsys_status = SCSI_REQ_INVALID; 1343 gSCSI->finished(request, 1); 1344 } 1345 break; 1346 case SCSI_OP_SYNCHRONIZE_CACHE: 1347 ScsiSynchronizeCache(request); 1348 break; 1349 case SCSI_OP_READ_6: 1350 case SCSI_OP_WRITE_6: 1351 { 1352 const scsi_cmd_rw_6* cmd = (const scsi_cmd_rw_6*)request->cdb; 1353 uint32 position = ((uint32)cmd->high_lba << 16) 1354 | ((uint32)cmd->mid_lba << 8) | (uint32)cmd->low_lba; 1355 size_t length = cmd->length != 0 ? cmd->length : 256; 1356 bool isWrite = request->cdb[0] == SCSI_OP_WRITE_6; 1357 ScsiReadWrite(request, position, length, isWrite); 1358 break; 1359 } 1360 case SCSI_OP_READ_10: 1361 case SCSI_OP_WRITE_10: 1362 { 1363 const scsi_cmd_rw_10* cmd = (const scsi_cmd_rw_10*)request->cdb; 1364 uint32 position = B_BENDIAN_TO_HOST_INT32(cmd->lba); 1365 size_t length = B_BENDIAN_TO_HOST_INT16(cmd->length); 1366 bool isWrite = request->cdb[0] == SCSI_OP_WRITE_10; 1367 if (length) { 1368 ScsiReadWrite(request, position, length, isWrite); 1369 } else { 1370 ERROR("AHCIPort::ScsiExecuteRequest error: transfer without " 1371 "data!\n"); 1372 request->subsys_status = SCSI_REQ_INVALID; 1373 gSCSI->finished(request, 1); 1374 } 1375 break; 1376 } 1377 case SCSI_OP_READ_12: 1378 case SCSI_OP_WRITE_12: 1379 { 1380 const scsi_cmd_rw_12* cmd = (const scsi_cmd_rw_12*)request->cdb; 1381 uint32 position = B_BENDIAN_TO_HOST_INT32(cmd->lba); 1382 size_t length = B_BENDIAN_TO_HOST_INT32(cmd->length); 1383 bool isWrite = request->cdb[0] == SCSI_OP_WRITE_12; 1384 if (length) { 1385 ScsiReadWrite(request, position, length, isWrite); 1386 } else { 1387 ERROR("AHCIPort::ScsiExecuteRequest error: transfer without " 1388 "data!\n"); 1389 request->subsys_status = SCSI_REQ_INVALID; 1390 gSCSI->finished(request, 1); 1391 } 1392 break; 1393 } 1394 case SCSI_OP_READ_16: 1395 case SCSI_OP_WRITE_16: 1396 { 1397 const scsi_cmd_rw_16* cmd = (const scsi_cmd_rw_16*)request->cdb; 1398 uint64 position = B_BENDIAN_TO_HOST_INT64(cmd->lba); 1399 size_t length = B_BENDIAN_TO_HOST_INT32(cmd->length); 1400 bool isWrite = request->cdb[0] == SCSI_OP_WRITE_16; 1401 if (length) { 1402 ScsiReadWrite(request, position, length, isWrite); 1403 } else { 1404 ERROR("AHCIPort::ScsiExecuteRequest error: transfer without " 1405 "data!\n"); 1406 request->subsys_status = SCSI_REQ_INVALID; 1407 gSCSI->finished(request, 1); 1408 } 1409 break; 1410 } 1411 case SCSI_OP_UNMAP: 1412 { 1413 const scsi_cmd_unmap* cmd = (const scsi_cmd_unmap*)request->cdb; 1414 1415 if (!fTrimSupported) { 1416 ERROR("%s port %d: unsupported request opcode 0x%02x\n", 1417 __func__, fIndex, request->cdb[0]); 1418 request->subsys_status = SCSI_REQ_ABORTED; 1419 gSCSI->finished(request, 1); 1420 break; 1421 } 1422 1423 scsi_unmap_parameter_list* unmapBlocks 1424 = (scsi_unmap_parameter_list*)request->data; 1425 if (unmapBlocks == NULL 1426 || (uint16)B_BENDIAN_TO_HOST_INT16(cmd->length) 1427 != request->data_length 1428 || (uint16)B_BENDIAN_TO_HOST_INT16(unmapBlocks->data_length) 1429 != request->data_length 1430 - offsetof(scsi_unmap_parameter_list, block_data_length) 1431 || (uint16)B_BENDIAN_TO_HOST_INT16( 1432 unmapBlocks->block_data_length) 1433 != request->data_length 1434 - offsetof(scsi_unmap_parameter_list, blocks)) { 1435 ERROR("%s port %d: invalid unmap parameter data length\n", 1436 __func__, fIndex); 1437 request->subsys_status = SCSI_REQ_ABORTED; 1438 gSCSI->finished(request, 1); 1439 } else { 1440 ScsiUnmap(request, unmapBlocks); 1441 } 1442 break; 1443 } 1444 default: 1445 ERROR("AHCIPort::ScsiExecuteRequest port %d unsupported request " 1446 "opcode 0x%02x\n", fIndex, request->cdb[0]); 1447 request->subsys_status = SCSI_REQ_ABORTED; 1448 gSCSI->finished(request, 1); 1449 } 1450 } 1451 1452 1453 uchar 1454 AHCIPort::ScsiAbortRequest(scsi_ccb* request) 1455 { 1456 return SCSI_REQ_CMP; 1457 } 1458 1459 1460 uchar 1461 AHCIPort::ScsiTerminateRequest(scsi_ccb* request) 1462 { 1463 return SCSI_REQ_CMP; 1464 } 1465 1466 1467 uchar 1468 AHCIPort::ScsiResetDevice() 1469 { 1470 return SCSI_REQ_CMP; 1471 } 1472 1473 1474 void 1475 AHCIPort::ScsiGetRestrictions(bool* isATAPI, bool* noAutoSense, 1476 uint32* maxBlocks) 1477 { 1478 *isATAPI = fIsATAPI; 1479 *noAutoSense = fIsATAPI; // emulated auto sense for ATA, but not ATAPI 1480 *maxBlocks = fUse48BitCommands ? 65536 : 256; 1481 TRACE("AHCIPort::ScsiGetRestrictions port %d: isATAPI %d, noAutoSense %d, " 1482 "maxBlocks %" B_PRIu32 "\n", fIndex, *isATAPI, *noAutoSense, 1483 *maxBlocks); 1484 } 1485 1486 1487 bool 1488 AHCIPort::Enable() 1489 { 1490 // Spec v1.3.1, §10.3.1 Start (PxCMD.ST) 1491 TRACE("%s: port %d\n", __func__, fIndex); 1492 1493 if ((fRegs->cmd & PORT_CMD_ST) != 0) { 1494 ERROR("%s: Starting port already running!\n", __func__); 1495 return false; 1496 } 1497 1498 if ((fRegs->cmd & PORT_CMD_FRE) == 0) { 1499 ERROR("%s: Unable to start port without FRE enabled!\n", __func__); 1500 return false; 1501 } 1502 1503 // Clear DMA engine and wait for completion 1504 if (wait_until_clear(&fRegs->cmd, PORT_CMD_CR, 500000) < B_OK) { 1505 ERROR("%s: port %d error DMA engine still running\n", __func__, 1506 fIndex); 1507 return false; 1508 } 1509 // Start port 1510 fRegs->cmd |= PORT_CMD_ST; 1511 FlushPostedWrites(); 1512 return true; 1513 } 1514 1515 1516 bool 1517 AHCIPort::Disable() 1518 { 1519 TRACE("%s: port %d\n", __func__, fIndex); 1520 1521 if ((fRegs->cmd & PORT_CMD_ST) == 0) { 1522 // Port already disabled, carry on. 1523 TRACE("%s: port %d attempting to disable stopped port.\n", 1524 __func__, fIndex); 1525 } else { 1526 // Disable port 1527 fRegs->cmd &= ~PORT_CMD_ST; 1528 FlushPostedWrites(); 1529 } 1530 1531 // Spec v1.3.1, §10.4.2 Port Reset - assume hung after 500 mil. 1532 // Clear DMA engine and wait for completion 1533 if (wait_until_clear(&fRegs->cmd, PORT_CMD_CR, 500000) < B_OK) { 1534 ERROR("%s: port %d error DMA engine still running\n", __func__, 1535 fIndex); 1536 return false; 1537 } 1538 1539 return true; 1540 } 1541 1542 1543 void 1544 AHCIPort::_ClearErrorRegister() 1545 { 1546 // clear error bits 1547 fRegs->serr = fRegs->serr; 1548 FlushPostedWrites(); 1549 } 1550