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