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