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