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