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