1 /* 2 * Copyright 2009, Michael Lotz, mmlr@mlotz.ch. 3 * Copyright 2008, Marcus Overhagen. 4 * Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de. 5 * Copyright 2002-2003, Thomas Kurschel. 6 * 7 * Distributed under the terms of the MIT License. 8 */ 9 10 #include "ATAPrivate.h" 11 12 13 ATADevice::ATADevice(ATAChannel *channel, uint8 index) 14 : 15 fChannel(channel), 16 fRegisterMask(0), 17 fUseDMA(channel->UseDMA()), 18 fDMAMode(0), 19 fDMAFailures(0), 20 fTotalSectors(0), 21 fBlockSize(512), 22 fPhysicalBlockSize(512), 23 fBlockOffset(0), 24 fIndex(index), 25 fUse48Bits(false) 26 { 27 memset(&fInfoBlock, 0, sizeof(fInfoBlock)); 28 memset(&fTaskFile, 0, sizeof(fTaskFile)); 29 } 30 31 32 ATADevice::~ATADevice() 33 { 34 } 35 36 37 status_t 38 ATADevice::TestUnitReady(ATARequest *request) 39 { 40 TRACE_FUNCTION("%p\n", request); 41 42 fRegisterMask = 0; 43 fTaskFile.write.command = ATA_COMMAND_GET_MEDIA_STATUS; 44 45 request->SetTimeout(15 * 1000 * 1000); 46 status_t result = fChannel->SendRequest(request, ATA_DEVICE_READY_REQUIRED); 47 if (result != B_OK) { 48 TRACE_ERROR("failed to send test unit ready request\n"); 49 return result; 50 } 51 52 return fChannel->FinishRequest(request, ATA_WAIT_FINISH 53 | ATA_DEVICE_READY_REQUIRED, ATA_ERROR_NO_MEDIA | ATA_ERROR_ABORTED 54 | ATA_ERROR_MEDIA_CHANGE_REQUESTED | ATA_ERROR_MEDIUM_CHANGED); 55 } 56 57 58 status_t 59 ATADevice::SynchronizeCache(ATARequest *request) 60 { 61 TRACE_FUNCTION("%p\n", request); 62 63 // we should also ask for FLUSH CACHE support, but everyone denies it 64 // (looks like they cheat to gain some performance advantage, but 65 // that's pretty useless: everyone does it...) 66 if (!fInfoBlock.write_cache_supported) 67 return B_OK; 68 69 fRegisterMask = 0; 70 fTaskFile.lba.command 71 = fUse48Bits ? ATA_COMMAND_FLUSH_CACHE_EXT : ATA_COMMAND_FLUSH_CACHE; 72 73 request->SetTimeout(60 * 1000 * 1000); 74 status_t result = fChannel->SendRequest(request, ATA_DEVICE_READY_REQUIRED); 75 if (result != B_OK) { 76 TRACE_ERROR("failed to send synchronize cache request\n"); 77 return result; 78 } 79 80 return fChannel->FinishRequest(request, ATA_WAIT_FINISH 81 | ATA_DEVICE_READY_REQUIRED, ATA_ERROR_ABORTED); 82 } 83 84 85 status_t 86 ATADevice::Eject(ATARequest *request) 87 { 88 TRACE_FUNCTION("%p\n", request); 89 90 fRegisterMask = 0; 91 fTaskFile.lba.command = ATA_COMMAND_MEDIA_EJECT; 92 93 request->SetTimeout(15 * 1000 * 1000); 94 status_t result = fChannel->SendRequest(request, ATA_DEVICE_READY_REQUIRED); 95 if (result != B_OK) { 96 TRACE_ERROR("failed to send eject request\n"); 97 return result; 98 } 99 100 return fChannel->FinishRequest(request, ATA_WAIT_FINISH 101 | ATA_DEVICE_READY_REQUIRED, ATA_ERROR_ABORTED | ATA_ERROR_NO_MEDIA); 102 } 103 104 105 status_t 106 ATADevice::Inquiry(ATARequest *request) 107 { 108 TRACE_FUNCTION("%p\n", request); 109 110 scsi_ccb *ccb = request->CCB(); 111 scsi_cmd_inquiry *command = (scsi_cmd_inquiry *)ccb->cdb; 112 if (command->evpd || command->page_code) { 113 request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_CDB_FIELD); 114 return B_ERROR; 115 } 116 117 scsi_res_inquiry data; 118 memset(&data, 0, sizeof(data)); 119 120 data.device_type = IsATAPI() 121 ? fInfoBlock.word_0.atapi.command_packet_set : scsi_dev_direct_access; 122 data.device_qualifier = scsi_periph_qual_connected; 123 124 data.device_type_modifier = 0; 125 data.removable_medium = fInfoBlock.word_0.ata.removable_media_device; 126 127 data.ansi_version = 2; 128 data.ecma_version = 0; 129 data.iso_version = 0; 130 131 data.response_data_format = 2; 132 data.term_iop = false; 133 // to be changed if we support TERM I/O 134 135 data.additional_length = sizeof(scsi_res_inquiry) - 4; 136 137 data.soft_reset = false; 138 data.cmd_queue = 0; 139 data.linked = false; 140 141 // these values are free-style 142 data.sync = false; 143 data.write_bus16 = true; 144 data.write_bus32 = false; 145 146 data.relative_address = false; 147 148 // the following fields are *much* to small, sigh... 149 memcpy(data.vendor_ident, fInfoBlock.model_number, 150 sizeof(data.vendor_ident)); 151 swap_words(data.vendor_ident, sizeof(data.vendor_ident)); 152 153 memcpy(data.product_ident, fInfoBlock.model_number + 8, 154 sizeof(data.product_ident)); 155 swap_words(data.product_ident, sizeof(data.product_ident)); 156 157 memcpy(data.product_rev, " ", sizeof(data.product_rev)); 158 159 uint32 allocationLength = command->allocation_length; 160 copy_sg_data(ccb, 0, allocationLength, &data, sizeof(data), false); 161 ccb->data_resid = ccb->data_length - MIN(MIN(sizeof(data), 162 allocationLength), ccb->data_length); 163 return B_OK; 164 } 165 166 167 status_t 168 ATADevice::ReadCapacity(ATARequest *request) 169 { 170 TRACE_FUNCTION("%p\n", request); 171 172 scsi_ccb *ccb = request->CCB(); 173 scsi_cmd_read_capacity *command = (scsi_cmd_read_capacity *)ccb->cdb; 174 if (command->pmi || command->lba) { 175 request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_CDB_FIELD); 176 return B_ERROR; 177 } 178 179 scsi_res_read_capacity data; 180 data.block_size = B_HOST_TO_BENDIAN_INT32(fBlockSize); 181 182 if (fTotalSectors <= UINT_MAX) { 183 uint32 lastBlock = fTotalSectors - 1; 184 data.lba = B_HOST_TO_BENDIAN_INT32(lastBlock); 185 } else 186 data.lba = UINT_MAX; 187 TRACE("returning last block: %lu\n", B_BENDIAN_TO_HOST_INT32(data.lba)); 188 189 copy_sg_data(ccb, 0, ccb->data_length, &data, sizeof(data), false); 190 ccb->data_resid = MAX(ccb->data_length - sizeof(data), 0); 191 return B_OK; 192 } 193 194 195 status_t 196 ATADevice::ReadCapacity16(ATARequest *request) 197 { 198 TRACE_FUNCTION("%p\n", request); 199 200 scsi_ccb *ccb = request->CCB(); 201 scsi_res_read_capacity_long data; 202 data.block_size = B_HOST_TO_BENDIAN_INT32(fBlockSize); 203 204 uint64 lastBlock = fTotalSectors - 1; 205 data.lba = B_HOST_TO_BENDIAN_INT64(lastBlock); 206 TRACE("returning last block: %llu\n", data.lba); 207 208 copy_sg_data(ccb, 0, ccb->data_length, &data, sizeof(data), false); 209 ccb->data_resid = MAX(ccb->data_length - sizeof(data), 0); 210 return B_OK; 211 } 212 213 214 status_t 215 ATADevice::ExecuteIO(ATARequest *request) 216 { 217 TRACE_FUNCTION("%p\n", request); 218 219 scsi_ccb *ccb = request->CCB(); 220 request->SetDevice(this); 221 222 // ATA devices have one LUN only 223 if (ccb->target_lun != 0) { 224 TRACE_ERROR("invalid target lun %d for ATA device\n", ccb->target_lun); 225 request->SetStatus(SCSI_SEL_TIMEOUT); 226 return B_BAD_INDEX; 227 } 228 229 TRACE("request: 0x%02x\n", ccb->cdb[0]); 230 231 switch (ccb->cdb[0]) { 232 case SCSI_OP_TEST_UNIT_READY: 233 return TestUnitReady(request); 234 235 case SCSI_OP_FORMAT: /* FORMAT UNIT */ 236 // we could forward ccb to disk, but modern disks cannot 237 // be formatted anyway, so we just refuse ccb 238 // (exceptions are removable media devices, but to my knowledge 239 // they don't have to be formatted as well) 240 request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE); 241 return B_ERROR; 242 243 case SCSI_OP_INQUIRY: 244 return Inquiry(request); 245 246 case SCSI_OP_START_STOP: 247 { 248 scsi_cmd_ssu *command = (scsi_cmd_ssu *)ccb->cdb; 249 250 // with no LoEj bit set, we should only allow/deny further access 251 // we ignore that (unsupported for ATA) 252 // with LoEj bit set, we should additionally either load or eject 253 // the medium (start = 0 - eject; start = 1 - load) 254 255 if (!command->start) { 256 // we must always flush cache if start = 0 257 SynchronizeCache(request); 258 } 259 260 if (command->load_eject) { 261 if (!command->start) 262 return Eject(request); 263 else { 264 request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST, 265 SCSIS_ASC_PARAM_NOT_SUPPORTED); 266 return B_ERROR; 267 } 268 } 269 270 return B_OK; 271 } 272 273 case SCSI_OP_READ_CAPACITY: 274 return ReadCapacity(request); 275 276 case SCSI_OP_SERVICE_ACTION_IN: 277 if ((ccb->cdb[1] & 0x1f) == SCSI_SAI_READ_CAPACITY_16) 278 return ReadCapacity16(request); 279 break; 280 281 case SCSI_OP_SYNCHRONIZE_CACHE: 282 // we ignore range and immediate bit, we always immediately 283 // flush everything 284 return SynchronizeCache(request); 285 286 // sadly, there are two possible read/write operation codes; 287 // at least, the third one, read/write(12), is not valid for DAS 288 case SCSI_OP_READ_6: 289 case SCSI_OP_WRITE_6: 290 { 291 scsi_cmd_rw_6 *command = (scsi_cmd_rw_6 *)ccb->cdb; 292 uint32 address = ((uint32)command->high_lba << 16) 293 | ((uint32)command->mid_lba << 8) | (uint32)command->low_lba; 294 295 request->SetIsWrite(command->opcode == SCSI_OP_WRITE_6); 296 return ExecuteReadWrite(request, address, command->length != 0 297 ? command->length : 256); 298 } 299 300 case SCSI_OP_READ_10: 301 case SCSI_OP_WRITE_10: 302 { 303 scsi_cmd_rw_10 *command = (scsi_cmd_rw_10 *)ccb->cdb; 304 uint32 address = B_BENDIAN_TO_HOST_INT32(command->lba); 305 uint32 sectorCount = B_BENDIAN_TO_HOST_INT16(command->length); 306 307 request->SetIsWrite(command->opcode == SCSI_OP_WRITE_10); 308 if (sectorCount > 0) 309 return ExecuteReadWrite(request, address, sectorCount); 310 else { 311 // we cannot transfer zero blocks (apart from LBA48) 312 request->SetStatus(SCSI_REQ_CMP); 313 return B_OK; 314 } 315 } 316 317 case SCSI_OP_READ_12: 318 case SCSI_OP_WRITE_12: 319 { 320 scsi_cmd_rw_12 *command = (scsi_cmd_rw_12 *)ccb->cdb; 321 uint32 address = B_BENDIAN_TO_HOST_INT32(command->lba); 322 uint32 sectorCount = B_BENDIAN_TO_HOST_INT32(command->length); 323 324 request->SetIsWrite(command->opcode == SCSI_OP_WRITE_12); 325 if (sectorCount > 0) 326 return ExecuteReadWrite(request, address, sectorCount); 327 else { 328 // we cannot transfer zero blocks (apart from LBA48) 329 request->SetStatus(SCSI_REQ_CMP); 330 return B_OK; 331 } 332 } 333 334 case SCSI_OP_READ_16: 335 case SCSI_OP_WRITE_16: 336 { 337 scsi_cmd_rw_16 *command = (scsi_cmd_rw_16 *)ccb->cdb; 338 uint64 address = B_BENDIAN_TO_HOST_INT64(command->lba); 339 uint32 sectorCount = B_BENDIAN_TO_HOST_INT32(command->length); 340 341 request->SetIsWrite(command->opcode == SCSI_OP_WRITE_16); 342 if (sectorCount > 0) 343 return ExecuteReadWrite(request, address, sectorCount); 344 else { 345 // we cannot transfer zero blocks (apart from LBA48) 346 request->SetStatus(SCSI_REQ_CMP); 347 return B_OK; 348 } 349 } 350 } 351 352 TRACE("command not implemented\n"); 353 request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE); 354 return B_ERROR; 355 } 356 357 358 void 359 ATADevice::GetRestrictions(bool *noAutoSense, uint32 *maxBlocks) 360 { 361 if (IsATAPI()) 362 *noAutoSense = true; 363 else { 364 if (fUse48Bits) 365 *maxBlocks = 0xffff; 366 else 367 *maxBlocks = 0x100; 368 } 369 } 370 371 372 status_t 373 ATADevice::Control(uint32 opcode, void *buffer, size_t length) 374 { 375 if (opcode == B_GET_DEVICE_NAME) { 376 // Swap words 377 char name[sizeof(fInfoBlock.model_number)]; 378 memcpy(name, fInfoBlock.model_number, sizeof(name)); 379 swap_words(name, sizeof(name)); 380 381 // Remove trailing spaces 382 int32 nameLength = sizeof(name) - 2; 383 while (nameLength > 0 && name[nameLength - 1] == ' ') 384 nameLength--; 385 386 // TODO: make string prettier, ie. "WDC" -> "Western Digital", ... 387 return user_strlcpy((char*)buffer, name, 388 min_c((size_t)nameLength + 1, length)) >= 0 ? B_OK : B_BAD_ADDRESS; 389 } 390 return B_BAD_VALUE; 391 } 392 393 394 status_t 395 ATADevice::Select() 396 { 397 status_t err = fChannel->SelectDevice(fIndex); 398 #if 1 399 // for debugging only 400 if (fChannel->SelectedDevice() != fIndex) { 401 TRACE_ERROR("device %d not selected!\n", fIndex); 402 return B_ERROR; 403 } 404 #endif 405 return err; 406 } 407 408 409 status_t 410 ATADevice::SetFeature(int feature) 411 { 412 TRACE("device_set_feature: feature %d\n", feature); 413 414 ATARequest request(false); 415 request.SetDevice(this); 416 request.SetTimeout(1 * 1000 * 1000); 417 418 fTaskFile.write.features = feature; 419 fTaskFile.write.command = ATA_COMMAND_SET_FEATURES; 420 fRegisterMask = ATA_MASK_FEATURES; 421 422 status_t result = fChannel->SendRequest(&request, ATA_DEVICE_READY_REQUIRED); 423 if (result != B_OK) { 424 TRACE_ERROR("sending set feature request failed\n"); 425 return result; 426 } 427 428 result = fChannel->FinishRequest(&request, 429 ATA_WAIT_FINISH | ATA_DEVICE_READY_REQUIRED, ATA_ERROR_ABORTED); 430 if (result != B_OK) { 431 TRACE_ERROR("set feature request failed\n"); 432 return result; 433 } 434 435 return B_OK; 436 } 437 438 439 status_t 440 ATADevice::DisableCommandQueueing() 441 { 442 if (!fInfoBlock.read_write_dma_queued_supported) 443 return B_OK; 444 445 if (fInfoBlock.release_interrupt_supported) { 446 status_t result = SetFeature( 447 ATA_COMMAND_SET_FEATURES_DISABLE_RELEASE_INT); 448 if (result != B_OK) { 449 TRACE_ERROR("failed to disable release interrupt\n"); 450 return result; 451 } 452 } 453 454 if (fInfoBlock.service_interrupt_supported) { 455 status_t result = SetFeature( 456 ATA_COMMAND_SET_FEATURES_DISABLE_SERVICE_INT); 457 if (result != B_OK) { 458 TRACE_ERROR("failed to disable service interrupt\n"); 459 return result; 460 } 461 } 462 463 return B_OK; 464 } 465 466 467 status_t 468 ATADevice::ConfigureDMA() 469 { 470 if (!fUseDMA) 471 return B_OK; 472 473 if (!fInfoBlock.dma_supported) { 474 TRACE_ALWAYS("DMA not supported by device\n"); 475 fUseDMA = false; 476 return B_OK; 477 } 478 479 #define CHECK_DMA_MODE(element, mode) \ 480 if (fInfoBlock.element) { \ 481 fDMAMode = mode; \ 482 modeCount++; \ 483 } 484 485 uint32 modeCount = 0; 486 487 CHECK_DMA_MODE(multiword_dma_0_selected, 0x00); 488 CHECK_DMA_MODE(multiword_dma_1_selected, 0x01); 489 CHECK_DMA_MODE(multiword_dma_2_selected, 0x02); 490 491 if (fInfoBlock.word_88_valid) { 492 CHECK_DMA_MODE(ultra_dma_0_selected, 0x10); 493 CHECK_DMA_MODE(ultra_dma_1_selected, 0x11); 494 CHECK_DMA_MODE(ultra_dma_2_selected, 0x12); 495 CHECK_DMA_MODE(ultra_dma_3_selected, 0x13); 496 CHECK_DMA_MODE(ultra_dma_4_selected, 0x14); 497 CHECK_DMA_MODE(ultra_dma_5_selected, 0x15); 498 CHECK_DMA_MODE(ultra_dma_6_selected, 0x16); 499 } 500 501 #undef CHECK_DMA_MODE 502 503 if (modeCount != 1) { 504 TRACE_ERROR("more than one DMA mode selected, not using DMA\n"); 505 fUseDMA = false; 506 return B_OK; 507 } 508 509 TRACE_ALWAYS("using DMA mode 0x%02x\n", fDMAMode); 510 return B_OK; 511 } 512 513 514 status_t 515 ATADevice::Configure() 516 { 517 // warning: ata == 0 means "this is ata"... 518 if (fInfoBlock.word_0.ata.ata_device != ATA_WORD_0_ATA_DEVICE) { 519 // CF has either magic header or CFA bit set 520 // we merge it to "CFA bit set" for easier (later) testing 521 if (fInfoBlock.word_0.raw == ATA_WORD_0_CFA_MAGIC) 522 fInfoBlock.compact_flash_assoc_supported = true; 523 else { 524 TRACE_ERROR("infoblock indicates non-ata device\n"); 525 return B_ERROR; 526 } 527 } 528 529 if (!fInfoBlock.lba_supported || (fInfoBlock.lba_sector_count == 0 530 && fInfoBlock.lba48_sector_count == 0)) { 531 TRACE_ERROR("non-lba devices not supported\n"); 532 return B_ERROR; 533 } 534 535 fTotalSectors = fInfoBlock.SectorCount(fUse48Bits, false); 536 fBlockSize = fInfoBlock.SectorSize(); 537 fPhysicalBlockSize = fInfoBlock.PhysicalSectorSize(); 538 fBlockOffset = fInfoBlock.BlockOffset(); 539 540 fTaskFile.lba.mode = ATA_MODE_LBA; 541 fTaskFile.lba.device = fIndex; 542 543 status_t result = ConfigureDMA(); 544 if (result != B_OK) 545 return result; 546 547 result = DisableCommandQueueing(); 548 if (result != B_OK) 549 return result; 550 551 return B_OK; 552 } 553 554 555 status_t 556 ATADevice::Identify() 557 { 558 snprintf(fDebugContext, sizeof(fDebugContext), "%s %" B_PRIu32 "-%u", 559 IsATAPI() ? "pi" : "", fChannel->ChannelID(), fIndex); 560 561 ATARequest request(false); 562 request.SetDevice(this); 563 request.SetTimeout(20 * 1000 * 1000); 564 565 fRegisterMask = 0; 566 fTaskFile.write.command = IsATAPI() ? ATA_COMMAND_IDENTIFY_PACKET_DEVICE 567 : ATA_COMMAND_IDENTIFY_DEVICE; 568 569 if (fChannel->SendRequest(&request, 570 IsATAPI() ? 0 : ATA_DEVICE_READY_REQUIRED) != B_OK) { 571 TRACE_ERROR("sending identify request failed\n"); 572 return B_ERROR; 573 } 574 575 if (fChannel->Wait(ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST, 0, 576 ATA_WAIT_ANY_BIT, 100 * 1000) != B_OK) { 577 TRACE_ALWAYS("no data request and not busy within 100ms, assuming " 578 "no device present\n"); 579 return B_TIMED_OUT; 580 } 581 582 if (fChannel->Wait(ATA_STATUS_DATA_REQUEST, ATA_STATUS_BUSY, 583 ATA_CHECK_ERROR_BIT | ATA_CHECK_DEVICE_FAULT, 584 IsATAPI() ? 20 * 1000 * 1000 : 500 * 1000) != B_OK) { 585 TRACE_ERROR("timeout waiting for identify request\n"); 586 return B_TIMED_OUT; 587 } 588 589 // get the infoblock 590 fChannel->ReadPIO((uint8 *)&fInfoBlock, sizeof(fInfoBlock)); 591 592 if (fChannel->WaitDataRequest(false) != B_OK) { 593 TRACE_ERROR("device disagrees on info block length\n"); 594 return B_ERROR; 595 } 596 597 if (fChannel->FinishRequest(&request, 598 ATA_WAIT_FINISH | (IsATAPI() ? 0 : ATA_DEVICE_READY_REQUIRED), 599 ATA_ERROR_ABORTED) != B_OK) { 600 TRACE_ERROR("failed to finish identify request\n"); 601 return B_ERROR; 602 } 603 604 if (1) { 605 // print device information 606 char modelNumber[sizeof(fInfoBlock.model_number) + 1]; 607 char serialNumber[sizeof(fInfoBlock.serial_number) + 1]; 608 char firmwareRev[sizeof(fInfoBlock.firmware_revision) + 1]; 609 strlcpy(modelNumber, fInfoBlock.model_number, sizeof(modelNumber)); 610 strlcpy(serialNumber, fInfoBlock.serial_number, sizeof(serialNumber)); 611 strlcpy(firmwareRev, fInfoBlock.firmware_revision, sizeof(firmwareRev)); 612 swap_words(modelNumber, sizeof(modelNumber) - 1); 613 swap_words(serialNumber, sizeof(serialNumber) - 1); 614 swap_words(firmwareRev, sizeof(firmwareRev) - 1); 615 TRACE_ALWAYS("model number: %s\n", modelNumber); 616 TRACE_ALWAYS("serial number: %s\n", serialNumber); 617 TRACE_ALWAYS("firmware rev.: %s\n", firmwareRev); 618 } 619 620 return B_OK; 621 } 622 623 624 status_t 625 ATADevice::ExecuteReadWrite(ATARequest *request, uint64 address, 626 uint32 sectorCount) 627 { 628 request->SetUseDMA(fUseDMA && fChannel->PrepareDMA(request) == B_OK); 629 if (!request->UseDMA()) 630 request->PrepareSGInfo(); 631 632 request->SetBytesLeft(sectorCount * fBlockSize); 633 if (_FillTaskFile(request, address) != B_OK) { 634 TRACE_ERROR("failed to setup transfer request\n"); 635 if (request->UseDMA()) 636 fChannel->FinishDMA(); 637 return B_ERROR; 638 } 639 640 status_t result = fChannel->SendRequest(request, 641 IsATAPI() ? 0 : ATA_DEVICE_READY_REQUIRED); 642 if (result != B_OK) { 643 TRACE_ERROR("failed to send transfer request\n"); 644 if (request->UseDMA()) 645 fChannel->FinishDMA(); 646 return result; 647 } 648 649 if (request->UseDMA()) { 650 fChannel->PrepareWaitingForInterrupt(); 651 fChannel->StartDMA(); 652 653 result = fChannel->WaitForInterrupt(request->Timeout()); 654 status_t dmaResult = fChannel->FinishDMA(); 655 if (result == B_OK && dmaResult == B_OK) { 656 fDMAFailures = 0; 657 request->CCB()->data_resid = 0; 658 } else { 659 if (dmaResult != B_OK) { 660 request->SetSense(SCSIS_KEY_HARDWARE_ERROR, 661 SCSIS_ASC_LUN_COM_FAILURE); 662 fDMAFailures++; 663 if (fDMAFailures >= ATA_MAX_DMA_FAILURES) { 664 TRACE_ALWAYS("disabling DMA after %u failures\n", 665 fDMAFailures); 666 fUseDMA = false; 667 } 668 } else { 669 // timeout 670 request->SetStatus(SCSI_CMD_TIMEOUT); 671 } 672 } 673 } else { 674 if (fChannel->Wait(ATA_STATUS_DATA_REQUEST, 0, ATA_CHECK_ERROR_BIT 675 | ATA_CHECK_DEVICE_FAULT, request->Timeout()) != B_OK) { 676 TRACE_ERROR("timeout waiting for device to request data\n"); 677 request->SetStatus(SCSI_CMD_TIMEOUT); 678 return B_TIMED_OUT; 679 } 680 681 if (fChannel->ExecutePIOTransfer(request) != B_OK) { 682 TRACE_ERROR("executing pio transfer failed\n"); 683 request->SetStatus(SCSI_SEQUENCE_FAIL); 684 } 685 } 686 687 return fChannel->FinishRequest(request, ATA_WAIT_FINISH 688 | ATA_DEVICE_READY_REQUIRED, ATA_ERROR_ALL); 689 } 690 691 692 status_t 693 ATADevice::_FillTaskFile(ATARequest *request, uint64 address) 694 { 695 // list of LBA48 opcodes 696 static const uint8 s48BitCommands[2][2] = { 697 { ATA_COMMAND_READ_SECTORS_EXT, ATA_COMMAND_WRITE_SECTORS_EXT }, 698 { ATA_COMMAND_READ_DMA_EXT, ATA_COMMAND_WRITE_DMA_EXT } 699 }; 700 701 // list of normal LBA opcodes 702 static const uint8 s28BitCommands[2][2] = { 703 { ATA_COMMAND_READ_SECTORS, ATA_COMMAND_WRITE_SECTORS }, 704 { ATA_COMMAND_READ_DMA, ATA_COMMAND_WRITE_DMA } 705 }; 706 707 uint32 sectorCount = *request->BytesLeft() / fBlockSize; 708 TRACE("about to transfer %lu sectors\n", sectorCount); 709 710 if (fUse48Bits 711 && (address + sectorCount > 0xfffffff || sectorCount > 0x100)) { 712 // use LBA48 only if necessary 713 if (sectorCount > 0xffff) { 714 TRACE_ERROR("invalid sector count %lu\n", sectorCount); 715 request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST, 716 SCSIS_ASC_INV_CDB_FIELD); 717 return B_ERROR; 718 } 719 720 fRegisterMask = ATA_MASK_SECTOR_COUNT_48 721 | ATA_MASK_LBA_LOW_48 722 | ATA_MASK_LBA_MID_48 723 | ATA_MASK_LBA_HIGH_48; 724 725 fTaskFile.lba48.sector_count_0_7 = sectorCount & 0xff; 726 fTaskFile.lba48.sector_count_8_15 = (sectorCount >> 8) & 0xff; 727 fTaskFile.lba48.lba_0_7 = address & 0xff; 728 fTaskFile.lba48.lba_8_15 = (address >> 8) & 0xff; 729 fTaskFile.lba48.lba_16_23 = (address >> 16) & 0xff; 730 fTaskFile.lba48.lba_24_31 = (address >> 24) & 0xff; 731 fTaskFile.lba48.lba_32_39 = (address >> 32) & 0xff; 732 fTaskFile.lba48.lba_40_47 = (address >> 40) & 0xff; 733 fTaskFile.lba48.command = s48BitCommands[request->UseDMA() 734 ? 1 : 0][request->IsWrite() ? 1 : 0]; 735 } else { 736 // normal LBA 737 if (sectorCount > 0x100) { 738 TRACE_ERROR("invalid sector count %lu\n", sectorCount); 739 request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST, 740 SCSIS_ASC_INV_CDB_FIELD); 741 return B_ERROR; 742 } 743 744 fRegisterMask = ATA_MASK_SECTOR_COUNT 745 | ATA_MASK_LBA_LOW 746 | ATA_MASK_LBA_MID 747 | ATA_MASK_LBA_HIGH 748 | ATA_MASK_DEVICE_HEAD; 749 750 fTaskFile.lba.sector_count = sectorCount & 0xff; 751 fTaskFile.lba.lba_0_7 = address & 0xff; 752 fTaskFile.lba.lba_8_15 = (address >> 8) & 0xff; 753 fTaskFile.lba.lba_16_23 = (address >> 16) & 0xff; 754 fTaskFile.lba.lba_24_27 = (address >> 24) & 0xf; 755 fTaskFile.lba.command = s28BitCommands[request->UseDMA() 756 ? 1 : 0][request->IsWrite() ? 1 : 0]; 757 } 758 759 return B_OK; 760 } 761