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