xref: /haiku/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp (revision b5eb03683b3ae87f263bab7dc31b8ba72d534924)
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 	if (1) {
516 		// print device information
517 		char modelNumber[sizeof(fInfoBlock.model_number) + 1];
518 		char serialNumber[sizeof(fInfoBlock.serial_number) + 1];
519 		char firmwareRev[sizeof(fInfoBlock.firmware_revision) + 1];
520 		strlcpy(modelNumber, fInfoBlock.model_number, sizeof(modelNumber));
521 		strlcpy(serialNumber, fInfoBlock.serial_number, sizeof(serialNumber));
522 		strlcpy(firmwareRev, fInfoBlock.firmware_revision, sizeof(firmwareRev));
523 		swap_words(modelNumber, sizeof(modelNumber) - 1);
524 		swap_words(serialNumber, sizeof(serialNumber) - 1);
525 		swap_words(firmwareRev, sizeof(firmwareRev) - 1);
526 		TRACE_ALWAYS("model number: %s\n", modelNumber);
527 		TRACE_ALWAYS("serial number: %s\n", serialNumber);
528   		TRACE_ALWAYS("firmware rev.: %s\n", firmwareRev);
529 	}
530 
531 	return B_OK;
532 }
533 
534 
535 status_t
536 ATADevice::ExecuteReadWrite(ATARequest *request, uint64 address,
537 	uint32 sectorCount)
538 {
539 	request->SetUseDMA(fUseDMA && fChannel->PrepareDMA(request) == B_OK);
540 	if (!request->UseDMA())
541 		request->PrepareSGInfo();
542 
543 	request->SetBytesLeft(sectorCount * ATA_BLOCK_SIZE);
544 	if (_FillTaskFile(request, address) != B_OK) {
545 		TRACE_ERROR("failed to setup transfer request\n");
546 		if (request->UseDMA())
547 			fChannel->FinishDMA();
548 		return B_ERROR;
549 	}
550 
551 	status_t result = fChannel->SendRequest(request,
552 		IsATAPI() ? 0 : ATA_DEVICE_READY_REQUIRED);
553 	if (result != B_OK) {
554 		TRACE_ERROR("failed to send transfer request\n");
555 		if (request->UseDMA())
556 			fChannel->FinishDMA();
557 		return result;
558 	}
559 
560 	if (request->UseDMA()) {
561 		fChannel->PrepareWaitingForInterrupt();
562 		fChannel->StartDMA();
563 
564 		result = fChannel->WaitForInterrupt(request->Timeout());
565 		status_t dmaResult = fChannel->FinishDMA();
566 		if (result == B_OK && dmaResult == B_OK) {
567 			fDMAFailures = 0;
568 			request->CCB()->data_resid = 0;
569 		} else {
570 			if (dmaResult != B_OK) {
571 				request->SetSense(SCSIS_KEY_HARDWARE_ERROR,
572 					SCSIS_ASC_LUN_COM_FAILURE);
573 				fDMAFailures++;
574 				if (fDMAFailures >= ATA_MAX_DMA_FAILURES) {
575 					TRACE_ALWAYS("disabling DMA after %u failures\n",
576 						fDMAFailures);
577 					fUseDMA = false;
578 				}
579 			} else {
580 				// timeout
581 				request->SetStatus(SCSI_CMD_TIMEOUT);
582 			}
583 		}
584 	} else {
585 		if (fChannel->Wait(ATA_STATUS_DATA_REQUEST, 0, ATA_CHECK_ERROR_BIT
586 				| ATA_CHECK_DEVICE_FAULT, request->Timeout()) != B_OK) {
587 			TRACE_ERROR("timeout waiting for device to request data\n");
588 			request->SetStatus(SCSI_CMD_TIMEOUT);
589 			return B_TIMED_OUT;
590 		}
591 
592 		if (fChannel->ExecutePIOTransfer(request) != B_OK) {
593 			TRACE_ERROR("executing pio transfer failed\n");
594 			request->SetStatus(SCSI_SEQUENCE_FAIL);
595 		}
596 	}
597 
598 	return fChannel->FinishRequest(request, ATA_WAIT_FINISH
599 		| ATA_DEVICE_READY_REQUIRED, ATA_ERROR_ALL);
600 }
601 
602 
603 status_t
604 ATADevice::_FillTaskFile(ATARequest *request, uint64 address)
605 {
606 	// list of LBA48 opcodes
607 	static const uint8 s48BitCommands[2][2] = {
608 		{ ATA_COMMAND_READ_SECTORS_EXT, ATA_COMMAND_WRITE_SECTORS_EXT },
609 		{ ATA_COMMAND_READ_DMA_EXT, ATA_COMMAND_WRITE_DMA_EXT }
610 	};
611 
612 	// list of normal LBA opcodes
613 	static const uint8 s28BitCommands[2][2] = {
614 		{ ATA_COMMAND_READ_SECTORS, ATA_COMMAND_WRITE_SECTORS },
615 		{ ATA_COMMAND_READ_DMA, ATA_COMMAND_WRITE_DMA }
616 	};
617 
618 	uint32 sectorCount = *request->BytesLeft() / ATA_BLOCK_SIZE;
619 	TRACE("about to transfer %lu sectors\n", sectorCount);
620 
621 	if (fUse48Bits
622 		&& (address + sectorCount > 0xfffffff || sectorCount > 0x100)) {
623 		// use LBA48 only if necessary
624 		if (sectorCount > 0xffff) {
625 			TRACE_ERROR("invalid sector count %lu\n", sectorCount);
626 			request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST,
627 				SCSIS_ASC_INV_CDB_FIELD);
628 			return B_ERROR;
629 		}
630 
631 		fRegisterMask = ATA_MASK_SECTOR_COUNT_48
632 			| ATA_MASK_LBA_LOW_48
633 			| ATA_MASK_LBA_MID_48
634 			| ATA_MASK_LBA_HIGH_48;
635 
636 		fTaskFile.lba48.sector_count_0_7 = sectorCount & 0xff;
637 		fTaskFile.lba48.sector_count_8_15 = (sectorCount >> 8) & 0xff;
638 		fTaskFile.lba48.lba_0_7 = address & 0xff;
639 		fTaskFile.lba48.lba_8_15 = (address >> 8) & 0xff;
640 		fTaskFile.lba48.lba_16_23 = (address >> 16) & 0xff;
641 		fTaskFile.lba48.lba_24_31 = (address >> 24) & 0xff;
642 		fTaskFile.lba48.lba_32_39 = (address >> 32) & 0xff;
643 		fTaskFile.lba48.lba_40_47 = (address >> 40) & 0xff;
644 		fTaskFile.lba48.command = s48BitCommands[request->UseDMA()
645 			? 1 : 0][request->IsWrite() ? 1 : 0];
646 	} else {
647 		// normal LBA
648 		if (sectorCount > 0x100) {
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
656 			| ATA_MASK_LBA_LOW
657 			| ATA_MASK_LBA_MID
658 			| ATA_MASK_LBA_HIGH
659 			| ATA_MASK_DEVICE_HEAD;
660 
661 		fTaskFile.lba.sector_count = sectorCount & 0xff;
662 		fTaskFile.lba.lba_0_7 = address & 0xff;
663 		fTaskFile.lba.lba_8_15 = (address >> 8) & 0xff;
664 		fTaskFile.lba.lba_16_23 = (address >> 16) & 0xff;
665 		fTaskFile.lba.lba_24_27 = (address >> 24) & 0xf;
666 		fTaskFile.lba.command = s28BitCommands[request->UseDMA()
667 			? 1 : 0][request->IsWrite() ? 1 : 0];
668 	}
669 
670 	return B_OK;
671 }
672