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.
7 * Distributed under the terms of the MIT License.
10 #include "ATAPrivate.h"
13 ATADevice::ATADevice(ATAChannel
*channel
, uint8 index
)
17 fUseDMA(channel
->UseDMA()),
22 fPhysicalBlockSize(512),
27 memset(&fInfoBlock
, 0, sizeof(fInfoBlock
));
28 memset(&fTaskFile
, 0, sizeof(fTaskFile
));
32 ATADevice::~ATADevice()
38 ATADevice::TestUnitReady(ATARequest
*request
)
40 TRACE_FUNCTION("%p\n", request
);
43 fTaskFile
.write
.command
= ATA_COMMAND_GET_MEDIA_STATUS
;
45 request
->SetTimeout(15 * 1000 * 1000);
46 status_t result
= fChannel
->SendRequest(request
, ATA_DEVICE_READY_REQUIRED
);
48 TRACE_ERROR("failed to send test unit ready request\n");
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
);
59 ATADevice::SynchronizeCache(ATARequest
*request
)
61 TRACE_FUNCTION("%p\n", request
);
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
)
71 = fUse48Bits
? ATA_COMMAND_FLUSH_CACHE_EXT
: ATA_COMMAND_FLUSH_CACHE
;
73 request
->SetTimeout(60 * 1000 * 1000);
74 status_t result
= fChannel
->SendRequest(request
, ATA_DEVICE_READY_REQUIRED
);
76 TRACE_ERROR("failed to send synchronize cache request\n");
80 return fChannel
->FinishRequest(request
, ATA_WAIT_FINISH
81 | ATA_DEVICE_READY_REQUIRED
, ATA_ERROR_ABORTED
);
86 ATADevice::Eject(ATARequest
*request
)
88 TRACE_FUNCTION("%p\n", request
);
91 fTaskFile
.lba
.command
= ATA_COMMAND_MEDIA_EJECT
;
93 request
->SetTimeout(15 * 1000 * 1000);
94 status_t result
= fChannel
->SendRequest(request
, ATA_DEVICE_READY_REQUIRED
);
96 TRACE_ERROR("failed to send eject request\n");
100 return fChannel
->FinishRequest(request
, ATA_WAIT_FINISH
101 | ATA_DEVICE_READY_REQUIRED
, ATA_ERROR_ABORTED
| ATA_ERROR_NO_MEDIA
);
106 ATADevice::Inquiry(ATARequest
*request
)
108 TRACE_FUNCTION("%p\n", request
);
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
);
117 scsi_res_inquiry data
;
118 memset(&data
, 0, sizeof(data
));
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
;
124 data
.device_type_modifier
= 0;
125 data
.removable_medium
= fInfoBlock
.word_0
.ata
.removable_media_device
;
127 data
.ansi_version
= 2;
128 data
.ecma_version
= 0;
129 data
.iso_version
= 0;
131 data
.response_data_format
= 2;
132 data
.term_iop
= false;
133 // to be changed if we support TERM I/O
135 data
.additional_length
= sizeof(scsi_res_inquiry
) - 4;
137 data
.soft_reset
= false;
141 // these values are free-style
143 data
.write_bus16
= true;
144 data
.write_bus32
= false;
146 data
.relative_address
= false;
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
));
153 memcpy(data
.product_ident
, fInfoBlock
.model_number
+ 8,
154 sizeof(data
.product_ident
));
155 swap_words(data
.product_ident
, sizeof(data
.product_ident
));
157 memcpy(data
.product_rev
, " ", sizeof(data
.product_rev
));
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
);
168 ATADevice::ReadCapacity(ATARequest
*request
)
170 TRACE_FUNCTION("%p\n", request
);
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
);
179 scsi_res_read_capacity data
;
180 data
.block_size
= B_HOST_TO_BENDIAN_INT32(fBlockSize
);
182 if (fTotalSectors
<= UINT_MAX
) {
183 uint32 lastBlock
= fTotalSectors
- 1;
184 data
.lba
= B_HOST_TO_BENDIAN_INT32(lastBlock
);
187 TRACE("returning last block: %lu\n", B_BENDIAN_TO_HOST_INT32(data
.lba
));
189 copy_sg_data(ccb
, 0, ccb
->data_length
, &data
, sizeof(data
), false);
190 ccb
->data_resid
= MAX(ccb
->data_length
- sizeof(data
), 0);
196 ATADevice::ReadCapacity16(ATARequest
*request
)
198 TRACE_FUNCTION("%p\n", request
);
200 scsi_ccb
*ccb
= request
->CCB();
201 scsi_res_read_capacity_long data
;
202 data
.block_size
= B_HOST_TO_BENDIAN_INT32(fBlockSize
);
204 uint64 lastBlock
= fTotalSectors
- 1;
205 data
.lba
= B_HOST_TO_BENDIAN_INT64(lastBlock
);
206 TRACE("returning last block: %llu\n", data
.lba
);
208 copy_sg_data(ccb
, 0, ccb
->data_length
, &data
, sizeof(data
), false);
209 ccb
->data_resid
= MAX(ccb
->data_length
- sizeof(data
), 0);
215 ATADevice::ExecuteIO(ATARequest
*request
)
217 TRACE_FUNCTION("%p\n", request
);
219 scsi_ccb
*ccb
= request
->CCB();
220 request
->SetDevice(this);
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
);
229 TRACE("request: 0x%02x\n", ccb
->cdb
[0]);
231 switch (ccb
->cdb
[0]) {
232 case SCSI_OP_TEST_UNIT_READY
:
233 return TestUnitReady(request
);
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
);
243 case SCSI_OP_INQUIRY
:
244 return Inquiry(request
);
246 case SCSI_OP_START_STOP
:
248 scsi_cmd_ssu
*command
= (scsi_cmd_ssu
*)ccb
->cdb
;
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)
255 if (!command
->start
) {
256 // we must always flush cache if start = 0
257 SynchronizeCache(request
);
260 if (command
->load_eject
) {
262 return Eject(request
);
264 request
->SetSense(SCSIS_KEY_ILLEGAL_REQUEST
,
265 SCSIS_ASC_PARAM_NOT_SUPPORTED
);
273 case SCSI_OP_READ_CAPACITY
:
274 return ReadCapacity(request
);
276 case SCSI_OP_SERVICE_ACTION_IN
:
277 if ((ccb
->cdb
[1] & 0x1f) == SCSI_SAI_READ_CAPACITY_16
)
278 return ReadCapacity16(request
);
281 case SCSI_OP_SYNCHRONIZE_CACHE
:
282 // we ignore range and immediate bit, we always immediately
284 return SynchronizeCache(request
);
286 // sadly, there are two possible read/write operation codes;
287 // at least, the third one, read/write(12), is not valid for DAS
289 case SCSI_OP_WRITE_6
:
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
;
295 request
->SetIsWrite(command
->opcode
== SCSI_OP_WRITE_6
);
296 return ExecuteReadWrite(request
, address
, command
->length
!= 0
297 ? command
->length
: 256);
300 case SCSI_OP_READ_10
:
301 case SCSI_OP_WRITE_10
:
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
);
307 request
->SetIsWrite(command
->opcode
== SCSI_OP_WRITE_10
);
309 return ExecuteReadWrite(request
, address
, sectorCount
);
311 // we cannot transfer zero blocks (apart from LBA48)
312 request
->SetStatus(SCSI_REQ_CMP
);
317 case SCSI_OP_READ_12
:
318 case SCSI_OP_WRITE_12
:
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
);
324 request
->SetIsWrite(command
->opcode
== SCSI_OP_WRITE_12
);
326 return ExecuteReadWrite(request
, address
, sectorCount
);
328 // we cannot transfer zero blocks (apart from LBA48)
329 request
->SetStatus(SCSI_REQ_CMP
);
334 case SCSI_OP_READ_16
:
335 case SCSI_OP_WRITE_16
:
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
);
341 request
->SetIsWrite(command
->opcode
== SCSI_OP_WRITE_16
);
343 return ExecuteReadWrite(request
, address
, sectorCount
);
345 // we cannot transfer zero blocks (apart from LBA48)
346 request
->SetStatus(SCSI_REQ_CMP
);
352 TRACE("command not implemented\n");
353 request
->SetSense(SCSIS_KEY_ILLEGAL_REQUEST
, SCSIS_ASC_INV_OPCODE
);
359 ATADevice::GetRestrictions(bool *noAutoSense
, uint32
*maxBlocks
)
373 ATADevice::Control(uint32 opcode
, void *buffer
, size_t length
)
375 if (opcode
== B_GET_DEVICE_NAME
) {
377 char name
[sizeof(fInfoBlock
.model_number
)];
378 memcpy(name
, fInfoBlock
.model_number
, sizeof(name
));
379 swap_words(name
, sizeof(name
));
381 // Remove trailing spaces
382 int32 nameLength
= sizeof(name
) - 2;
383 while (nameLength
> 0 && name
[nameLength
- 1] == ' ')
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
;
397 status_t err
= fChannel
->SelectDevice(fIndex
);
399 // for debugging only
400 if (fChannel
->SelectedDevice() != fIndex
) {
401 TRACE_ERROR("device %d not selected!\n", fIndex
);
410 ATADevice::SetFeature(int feature
)
412 TRACE("device_set_feature: feature %d\n", feature
);
414 ATARequest
request(false);
415 request
.SetDevice(this);
416 request
.SetTimeout(1 * 1000 * 1000);
418 fTaskFile
.write
.features
= feature
;
419 fTaskFile
.write
.command
= ATA_COMMAND_SET_FEATURES
;
420 fRegisterMask
= ATA_MASK_FEATURES
;
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");
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");
440 ATADevice::DisableCommandQueueing()
442 if (!fInfoBlock
.read_write_dma_queued_supported
)
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");
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");
468 ATADevice::ConfigureDMA()
473 if (!fInfoBlock
.dma_supported
) {
474 TRACE_ALWAYS("DMA not supported by device\n");
479 #define CHECK_DMA_MODE(element, mode) \
480 if (fInfoBlock.element) { \
485 uint32 modeCount
= 0;
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);
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);
501 #undef CHECK_DMA_MODE
503 if (modeCount
!= 1) {
504 TRACE_ERROR("more than one DMA mode selected, not using DMA\n");
509 TRACE_ALWAYS("using DMA mode 0x%02x\n", fDMAMode
);
515 ATADevice::Configure()
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;
524 TRACE_ERROR("infoblock indicates non-ata device\n");
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");
535 fTotalSectors
= fInfoBlock
.SectorCount(fUse48Bits
, false);
536 fBlockSize
= fInfoBlock
.SectorSize();
537 fPhysicalBlockSize
= fInfoBlock
.PhysicalSectorSize();
538 fBlockOffset
= fInfoBlock
.BlockOffset();
540 fTaskFile
.lba
.mode
= ATA_MODE_LBA
;
541 fTaskFile
.lba
.device
= fIndex
;
543 status_t result
= ConfigureDMA();
547 result
= DisableCommandQueueing();
556 ATADevice::Identify()
558 snprintf(fDebugContext
, sizeof(fDebugContext
), "%s %" B_PRIu32
"-%u",
559 IsATAPI() ? "pi" : "", fChannel
->ChannelID(), fIndex
);
561 ATARequest
request(false);
562 request
.SetDevice(this);
563 request
.SetTimeout(20 * 1000 * 1000);
566 fTaskFile
.write
.command
= IsATAPI() ? ATA_COMMAND_IDENTIFY_PACKET_DEVICE
567 : ATA_COMMAND_IDENTIFY_DEVICE
;
569 if (fChannel
->SendRequest(&request
,
570 IsATAPI() ? 0 : ATA_DEVICE_READY_REQUIRED
) != B_OK
) {
571 TRACE_ERROR("sending identify request failed\n");
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");
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");
590 fChannel
->ReadPIO((uint8
*)&fInfoBlock
, sizeof(fInfoBlock
));
592 if (fChannel
->WaitDataRequest(false) != B_OK
) {
593 TRACE_ERROR("device disagrees on info block length\n");
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");
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
);
625 ATADevice::ExecuteReadWrite(ATARequest
*request
, uint64 address
,
628 request
->SetUseDMA(fUseDMA
&& fChannel
->PrepareDMA(request
) == B_OK
);
629 if (!request
->UseDMA())
630 request
->PrepareSGInfo();
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();
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();
649 if (request
->UseDMA()) {
650 fChannel
->PrepareWaitingForInterrupt();
651 fChannel
->StartDMA();
653 result
= fChannel
->WaitForInterrupt(request
->Timeout());
654 status_t dmaResult
= fChannel
->FinishDMA();
655 if (result
== B_OK
&& dmaResult
== B_OK
) {
657 request
->CCB()->data_resid
= 0;
659 if (dmaResult
!= B_OK
) {
660 request
->SetSense(SCSIS_KEY_HARDWARE_ERROR
,
661 SCSIS_ASC_LUN_COM_FAILURE
);
663 if (fDMAFailures
>= ATA_MAX_DMA_FAILURES
) {
664 TRACE_ALWAYS("disabling DMA after %u failures\n",
670 request
->SetStatus(SCSI_CMD_TIMEOUT
);
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
);
681 if (fChannel
->ExecutePIOTransfer(request
) != B_OK
) {
682 TRACE_ERROR("executing pio transfer failed\n");
683 request
->SetStatus(SCSI_SEQUENCE_FAIL
);
687 return fChannel
->FinishRequest(request
, ATA_WAIT_FINISH
688 | ATA_DEVICE_READY_REQUIRED
, ATA_ERROR_ALL
);
693 ATADevice::_FillTaskFile(ATARequest
*request
, uint64 address
)
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
}
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
}
707 uint32 sectorCount
= *request
->BytesLeft() / fBlockSize
;
708 TRACE("about to transfer %lu sectors\n", sectorCount
);
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
);
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
;
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];
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
);
744 fRegisterMask
= ATA_MASK_SECTOR_COUNT
748 | ATA_MASK_DEVICE_HEAD
;
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];