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