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
13ATAChannel::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
86ATAChannel::~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
98status_t
99ATAChannel::InitCheck()
100{
101	return fStatus;
102}
103
104
105void
106ATAChannel::SetBus(scsi_bus bus)
107{
108	fSCSIBus = bus;
109}
110
111
112bool
113ATAChannel::_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
144status_t
145ATAChannel::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
253void
254ATAChannel::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
279void
280ATAChannel::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
293status_t
294ATAChannel::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
335status_t
336ATAChannel::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
345status_t
346ATAChannel::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
371uint8
372ATAChannel::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
388status_t
389ATAChannel::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
419status_t
420ATAChannel::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
488status_t
489ATAChannel::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
496status_t
497ATAChannel::WaitDeviceReady()
498{
499	return Wait(ATA_STATUS_DEVICE_READY, 0, 0, 5 * 1000 * 1000);
500}
501
502
503status_t
504ATAChannel::WaitForIdle()
505{
506	return Wait(0, ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST, 0, 50 * 1000);
507}
508
509
510status_t
511ATAChannel::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
531void
532ATAChannel::PrepareWaitingForInterrupt()
533{
534	TRACE_FUNCTION("\n");
535	InterruptsSpinLocker locker(fInterruptLock);
536	fExpectsInterrupt = true;
537	fInterruptCondition.Add(&fInterruptConditionEntry);
538}
539
540
541status_t
542ATAChannel::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
568status_t
569ATAChannel::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
582status_t
583ATAChannel::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
631status_t
632ATAChannel::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
732status_t
733ATAChannel::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
741status_t
742ATAChannel::StartDMA()
743{
744	return fController->start_dma(fCookie);
745}
746
747
748status_t
749ATAChannel::FinishDMA()
750{
751	return fController->finish_dma(fCookie);
752}
753
754
755status_t
756ATAChannel::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
800status_t
801ATAChannel::ReadRegs(ATADevice *device)
802{
803	return _ReadRegs(device->TaskFile(), device->RegisterMask());
804}
805
806
807uint8
808ATAChannel::AltStatus()
809{
810	return fController->get_altstatus(fCookie);
811}
812
813
814status_t
815ATAChannel::ReadPIO(uint8 *buffer, size_t length)
816{
817	return fController->read_pio(fCookie, (uint16 *)buffer,
818		length / sizeof(uint16), false);
819}
820
821
822status_t
823ATAChannel::WritePIO(uint8 *buffer, size_t length)
824{
825	return fController->write_pio(fCookie, (uint16 *)buffer,
826		length / sizeof(uint16), true);
827}
828
829
830status_t
831ATAChannel::_ReadRegs(ata_task_file *taskFile, ata_reg_mask mask)
832{
833	return fController->read_command_block_regs(fCookie, taskFile, mask);
834}
835
836
837status_t
838ATAChannel::_WriteRegs(ata_task_file *taskFile, ata_reg_mask mask)
839{
840	return fController->write_command_block_regs(fCookie, taskFile, mask);
841}
842
843
844uint8
845ATAChannel::_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
854status_t
855ATAChannel::_WriteControl(uint8 value)
856{
857	return fController->write_device_control(fCookie, ATA_DEVICE_CONTROL_BIT3
858		| value);
859}
860
861
862void
863ATAChannel::_FlushAndWait(bigtime_t waitTime)
864{
865	AltStatus();
866	if (waitTime > 100)
867		snooze(waitTime);
868	else
869		spin(waitTime);
870}
871
872
873status_t
874ATAChannel::_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
915status_t
916ATAChannel::_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
964status_t
965ATAChannel::_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
1000status_t
1001ATAChannel::_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
1043status_t
1044ATAChannel::_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