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