xref: /haiku/src/add-ons/kernel/bus_managers/ata/ATAChannel.cpp (revision 323b65468e5836bb27a5e373b14027d902349437)
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 ATAChannel::ATAChannel(device_node *node)
14 	:
15 	fNode(node),
16 	fChannelID(0),
17 	fController(NULL),
18 	fCookie(NULL),
19 	fExpectsInterrupt(false),
20 	fStatus(B_NO_INIT),
21 	fSCSIBus(NULL),
22 	fDeviceCount(0),
23 	fDevices(NULL),
24 	fUseDMA(true),
25 	fRequest(NULL)
26 {
27 	B_INITIALIZE_SPINLOCK(&fInterruptLock);
28 	fInterruptCondition.Init(this, "ata dma transfer");
29 
30 	gDeviceManager->get_attr_uint32(node, ATA_CHANNEL_ID_ITEM, &fChannelID,
31 		true);
32 	snprintf(fDebugContext, sizeof(fDebugContext), " %lu", fChannelID);
33 
34 	if (fUseDMA) {
35 		void *settings = load_driver_settings(B_SAFEMODE_DRIVER_SETTINGS);
36 		if (settings != NULL) {
37 			if (get_driver_boolean_parameter(settings,
38 				B_SAFEMODE_DISABLE_IDE_DMA, false, false)) {
39 				TRACE_ALWAYS("disabling DMA because of safemode setting\n");
40 				fUseDMA = false;
41 			}
42 
43 			unload_driver_settings(settings);
44 		}
45 	}
46 
47 	if (fUseDMA) {
48 		uint8 canDMA;
49 		if (gDeviceManager->get_attr_uint8(node, ATA_CONTROLLER_CAN_DMA_ITEM,
50 			&canDMA, true) != B_OK) {
51 			TRACE_ERROR("unknown if controller supports DMA, not using it\n");
52 			fUseDMA = false;
53 		}
54 
55 		if (canDMA == 0) {
56 			TRACE_ALWAYS("controller doesn't support DMA, disabling\n");
57 			fUseDMA = false;
58 		}
59 	}
60 
61 	fRequest = new(std::nothrow) ATARequest(true);
62 	if (fRequest == NULL) {
63 		fStatus = B_NO_MEMORY;
64 		return;
65 	}
66 
67 	uint8 maxDevices = 2;
68 	if (gDeviceManager->get_attr_uint8(node, ATA_CONTROLLER_MAX_DEVICES_ITEM,
69 			&maxDevices, true) != B_OK) {
70 		maxDevices = 2;
71 	}
72 
73 	fDeviceCount = MIN(maxDevices, 2);
74 	fDevices = new(std::nothrow) ATADevice *[fDeviceCount];
75 	if (fDevices == NULL) {
76 		fStatus = B_NO_MEMORY;
77 		return;
78 	}
79 
80 	for (uint8 i = 0; i < fDeviceCount; i++)
81 		fDevices[i] = NULL;
82 
83 	device_node *parent = gDeviceManager->get_parent_node(node);
84 	fStatus = gDeviceManager->get_driver(parent,
85 		(driver_module_info **)&fController, &fCookie);
86 	gDeviceManager->put_node(parent);
87 
88 	fController->set_channel(fCookie, this);
89 }
90 
91 
92 ATAChannel::~ATAChannel()
93 {
94 	if (fDevices) {
95 		for (uint8 i = 0; i < fDeviceCount; i++)
96 			delete fDevices[i];
97 		delete [] fDevices;
98 	}
99 
100 	delete fRequest;
101 }
102 
103 
104 status_t
105 ATAChannel::InitCheck()
106 {
107 	return fStatus;
108 }
109 
110 
111 void
112 ATAChannel::SetBus(scsi_bus bus)
113 {
114 	fSCSIBus = bus;
115 }
116 
117 
118 bool
119 ATAChannel::_DevicePresent(int device)
120 {
121 	SelectDevice(device);
122 
123 	if (SelectedDevice() != device) {
124 		TRACE_ALWAYS("_DevicePresent: device selection failed for device %i\n",
125 		device);
126 		return false;
127 	}
128 
129 	ata_task_file taskFile;
130 	taskFile.chs.sector_count = 0x5a;
131 	taskFile.chs.sector_number = 0xa5;
132 	if (_WriteRegs(&taskFile, ATA_MASK_SECTOR_COUNT
133 		| ATA_MASK_SECTOR_NUMBER) != B_OK) {
134 		TRACE_ERROR("_DevicePresent: writing registers failed\n");
135 		return false;
136 	}
137 	if (_ReadRegs(&taskFile, ATA_MASK_SECTOR_COUNT
138 		| ATA_MASK_SECTOR_NUMBER) != B_OK) {
139 		TRACE_ERROR("_DevicePresent: reading registers failed\n");
140 		return false;
141 	}
142 	bool present = (taskFile.chs.sector_count == 0x5a &&
143 		taskFile.chs.sector_number == 0xa5);
144 
145 	TRACE_ALWAYS("_DevicePresent: device %i, presence %d\n", device, present);
146 	return present;
147 }
148 
149 
150 status_t
151 ATAChannel::ScanBus()
152 {
153 	uint deviceMask = 0;
154 
155 	for (int i = 0; i < fDeviceCount; i++)
156 		deviceMask |= (int)_DevicePresent(i) << i;
157 
158 	status_t result = Reset();
159 	if (result != B_OK) {
160 		TRACE_ERROR("resetting the channel failed\n");
161 		return result;
162 	}
163 
164 	TRACE_ALWAYS("deviceMask %d\n", deviceMask);
165 
166 	for (int i = 0; i < fDeviceCount; i++) {
167 		if (!(deviceMask & (1 << i))) {
168 			TRACE_ALWAYS("ignoring device %d\n", i);
169 			continue;
170 		}
171 
172 		TRACE_ALWAYS("probing device %d\n", i);
173 		SelectDevice(i);
174 
175 		// ensure interrupts are disabled for this device
176 		_WriteControl(ATA_DEVICE_CONTROL_DISABLE_INTS);
177 
178 		// wait up to 3 seconds for busy to clear
179 		if (Wait(0, ATA_STATUS_BUSY, 0, 3 * 1000 * 1000) != B_OK) {
180 			uint8 status = AltStatus();
181 			if (status == 0xff || status == 0x7f) {
182 				TRACE_ALWAYS("illegal status value 0x%02x for device %d\n",
183 					status, i);
184 				continue;
185 			} else {
186 				TRACE_ALWAYS("device %d is slow\n", i);
187 			}
188 		}
189 
190 		// wait up to 31 seconds for busy to clear (already 3 sec. waited)
191 		if (Wait(0, ATA_STATUS_BUSY, 0, 28 * 1000 * 1000) != B_OK) {
192 			TRACE_ALWAYS("device %d reset timeout\n", i);
193 			continue;
194 		}
195 
196 		// reselect device
197 		SelectDevice(i);
198 		WaitForIdle();
199 
200 		if (SelectedDevice() != i) {
201 			TRACE_ALWAYS("device selection failed for device %i\n", i);
202 			continue;
203 		}
204 
205 		ata_task_file taskFile;
206 		if (_ReadRegs(&taskFile, ATA_MASK_LBA_MID | ATA_MASK_LBA_HIGH
207 				| ATA_MASK_ERROR) != B_OK) {
208 			TRACE_ERROR("reading status failed\n");
209 			return B_ERROR;
210 		}
211 
212 		// for information only
213 		if ((i == 0) && (taskFile.read.error & 0x80)) {
214 			TRACE_ERROR("device 0 indicates that device 1 failed"
215 				" error code is 0x%02x\n", taskFile.read.error);
216 		} else if (taskFile.read.error != 0x01) {
217 			TRACE_ERROR("device %d failed, error code is 0x%02x\n",
218 				i, taskFile.read.error);
219 		}
220 
221 		uint16 signature = taskFile.lba.lba_8_15
222 			| (((uint16)taskFile.lba.lba_16_23) << 8);
223 		TRACE_ALWAYS("signature of device %d: 0x%04x\n", i, signature);
224 
225 		ATADevice *device = NULL;
226 		if (signature == ATA_SIGNATURE_ATAPI)
227 			device = new(std::nothrow) ATAPIDevice(this, i);
228 		else
229 			device = new(std::nothrow) ATADevice(this, i);
230 
231 		if (device == NULL) {
232 			TRACE_ERROR("out of memory allocating device\n");
233 			return B_NO_MEMORY;
234 		}
235 
236 		TRACE("trying ATA%s device %u\n", device->IsATAPI() ? "PI" : "", i);
237 
238 		if (device->Identify() != B_OK) {
239 			delete device;
240 			continue;
241 		}
242 
243 		if (device->Configure() != B_OK) {
244 			TRACE_ERROR("failed to configure device\n");
245 			delete device;
246 			continue;
247 		}
248 
249 		TRACE_ALWAYS("identified ATA%s device %u\n", device->IsATAPI()
250 			? "PI" : "", i);
251 
252 		fDevices[i] = device;
253 	}
254 
255 	return B_OK;
256 }
257 
258 
259 void
260 ATAChannel::PathInquiry(scsi_path_inquiry *info)
261 {
262 	info->hba_inquiry = SCSI_PI_TAG_ABLE | SCSI_PI_WIDE_16;
263 	info->hba_misc = 0;
264 	info->sim_priv = 0;
265 	info->initiator_id = 2;
266 	info->hba_queue_size = 1;
267 	memset(info->vuhba_flags, 0, sizeof(info->vuhba_flags));
268 
269 	strlcpy(info->sim_vid, "Haiku", SCSI_SIM_ID);
270 
271 	const char *controllerName = NULL;
272 	if (gDeviceManager->get_attr_string(fNode,
273 			SCSI_DESCRIPTION_CONTROLLER_NAME, &controllerName, true) == B_OK)
274 		strlcpy(info->hba_vid, controllerName, SCSI_HBA_ID);
275 	else
276 		strlcpy(info->hba_vid, "unknown", SCSI_HBA_ID);
277 
278 	strlcpy(info->sim_version, "1.0", SCSI_VERS);
279 	strlcpy(info->hba_version, "1.0", SCSI_VERS);
280 	strlcpy(info->controller_family, "ATA", SCSI_FAM_ID);
281 	strlcpy(info->controller_type, "ATA", SCSI_TYPE_ID);
282 }
283 
284 
285 void
286 ATAChannel::GetRestrictions(uint8 targetID, bool *isATAPI, bool *noAutoSense,
287 	uint32 *maxBlocks)
288 {
289 	// we always indicate ATAPI so we have to emulate fewer commands
290 	*isATAPI = true;
291 	*noAutoSense = false;
292 	*maxBlocks = 0x100;
293 
294 	if (targetID < fDeviceCount && fDevices[targetID] != NULL)
295 		fDevices[targetID]->GetRestrictions(noAutoSense, maxBlocks);
296 }
297 
298 
299 status_t
300 ATAChannel::ExecuteIO(scsi_ccb *ccb)
301 {
302 	TRACE_FUNCTION("%p\n", ccb);
303 	status_t result = fRequest->Start(ccb);
304 	if (result != B_OK)
305 		return result;
306 
307 	if (ccb->cdb[0] == SCSI_OP_REQUEST_SENSE && fRequest->HasSense()) {
308 		TRACE("request sense\n");
309 		fRequest->RequestSense();
310 		fRequest->Finish(false);
311 		return B_OK;
312 	}
313 
314 	// we aren't a check sense request, clear sense data for new request
315 	fRequest->ClearSense();
316 
317 	if (ccb->target_id >= fDeviceCount) {
318 		TRACE_ERROR("invalid target device\n");
319 		fRequest->SetStatus(SCSI_SEL_TIMEOUT);
320 		fRequest->Finish(false);
321 		return B_BAD_INDEX;
322 	}
323 
324 	ATADevice *device = fDevices[ccb->target_id];
325 	if (device == NULL) {
326 		TRACE_ERROR("target device not present\n");
327 		fRequest->SetStatus(SCSI_SEL_TIMEOUT);
328 		fRequest->Finish(false);
329 		return B_BAD_INDEX;
330 	}
331 
332 	fRequest->SetTimeout(ccb->timeout > 0 ? ccb->timeout * 1000 * 1000
333 		: ATA_STANDARD_TIMEOUT);
334 
335 	result = device->ExecuteIO(fRequest);
336 	fRequest->Finish(false);
337 	return result;
338 }
339 
340 
341 status_t
342 ATAChannel::Control(uint8 targetID, uint32 opcode, void *buffer, size_t length)
343 {
344 	if (targetID < fDeviceCount && fDevices[targetID] != NULL)
345 		return fDevices[targetID]->Control(opcode, buffer, length);
346 
347 	return B_BAD_VALUE;
348 }
349 
350 
351 status_t
352 ATAChannel::SelectDevice(uint8 device)
353 {
354 	TRACE_FUNCTION("device: %u\n", device);
355 
356 	if (device > 1)
357 		return B_BAD_INDEX;
358 
359 	ata_task_file taskFile;
360 	taskFile.lba.lba_24_27 = 0;
361 	taskFile.lba.mode = ATA_MODE_LBA;
362 	taskFile.lba.device = device;
363 
364 	status_t result = _WriteRegs(&taskFile, ATA_MASK_DEVICE_HEAD);
365 	if (result != B_OK) {
366 		TRACE_ERROR("writing register failed when trying to select device %d\n",
367 			device);
368 		return result;
369 	}
370 
371 	_FlushAndWait(1);
372 
373 	return B_OK;
374 }
375 
376 
377 uint8
378 ATAChannel::SelectedDevice()
379 {
380 	ata_task_file taskFile;
381 	if (_ReadRegs(&taskFile, ATA_MASK_DEVICE_HEAD) != B_OK) {
382 		TRACE_ERROR("reading register failed when detecting selected device\n");
383 		// Return an invalid device number so that the
384 		// SelectedDevice() == "expected device" check fails.
385 		// Due to the device number being a bit, we can't really get values
386 		// other than 0 and 1, so anything >= 2 can be regarded as invalid.
387 		return 234;
388 	}
389 
390 	return taskFile.lba.device;
391 }
392 
393 
394 status_t
395 ATAChannel::Reset()
396 {
397 	TRACE_FUNCTION("\n");
398 
399 	SelectDevice(0);
400 
401 	// disable interrupts and assert SRST for at least 5 usec
402 	if (_WriteControl(ATA_DEVICE_CONTROL_DISABLE_INTS
403 		| ATA_DEVICE_CONTROL_SOFT_RESET) != B_OK) {
404 		TRACE_ERROR("failed to set reset signaling\n");
405 		return B_ERROR;
406 	}
407 
408 	_FlushAndWait(20);
409 
410 	// clear reset and wait for at least 2 ms (wait 150ms like everyone else)
411 	if (_WriteControl(ATA_DEVICE_CONTROL_DISABLE_INTS) != B_OK) {
412 		TRACE_ERROR("failed to clear reset signaling\n");
413 		return B_ERROR;
414 	}
415 
416 	_FlushAndWait(150 * 1000);
417 
418 	// read status to clear any pending interrupts
419 	_Status();
420 
421 	return B_OK;
422 }
423 
424 
425 status_t
426 ATAChannel::Wait(uint8 setBits, uint8 clearedBits, uint32 flags,
427 	bigtime_t timeout)
428 {
429 	bigtime_t startTime = system_time();
430 	_FlushAndWait(1);
431 
432 	TRACE("wait for set bits 0x%02x and cleared bits 0x%02x\n",
433 		setBits, clearedBits);
434 
435 #if ATA_TRACING
436 	unsigned lastStatus = 0x100;
437 #endif
438 	while (true) {
439 		uint8 status = AltStatus();
440 		if ((flags & ATA_CHECK_ERROR_BIT) != 0
441 			&& (status & ATA_STATUS_BUSY) == 0
442 			&& (status & ATA_STATUS_ERROR) != 0) {
443 			TRACE("wait failed, error bit set, status 0x%02x\n", status);
444 			return B_ERROR;
445 		}
446 
447 		if ((flags & ATA_CHECK_DEVICE_FAULT) != 0
448 			&& (status & ATA_STATUS_BUSY) == 0
449 			&& (status & ATA_STATUS_DEVICE_FAULT) != 0) {
450 			TRACE("wait failed, device fault bit set, status 0x%02x\n", status);
451 			return B_ERROR;
452 		}
453 
454 		if ((status & clearedBits) == 0) {
455 			if ((flags & ATA_WAIT_ANY_BIT) != 0 && (status & setBits) != 0) {
456 				TRACE("wait success, status 0x%02x\n", status);
457 				return B_OK;
458 			}
459 			if ((status & setBits) == setBits) {
460 				TRACE("wait success, status 0x%02x\n", status);
461 				return B_OK;
462 			}
463 		}
464 
465 		bigtime_t elapsedTime = system_time() - startTime;
466 #if ATA_TRACING
467 		if (lastStatus != status) {
468 			TRACE("wait status changed after %lld, status 0x%02x\n",
469 				elapsedTime, status);
470 			lastStatus = status;
471 		}
472 #endif
473 
474 		if (elapsedTime > timeout) {
475 			TRACE("wait timeout after %lld, status 0x%02x\n",
476 				elapsedTime, status);
477 			return B_TIMED_OUT;
478 		}
479 
480 		// The device may be ready almost immediatelly. If it isn't,
481 		// poll often during the first 20ms, otherwise poll lazyly.
482 		if (elapsedTime < 1000)
483 			spin(1);
484 		else if (elapsedTime < 20000)
485 			snooze(1000);
486 		else
487 			snooze(50000);
488 	}
489 
490 	return B_ERROR;
491 }
492 
493 
494 status_t
495 ATAChannel::WaitDataRequest(bool high)
496 {
497 	return Wait(high ? ATA_STATUS_DATA_REQUEST : 0,
498 		high ? 0 : ATA_STATUS_DATA_REQUEST, 0, (high ? 10 : 1) * 1000 * 1000);
499 }
500 
501 
502 status_t
503 ATAChannel::WaitDeviceReady()
504 {
505 	return Wait(ATA_STATUS_DEVICE_READY, 0, 0, 5 * 1000 * 1000);
506 }
507 
508 
509 status_t
510 ATAChannel::WaitForIdle()
511 {
512 	return Wait(0, ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST, 0, 50 * 1000);
513 }
514 
515 
516 status_t
517 ATAChannel::Interrupt(uint8 status)
518 {
519 	SpinLocker locker(fInterruptLock);
520 	if (!fExpectsInterrupt) {
521 		TRACE("interrupt when not expecting transfer\n");
522 		return B_UNHANDLED_INTERRUPT;
523 	}
524 
525 	if ((status & ATA_STATUS_BUSY) != 0) {
526 		TRACE("interrupt while device is busy\n");
527 		return B_UNHANDLED_INTERRUPT;
528 	}
529 
530 	TRACE("interrupt\n");
531 
532 	fInterruptCondition.NotifyAll();
533 	return B_INVOKE_SCHEDULER;
534 }
535 
536 
537 void
538 ATAChannel::PrepareWaitingForInterrupt()
539 {
540 	TRACE_FUNCTION("\n");
541 	InterruptsSpinLocker locker(fInterruptLock);
542 	fExpectsInterrupt = true;
543 	fInterruptCondition.Add(&fInterruptConditionEntry);
544 }
545 
546 
547 status_t
548 ATAChannel::WaitForInterrupt(bigtime_t timeout)
549 {
550 	TRACE_FUNCTION("timeout: %lld\n", timeout);
551 	status_t result = fInterruptConditionEntry.Wait(B_RELATIVE_TIMEOUT,
552 		timeout);
553 
554 	InterruptsSpinLocker locker(fInterruptLock);
555 	fExpectsInterrupt = false;
556 	locker.Unlock();
557 
558 	if (result != B_OK) {
559 		TRACE_ERROR("timeout waiting for interrupt\n");
560 		result = RecoverLostInterrupt();
561 	}
562 
563 	// disable interrupts
564 	_WriteControl(ATA_DEVICE_CONTROL_DISABLE_INTS);
565 
566 	if (result != B_OK) {
567 		return B_TIMED_OUT;
568 	}
569 
570 	return B_OK;
571 }
572 
573 
574 status_t
575 ATAChannel::RecoverLostInterrupt()
576 {
577 	// read status to clear any pending interrupts
578 	uint8 status = _Status();
579 	if (status & (ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST)) {
580 		TRACE_ERROR("RecoverLostInterrupt: device busy, status 0x%02x\n", status);
581 		return B_ERROR;
582 	}
583 	TRACE_ERROR("RecoverLostInterrupt: lost interrupt, status 0x%02x\n", status);
584 	return B_OK;
585 }
586 
587 
588 status_t
589 ATAChannel::SendRequest(ATARequest *request, uint32 flags)
590 {
591 	// TODO: implement this:
592 	// resetting the device here would discard current configuration,
593 	// it's better when the SCSI bus manager requests an external reset.
594 
595 	TRACE_FUNCTION("\n");
596 	ATADevice *device = request->Device();
597 
598 	TRACE("SendRequest status 0x%02x\n", AltStatus());
599 
600 	if (request->UseDMA())
601 		_WriteControl(0); // enable interrupts
602 
603 	if (device->Select() != B_OK) {
604 		TRACE_ERROR("device selection failed\n");
605 		request->SetStatus(SCSI_SEL_TIMEOUT);
606 		_WriteControl(ATA_DEVICE_CONTROL_DISABLE_INTS);
607 		return B_TIMED_OUT;
608 	}
609 
610 	if (WaitForIdle() != B_OK) {
611 		TRACE_ERROR("device selection timeout\n");
612 		request->SetStatus(SCSI_SEL_TIMEOUT);
613 		_WriteControl(ATA_DEVICE_CONTROL_DISABLE_INTS);
614 		return B_TIMED_OUT;
615 	}
616 
617 	if ((flags & ATA_DEVICE_READY_REQUIRED) != 0
618 		&& (AltStatus() & ATA_STATUS_DEVICE_READY) == 0) {
619 		TRACE_ERROR("device ready not set\n");
620 		request->SetStatus(SCSI_SEQUENCE_FAIL);
621 		_WriteControl(ATA_DEVICE_CONTROL_DISABLE_INTS);
622 		return B_ERROR;
623 	}
624 
625 	if (_WriteRegs(device->TaskFile(), device->RegisterMask()
626 			| ATA_MASK_COMMAND) != B_OK) {
627 		TRACE_ERROR("can't write command\n");
628 		request->SetStatus(SCSI_HBA_ERR);
629 		_WriteControl(ATA_DEVICE_CONTROL_DISABLE_INTS);
630 		return B_ERROR;
631 	}
632 
633 	return B_OK;
634 }
635 
636 
637 status_t
638 ATAChannel::FinishRequest(ATARequest *request, uint32 flags, uint8 errorMask)
639 {
640 	TRACE_FUNCTION("\n");
641 	if (flags & ATA_WAIT_FINISH) {
642 		// wait for the device to finish current command (device no longer busy)
643 		status_t result = Wait(0, ATA_STATUS_BUSY, flags, request->Timeout());
644 		if (result != B_OK) {
645 			TRACE_ERROR("timeout waiting for request finish\n");
646 			request->SetStatus(SCSI_CMD_TIMEOUT);
647 			return result;
648 		}
649 	}
650 
651 	ata_task_file *taskFile = request->Device()->TaskFile();
652 
653 	// read status, this also acknowledges pending interrupts
654 	status_t result = _ReadRegs(taskFile, ATA_MASK_STATUS | ATA_MASK_ERROR);
655 	if (result != B_OK) {
656 		TRACE("reading status failed\n");
657 		request->SetStatus(SCSI_SEQUENCE_FAIL);
658 		return result;
659 	}
660 
661 	if (taskFile->read.status & ATA_STATUS_BUSY) {
662 		TRACE("command failed, device still busy\n");
663 		request->SetStatus(SCSI_SEQUENCE_FAIL);
664 		return B_ERROR;
665 	}
666 
667 	if ((flags & ATA_DEVICE_READY_REQUIRED)
668 		&& (taskFile->read.status & ATA_STATUS_DEVICE_READY) == 0) {
669 		TRACE("command failed, device ready required but not set\n");
670 		request->SetStatus(SCSI_SEQUENCE_FAIL);
671 		return B_ERROR;
672 	}
673 
674 	uint8 checkFlags = ATA_STATUS_ERROR;
675 	if (flags & ATA_CHECK_DEVICE_FAULT)
676 		checkFlags |= ATA_STATUS_DEVICE_FAULT;
677 
678 	if ((taskFile->read.status & checkFlags) == 0)
679 		return B_OK;
680 
681 	if ((taskFile->read.error & ATA_ERROR_MEDIUM_CHANGED)
682 			!= ATA_ERROR_MEDIUM_CHANGED) {
683 		TRACE_ERROR("command failed, error bit is set. status 0x%02x, error 0x%02x\n",
684 			taskFile->read.status, taskFile->read.error);
685 	}
686 
687 	uint8 error = taskFile->read.error & errorMask;
688 	if (error & ATA_ERROR_INTERFACE_CRC) {
689 		TRACE_ERROR("interface crc error\n");
690 		request->SetSense(SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_CRC);
691 		return B_ERROR;
692 	}
693 
694 	if (request->IsWrite()) {
695 		if (error & ATA_ERROR_WRITE_PROTECTED) {
696 			request->SetSense(SCSIS_KEY_DATA_PROTECT, SCSIS_ASC_WRITE_PROTECTED);
697 			return B_ERROR;
698 		}
699 	} else {
700 		if (error & ATA_ERROR_UNCORRECTABLE) {
701 			request->SetSense(SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_UNREC_READ_ERR);
702 			return B_ERROR;
703 		}
704 	}
705 
706 	if (error & ATA_ERROR_MEDIUM_CHANGED) {
707 		request->SetSense(SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_MEDIUM_CHANGED);
708 		return B_ERROR;
709 	}
710 
711 	if (error & ATA_ERROR_INVALID_ADDRESS) {
712 		// XXX strange error code, don't really know what it means
713 		request->SetSense(SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_RANDOM_POS_ERROR);
714 		return B_ERROR;
715 	}
716 
717 	if (error & ATA_ERROR_MEDIA_CHANGE_REQUESTED) {
718 		request->SetSense(SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_REMOVAL_REQUESTED);
719 		return B_ERROR;
720 	}
721 
722 	if (error & ATA_ERROR_NO_MEDIA) {
723 		request->SetSense(SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_NO_MEDIUM);
724 		return B_ERROR;
725 	}
726 
727 	if (error & ATA_ERROR_ABORTED) {
728 		request->SetSense(SCSIS_KEY_ABORTED_COMMAND, SCSIS_ASC_NO_SENSE);
729 		return B_ERROR;
730 	}
731 
732 	// either there was no error bit set or it was masked out
733 	request->SetSense(SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE);
734 	return B_ERROR;
735 }
736 
737 
738 status_t
739 ATAChannel::PrepareDMA(ATARequest *request)
740 {
741 	scsi_ccb *ccb = request->CCB();
742 	return fController->prepare_dma(fCookie, ccb->sg_list, ccb->sg_count,
743 		request->IsWrite());
744 }
745 
746 
747 status_t
748 ATAChannel::StartDMA()
749 {
750 	return fController->start_dma(fCookie);
751 }
752 
753 
754 status_t
755 ATAChannel::FinishDMA()
756 {
757 	return fController->finish_dma(fCookie);
758 }
759 
760 
761 status_t
762 ATAChannel::ExecutePIOTransfer(ATARequest *request)
763 {
764 	bigtime_t timeout = request->Timeout();
765 	status_t result = B_OK;
766 	size_t *bytesLeft = request->BytesLeft();
767 	while (*bytesLeft > 0) {
768 		size_t currentLength = MIN(*bytesLeft, request->Device()->BlockSize());
769 		if (request->IsWrite()) {
770 			result = _WritePIOBlock(request, currentLength);
771 			if (result != B_OK) {
772 				TRACE_ERROR("failed to write pio block\n");
773 				break;
774 			}
775 		} else {
776 			result = _ReadPIOBlock(request, currentLength);
777 			if (result != B_OK) {
778 				TRACE_ERROR("failed to read pio block\n");
779 				break;
780 			}
781 		}
782 
783 		*bytesLeft -= currentLength;
784 
785 		if (*bytesLeft > 0) {
786 			// wait for next block to be ready
787 			if (Wait(ATA_STATUS_DATA_REQUEST, ATA_STATUS_BUSY,
788 				ATA_CHECK_ERROR_BIT | ATA_CHECK_DEVICE_FAULT,
789 				timeout) != B_OK) {
790 				TRACE_ERROR("timeout waiting for device to request data\n");
791 				result = B_TIMED_OUT;
792 				break;
793 			}
794 		}
795 	}
796 
797 	if (result == B_OK && WaitDataRequest(false) != B_OK) {
798 		TRACE_ERROR("device still expects data transfer\n");
799 		result = B_ERROR;
800 	}
801 
802 	return result;
803 }
804 
805 
806 status_t
807 ATAChannel::ReadRegs(ATADevice *device)
808 {
809 	return _ReadRegs(device->TaskFile(), device->RegisterMask());
810 }
811 
812 
813 uint8
814 ATAChannel::AltStatus()
815 {
816 	return fController->get_altstatus(fCookie);
817 }
818 
819 
820 status_t
821 ATAChannel::ReadPIO(uint8 *buffer, size_t length)
822 {
823 	return fController->read_pio(fCookie, (uint16 *)buffer,
824 		length / sizeof(uint16), false);
825 }
826 
827 
828 status_t
829 ATAChannel::WritePIO(uint8 *buffer, size_t length)
830 {
831 	return fController->write_pio(fCookie, (uint16 *)buffer,
832 		length / sizeof(uint16), true);
833 }
834 
835 
836 status_t
837 ATAChannel::_ReadRegs(ata_task_file *taskFile, ata_reg_mask mask)
838 {
839 	return fController->read_command_block_regs(fCookie, taskFile, mask);
840 }
841 
842 
843 status_t
844 ATAChannel::_WriteRegs(ata_task_file *taskFile, ata_reg_mask mask)
845 {
846 	return fController->write_command_block_regs(fCookie, taskFile, mask);
847 }
848 
849 
850 uint8
851 ATAChannel::_Status()
852 {
853 	ata_task_file taskFile;
854 	if (_ReadRegs(&taskFile, ATA_MASK_STATUS) != B_OK)
855 		return 0x01;
856 	return taskFile.read.status;
857 }
858 
859 
860 status_t
861 ATAChannel::_WriteControl(uint8 value)
862 {
863 	return fController->write_device_control(fCookie, ATA_DEVICE_CONTROL_BIT3
864 		| value);
865 }
866 
867 
868 void
869 ATAChannel::_FlushAndWait(bigtime_t waitTime)
870 {
871 	AltStatus();
872 	if (waitTime > 100)
873 		snooze(waitTime);
874 	else
875 		spin(waitTime);
876 }
877 
878 
879 status_t
880 ATAChannel::_ReadPIOBlock(ATARequest *request, size_t length)
881 {
882 	uint32 transferred = 0;
883 	status_t result = _TransferPIOBlock(request, length, &transferred);
884 	request->CCB()->data_resid -= transferred;
885 
886 	// if length was odd, there's an extra byte waiting in request->OddByte()
887 	if (request->GetOddByte(NULL)) {
888 		// discard byte and adjust res_id as the extra byte didn't reach the
889 		// buffer
890 		request->CCB()->data_resid++;
891 	}
892 
893 	if (result != B_BUFFER_OVERFLOW)
894 		return result;
895 
896 	// the device returns more data then the buffer can store;
897 	// for ATAPI this is OK - we just discard remaining bytes (there
898 	// is no way to tell ATAPI about that, but we "only" waste time)
899 
900 	// perhaps discarding the extra odd-byte was sufficient
901 	if (transferred >= length)
902 		return B_OK;
903 
904 	TRACE_ERROR("pio read: discarding after %lu bytes\n", transferred);
905 
906 	uint8 buffer[32];
907 	length -= transferred;
908 	// discard 32 bytes at once	(see _WritePIOBlock())
909 	while (length > 0) {
910 		// read extra byte if length is odd (that's the "length + 1")
911 		size_t currentLength = MIN(length + 1, (uint32)sizeof(buffer))
912 			/ sizeof(uint16);
913 		fController->read_pio(fCookie, (uint16 *)buffer, currentLength, false);
914 		length -= currentLength * 2;
915 	}
916 
917 	return B_OK;
918 }
919 
920 
921 status_t
922 ATAChannel::_WritePIOBlock(ATARequest *request, size_t length)
923 {
924 	size_t transferred = 0;
925 	status_t result = _TransferPIOBlock(request, length, &transferred);
926 	request->CCB()->data_resid -= transferred;
927 
928 	if (result != B_BUFFER_OVERFLOW)
929 		return result;
930 
931 	// there may be a pending odd byte - transmit that now
932 	uint8 byte;
933 	if (request->GetOddByte(&byte)) {
934 		uint8 buffer[2];
935 		buffer[0] = byte;
936 		buffer[1] = 0;
937 
938 		fController->write_pio(fCookie, (uint16 *)buffer, 1, false);
939 		request->CCB()->data_resid--;
940 		transferred += 2;
941 	}
942 
943 	// "transferred" may actually be larger then length because the last odd-byte
944 	// is sent together with an extra zero-byte
945 	if (transferred >= length)
946 		return B_OK;
947 
948 	// Ouch! the device asks for data but we haven't got any left.
949 	// Sadly, this behaviour is OK for ATAPI packets, but there is no
950 	// way to tell the device that we don't have any data left;
951 	// only solution is to send zero bytes, though it's BAD
952 	static const uint8 buffer[32] = {};
953 
954 	TRACE_ERROR("pio write: discarding after %lu bytes\n", transferred);
955 
956 	length -= transferred;
957 	while (length > 0) {
958 		// if device asks for odd number of bytes, append an extra byte to
959 		// make length even (this is the "length + 1" term)
960 		size_t currentLength = MIN(length + 1, (int)(sizeof(buffer)))
961 			/ sizeof(uint16);
962 		fController->write_pio(fCookie, (uint16 *)buffer, currentLength, false);
963 		length -= currentLength * 2;
964 	}
965 
966 	return B_BUFFER_OVERFLOW;
967 }
968 
969 
970 status_t
971 ATAChannel::_TransferPIOBlock(ATARequest *request, size_t length,
972 	size_t *transferred)
973 {
974 	// data is usually split up into multiple scatter/gather blocks
975 	while (length > 0) {
976 		if (request->SGElementsLeft() == 0) {
977 			// ups - buffer too small (for ATAPI data, this is OK)
978 			return B_BUFFER_OVERFLOW;
979 		}
980 
981 		// we might have transmitted part of a scatter/entry already
982 		const physical_entry *entry = request->CurrentSGElement();
983 		uint32 offset = request->CurrentSGOffset();
984 		uint32 currentLength = MIN(entry->size - offset, length);
985 
986 		status_t result = _TransferPIOPhysical(request,
987 			entry->address + offset, currentLength, transferred);
988 		if (result != B_OK) {
989 			request->SetSense(SCSIS_KEY_HARDWARE_ERROR,
990 				SCSIS_ASC_INTERNAL_FAILURE);
991 			return result;
992 		}
993 
994 		request->AdvanceSG(currentLength);
995 		length -= currentLength;
996 	}
997 
998 	return B_OK;
999 }
1000 
1001 
1002 // TODO: this should not be necessary, we could directly use virtual addresses
1003 #include <vm/vm.h>
1004 #include <thread.h>
1005 
1006 status_t
1007 ATAChannel::_TransferPIOPhysical(ATARequest *request, addr_t physicalAddress,
1008 	size_t length, size_t *transferred)
1009 {
1010 	// we must split up chunk into B_PAGE_SIZE blocks as we can map only
1011 	// one page into address space at once
1012 	while (length > 0) {
1013 		Thread *thread = thread_get_current_thread();
1014 		thread_pin_to_current_cpu(thread);
1015 
1016 		void *handle;
1017 		addr_t virtualAddress;
1018 		if (vm_get_physical_page_current_cpu(physicalAddress, &virtualAddress,
1019 				&handle) != B_OK) {
1020 			thread_unpin_from_current_cpu(thread);
1021 			// ouch: this should never ever happen
1022 			return B_ERROR;
1023 		}
1024 
1025 		ASSERT(physicalAddress % B_PAGE_SIZE == virtualAddress % B_PAGE_SIZE);
1026 
1027 		// if chunk starts in the middle of a page, we have even less then
1028 		// a page left
1029 		size_t pageLeft = B_PAGE_SIZE - physicalAddress % B_PAGE_SIZE;
1030 		size_t currentLength = MIN(pageLeft, length);
1031 
1032 		status_t result = _TransferPIOVirtual(request, (uint8 *)virtualAddress,
1033 			currentLength, transferred);
1034 
1035 		vm_put_physical_page_current_cpu(virtualAddress, handle);
1036 		thread_unpin_from_current_cpu(thread);
1037 
1038 		if (result != B_OK)
1039 			return result;
1040 
1041 		length -= currentLength;
1042 		physicalAddress += currentLength;
1043 	}
1044 
1045 	return B_OK;
1046 }
1047 
1048 
1049 status_t
1050 ATAChannel::_TransferPIOVirtual(ATARequest *request, uint8 *virtualAddress,
1051 	size_t length, size_t *transferred)
1052 {
1053 	if (request->IsWrite()) {
1054 		// if there is a byte left from last chunk, transmit it together
1055 		// with the first byte of the current chunk (IDE requires 16 bits
1056 		// to be transmitted at once)
1057 		uint8 byte;
1058 		if (request->GetOddByte(&byte)) {
1059 			uint8 buffer[2];
1060 
1061 			buffer[0] = byte;
1062 			buffer[1] = *virtualAddress++;
1063 
1064 			fController->write_pio(fCookie, (uint16 *)buffer, 1, false);
1065 
1066 			length--;
1067 			*transferred += 2;
1068 		}
1069 
1070 		fController->write_pio(fCookie, (uint16 *)virtualAddress, length / 2,
1071 			false);
1072 
1073 		// take care if chunk size was odd, which means that 1 byte remains
1074 		virtualAddress += length & ~1;
1075 		*transferred += length & ~1;
1076 
1077 		if ((length & 1) != 0)
1078 			request->SetOddByte(*virtualAddress);
1079 	} else {
1080 		// if we read one byte too much last time, push it into current chunk
1081 		uint8 byte;
1082 		if (request->GetOddByte(&byte)) {
1083 			*virtualAddress++ = byte;
1084 			length--;
1085 		}
1086 
1087 		fController->read_pio(fCookie, (uint16 *)virtualAddress, length / 2,
1088 			false);
1089 
1090 		// take care of odd chunk size;
1091 		// in this case we read 1 byte to few!
1092 		virtualAddress += length & ~1;
1093 		*transferred += length & ~1;
1094 
1095 		if ((length & 1) != 0) {
1096 			uint8 buffer[2];
1097 
1098 			// now read the missing byte; as we have to read 2 bytes at once,
1099 			// we'll read one byte too much
1100 			fController->read_pio(fCookie, (uint16 *)buffer, 1, false);
1101 
1102 			*virtualAddress = buffer[0];
1103 			request->SetOddByte(buffer[1]);
1104 
1105 			*transferred += 2;
1106 		}
1107 	}
1108 
1109 	return B_OK;
1110 }
1111