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