xref: /haiku/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp (revision 8b1d35bdbb2cc7dd27772fc08da71461d24b53fa)
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 
ATADevice(ATAChannel * channel,uint8 index)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 
~ATADevice()32 ATADevice::~ATADevice()
33 {
34 }
35 
36 
37 status_t
TestUnitReady(ATARequest * request)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
SynchronizeCache(ATARequest * request)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
Eject(ATARequest * request)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
Inquiry(ATARequest * request)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
ReadCapacity(ATARequest * request)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 	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 
198 status_t
ReadCapacity16(ATARequest * request)199 ATADevice::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 
231 status_t
ExecuteIO(ATARequest * request)232 ATADevice::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 
375 void
GetRestrictions(bool * noAutoSense,uint32 * maxBlocks)376 ATADevice::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 
389 status_t
Control(uint32 opcode,void * buffer,size_t length)390 ATADevice::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 
411 status_t
Select()412 ATADevice::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 
426 status_t
SetFeature(int feature)427 ATADevice::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 
456 status_t
DisableCommandQueueing()457 ATADevice::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 
484 status_t
ConfigureDMA()485 ATADevice::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 
531 status_t
Configure()532 ATADevice::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 
572 status_t
Identify()573 ATADevice::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 
641 status_t
ExecuteReadWrite(ATARequest * request,uint64 address,uint32 sectorCount)642 ATADevice::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 
709 status_t
_FillTaskFile(ATARequest * request,uint64 address)710 ATADevice::_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