xref: /haiku/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp (revision b6b82488dfda5ae59f0a48b5371c8a24fb4a24aa)
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 		fUseLBA(false),
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 = fUse48Bits ? ATA_COMMAND_FLUSH_CACHE_EXT
68 		: 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 = scsi_dev_direct_access;
118 	data.device_qualifier = scsi_periph_qual_connected;
119 
120 	data.device_type_modifier = 0;
121 	data.removable_medium = false;
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.DMA_QUEUED_supported)
345 		return B_OK;
346 
347 	if (fInfoBlock.RELEASE_irq_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_irq_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(MDMA0_selected, 0x00);
390 	CHECK_DMA_MODE(MDMA1_selected, 0x01);
391 	CHECK_DMA_MODE(MDMA2_selected, 0x02);
392 
393 	if (fInfoBlock._88_valid) {
394 		CHECK_DMA_MODE(UDMA0_selected, 0x10);
395 		CHECK_DMA_MODE(UDMA1_selected, 0x11);
396 		CHECK_DMA_MODE(UDMA2_selected, 0x12);
397 		CHECK_DMA_MODE(UDMA3_selected, 0x13);
398 		CHECK_DMA_MODE(UDMA4_selected, 0x14);
399 		CHECK_DMA_MODE(UDMA5_selected, 0x15);
400 		CHECK_DMA_MODE(UDMA6_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._0.ata.ATA != 0) {
421 		// CF has either magic header or CFA bit set
422 		// we merge it to "CFA bit set" for easier (later) testing
423 		if (*(uint16 *)&fInfoBlock == 0x848a)
424 			fInfoBlock.CFA_supported = true;
425 		else
426 			return B_ERROR;
427 	}
428 
429 	if (!fInfoBlock._54_58_valid) {
430 		// normally, current_xxx contains active CHS mapping,
431 		// but if BIOS didn't call INITIALIZE DEVICE PARAMETERS
432 		// the default mapping is used
433 		fInfoBlock.current_sectors = fInfoBlock.sectors;
434 		fInfoBlock.current_cylinders = fInfoBlock.cylinders;
435 		fInfoBlock.current_heads = fInfoBlock.heads;
436 	}
437 
438 	// just in case capacity_xxx isn't initialized - calculate it manually
439 	// (seems that this information is really redundant; hopefully)
440 	uint32 chsCapacity = fInfoBlock.current_sectors
441 		* fInfoBlock.current_cylinders * fInfoBlock.current_heads;
442 
443 	fInfoBlock.capacity_low = chsCapacity & 0xff;
444 	fInfoBlock.capacity_high = chsCapacity >> 8;
445 
446 	// checking LBA_supported flag should be sufficient, but it seems
447 	// that checking LBA_total_sectors is a good idea
448 	fUseLBA = fInfoBlock.LBA_supported && fInfoBlock.LBA_total_sectors != 0;
449 
450 	if (fUseLBA) {
451 		fTotalSectors = fInfoBlock.LBA_total_sectors;
452 		fTaskFile.lba.mode = ATA_MODE_LBA;
453 		fTaskFile.lba.device = fIndex;
454 	} else {
455 		fTotalSectors = chsCapacity;
456 		fTaskFile.chs.mode = ATA_MODE_CHS;
457 		fTaskFile.chs.device = fIndex;
458 	}
459 
460 	fUse48Bits = fInfoBlock._48_bit_addresses_supported;
461 	if (fUse48Bits)
462 		fTotalSectors = fInfoBlock.LBA48_total_sectors;
463 
464 	status_t result = ConfigureDMA();
465 	if (result != B_OK)
466 		return result;
467 
468 	result = DisableCommandQueueing();
469 	if (result != B_OK)
470 		return result;
471 
472 	return B_OK;
473 }
474 
475 
476 status_t
477 ATADevice::Identify()
478 {
479 	snprintf(fDebugContext, sizeof(fDebugContext), "%s %lu-%u",
480 		IsATAPI() ? "pi" : "", fChannel->ChannelID(), fIndex);
481 
482 	ATARequest request(false);
483 	request.SetDevice(this);
484 	request.SetTimeout(20 * 1000 * 1000);
485 
486 	fRegisterMask = 0;
487 	fTaskFile.write.command = IsATAPI() ? ATA_COMMAND_IDENTIFY_PACKET_DEVICE
488 		: ATA_COMMAND_IDENTIFY_DEVICE;
489 
490 	if (fChannel->SendRequest(&request, IsATAPI() ? 0
491 		: ATA_DEVICE_READY_REQUIRED) != B_OK) {
492 		TRACE_ERROR("sending identify request failed\n");
493 		return B_ERROR;
494 	}
495 
496 	if (fChannel->Wait(ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST, 0,
497 		ATA_WAIT_ANY_BIT, 100 * 1000) != B_OK) {
498 		TRACE_ALWAYS("no data request and not busy within 100ms, assuming "
499 			"no device present\n");
500 		return B_TIMED_OUT;
501 	}
502 
503 	if (fChannel->Wait(ATA_STATUS_DATA_REQUEST, ATA_STATUS_BUSY,
504 		ATA_CHECK_ERROR_BIT | ATA_CHECK_DEVICE_FAULT, IsATAPI()
505 		? 20 * 1000 * 1000 : 500 * 1000) != B_OK) {
506 		TRACE_ERROR("timeout waiting for identify request\n");
507 		return B_TIMED_OUT;
508 	}
509 
510 	// get the infoblock
511 	fChannel->ReadPIO((uint8 *)&fInfoBlock, sizeof(fInfoBlock));
512 
513 	if (fChannel->WaitDataRequest(false) != B_OK) {
514 		TRACE_ERROR("device disagrees on info block length\n");
515 		return B_ERROR;
516 	}
517 
518 	if (fChannel->FinishRequest(&request, ATA_WAIT_FINISH | (IsATAPI() ? 0
519 		: ATA_DEVICE_READY_REQUIRED), ATA_ERROR_ABORTED) != B_OK) {
520 		TRACE_ERROR("failed to finish identify request\n");
521 		return B_ERROR;
522 	}
523 
524 	return B_OK;
525 }
526 
527 
528 status_t
529 ATADevice::ExecuteReadWrite(ATARequest *request, uint64 address,
530 	uint32 sectorCount)
531 {
532 	request->SetUseDMA(fUseDMA && fChannel->PrepareDMA(request) == B_OK);
533 	if (!request->UseDMA())
534 		request->PrepareSGInfo();
535 
536 	request->SetBytesLeft(sectorCount * ATA_BLOCK_SIZE);
537 	if (_FillTaskFile(request, address) != B_OK) {
538 		TRACE_ERROR("failed to setup transfer request\n");
539 		if (request->UseDMA())
540 			fChannel->FinishDMA();
541 		return B_ERROR;
542 	}
543 
544 	status_t result = fChannel->SendRequest(request, IsATAPI()
545 		? 0 : ATA_DEVICE_READY_REQUIRED);
546 	if (result != B_OK) {
547 		TRACE_ERROR("failed to send transfer request\n");
548 		if (request->UseDMA())
549 			fChannel->FinishDMA();
550 		return result;
551 	}
552 
553 	if (fChannel->Wait(ATA_STATUS_DATA_REQUEST, 0, ATA_CHECK_ERROR_BIT
554 		| ATA_CHECK_DEVICE_FAULT, request->Timeout()) != B_OK) {
555 		TRACE_ERROR("timeout waiting for device to request data\n");
556 		request->SetStatus(SCSI_CMD_TIMEOUT);
557 		return B_TIMED_OUT;
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->ExecutePIOTransfer(request) != B_OK) {
586 			TRACE_ERROR("executing pio transfer failed\n");
587 			request->SetStatus(SCSI_SEQUENCE_FAIL);
588 		}
589 	}
590 
591 	return fChannel->FinishRequest(request, ATA_WAIT_FINISH
592 		| ATA_DEVICE_READY_REQUIRED, ATA_ERROR_ALL);
593 }
594 
595 
596 status_t
597 ATADevice::_FillTaskFile(ATARequest *request, uint64 address)
598 {
599 	// list of LBA48 opcodes
600 	static const uint8 s48BitCommands[2][2] = {
601 		{ ATA_COMMAND_READ_SECTORS_EXT, ATA_COMMAND_WRITE_SECTORS_EXT },
602 		{ ATA_COMMAND_READ_DMA_EXT, ATA_COMMAND_WRITE_DMA_EXT }
603 	};
604 
605 	// list of normal LBA opcodes
606 	static const uint8 s28BitCommands[2][2] = {
607 		{ ATA_COMMAND_READ_SECTORS, ATA_COMMAND_WRITE_SECTORS },
608 		{ ATA_COMMAND_READ_DMA, ATA_COMMAND_WRITE_DMA }
609 	};
610 
611 	uint32 sectorCount = *request->BytesLeft() / ATA_BLOCK_SIZE;
612 	TRACE("about to transfer %lu sectors\n", sectorCount);
613 
614 	if (fUseLBA) {
615 		if (fUse48Bits
616 			&& (address + sectorCount > 0xfffffff || sectorCount > 0x100)) {
617 			// use LBA48 only if necessary
618 			if (sectorCount > 0xffff) {
619 				TRACE_ERROR("invalid sector count %lu\n", sectorCount);
620 				request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST,
621 					SCSIS_ASC_INV_CDB_FIELD);
622 				return B_ERROR;
623 			}
624 
625 			fRegisterMask = ATA_MASK_SECTOR_COUNT_48
626 				| ATA_MASK_LBA_LOW_48
627 				| ATA_MASK_LBA_MID_48
628 				| ATA_MASK_LBA_HIGH_48;
629 
630 			fTaskFile.lba48.sector_count_0_7 = sectorCount & 0xff;
631 			fTaskFile.lba48.sector_count_8_15 = (sectorCount >> 8) & 0xff;
632 			fTaskFile.lba48.lba_0_7 = address & 0xff;
633 			fTaskFile.lba48.lba_8_15 = (address >> 8) & 0xff;
634 			fTaskFile.lba48.lba_16_23 = (address >> 16) & 0xff;
635 			fTaskFile.lba48.lba_24_31 = (address >> 24) & 0xff;
636 			fTaskFile.lba48.lba_32_39 = (address >> 32) & 0xff;
637 			fTaskFile.lba48.lba_40_47 = (address >> 40) & 0xff;
638 			fTaskFile.lba48.command = s48BitCommands[request->UseDMA()
639 				? 1 : 0][request->IsWrite() ? 1 : 0];
640 		} else {
641 			// normal LBA
642 			if (sectorCount > 0x100) {
643 				TRACE_ERROR("invalid sector count %lu\n", sectorCount);
644 				request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST,
645 					SCSIS_ASC_INV_CDB_FIELD);
646 				return B_ERROR;
647 			}
648 
649 			fRegisterMask = ATA_MASK_SECTOR_COUNT
650 				| ATA_MASK_LBA_LOW
651 				| ATA_MASK_LBA_MID
652 				| ATA_MASK_LBA_HIGH
653 				| ATA_MASK_DEVICE_HEAD;
654 
655 			fTaskFile.lba.sector_count = sectorCount & 0xff;
656 			fTaskFile.lba.lba_0_7 = address & 0xff;
657 			fTaskFile.lba.lba_8_15 = (address >> 8) & 0xff;
658 			fTaskFile.lba.lba_16_23 = (address >> 16) & 0xff;
659 			fTaskFile.lba.lba_24_27 = (address >> 24) & 0xf;
660 			fTaskFile.lba.command = s28BitCommands[request->UseDMA()
661 				? 1 : 0][request->IsWrite() ? 1 : 0];
662 		}
663 	} else {
664 		// CHS mode - we do not support it anymore
665 		TRACE_ERROR("chs mode not supported\n");
666 		request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_CDB_FIELD);
667 		return B_ERROR;
668 	}
669 
670 	return B_OK;
671 }
672