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