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