BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / bus_managers / ata / ATADevice.cpp
blob41f633da5a61af457d6dab4c0a148335441f21cb
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.
7 * Distributed under the terms of the MIT License.
8 */
10 #include "ATAPrivate.h"
13 ATADevice::ATADevice(ATAChannel *channel, uint8 index)
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)
27 memset(&fInfoBlock, 0, sizeof(fInfoBlock));
28 memset(&fTaskFile, 0, sizeof(fTaskFile));
32 ATADevice::~ATADevice()
37 status_t
38 ATADevice::TestUnitReady(ATARequest *request)
40 TRACE_FUNCTION("%p\n", request);
42 fRegisterMask = 0;
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);
47 if (result != B_OK) {
48 TRACE_ERROR("failed to send test unit ready request\n");
49 return result;
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);
58 status_t
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)
67 return B_OK;
69 fRegisterMask = 0;
70 fTaskFile.lba.command
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);
75 if (result != B_OK) {
76 TRACE_ERROR("failed to send synchronize cache request\n");
77 return result;
80 return fChannel->FinishRequest(request, ATA_WAIT_FINISH
81 | ATA_DEVICE_READY_REQUIRED, ATA_ERROR_ABORTED);
85 status_t
86 ATADevice::Eject(ATARequest *request)
88 TRACE_FUNCTION("%p\n", request);
90 fRegisterMask = 0;
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);
95 if (result != B_OK) {
96 TRACE_ERROR("failed to send eject request\n");
97 return result;
100 return fChannel->FinishRequest(request, ATA_WAIT_FINISH
101 | ATA_DEVICE_READY_REQUIRED, ATA_ERROR_ABORTED | ATA_ERROR_NO_MEDIA);
105 status_t
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);
114 return B_ERROR;
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;
138 data.cmd_queue = 0;
139 data.linked = false;
141 // these values are free-style
142 data.sync = false;
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);
163 return B_OK;
167 status_t
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);
176 return B_ERROR;
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);
185 } else
186 data.lba = UINT_MAX;
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);
191 return B_OK;
195 status_t
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);
210 return B_OK;
214 status_t
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);
226 return B_BAD_INDEX;
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);
241 return B_ERROR;
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) {
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;
270 return B_OK;
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);
279 break;
281 case SCSI_OP_SYNCHRONIZE_CACHE:
282 // we ignore range and immediate bit, we always immediately
283 // flush everything
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
288 case SCSI_OP_READ_6:
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);
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;
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);
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;
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);
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;
352 TRACE("command not implemented\n");
353 request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE);
354 return B_ERROR;
358 void
359 ATADevice::GetRestrictions(bool *noAutoSense, uint32 *maxBlocks)
361 if (IsATAPI())
362 *noAutoSense = true;
363 else {
364 if (fUse48Bits)
365 *maxBlocks = 0xffff;
366 else
367 *maxBlocks = 0x100;
372 status_t
373 ATADevice::Control(uint32 opcode, void *buffer, size_t length)
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));
381 // Remove trailing spaces
382 int32 nameLength = sizeof(name) - 2;
383 while (nameLength > 0 && name[nameLength - 1] == ' ')
384 nameLength--;
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;
390 return B_BAD_VALUE;
394 status_t
395 ATADevice::Select()
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;
404 #endif
405 return err;
409 status_t
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");
425 return result;
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;
435 return B_OK;
439 status_t
440 ATADevice::DisableCommandQueueing()
442 if (!fInfoBlock.read_write_dma_queued_supported)
443 return B_OK;
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;
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;
463 return B_OK;
467 status_t
468 ATADevice::ConfigureDMA()
470 if (!fUseDMA)
471 return B_OK;
473 if (!fInfoBlock.dma_supported) {
474 TRACE_ALWAYS("DMA not supported by device\n");
475 fUseDMA = false;
476 return B_OK;
479 #define CHECK_DMA_MODE(element, mode) \
480 if (fInfoBlock.element) { \
481 fDMAMode = mode; \
482 modeCount++; \
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");
505 fUseDMA = false;
506 return B_OK;
509 TRACE_ALWAYS("using DMA mode 0x%02x\n", fDMAMode);
510 return B_OK;
514 status_t
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;
523 else {
524 TRACE_ERROR("infoblock indicates non-ata device\n");
525 return B_ERROR;
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;
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();
544 if (result != B_OK)
545 return result;
547 result = DisableCommandQueueing();
548 if (result != B_OK)
549 return result;
551 return B_OK;
555 status_t
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);
565 fRegisterMask = 0;
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");
572 return B_ERROR;
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;
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;
589 // get the infoblock
590 fChannel->ReadPIO((uint8 *)&fInfoBlock, sizeof(fInfoBlock));
592 if (fChannel->WaitDataRequest(false) != B_OK) {
593 TRACE_ERROR("device disagrees on info block length\n");
594 return B_ERROR;
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;
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);
620 return B_OK;
624 status_t
625 ATADevice::ExecuteReadWrite(ATARequest *request, uint64 address,
626 uint32 sectorCount)
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();
637 return B_ERROR;
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;
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) {
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;
668 } else {
669 // timeout
670 request->SetStatus(SCSI_CMD_TIMEOUT);
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;
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);
692 status_t
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);
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;
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];
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;
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;
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];
759 return B_OK;