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 memset(&data, 0, sizeof(data)); 181 182 data.block_size = B_HOST_TO_BENDIAN_INT32(fBlockSize); 183 184 if (fTotalSectors <= UINT_MAX) { 185 uint32 lastBlock = fTotalSectors - 1; 186 data.lba = B_HOST_TO_BENDIAN_INT32(lastBlock); 187 } else 188 data.lba = UINT_MAX; 189 TRACE("returning last block: %" B_PRIu32 "\n", 190 B_BENDIAN_TO_HOST_INT32(data.lba)); 191 192 copy_sg_data(ccb, 0, ccb->data_length, &data, sizeof(data), false); 193 ccb->data_resid = MAX(ccb->data_length - sizeof(data), 0); 194 return B_OK; 195 } 196 197 198 status_t 199 ATADevice::ReadCapacity16(ATARequest *request) 200 { 201 TRACE_FUNCTION("%p\n", request); 202 203 scsi_ccb *ccb = request->CCB(); 204 scsi_cmd_read_capacity_long *command 205 = (scsi_cmd_read_capacity_long *)ccb->cdb; 206 if (command->pmi || command->lba) { 207 request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_CDB_FIELD); 208 return B_ERROR; 209 } 210 211 uint32 allocationLength = B_BENDIAN_TO_HOST_INT32(command->alloc_length); 212 213 scsi_res_read_capacity_long data; 214 memset(&data, 0, sizeof(data)); 215 216 data.block_size = B_HOST_TO_BENDIAN_INT32(fBlockSize); 217 218 uint64 lastBlock = fTotalSectors - 1; 219 data.lba = B_HOST_TO_BENDIAN_INT64(lastBlock); 220 TRACE("returning last block: %" B_PRIu64 "\n", 221 B_BENDIAN_TO_HOST_INT64(data.lba)); 222 223 size_t copySize = min_c(allocationLength, sizeof(data)); 224 225 copy_sg_data(ccb, 0, ccb->data_length, &data, copySize, false); 226 ccb->data_resid = MAX(ccb->data_length - copySize, 0); 227 return B_OK; 228 } 229 230 231 status_t 232 ATADevice::ExecuteIO(ATARequest *request) 233 { 234 TRACE_FUNCTION("%p\n", request); 235 236 scsi_ccb *ccb = request->CCB(); 237 request->SetDevice(this); 238 239 // ATA devices have one LUN only 240 if (ccb->target_lun != 0) { 241 TRACE_ERROR("invalid target lun %d for ATA device\n", ccb->target_lun); 242 request->SetStatus(SCSI_SEL_TIMEOUT); 243 return B_BAD_INDEX; 244 } 245 246 TRACE("request: 0x%02x\n", ccb->cdb[0]); 247 248 switch (ccb->cdb[0]) { 249 case SCSI_OP_TEST_UNIT_READY: 250 return TestUnitReady(request); 251 252 case SCSI_OP_FORMAT: /* FORMAT UNIT */ 253 // we could forward ccb to disk, but modern disks cannot 254 // be formatted anyway, so we just refuse ccb 255 // (exceptions are removable media devices, but to my knowledge 256 // they don't have to be formatted as well) 257 request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE); 258 return B_ERROR; 259 260 case SCSI_OP_INQUIRY: 261 return Inquiry(request); 262 263 case SCSI_OP_START_STOP: 264 { 265 scsi_cmd_ssu *command = (scsi_cmd_ssu *)ccb->cdb; 266 267 // with no LoEj bit set, we should only allow/deny further access 268 // we ignore that (unsupported for ATA) 269 // with LoEj bit set, we should additionally either load or eject 270 // the medium (start = 0 - eject; start = 1 - load) 271 272 if (!command->start) { 273 // we must always flush cache if start = 0 274 SynchronizeCache(request); 275 } 276 277 if (command->load_eject) { 278 if (!command->start) 279 return Eject(request); 280 else { 281 request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST, 282 SCSIS_ASC_PARAM_NOT_SUPPORTED); 283 return B_ERROR; 284 } 285 } 286 287 return B_OK; 288 } 289 290 case SCSI_OP_READ_CAPACITY: 291 return ReadCapacity(request); 292 293 case SCSI_OP_SERVICE_ACTION_IN: 294 if ((ccb->cdb[1] & 0x1f) == SCSI_SAI_READ_CAPACITY_16) 295 return ReadCapacity16(request); 296 break; 297 298 case SCSI_OP_SYNCHRONIZE_CACHE: 299 // we ignore range and immediate bit, we always immediately 300 // flush everything 301 return SynchronizeCache(request); 302 303 // sadly, there are two possible read/write operation codes; 304 // at least, the third one, read/write(12), is not valid for DAS 305 case SCSI_OP_READ_6: 306 case SCSI_OP_WRITE_6: 307 { 308 scsi_cmd_rw_6 *command = (scsi_cmd_rw_6 *)ccb->cdb; 309 uint32 address = ((uint32)command->high_lba << 16) 310 | ((uint32)command->mid_lba << 8) | (uint32)command->low_lba; 311 312 request->SetIsWrite(command->opcode == SCSI_OP_WRITE_6); 313 return ExecuteReadWrite(request, address, command->length != 0 314 ? command->length : 256); 315 } 316 317 case SCSI_OP_READ_10: 318 case SCSI_OP_WRITE_10: 319 { 320 scsi_cmd_rw_10 *command = (scsi_cmd_rw_10 *)ccb->cdb; 321 uint32 address = B_BENDIAN_TO_HOST_INT32(command->lba); 322 uint32 sectorCount = B_BENDIAN_TO_HOST_INT16(command->length); 323 324 request->SetIsWrite(command->opcode == SCSI_OP_WRITE_10); 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_12: 335 case SCSI_OP_WRITE_12: 336 { 337 scsi_cmd_rw_12 *command = (scsi_cmd_rw_12 *)ccb->cdb; 338 uint32 address = B_BENDIAN_TO_HOST_INT32(command->lba); 339 uint32 sectorCount = B_BENDIAN_TO_HOST_INT32(command->length); 340 341 request->SetIsWrite(command->opcode == SCSI_OP_WRITE_12); 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 case SCSI_OP_READ_16: 352 case SCSI_OP_WRITE_16: 353 { 354 scsi_cmd_rw_16 *command = (scsi_cmd_rw_16 *)ccb->cdb; 355 uint64 address = B_BENDIAN_TO_HOST_INT64(command->lba); 356 uint32 sectorCount = B_BENDIAN_TO_HOST_INT32(command->length); 357 358 request->SetIsWrite(command->opcode == SCSI_OP_WRITE_16); 359 if (sectorCount > 0) 360 return ExecuteReadWrite(request, address, sectorCount); 361 else { 362 // we cannot transfer zero blocks (apart from LBA48) 363 request->SetStatus(SCSI_REQ_CMP); 364 return B_OK; 365 } 366 } 367 } 368 369 TRACE("command not implemented\n"); 370 request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE); 371 return B_ERROR; 372 } 373 374 375 void 376 ATADevice::GetRestrictions(bool *noAutoSense, uint32 *maxBlocks) 377 { 378 if (IsATAPI()) 379 *noAutoSense = true; 380 else { 381 if (fUse48Bits) 382 *maxBlocks = 0xffff; 383 else 384 *maxBlocks = 0x100; 385 } 386 } 387 388 389 status_t 390 ATADevice::Control(uint32 opcode, void *buffer, size_t length) 391 { 392 if (opcode == B_GET_DEVICE_NAME) { 393 // Swap words 394 char name[sizeof(fInfoBlock.model_number)]; 395 memcpy(name, fInfoBlock.model_number, sizeof(name)); 396 swap_words(name, sizeof(name)); 397 398 // Remove trailing spaces 399 int32 nameLength = sizeof(name) - 2; 400 while (nameLength > 0 && name[nameLength - 1] == ' ') 401 nameLength--; 402 403 // TODO: make string prettier, ie. "WDC" -> "Western Digital", ... 404 return user_strlcpy((char*)buffer, name, 405 min_c((size_t)nameLength + 1, length)) >= 0 ? B_OK : B_BAD_ADDRESS; 406 } 407 return B_BAD_VALUE; 408 } 409 410 411 status_t 412 ATADevice::Select() 413 { 414 status_t err = fChannel->SelectDevice(fIndex); 415 #if 1 416 // for debugging only 417 if (fChannel->SelectedDevice() != fIndex) { 418 TRACE_ERROR("device %d not selected!\n", fIndex); 419 return B_ERROR; 420 } 421 #endif 422 return err; 423 } 424 425 426 status_t 427 ATADevice::SetFeature(int feature) 428 { 429 TRACE("device_set_feature: feature %d\n", feature); 430 431 ATARequest request(false); 432 request.SetDevice(this); 433 request.SetTimeout(1 * 1000 * 1000); 434 435 fTaskFile.write.features = feature; 436 fTaskFile.write.command = ATA_COMMAND_SET_FEATURES; 437 fRegisterMask = ATA_MASK_FEATURES; 438 439 status_t result = fChannel->SendRequest(&request, ATA_DEVICE_READY_REQUIRED); 440 if (result != B_OK) { 441 TRACE_ERROR("sending set feature request failed\n"); 442 return result; 443 } 444 445 result = fChannel->FinishRequest(&request, 446 ATA_WAIT_FINISH | ATA_DEVICE_READY_REQUIRED, ATA_ERROR_ABORTED); 447 if (result != B_OK) { 448 TRACE_ERROR("set feature request failed\n"); 449 return result; 450 } 451 452 return B_OK; 453 } 454 455 456 status_t 457 ATADevice::DisableCommandQueueing() 458 { 459 if (!fInfoBlock.read_write_dma_queued_supported) 460 return B_OK; 461 462 if (fInfoBlock.release_interrupt_supported) { 463 status_t result = SetFeature( 464 ATA_COMMAND_SET_FEATURES_DISABLE_RELEASE_INT); 465 if (result != B_OK) { 466 TRACE_ERROR("failed to disable release interrupt\n"); 467 return result; 468 } 469 } 470 471 if (fInfoBlock.service_interrupt_supported) { 472 status_t result = SetFeature( 473 ATA_COMMAND_SET_FEATURES_DISABLE_SERVICE_INT); 474 if (result != B_OK) { 475 TRACE_ERROR("failed to disable service interrupt\n"); 476 return result; 477 } 478 } 479 480 return B_OK; 481 } 482 483 484 status_t 485 ATADevice::ConfigureDMA() 486 { 487 if (!fUseDMA) 488 return B_OK; 489 490 if (!fInfoBlock.dma_supported) { 491 TRACE_ALWAYS("DMA not supported by device\n"); 492 fUseDMA = false; 493 return B_OK; 494 } 495 496 #define CHECK_DMA_MODE(element, mode) \ 497 if (fInfoBlock.element) { \ 498 fDMAMode = mode; \ 499 modeCount++; \ 500 } 501 502 uint32 modeCount = 0; 503 504 CHECK_DMA_MODE(multiword_dma_0_selected, 0x00); 505 CHECK_DMA_MODE(multiword_dma_1_selected, 0x01); 506 CHECK_DMA_MODE(multiword_dma_2_selected, 0x02); 507 508 if (fInfoBlock.word_88_valid) { 509 CHECK_DMA_MODE(ultra_dma_0_selected, 0x10); 510 CHECK_DMA_MODE(ultra_dma_1_selected, 0x11); 511 CHECK_DMA_MODE(ultra_dma_2_selected, 0x12); 512 CHECK_DMA_MODE(ultra_dma_3_selected, 0x13); 513 CHECK_DMA_MODE(ultra_dma_4_selected, 0x14); 514 CHECK_DMA_MODE(ultra_dma_5_selected, 0x15); 515 CHECK_DMA_MODE(ultra_dma_6_selected, 0x16); 516 } 517 518 #undef CHECK_DMA_MODE 519 520 if (modeCount != 1) { 521 TRACE_ERROR("more than one DMA mode selected, not using DMA\n"); 522 fUseDMA = false; 523 return B_OK; 524 } 525 526 TRACE_ALWAYS("using DMA mode 0x%02x\n", fDMAMode); 527 return B_OK; 528 } 529 530 531 status_t 532 ATADevice::Configure() 533 { 534 // warning: ata == 0 means "this is ata"... 535 if (fInfoBlock.word_0.ata.ata_device != ATA_WORD_0_ATA_DEVICE) { 536 // CF has either magic header or CFA bit set 537 // we merge it to "CFA bit set" for easier (later) testing 538 if (fInfoBlock.word_0.raw == ATA_WORD_0_CFA_MAGIC) 539 fInfoBlock.compact_flash_assoc_supported = true; 540 else { 541 TRACE_ERROR("infoblock indicates non-ata device\n"); 542 return B_ERROR; 543 } 544 } 545 546 if (!fInfoBlock.lba_supported || (fInfoBlock.lba_sector_count == 0 547 && fInfoBlock.lba48_sector_count == 0)) { 548 TRACE_ERROR("non-lba devices not supported\n"); 549 return B_ERROR; 550 } 551 552 fTotalSectors = fInfoBlock.SectorCount(fUse48Bits, false); 553 fBlockSize = fInfoBlock.SectorSize(); 554 fPhysicalBlockSize = fInfoBlock.PhysicalSectorSize(); 555 fBlockOffset = fInfoBlock.BlockOffset(); 556 557 fTaskFile.lba.mode = ATA_MODE_LBA; 558 fTaskFile.lba.device = fIndex; 559 560 status_t result = ConfigureDMA(); 561 if (result != B_OK) 562 return result; 563 564 result = DisableCommandQueueing(); 565 if (result != B_OK) 566 return result; 567 568 return B_OK; 569 } 570 571 572 status_t 573 ATADevice::Identify() 574 { 575 snprintf(fDebugContext, sizeof(fDebugContext), "%s %" B_PRIu32 "-%u", 576 IsATAPI() ? "pi" : "", fChannel->ChannelID(), fIndex); 577 578 ATARequest request(false); 579 request.SetDevice(this); 580 request.SetTimeout(20 * 1000 * 1000); 581 582 fRegisterMask = 0; 583 fTaskFile.write.command = IsATAPI() ? ATA_COMMAND_IDENTIFY_PACKET_DEVICE 584 : ATA_COMMAND_IDENTIFY_DEVICE; 585 586 if (fChannel->SendRequest(&request, 587 IsATAPI() ? 0 : ATA_DEVICE_READY_REQUIRED) != B_OK) { 588 TRACE_ERROR("sending identify request failed\n"); 589 return B_ERROR; 590 } 591 592 if (fChannel->Wait(ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST, 0, 593 ATA_WAIT_ANY_BIT, 100 * 1000) != B_OK) { 594 TRACE_ALWAYS("no data request and not busy within 100ms, assuming " 595 "no device present\n"); 596 return B_TIMED_OUT; 597 } 598 599 if (fChannel->Wait(ATA_STATUS_DATA_REQUEST, ATA_STATUS_BUSY, 600 ATA_CHECK_ERROR_BIT | ATA_CHECK_DEVICE_FAULT, 601 IsATAPI() ? 20 * 1000 * 1000 : 500 * 1000) != B_OK) { 602 TRACE_ERROR("timeout waiting for identify request\n"); 603 return B_TIMED_OUT; 604 } 605 606 // get the infoblock 607 fChannel->ReadPIO((uint8 *)&fInfoBlock, sizeof(fInfoBlock)); 608 609 if (fChannel->WaitDataRequest(false) != B_OK) { 610 TRACE_ERROR("device disagrees on info block length\n"); 611 return B_ERROR; 612 } 613 614 if (fChannel->FinishRequest(&request, 615 ATA_WAIT_FINISH | (IsATAPI() ? 0 : ATA_DEVICE_READY_REQUIRED), 616 ATA_ERROR_ABORTED) != B_OK) { 617 TRACE_ERROR("failed to finish identify request\n"); 618 return B_ERROR; 619 } 620 621 if (1) { 622 // print device information 623 char modelNumber[sizeof(fInfoBlock.model_number) + 1]; 624 char serialNumber[sizeof(fInfoBlock.serial_number) + 1]; 625 char firmwareRev[sizeof(fInfoBlock.firmware_revision) + 1]; 626 strlcpy(modelNumber, fInfoBlock.model_number, sizeof(modelNumber)); 627 strlcpy(serialNumber, fInfoBlock.serial_number, sizeof(serialNumber)); 628 strlcpy(firmwareRev, fInfoBlock.firmware_revision, sizeof(firmwareRev)); 629 swap_words(modelNumber, sizeof(modelNumber) - 1); 630 swap_words(serialNumber, sizeof(serialNumber) - 1); 631 swap_words(firmwareRev, sizeof(firmwareRev) - 1); 632 TRACE_ALWAYS("model number: %s\n", modelNumber); 633 TRACE_ALWAYS("serial number: %s\n", serialNumber); 634 TRACE_ALWAYS("firmware rev.: %s\n", firmwareRev); 635 } 636 637 return B_OK; 638 } 639 640 641 status_t 642 ATADevice::ExecuteReadWrite(ATARequest *request, uint64 address, 643 uint32 sectorCount) 644 { 645 request->SetUseDMA(fUseDMA && fChannel->PrepareDMA(request) == B_OK); 646 if (!request->UseDMA()) 647 request->PrepareSGInfo(); 648 649 request->SetBytesLeft(sectorCount * fBlockSize); 650 if (_FillTaskFile(request, address) != B_OK) { 651 TRACE_ERROR("failed to setup transfer request\n"); 652 if (request->UseDMA()) 653 fChannel->FinishDMA(); 654 return B_ERROR; 655 } 656 657 status_t result = fChannel->SendRequest(request, 658 IsATAPI() ? 0 : ATA_DEVICE_READY_REQUIRED); 659 if (result != B_OK) { 660 TRACE_ERROR("failed to send transfer request\n"); 661 if (request->UseDMA()) 662 fChannel->FinishDMA(); 663 return result; 664 } 665 666 if (request->UseDMA()) { 667 fChannel->PrepareWaitingForInterrupt(); 668 fChannel->StartDMA(); 669 670 result = fChannel->WaitForInterrupt(request->Timeout()); 671 status_t dmaResult = fChannel->FinishDMA(); 672 if (result == B_OK && dmaResult == B_OK) { 673 fDMAFailures = 0; 674 request->CCB()->data_resid = 0; 675 } else { 676 if (dmaResult != B_OK) { 677 request->SetSense(SCSIS_KEY_HARDWARE_ERROR, 678 SCSIS_ASC_LUN_COM_FAILURE); 679 fDMAFailures++; 680 if (fDMAFailures >= ATA_MAX_DMA_FAILURES) { 681 TRACE_ALWAYS("disabling DMA after %u failures\n", 682 fDMAFailures); 683 fUseDMA = false; 684 } 685 } else { 686 // timeout 687 request->SetStatus(SCSI_CMD_TIMEOUT); 688 } 689 } 690 } else { 691 if (fChannel->Wait(ATA_STATUS_DATA_REQUEST, 0, ATA_CHECK_ERROR_BIT 692 | ATA_CHECK_DEVICE_FAULT, request->Timeout()) != B_OK) { 693 TRACE_ERROR("timeout waiting for device to request data\n"); 694 request->SetStatus(SCSI_CMD_TIMEOUT); 695 return B_TIMED_OUT; 696 } 697 698 if (fChannel->ExecutePIOTransfer(request) != B_OK) { 699 TRACE_ERROR("executing pio transfer failed\n"); 700 request->SetStatus(SCSI_SEQUENCE_FAIL); 701 } 702 } 703 704 return fChannel->FinishRequest(request, ATA_WAIT_FINISH 705 | ATA_DEVICE_READY_REQUIRED, ATA_ERROR_ALL); 706 } 707 708 709 status_t 710 ATADevice::_FillTaskFile(ATARequest *request, uint64 address) 711 { 712 // list of LBA48 opcodes 713 static const uint8 s48BitCommands[2][2] = { 714 { ATA_COMMAND_READ_SECTORS_EXT, ATA_COMMAND_WRITE_SECTORS_EXT }, 715 { ATA_COMMAND_READ_DMA_EXT, ATA_COMMAND_WRITE_DMA_EXT } 716 }; 717 718 // list of normal LBA opcodes 719 static const uint8 s28BitCommands[2][2] = { 720 { ATA_COMMAND_READ_SECTORS, ATA_COMMAND_WRITE_SECTORS }, 721 { ATA_COMMAND_READ_DMA, ATA_COMMAND_WRITE_DMA } 722 }; 723 724 uint32 sectorCount = *request->BytesLeft() / fBlockSize; 725 TRACE("about to transfer %lu sectors\n", sectorCount); 726 727 if (fUse48Bits 728 && (address + sectorCount > 0xfffffff || sectorCount > 0x100)) { 729 // use LBA48 only if necessary 730 if (sectorCount > 0xffff) { 731 TRACE_ERROR("invalid sector count %lu\n", sectorCount); 732 request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST, 733 SCSIS_ASC_INV_CDB_FIELD); 734 return B_ERROR; 735 } 736 737 fRegisterMask = ATA_MASK_SECTOR_COUNT_48 738 | ATA_MASK_LBA_LOW_48 739 | ATA_MASK_LBA_MID_48 740 | ATA_MASK_LBA_HIGH_48; 741 742 fTaskFile.lba48.sector_count_0_7 = sectorCount & 0xff; 743 fTaskFile.lba48.sector_count_8_15 = (sectorCount >> 8) & 0xff; 744 fTaskFile.lba48.lba_0_7 = address & 0xff; 745 fTaskFile.lba48.lba_8_15 = (address >> 8) & 0xff; 746 fTaskFile.lba48.lba_16_23 = (address >> 16) & 0xff; 747 fTaskFile.lba48.lba_24_31 = (address >> 24) & 0xff; 748 fTaskFile.lba48.lba_32_39 = (address >> 32) & 0xff; 749 fTaskFile.lba48.lba_40_47 = (address >> 40) & 0xff; 750 fTaskFile.lba48.command = s48BitCommands[request->UseDMA() 751 ? 1 : 0][request->IsWrite() ? 1 : 0]; 752 } else { 753 // normal LBA 754 if (sectorCount > 0x100) { 755 TRACE_ERROR("invalid sector count %lu\n", sectorCount); 756 request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST, 757 SCSIS_ASC_INV_CDB_FIELD); 758 return B_ERROR; 759 } 760 761 fRegisterMask = ATA_MASK_SECTOR_COUNT 762 | ATA_MASK_LBA_LOW 763 | ATA_MASK_LBA_MID 764 | ATA_MASK_LBA_HIGH 765 | ATA_MASK_DEVICE_HEAD; 766 767 fTaskFile.lba.sector_count = sectorCount & 0xff; 768 fTaskFile.lba.lba_0_7 = address & 0xff; 769 fTaskFile.lba.lba_8_15 = (address >> 8) & 0xff; 770 fTaskFile.lba.lba_16_23 = (address >> 16) & 0xff; 771 fTaskFile.lba.lba_24_27 = (address >> 24) & 0xf; 772 fTaskFile.lba.command = s28BitCommands[request->UseDMA() 773 ? 1 : 0][request->IsWrite() ? 1 : 0]; 774 } 775 776 return B_OK; 777 } 778