xref: /haiku/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp (revision 6f80a9801fedbe7355c4360bd204ba746ec3ec2d)
1 /*
2  * Copyright 2008-2021 Haiku, Inc. All rights reserved.
3  * Copyright 2007-2009, Marcus Overhagen. All rights reserved.
4  * Distributed under the terms of the MIT License.
5  *
6  * Authors:
7  *		Axel Dörfler, axeld@pinc-software.de
8  *		Michael Lotz, mmlr@mlotz.ch
9  *		Alexander von Gluck IV, kallisti5@unixzen.com
10  *		David Sebek, dasebek@gmail.com
11  */
12 
13 
14 #include "ahci_port.h"
15 
16 #include <new>
17 #include <stdio.h>
18 #include <string.h>
19 
20 #include <ByteOrder.h>
21 #include <KernelExport.h>
22 
23 #include <ATACommands.h>
24 #include <ATAInfoBlock.h>
25 #include <AutoDeleter.h>
26 
27 #include "ahci_controller.h"
28 #include "ahci_tracing.h"
29 #include "sata_request.h"
30 #include "scsi_cmds.h"
31 #include "util.h"
32 
33 
34 //#define TRACE_AHCI
35 #ifdef TRACE_AHCI
36 #	define TRACE(a...) dprintf("ahci: " a)
37 #else
38 #	define TRACE(a...)
39 #endif
40 
41 #define ERROR(a...) dprintf("ahci: " a)
42 //#define FLOW(a...)	dprintf("ahci: " a)
43 //#define RWTRACE(a...) dprintf("ahci: " a)
44 #define FLOW(a...)
45 #define RWTRACE(a...)
46 
47 
48 #define INQUIRY_BASE_LENGTH 36
49 
50 
51 // DATA SET MANAGEMENT command limits
52 
53 #define DSM_MAX_COUNT_48			UINT16_MAX
54 	// max number of 512-byte blocks (48-bit command)
55 #define DSM_MAX_COUNT_28			UINT8_MAX
56 	// max number of 512-byte blocks (28-bit command)
57 #define DSM_RANGE_BLOCK_ENTRIES		64
58 	// max entries in a 512-byte block (512 / 8)
59 #define DSM_MAX_RANGE_VALUE			UINT16_C(0xffff)
60 #define DSM_MAX_LBA_VALUE			UINT64_C(0xffffffffffff)
61 
62 
63 AHCIPort::AHCIPort(AHCIController* controller, int index)
64 	:
65 	fController(controller),
66 	fIndex(index),
67 	fRegs(&controller->fRegs->port[index]),
68 	fArea(-1),
69 	fCommandsActive(0),
70 	fRequestSem(-1),
71 	fResponseSem(-1),
72 	fDevicePresent(false),
73 	fUse48BitCommands(false),
74 	fSectorSize(0),
75 	fSectorCount(0),
76 	fIsATAPI(false),
77 	fTestUnitReadyActive(false),
78 	fPortReset(false),
79 	fError(false),
80 	fTrimSupported(false),
81 	fTrimReturnsZeros(false),
82 	fMaxTrimRangeBlocks(0)
83 {
84 	B_INITIALIZE_SPINLOCK(&fSpinlock);
85 	fRequestSem = create_sem(1, "ahci request");
86 	fResponseSem = create_sem(0, "ahci response");
87 }
88 
89 
90 AHCIPort::~AHCIPort()
91 {
92 	delete_sem(fRequestSem);
93 	delete_sem(fResponseSem);
94 }
95 
96 
97 status_t
98 AHCIPort::Init1()
99 {
100 	TRACE("AHCIPort::Init1 port %d\n", fIndex);
101 
102 	size_t size = sizeof(command_list_entry) * COMMAND_LIST_ENTRY_COUNT
103 		+ sizeof(fis) + sizeof(command_table)
104 		+ sizeof(prd) * PRD_TABLE_ENTRY_COUNT;
105 
106 	char* virtAddr;
107 	phys_addr_t physAddr;
108 	char name[32];
109 	snprintf(name, sizeof(name), "AHCI port %d", fIndex);
110 
111 	fArea = alloc_mem((void**)&virtAddr, &physAddr, size,
112 		B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, name);
113 	if (fArea < B_OK) {
114 		TRACE("failed allocating memory for port %d\n", fIndex);
115 		return fArea;
116 	}
117 	memset(virtAddr, 0, size);
118 
119 	fCommandList = (command_list_entry*)virtAddr;
120 	virtAddr += sizeof(command_list_entry) * COMMAND_LIST_ENTRY_COUNT;
121 	fFIS = (fis*)virtAddr;
122 	virtAddr += sizeof(fis);
123 	fCommandTable = (command_table*)virtAddr;
124 	virtAddr += sizeof(command_table);
125 	fPRDTable = (prd*)virtAddr;
126 	TRACE("PRD table is at %p\n", fPRDTable);
127 
128 	fRegs->clb  = LO32(physAddr);
129 	fRegs->clbu = HI32(physAddr);
130 	physAddr += sizeof(command_list_entry) * COMMAND_LIST_ENTRY_COUNT;
131 	fRegs->fb   = LO32(physAddr);
132 	fRegs->fbu  = HI32(physAddr);
133 	physAddr += sizeof(fis);
134 	fCommandList[0].ctba  = LO32(physAddr);
135 	fCommandList[0].ctbau = HI32(physAddr);
136 	// prdt follows after command table
137 
138 	// disable transitions to partial or slumber state
139 	fRegs->sctl |= (SCTL_PORT_IPM_NOPART | SCTL_PORT_IPM_NOSLUM);
140 
141 	// clear IRQ status bits
142 	fRegs->is = fRegs->is;
143 
144 	// clear error bits
145 	_ClearErrorRegister();
146 
147 	// power up device
148 	fRegs->cmd |= PORT_CMD_POD;
149 
150 	// spin up device
151 	fRegs->cmd |= PORT_CMD_SUD;
152 
153 	// activate link
154 	fRegs->cmd = (fRegs->cmd & ~PORT_CMD_ICC_MASK) | PORT_CMD_ICC_ACTIVE;
155 
156 	// enable FIS receive (enabled when fb set, only to be disabled when unset)
157 	fRegs->cmd |= PORT_CMD_FRE;
158 
159 	FlushPostedWrites();
160 
161 	return B_OK;
162 }
163 
164 
165 // called with global interrupts enabled
166 status_t
167 AHCIPort::Init2()
168 {
169 	TRACE("AHCIPort::Init2 port %d\n", fIndex);
170 
171 	// enable port
172 	Enable();
173 
174 	// enable interrupts
175 	fRegs->ie = PORT_INT_MASK;
176 
177 	FlushPostedWrites();
178 
179 	// reset port and probe info
180 	ResetDevice();
181 
182 	DumpHBAState();
183 
184 	TRACE("%s: port %d, device %s\n", __func__, fIndex,
185 		fDevicePresent ? "present" : "absent");
186 
187 	return B_OK;
188 }
189 
190 
191 void
192 AHCIPort::Uninit()
193 {
194 	TRACE("AHCIPort::Uninit port %d\n", fIndex);
195 
196 	// Spec v1.3.1, §10.3.2 - Shut down port before unsetting FRE
197 
198 	// shutdown the port
199 	if (!Disable()) {
200 		ERROR("%s: port %d error, unable to shutdown before FRE clear!\n",
201 			__func__, fIndex);
202 		return;
203 	}
204 
205 	// Clear FRE and wait for completion
206 	fRegs->cmd &= ~PORT_CMD_FRE;
207 	if (wait_until_clear(&fRegs->cmd, PORT_CMD_FR, 500000) < B_OK)
208 		ERROR("%s: port %d error FIS rx still running\n", __func__, fIndex);
209 
210 	// disable interrupts
211 	fRegs->ie = 0;
212 
213 	// clear pending interrupts
214 	fRegs->is = fRegs->is;
215 
216 	// invalidate DMA addresses
217 	fRegs->clb  = 0;
218 	fRegs->clbu = 0;
219 	fRegs->fb   = 0;
220 	fRegs->fbu  = 0;
221 
222 	delete_area(fArea);
223 }
224 
225 
226 void
227 AHCIPort::ResetDevice()
228 {
229 	// perform a hard reset
230 	if (PortReset() != B_OK) {
231 		ERROR("%s: port %d unable to hard reset device\n", __func__, fIndex);
232 		return;
233 	}
234 
235 	if (wait_until_set(&fRegs->ssts, SSTS_PORT_DET_NODEV, 100000) < B_OK)
236 		TRACE("AHCIPort::ResetDevice port %d no device detected\n", fIndex);
237 
238 	_ClearErrorRegister();
239 
240 	if (fRegs->ssts & SSTS_PORT_DET_NOPHY) {
241 		if (wait_until_set(&fRegs->ssts, 0x3, 500000) < B_OK) {
242 			TRACE("AHCIPort::ResetDevice port %d device present but no phy "
243 				"communication\n", fIndex);
244 		}
245 	}
246 
247 	_ClearErrorRegister();
248 }
249 
250 
251 status_t
252 AHCIPort::PortReset()
253 {
254 	TRACE("AHCIPort::PortReset port %d\n", fIndex);
255 
256 	if (!Disable()) {
257 		ERROR("%s: port %d unable to shutdown!\n", __func__, fIndex);
258 		return B_ERROR;
259 	}
260 
261 	_ClearErrorRegister();
262 
263 	// Wait for BSY and DRQ to clear (idle port)
264 	if (wait_until_clear(&fRegs->tfd, ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST,
265 		1000000) < B_OK) {
266 		// If we can't clear busy, do a full comreset
267 
268 		// Spec v1.3.1, §10.4.2 Port Reset
269 		// Physical comm between HBA and port disabled. More Intrusive
270 		ERROR("%s: port %d undergoing COMRESET\n", __func__, fIndex);
271 
272 		// Notice we're throwing out all other control flags.
273 		fRegs->sctl = (SSTS_PORT_IPM_ACTIVE | SSTS_PORT_IPM_PARTIAL
274 			| SCTL_PORT_DET_INIT);
275 		FlushPostedWrites();
276 		spin(1100);
277 		// You must wait 1ms at minimum
278 		fRegs->sctl = (fRegs->sctl & ~HBA_PORT_DET_MASK) | SCTL_PORT_DET_NOINIT;
279 		FlushPostedWrites();
280 	}
281 
282 	Enable();
283 
284 	if (wait_until_set(&fRegs->ssts, SSTS_PORT_DET_PRESENT, 500000) < B_OK) {
285 		TRACE("%s: port %d: no device detected\n", __func__, fIndex);
286 		fDevicePresent = false;
287 		return B_OK;
288 	}
289 
290 	return Probe();
291 }
292 
293 
294 status_t
295 AHCIPort::Probe()
296 {
297 	if ((fRegs->tfd & 0xff) == 0xff)
298 		snooze(200000);
299 
300 	if ((fRegs->tfd & 0xff) == 0xff) {
301 		TRACE("%s: port %d: invalid task file status 0xff\n", __func__,
302 			fIndex);
303 		return B_ERROR;
304 	}
305 
306 	if (!fTestUnitReadyActive) {
307 		switch (fRegs->ssts & HBA_PORT_SPD_MASK) {
308 			case 0x10:
309 				ERROR("%s: port %d link speed 1.5Gb/s\n", __func__, fIndex);
310 				break;
311 			case 0x20:
312 				ERROR("%s: port %d link speed 3.0Gb/s\n", __func__, fIndex);
313 				break;
314 			case 0x30:
315 				ERROR("%s: port %d link speed 6.0Gb/s\n", __func__, fIndex);
316 				break;
317 			default:
318 				ERROR("%s: port %d link speed unrestricted\n", __func__, fIndex);
319 				break;
320 		}
321 	}
322 
323 	wait_until_clear(&fRegs->tfd, ATA_STATUS_BUSY, 31000000);
324 
325 	fDevicePresent = (fRegs->ssts & HBA_PORT_DET_MASK) == SSTS_PORT_DET_PRESENT;
326 	fIsATAPI = fRegs->sig == SATA_SIG_ATAPI;
327 
328 	if (fIsATAPI)
329 		fRegs->cmd |= PORT_CMD_ATAPI;
330 	else
331 		fRegs->cmd &= ~PORT_CMD_ATAPI;
332 	FlushPostedWrites();
333 
334 	TRACE("device signature 0x%08" B_PRIx32 " (%s)\n", fRegs->sig,
335 		fRegs->sig == SATA_SIG_ATAPI ? "ATAPI" : fRegs->sig == SATA_SIG_ATA
336 			? "ATA" : "unknown");
337 
338 	return B_OK;
339 }
340 
341 
342 void
343 AHCIPort::DumpD2HFis()
344 {
345 	TRACE("D2H FIS:\n");
346 	TRACE("  DW0  %02x %02x %02x %02x\n", fFIS->rfis[3], fFIS->rfis[2],
347 		fFIS->rfis[1], fFIS->rfis[0]);
348 	TRACE("  DW1  %02x %02x %02x %02x\n", fFIS->rfis[7], fFIS->rfis[6],
349 		fFIS->rfis[5], fFIS->rfis[4]);
350 	TRACE("  DW2  %02x %02x %02x %02x\n", fFIS->rfis[11], fFIS->rfis[10],
351 		fFIS->rfis[9], fFIS->rfis[8]);
352 	TRACE("  DW3  %02x %02x %02x %02x\n", fFIS->rfis[15], fFIS->rfis[14],
353 		fFIS->rfis[13], fFIS->rfis[12]);
354 	TRACE("  DW4  %02x %02x %02x %02x\n", fFIS->rfis[19], fFIS->rfis[18],
355 		fFIS->rfis[17], fFIS->rfis[16]);
356 }
357 
358 
359 void
360 AHCIPort::DumpHBAState()
361 {
362 	TRACE("Port %d state:\n", fIndex);
363 	TRACE("  ie   0x%08" B_PRIx32 "\n", fRegs->ie);
364 	TRACE("  is   0x%08" B_PRIx32 "\n", fRegs->is);
365 	TRACE("  cmd  0x%08" B_PRIx32 "\n", fRegs->cmd);
366 	TRACE("  ssts 0x%08" B_PRIx32 "\n", fRegs->ssts);
367 	TRACE("  sctl 0x%08" B_PRIx32 "\n", fRegs->sctl);
368 	TRACE("  serr 0x%08" B_PRIx32 "\n", fRegs->serr);
369 	TRACE("  sact 0x%08" B_PRIx32 "\n", fRegs->sact);
370 	TRACE("  tfd  0x%08" B_PRIx32 "\n", fRegs->tfd);
371 }
372 
373 
374 void
375 AHCIPort::Interrupt()
376 {
377 	uint32 is = fRegs->is;
378 	fRegs->is = is; // clear interrupts
379 
380 	if (is & PORT_INT_ERROR) {
381 		InterruptErrorHandler(is);
382 		return;
383 	}
384 
385 	uint32 ci = fRegs->ci;
386 
387 	RWTRACE("[%lld] %ld AHCIPort::Interrupt port %d, fCommandsActive 0x%08"
388 		B_PRIx32 ", is 0x%08" B_PRIx32 ", ci 0x%08" B_PRIx32 "\n",
389 		system_time(), find_thread(NULL), fIndex, fCommandsActive, is, ci);
390 
391 	acquire_spinlock(&fSpinlock);
392 	if ((fCommandsActive & 1) && !(ci & 1)) {
393 		fCommandsActive &= ~1;
394 		release_sem_etc(fResponseSem, 1, B_DO_NOT_RESCHEDULE);
395 	}
396 	release_spinlock(&fSpinlock);
397 }
398 
399 
400 void
401 AHCIPort::InterruptErrorHandler(uint32 is)
402 {
403 	TRACE("AHCIPort::InterruptErrorHandler port %d, fCommandsActive 0x%08"
404 		B_PRIx32 ", is 0x%08" B_PRIx32 ", ci 0x%08" B_PRIx32 "\n", fIndex,
405 		fCommandsActive, is, fRegs->ci);
406 	TRACE("ssts 0x%08" B_PRIx32 "\n", fRegs->ssts);
407 	TRACE("sctl 0x%08" B_PRIx32 "\n", fRegs->sctl);
408 	TRACE("serr 0x%08" B_PRIx32 "\n", fRegs->serr);
409 	TRACE("sact 0x%08" B_PRIx32 "\n", fRegs->sact);
410 
411 	// read and clear SError
412 	_ClearErrorRegister();
413 
414 	if (is & PORT_INT_TFE) {
415 		TRACE("Task File Error\n");
416 
417 		fPortReset = true;
418 		fError = true;
419 	}
420 	if (is & PORT_INT_HBF) {
421 		ERROR("Host Bus Fatal Error\n");
422 		fPortReset = true;
423 		fError = true;
424 	}
425 	if (is & PORT_INT_HBD) {
426 		ERROR("Host Bus Data Error\n");
427 		fPortReset = true;
428 		fError = true;
429 	}
430 	if (is & PORT_INT_IF) {
431 		ERROR("Interface Fatal Error\n");
432 		fPortReset = true;
433 		fError = true;
434 	}
435 	if (is & PORT_INT_INF) {
436 		TRACE("Interface Non Fatal Error\n");
437 	}
438 	if (is & PORT_INT_OF) {
439 		TRACE("Overflow\n");
440 		fPortReset = true;
441 		fError = true;
442 	}
443 	if (is & PORT_INT_IPM) {
444 		TRACE("Incorrect Port Multiplier Status\n");
445 	}
446 	if (is & PORT_INT_PRC) {
447 		TRACE("PhyReady Change\n");
448 		//fPortReset = true;
449 	}
450 	if (is & PORT_INT_PC) {
451 		TRACE("Port Connect Change\n");
452 		// Unsolicited when we had a port connect change without us requesting
453 		// Spec v1.3, §6.2.2.3 Recovery of Unsolicited COMINIT
454 
455 		// XXX: This shouldn't be needed here... but we can loop without it
456 		//_ClearErrorRegister();
457 	}
458 	if (is & PORT_INT_UF) {
459 		TRACE("Unknown FIS\n");
460 		fPortReset = true;
461 	}
462 
463 	if (fError) {
464 		acquire_spinlock(&fSpinlock);
465 		if ((fCommandsActive & 1)) {
466 			fCommandsActive &= ~1;
467 			release_sem_etc(fResponseSem, 1, B_DO_NOT_RESCHEDULE);
468 		}
469 		release_spinlock(&fSpinlock);
470 	}
471 }
472 
473 
474 status_t
475 AHCIPort::FillPrdTable(volatile prd* prdTable, int* prdCount, int prdMax,
476 	const void* data, size_t dataSize)
477 {
478 	int maxEntries = prdMax + 1;
479 	physical_entry entries[maxEntries];
480 	uint32 entriesUsed = maxEntries;
481 
482 	status_t status = get_memory_map_etc(B_CURRENT_TEAM, data, dataSize,
483 		entries, &entriesUsed);
484 	if (status != B_OK) {
485 		ERROR("%s: get_memory_map() failed: %s\n", __func__, strerror(status));
486 		return B_ERROR;
487 	}
488 
489 	return FillPrdTable(prdTable, prdCount, prdMax, entries, entriesUsed,
490 		dataSize);
491 }
492 
493 
494 status_t
495 AHCIPort::FillPrdTable(volatile prd* prdTable, int* prdCount, int prdMax,
496 	const physical_entry* sgTable, int sgCount, size_t dataSize)
497 {
498 	*prdCount = 0;
499 	while (sgCount > 0 && dataSize > 0) {
500 		size_t size = min_c(sgTable->size, dataSize);
501 		phys_addr_t address = sgTable->address;
502 		T_PORT(AHCIPortPrdTable(fController, fIndex, address, size));
503 		FLOW("FillPrdTable: sg-entry addr %#" B_PRIxPHYSADDR ", size %lu\n",
504 			address, size);
505 		if (address & 1) {
506 			ERROR("AHCIPort::FillPrdTable: data alignment error\n");
507 			return B_ERROR;
508 		}
509 		dataSize -= size;
510 		while (size > 0) {
511 			size_t bytes = min_c(size, PRD_MAX_DATA_LENGTH);
512 			if (*prdCount == prdMax) {
513 				ERROR("AHCIPort::FillPrdTable: prd table exhausted\n");
514 				return B_ERROR;
515 			}
516 			FLOW("FillPrdTable: prd-entry %u, addr %p, size %lu\n",
517 				*prdCount, address, bytes);
518 
519 			prdTable->dba = LO32(address);
520 			prdTable->dbau = HI32(address);
521 			prdTable->res = 0;
522 			prdTable->dbc = bytes - 1;
523 			*prdCount += 1;
524 			prdTable++;
525 			address = address + bytes;
526 			size -= bytes;
527 		}
528 		sgTable++;
529 		sgCount--;
530 	}
531 	if (*prdCount == 0) {
532 		ERROR("%s: count is 0\n", __func__);
533 		return B_ERROR;
534 	}
535 	if (dataSize > 0) {
536 		ERROR("AHCIPort::FillPrdTable: sg table %ld bytes too small\n",
537 			dataSize);
538 		return B_ERROR;
539 	}
540 	return B_OK;
541 }
542 
543 
544 void
545 AHCIPort::StartTransfer()
546 {
547 	acquire_sem(fRequestSem);
548 }
549 
550 
551 status_t
552 AHCIPort::WaitForTransfer(int* tfd, bigtime_t timeout)
553 {
554 	status_t result = acquire_sem_etc(fResponseSem, 1, B_RELATIVE_TIMEOUT,
555 		timeout);
556 	if (result < B_OK) {
557 		cpu_status cpu = disable_interrupts();
558 		acquire_spinlock(&fSpinlock);
559 		fCommandsActive &= ~1;
560 		release_spinlock(&fSpinlock);
561 		restore_interrupts(cpu);
562 
563 		result = B_TIMED_OUT;
564 	} else if (fError) {
565 		*tfd = fRegs->tfd;
566 		result = B_ERROR;
567 		fError = false;
568 	} else {
569 		*tfd = fRegs->tfd;
570 	}
571 	return result;
572 }
573 
574 
575 void
576 AHCIPort::FinishTransfer()
577 {
578 	release_sem(fRequestSem);
579 }
580 
581 
582 void
583 AHCIPort::ScsiTestUnitReady(scsi_ccb* request)
584 {
585 	TRACE("AHCIPort::ScsiTestUnitReady port %d\n", fIndex);
586 	request->subsys_status = SCSI_REQ_CMP;
587 	gSCSI->finished(request, 1);
588 }
589 
590 
591 void
592 AHCIPort::ScsiVPDInquiry(scsi_ccb* request, ata_device_infoblock* ataData)
593 {
594 	TRACE("AHCIPort::ScsiVPDInquiry port %d\n", fIndex);
595 
596 	const scsi_cmd_inquiry* cmd = (const scsi_cmd_inquiry*)request->cdb;
597 
598 	size_t vpdDataLength = 0;
599 	status_t transactionResult = B_ERROR;
600 
601 	switch (cmd->page_code) {
602 		case SCSI_PAGE_SUPPORTED_VPD:
603 		{
604 			// supported pages should be in ascending numerical order
605 			const uint8 supportedPages[] = {
606 				SCSI_PAGE_SUPPORTED_VPD,
607 				SCSI_PAGE_BLOCK_LIMITS,
608 				SCSI_PAGE_LB_PROVISIONING
609 			};
610 
611 			const size_t bufferLength = sizeof(scsi_page_list)
612 				+ sizeof(supportedPages) - 1;
613 			uint8 buffer[bufferLength];
614 
615 			scsi_page_list* vpdPageData = (scsi_page_list*)buffer;
616 			memset(vpdPageData, 0, bufferLength);
617 
618 			vpdPageData->page_code = cmd->page_code;
619 			// Our supported pages
620 			vpdPageData->page_length = sizeof(supportedPages);
621 			memcpy(vpdPageData->pages, supportedPages, sizeof(supportedPages));
622 
623 			uint8 allocationLength = cmd->allocation_length;
624 			vpdDataLength = min_c(allocationLength, bufferLength);
625 
626 			transactionResult = sg_memcpy(request->sg_list, request->sg_count,
627 				vpdPageData, vpdDataLength);
628 			break;
629 		}
630 		case SCSI_PAGE_BLOCK_LIMITS:
631 		{
632 			scsi_page_block_limits vpdPageData;
633 			memset(&vpdPageData, 0, sizeof(vpdPageData));
634 
635 			vpdPageData.page_code = cmd->page_code;
636 			vpdPageData.page_length
637 				= B_HOST_TO_BENDIAN_INT16(sizeof(vpdPageData) - 4);
638 			if (fTrimSupported) {
639 				// We can handle anything as long as we have enough memory
640 				// (UNMAP structure can realistically be max. 65528 bytes)
641 				vpdPageData.max_unmap_lba_count
642 					= B_HOST_TO_BENDIAN_INT32(UINT32_MAX);
643 				vpdPageData.max_unmap_blk_count
644 					= B_HOST_TO_BENDIAN_INT32(UINT32_MAX);
645 			}
646 
647 			uint8 allocationLength = cmd->allocation_length;
648 			vpdDataLength = min_c(allocationLength, sizeof(vpdPageData));
649 
650 			transactionResult = sg_memcpy(request->sg_list, request->sg_count,
651 				&vpdPageData, vpdDataLength);
652 			break;
653 		}
654 		case SCSI_PAGE_LB_PROVISIONING:
655 		{
656 			scsi_page_lb_provisioning vpdPageData;
657 			memset(&vpdPageData, 0, sizeof(vpdPageData));
658 
659 			vpdPageData.page_code = cmd->page_code;
660 			vpdPageData.page_length
661 				= B_HOST_TO_BENDIAN_INT16(sizeof(vpdPageData) - 4);
662 			vpdPageData.lbpu = fTrimSupported;
663 			vpdPageData.lbprz = fTrimReturnsZeros;
664 
665 			uint8 allocationLength = cmd->allocation_length;
666 			vpdDataLength = min_c(allocationLength, sizeof(vpdPageData));
667 
668 			transactionResult = sg_memcpy(request->sg_list, request->sg_count,
669 				&vpdPageData, vpdDataLength);
670 			break;
671 		}
672 		case SCSI_PAGE_USN:
673 		case SCSI_PAGE_BLOCK_DEVICE_CHARS:
674 		case SCSI_PAGE_REFERRALS:
675 			ERROR("VPD AHCI page %d not yet implemented!\n",
676 				cmd->page_code);
677 			//request->subsys_status = SCSI_REQ_CMP;
678 			request->subsys_status = SCSI_REQ_ABORTED;
679 			return;
680 		default:
681 			ERROR("unknown VPD page code!\n");
682 			request->subsys_status = SCSI_REQ_ABORTED;
683 			return;
684 	}
685 
686 	if (transactionResult < B_OK) {
687 		request->subsys_status = SCSI_DATA_RUN_ERR;
688 	} else {
689 		request->subsys_status = SCSI_REQ_CMP;
690 		request->data_resid = request->data_length
691 			- vpdDataLength;
692 	}
693 }
694 
695 
696 void
697 AHCIPort::ScsiInquiry(scsi_ccb* request)
698 {
699 	TRACE("AHCIPort::ScsiInquiry port %d\n", fIndex);
700 
701 	const scsi_cmd_inquiry* cmd = (const scsi_cmd_inquiry*)request->cdb;
702 	scsi_res_inquiry scsiData;
703 	ata_device_infoblock ataData;
704 
705 	ASSERT(sizeof(ataData) == 512);
706 
707 	if (cmd->evpd) {
708 		TRACE("VPD inquiry page 0x%X\n", cmd->page_code);
709 		if (!request->data || request->data_length == 0) {
710 			ERROR("invalid VPD request\n");
711 			request->subsys_status = SCSI_REQ_ABORTED;
712 			gSCSI->finished(request, 1);
713 			return;
714 		}
715 	} else if (cmd->page_code) {
716 		// page_code without evpd is invalid per SCSI spec
717 		ERROR("page code 0x%X on non-VPD request\n", cmd->page_code);
718 		request->subsys_status = SCSI_REQ_ABORTED;
719 		request->device_status = SCSI_STATUS_CHECK_CONDITION;
720 		// TODO: Sense ILLEGAL REQUEST + INVALID FIELD IN CDB?
721 		gSCSI->finished(request, 1);
722 		return;
723 	} else if (request->data_length < INQUIRY_BASE_LENGTH) {
724 		ERROR("invalid request %" B_PRIu32 "\n", request->data_length);
725 		request->subsys_status = SCSI_REQ_ABORTED;
726 		gSCSI->finished(request, 1);
727 		return;
728 	}
729 
730 	memset(&ataData, 0, sizeof(ataData));
731 
732 	sata_request sreq;
733 	sreq.SetData(&ataData, sizeof(ataData));
734 	sreq.SetATACommand(fIsATAPI
735 		? ATA_COMMAND_IDENTIFY_PACKET_DEVICE : ATA_COMMAND_IDENTIFY_DEVICE);
736 	ExecuteSataRequest(&sreq);
737 	sreq.WaitForCompletion();
738 
739 	if ((sreq.CompletionStatus() & ATA_STATUS_ERROR) != 0) {
740 		ERROR("identify device failed\n");
741 		request->subsys_status = SCSI_REQ_CMP_ERR;
742 		gSCSI->finished(request, 1);
743 		return;
744 	}
745 
746 	if (cmd->evpd) {
747 		// Simulate SCSI VPD data.
748 		ScsiVPDInquiry(request, &ataData);
749 		gSCSI->finished(request, 1);
750 		return;
751 	}
752 
753 /*
754 	uint8* data = (uint8*)&ataData;
755 	for (int i = 0; i < 512; i += 8) {
756 		TRACE("  %02x %02x %02x %02x %02x %02x %02x %02x\n", data[i], data[i+1],
757 			data[i+2], data[i+3], data[i+4], data[i+5], data[i+6], data[i+7]);
758 	}
759 */
760 
761 	memset(&scsiData, 0, sizeof(scsiData));
762 
763 	scsiData.device_type = fIsATAPI
764 		? ataData.word_0.atapi.command_packet_set : scsi_dev_direct_access;
765 	scsiData.device_qualifier = scsi_periph_qual_connected;
766 	scsiData.device_type_modifier = 0;
767 	scsiData.removable_medium = ataData.word_0.ata.removable_media_device;
768 	scsiData.ansi_version = 5;
769 		// Set the version to SPC-3 so that scsi_periph
770 		// uses READ CAPACITY (16) and attempts to read VPD pages
771 	scsiData.ecma_version = 0;
772 	scsiData.iso_version = 0;
773 	scsiData.response_data_format = 2;
774 	scsiData.term_iop = false;
775 	scsiData.additional_length = sizeof(scsi_res_inquiry) - 4;
776 	scsiData.soft_reset = false;
777 	scsiData.cmd_queue = false;
778 	scsiData.linked = false;
779 	scsiData.sync = false;
780 	scsiData.write_bus16 = true;
781 	scsiData.write_bus32 = false;
782 	scsiData.relative_address = false;
783 
784 	if (!fIsATAPI) {
785 		fSectorCount = ataData.SectorCount(fUse48BitCommands, true);
786 		fSectorSize = ataData.SectorSize();
787 		fTrimSupported = ataData.data_set_management_support;
788 		fTrimReturnsZeros = ataData.supports_read_zero_after_trim;
789 		fMaxTrimRangeBlocks = B_LENDIAN_TO_HOST_INT16(
790 			ataData.max_data_set_management_lba_range_blocks);
791 		TRACE("lba %d, lba48 %d, fUse48BitCommands %d, sectors %" B_PRIu32
792 			", sectors48 %" B_PRIu64 ", size %" B_PRIu64 "\n",
793 			ataData.dma_supported != 0, ataData.lba48_supported != 0,
794 			fUse48BitCommands, ataData.lba_sector_count,
795 			ataData.lba48_sector_count, fSectorCount * fSectorSize);
796 		if (fTrimSupported) {
797 			if (fMaxTrimRangeBlocks == 0)
798 				fMaxTrimRangeBlocks = 1;
799 
800 			#ifdef TRACE_AHCI
801 			bool deterministic = ataData.supports_deterministic_read_after_trim;
802 			TRACE("trim supported, %" B_PRIu32 " ranges blocks, reads are "
803 				"%sdeterministic%s.\n", fMaxTrimRangeBlocks,
804 				deterministic ? "" : "non-", deterministic
805 					? (ataData.supports_read_zero_after_trim
806 						? ", zero" : ", undefined") : "");
807 			#endif
808 		}
809 	}
810 
811 #if 0
812 	if (fSectorCount < 0x0fffffff) {
813 		TRACE("disabling 48 bit commands\n");
814 		fUse48BitCommands = 0;
815 	}
816 #endif
817 
818 	char modelNumber[sizeof(ataData.model_number) + 1];
819 	char serialNumber[sizeof(ataData.serial_number) + 1];
820 	char firmwareRev[sizeof(ataData.firmware_revision) + 1];
821 
822 	strlcpy(modelNumber, ataData.model_number, sizeof(modelNumber));
823 	strlcpy(serialNumber, ataData.serial_number, sizeof(serialNumber));
824 	strlcpy(firmwareRev, ataData.firmware_revision, sizeof(firmwareRev));
825 
826 	swap_words(modelNumber, sizeof(modelNumber) - 1);
827 	swap_words(serialNumber, sizeof(serialNumber) - 1);
828 	swap_words(firmwareRev, sizeof(firmwareRev) - 1);
829 
830 	TRACE("model number: %s\n", modelNumber);
831 	TRACE("serial number: %s\n", serialNumber);
832 	TRACE("firmware rev.: %s\n", firmwareRev);
833 
834 	// There's not enough space to fit all of the data in. ATA has 40 bytes for
835 	// the model number, 20 for the serial number and another 8 for the
836 	// firmware revision. SCSI has room for 8 for vendor ident, 16 for product
837 	// ident and another 4 for product revision.
838 	size_t vendorLen = strcspn(modelNumber, " ");
839 	if (vendorLen >= sizeof(scsiData.vendor_ident))
840 		vendorLen = strcspn(modelNumber, "-");
841 	if (vendorLen < sizeof(scsiData.vendor_ident)) {
842 		// First we try to break things apart smartly.
843 		snprintf(scsiData.vendor_ident, vendorLen + 1, "%s", modelNumber);
844 		size_t modelRemain = (sizeof(modelNumber) - vendorLen);
845 		if (modelRemain > sizeof(scsiData.product_ident))
846 			modelRemain = sizeof(scsiData.product_ident);
847 		memcpy(scsiData.product_ident, modelNumber + (vendorLen + 1),
848 			modelRemain);
849 	} else {
850 		// If we're unable to smartly break apart the vendor and model, just
851 		// dumbly squeeze as much in as possible.
852 		memcpy(scsiData.vendor_ident, modelNumber, sizeof(scsiData.vendor_ident));
853 		memcpy(scsiData.product_ident, modelNumber + 8,
854 			sizeof(scsiData.product_ident));
855 	}
856 	// Take the last 4 digits of the serial number as product rev
857 	size_t serialLen = sizeof(scsiData.product_rev);
858 	size_t serialOff = sizeof(serialNumber) - serialLen;
859 	memcpy(scsiData.product_rev, serialNumber + serialOff, serialLen);
860 
861 	if (sg_memcpy(request->sg_list, request->sg_count, &scsiData,
862 			sizeof(scsiData)) < B_OK) {
863 		request->subsys_status = SCSI_DATA_RUN_ERR;
864 	} else {
865 		request->subsys_status = SCSI_REQ_CMP;
866 		request->data_resid = request->data_length - sizeof(scsiData);
867 	}
868 	gSCSI->finished(request, 1);
869 }
870 
871 
872 void
873 AHCIPort::ScsiSynchronizeCache(scsi_ccb* request)
874 {
875 	//TRACE("AHCIPort::ScsiSynchronizeCache port %d\n", fIndex);
876 
877 	sata_request* sreq = new(std::nothrow) sata_request(request);
878 	if (sreq == NULL) {
879 		ERROR("out of memory when allocating sync request\n");
880 		request->subsys_status = SCSI_REQ_ABORTED;
881 		gSCSI->finished(request, 1);
882 		return;
883 	}
884 
885 	sreq->SetATACommand(fUse48BitCommands
886 		? ATA_COMMAND_FLUSH_CACHE_EXT : ATA_COMMAND_FLUSH_CACHE);
887 	ExecuteSataRequest(sreq);
888 }
889 
890 
891 void
892 AHCIPort::ScsiReadCapacity(scsi_ccb* request)
893 {
894 	TRACE("AHCIPort::ScsiReadCapacity port %d\n", fIndex);
895 
896 	const scsi_cmd_read_capacity* cmd
897 		= (const scsi_cmd_read_capacity*)request->cdb;
898 	scsi_res_read_capacity scsiData;
899 
900 	if (cmd->pmi || cmd->lba || request->data_length < sizeof(scsiData)) {
901 		TRACE("invalid request\n");
902 		request->subsys_status = SCSI_REQ_ABORTED;
903 		gSCSI->finished(request, 1);
904 		return;
905 	}
906 
907 	TRACE("SectorSize %" B_PRIu32 ", SectorCount 0x%" B_PRIx64 "\n",
908 		fSectorSize, fSectorCount);
909 
910 	memset(&scsiData, 0, sizeof(scsiData));
911 
912 	scsiData.block_size = B_HOST_TO_BENDIAN_INT32(fSectorSize);
913 
914 	if (fSectorCount <= 0xffffffff)
915 		scsiData.lba = B_HOST_TO_BENDIAN_INT32(fSectorCount - 1);
916 	else
917 		scsiData.lba = 0xffffffff;
918 
919 	if (sg_memcpy(request->sg_list, request->sg_count, &scsiData,
920 			sizeof(scsiData)) < B_OK) {
921 		request->subsys_status = SCSI_DATA_RUN_ERR;
922 	} else {
923 		request->subsys_status = SCSI_REQ_CMP;
924 		request->data_resid = request->data_length - sizeof(scsiData);
925 	}
926 	gSCSI->finished(request, 1);
927 }
928 
929 
930 void
931 AHCIPort::ScsiReadCapacity16(scsi_ccb* request)
932 {
933 	TRACE("AHCIPort::ScsiReadCapacity16 port %d\n", fIndex);
934 
935 	const scsi_cmd_read_capacity_long* cmd
936 		= (const scsi_cmd_read_capacity_long*)request->cdb;
937 	scsi_res_read_capacity_long scsiData;
938 
939 	uint32 allocationLength = B_BENDIAN_TO_HOST_INT32(cmd->alloc_length);
940 	size_t copySize = min_c(allocationLength, sizeof(scsiData));
941 
942 	if (cmd->pmi || cmd->lba || request->data_length < copySize) {
943 		TRACE("invalid request\n");
944 		request->subsys_status = SCSI_REQ_ABORTED;
945 		gSCSI->finished(request, 1);
946 		return;
947 	}
948 
949 	TRACE("SectorSize %" B_PRIu32 ", SectorCount 0x%" B_PRIx64 "\n",
950 		fSectorSize, fSectorCount);
951 
952 	memset(&scsiData, 0, sizeof(scsiData));
953 
954 	scsiData.block_size = B_HOST_TO_BENDIAN_INT32(fSectorSize);
955 	scsiData.lba = B_HOST_TO_BENDIAN_INT64(fSectorCount - 1);
956 	scsiData.rc_basis = 0x01;
957 	scsiData.lbpme = fTrimSupported;
958 	scsiData.lbprz = fTrimReturnsZeros;
959 
960 	if (sg_memcpy(request->sg_list, request->sg_count, &scsiData,
961 			copySize) < B_OK) {
962 		request->subsys_status = SCSI_DATA_RUN_ERR;
963 	} else {
964 		request->subsys_status = SCSI_REQ_CMP;
965 		request->data_resid = request->data_length - copySize;
966 	}
967 	gSCSI->finished(request, 1);
968 }
969 
970 
971 void
972 AHCIPort::ScsiReadWrite(scsi_ccb* request, uint64 lba, size_t sectorCount,
973 	bool isWrite)
974 {
975 	RWTRACE("[%lld] %ld ScsiReadWrite: position %llu, size %lu, isWrite %d\n",
976 		system_time(), find_thread(NULL), lba * 512, sectorCount * 512,
977 		isWrite);
978 
979 #if 0
980 	if (isWrite) {
981 		TRACE("write request ignored\n");
982 		request->subsys_status = SCSI_REQ_CMP;
983 		request->data_resid = 0;
984 		gSCSI->finished(request, 1);
985 		return;
986 	}
987 #endif
988 
989 	ASSERT(request->data_length == sectorCount * 512);
990 	sata_request* sreq = new(std::nothrow) sata_request(request);
991 	if (sreq == NULL) {
992 		TRACE("out of memory when allocating read/write request\n");
993 		request->subsys_status = SCSI_REQ_ABORTED;
994 		gSCSI->finished(request, 1);
995 		return;
996 	}
997 
998 	if (fUse48BitCommands) {
999 		if (sectorCount > 65536) {
1000 			panic("ahci: ScsiReadWrite length too large, %lu sectors",
1001 				sectorCount);
1002 		}
1003 		if (lba > MAX_SECTOR_LBA_48)
1004 			panic("achi: ScsiReadWrite position too large for 48-bit LBA\n");
1005 		sreq->SetATA48Command(
1006 			isWrite ? ATA_COMMAND_WRITE_DMA_EXT : ATA_COMMAND_READ_DMA_EXT,
1007 			lba, sectorCount);
1008 	} else {
1009 		if (sectorCount > 256) {
1010 			panic("ahci: ScsiReadWrite length too large, %lu sectors",
1011 				sectorCount);
1012 		}
1013 		if (lba > MAX_SECTOR_LBA_28)
1014 			panic("achi: ScsiReadWrite position too large for normal LBA\n");
1015 		sreq->SetATA28Command(isWrite
1016 			? ATA_COMMAND_WRITE_DMA : ATA_COMMAND_READ_DMA, lba, sectorCount);
1017 	}
1018 
1019 	ExecuteSataRequest(sreq, isWrite);
1020 }
1021 
1022 
1023 void
1024 AHCIPort::ScsiUnmap(scsi_ccb* request, scsi_unmap_parameter_list* unmapBlocks)
1025 {
1026 	if (!fTrimSupported || fMaxTrimRangeBlocks == 0) {
1027 		ERROR("TRIM error: Invalid TRIM support values detected\n");
1028 		return;
1029 	}
1030 
1031 	// Determine how many blocks are supposed to be trimmed in total
1032 	uint32 scsiRangeCount = (uint16)B_BENDIAN_TO_HOST_INT16(
1033 		unmapBlocks->block_data_length) / sizeof(scsi_unmap_block_descriptor);
1034 
1035 #ifdef DEBUG_TRIM
1036 	dprintf("TRIM: AHCI: received a SCSI UNMAP command (blocks):\n");
1037 	for (uint32 i = 0; i < scsiRangeCount; i++) {
1038 		dprintf("[%3" B_PRIu32 "] %" B_PRIu64 " : %" B_PRIu32 "\n", i,
1039 			(uint64)B_BENDIAN_TO_HOST_INT64(unmapBlocks->blocks[i].lba),
1040 			(uint32)B_BENDIAN_TO_HOST_INT32(
1041 				unmapBlocks->blocks[i].block_count));
1042 	}
1043 #endif
1044 
1045 	if (scsiRangeCount == 0) {
1046 		request->subsys_status = SCSI_REQ_CMP;
1047 		request->data_resid = 0;
1048 		request->device_status = SCSI_STATUS_GOOD;
1049 		gSCSI->finished(request, 1);
1050 		return;
1051 	}
1052 
1053 	size_t lbaRangeCount = 0;
1054 	for (uint32 i = 0; i < scsiRangeCount; i++) {
1055 		uint32 range
1056 			= B_BENDIAN_TO_HOST_INT32(unmapBlocks->blocks[i].block_count);
1057 		lbaRangeCount += range / DSM_MAX_RANGE_VALUE;
1058 		if (range % DSM_MAX_RANGE_VALUE != 0)
1059 			lbaRangeCount++;
1060 	}
1061 	TRACE("Total number of ATA ranges: %" B_PRIuSIZE "\n", lbaRangeCount);
1062 
1063 	size_t lbaRangesAllocatedSize = lbaRangeCount * sizeof(uint64);
1064 	// Request data is transferred in 512-byte blocks
1065 	if (lbaRangesAllocatedSize % 512 != 0) {
1066 		lbaRangesAllocatedSize += 512 - (lbaRangesAllocatedSize % 512);
1067 	}
1068 	// Apply reported device limits
1069 	if (lbaRangesAllocatedSize > (size_t)fMaxTrimRangeBlocks * 512) {
1070 		lbaRangesAllocatedSize = (size_t)fMaxTrimRangeBlocks * 512;
1071 	}
1072 	// Allocate a single buffer and re-use it between requests
1073 	TRACE("Allocating a %" B_PRIuSIZE "-byte buffer for ATA request ranges\n",
1074 		lbaRangesAllocatedSize);
1075 	uint64* lbaRanges = (uint64*)malloc(lbaRangesAllocatedSize);
1076 	if (lbaRanges == NULL) {
1077 		ERROR("out of memory when allocating space for %" B_PRIuSIZE
1078 			" unmap ranges\n", lbaRangesAllocatedSize / sizeof(uint64));
1079 		request->subsys_status = SCSI_REQ_ABORTED;
1080 		gSCSI->finished(request, 1);
1081 		return;
1082 	}
1083 
1084 	MemoryDeleter deleter(lbaRanges);
1085 
1086 	memset(lbaRanges, 0, lbaRangesAllocatedSize);
1087 		// Entries with range length of 0 will be ignored
1088 	uint32 lbaIndex = 0;
1089 	for (uint32 i = 0; i < scsiRangeCount; i++) {
1090 		uint64 lba = B_BENDIAN_TO_HOST_INT64(unmapBlocks->blocks[i].lba);
1091 		uint64 length = (uint32)B_BENDIAN_TO_HOST_INT32(
1092 			unmapBlocks->blocks[i].block_count);
1093 
1094 		if (length == 0)
1095 			continue; // Length of 0 would be ignored by the device anyway
1096 
1097 		if (lba > DSM_MAX_LBA_VALUE) {
1098 			ERROR("LBA value is too large!"
1099 				" This unmap range will be skipped.\n");
1100 			continue;
1101 		}
1102 
1103 		// Split large ranges if needed.
1104 		// Range length is limited by:
1105 		//   - max value of the range field (DSM_MAX_RANGE_VALUE)
1106 		while (length > 0) {
1107 			uint64 ataRange = min_c(length, DSM_MAX_RANGE_VALUE);
1108 			lbaRanges[lbaIndex++]
1109 				= B_HOST_TO_LENDIAN_INT64((ataRange << 48) | lba);
1110 
1111 			// Split into multiple requests if needed.
1112 			// The number of entries in a request is limited by:
1113 			//   - the maximum number of 512-byte blocks reported by the device
1114 			//   - maximum possible value of the COUNT field
1115 			//   - the size of our buffer
1116 			if (lbaIndex >= fMaxTrimRangeBlocks * DSM_RANGE_BLOCK_ENTRIES
1117 				|| (((lbaIndex + 1) * sizeof(uint64) + 511) / 512)
1118 					> DSM_MAX_COUNT_48
1119 				|| lbaIndex >= lbaRangesAllocatedSize / sizeof(uint64)
1120 				|| (i == scsiRangeCount - 1 && length <= DSM_MAX_RANGE_VALUE))
1121 			{
1122 				uint32 lbaRangeCount = lbaIndex;
1123 				if (lbaRangeCount % DSM_RANGE_BLOCK_ENTRIES != 0)
1124 					lbaRangeCount += DSM_RANGE_BLOCK_ENTRIES
1125 						- (lbaRangeCount % DSM_RANGE_BLOCK_ENTRIES);
1126 				uint32 lbaRangesSize = lbaRangeCount * sizeof(uint64);
1127 
1128 #ifdef DEBUG_TRIM
1129 				dprintf("TRIM: AHCI: sending a DATA SET MANAGEMENT command"
1130 					" to the device (blocks):\n");
1131 				for (uint32 i = 0; i < lbaRangeCount; i++) {
1132 					uint64 value = B_LENDIAN_TO_HOST_INT64(lbaRanges[i]);
1133 					dprintf("[%3" B_PRIu32 "] %" B_PRIu64 " : %" B_PRIu64 "\n", i,
1134 						value & (((uint64)1 << 48) - 1), value >> 48);
1135 				}
1136 #endif
1137 
1138 				ASSERT(lbaRangesSize % 512 == 0);
1139 				ASSERT(lbaRangesSize <= lbaRangesAllocatedSize);
1140 
1141 				sata_request sreq;
1142 				sreq.SetATA48Command(ATA_COMMAND_DATA_SET_MANAGEMENT, 0,
1143 					lbaRangesSize / 512);
1144 				sreq.SetFeature(1);
1145 				sreq.SetData(lbaRanges, lbaRangesSize);
1146 
1147 				ExecuteSataRequest(&sreq, true);
1148 				sreq.WaitForCompletion();
1149 
1150 				if ((sreq.CompletionStatus() & ATA_STATUS_ERROR) != 0) {
1151 					ERROR("trim failed (%" B_PRIu32
1152 						" ATA ranges)!\n", lbaRangeCount);
1153 					request->subsys_status = SCSI_REQ_CMP_ERR;
1154 					request->device_status = SCSI_STATUS_CHECK_CONDITION;
1155 					gSCSI->finished(request, 1);
1156 					return;
1157 				} else
1158 					request->subsys_status = SCSI_REQ_CMP;
1159 
1160 				lbaIndex = 0;
1161 				memset(lbaRanges, 0, lbaRangesSize);
1162 			}
1163 
1164 			length -= ataRange;
1165 			lba += ataRange;
1166 		}
1167 	}
1168 
1169 	request->data_resid = 0;
1170 	request->device_status = SCSI_STATUS_GOOD;
1171 	gSCSI->finished(request, 1);
1172 }
1173 
1174 
1175 void
1176 AHCIPort::ExecuteSataRequest(sata_request* request, bool isWrite)
1177 {
1178 	FLOW("ExecuteAtaRequest port %d\n", fIndex);
1179 
1180 	StartTransfer();
1181 
1182 	int prdEntrys;
1183 
1184 	if (request->CCB() && request->CCB()->data_length) {
1185 		FillPrdTable(fPRDTable, &prdEntrys, PRD_TABLE_ENTRY_COUNT,
1186 			request->CCB()->sg_list, request->CCB()->sg_count,
1187 			request->CCB()->data_length);
1188 	} else if (request->Data() && request->Size()) {
1189 		FillPrdTable(fPRDTable, &prdEntrys, PRD_TABLE_ENTRY_COUNT,
1190 			request->Data(), request->Size());
1191 	} else
1192 		prdEntrys = 0;
1193 
1194 	FLOW("prdEntrys %d\n", prdEntrys);
1195 
1196 	fCommandList->prdtl_flags_cfl = 0;
1197 	fCommandList->cfl = 5; // 20 bytes, length in DWORDS
1198 	memcpy((char*)fCommandTable->cfis, request->FIS(), 20);
1199 
1200 	// We some hide messages when the test unit ready active is clear
1201 	// as empty removeable media resets constantly.
1202 	fTestUnitReadyActive = request->IsTestUnitReady();
1203 
1204 	if (request->IsATAPI()) {
1205 		// ATAPI PACKET is a 12 or 16 byte SCSI command
1206 		memset((char*)fCommandTable->acmd, 0, 32);
1207 		memcpy((char*)fCommandTable->acmd, request->CCB()->cdb,
1208 			request->CCB()->cdb_length);
1209 		fCommandList->a = 1;
1210 	}
1211 
1212 	if (isWrite)
1213 		fCommandList->w = 1;
1214 	fCommandList->prdtl = prdEntrys;
1215 	fCommandList->prdbc = 0;
1216 
1217 	if (wait_until_clear(&fRegs->tfd, ATA_STATUS_BUSY | ATA_STATUS_DATA_REQUEST,
1218 			1000000) < B_OK) {
1219 		ERROR("ExecuteAtaRequest port %d: device is busy\n", fIndex);
1220 		PortReset();
1221 		FinishTransfer();
1222 		request->Abort();
1223 		return;
1224 	}
1225 
1226 	cpu_status cpu = disable_interrupts();
1227 	acquire_spinlock(&fSpinlock);
1228 	fCommandsActive |= 1;
1229 	fRegs->ci = 1;
1230 	FlushPostedWrites();
1231 	release_spinlock(&fSpinlock);
1232 	restore_interrupts(cpu);
1233 
1234 	int tfd;
1235 	status_t status = WaitForTransfer(&tfd, 20000000);
1236 
1237 	FLOW("Port %d sata request flow:\n", fIndex);
1238 	FLOW("  tfd %#x\n", tfd);
1239 	FLOW("  prdbc %ld\n", fCommandList->prdbc);
1240 	FLOW("  ci   0x%08" B_PRIx32 "\n", fRegs->ci);
1241 	FLOW("  is   0x%08" B_PRIx32 "\n", fRegs->is);
1242 	FLOW("  serr 0x%08" B_PRIx32 "\n", fRegs->serr);
1243 
1244 /*
1245 	TRACE("ci   0x%08" B_PRIx32 "\n", fRegs->ci);
1246 	TRACE("ie   0x%08" B_PRIx32 "\n", fRegs->ie);
1247 	TRACE("is   0x%08" B_PRIx32 "\n", fRegs->is);
1248 	TRACE("cmd  0x%08" B_PRIx32 "\n", fRegs->cmd);
1249 	TRACE("ssts 0x%08" B_PRIx32 "\n", fRegs->ssts);
1250 	TRACE("sctl 0x%08" B_PRIx32 "\n", fRegs->sctl);
1251 	TRACE("serr 0x%08" B_PRIx32 "\n", fRegs->serr);
1252 	TRACE("sact 0x%08" B_PRIx32 "\n", fRegs->sact);
1253 	TRACE("tfd  0x%08" B_PRIx32 "\n", fRegs->tfd);
1254 */
1255 
1256 	if (fPortReset || status == B_TIMED_OUT) {
1257 		fPortReset = false;
1258 		PortReset();
1259 	}
1260 
1261 	size_t bytesTransfered = fCommandList->prdbc;
1262 
1263 	FinishTransfer();
1264 
1265 	if (status == B_TIMED_OUT) {
1266 		ERROR("ExecuteAtaRequest port %d: device timeout\n", fIndex);
1267 		request->Abort();
1268 		return;
1269 	}
1270 
1271 	request->Finish(tfd, bytesTransfered);
1272 }
1273 
1274 
1275 void
1276 AHCIPort::ScsiExecuteRequest(scsi_ccb* request)
1277 {
1278 //	TRACE("AHCIPort::ScsiExecuteRequest port %d, opcode 0x%02x, length %u\n", fIndex, request->cdb[0], request->cdb_length);
1279 
1280 	if (fIsATAPI) {
1281 		bool isWrite = false;
1282 		switch (request->flags & SCSI_DIR_MASK) {
1283 			case SCSI_DIR_NONE:
1284 				ASSERT(request->data_length == 0);
1285 				break;
1286 			case SCSI_DIR_IN:
1287 				break;
1288 			case SCSI_DIR_OUT:
1289 				isWrite = true;
1290 				ASSERT(request->data_length > 0);
1291 				break;
1292 			default:
1293 				panic("CDB has invalid direction mask");
1294 		}
1295 
1296 //		TRACE("AHCIPort::ScsiExecuteRequest ATAPI: port %d, opcode 0x%02x, length %u\n", fIndex, request->cdb[0], request->cdb_length);
1297 
1298 		sata_request* sreq = new(std::nothrow) sata_request(request);
1299 		if (sreq == NULL) {
1300 			ERROR("out of memory when allocating atapi request\n");
1301 			request->subsys_status = SCSI_REQ_ABORTED;
1302 			gSCSI->finished(request, 1);
1303 			return;
1304 		}
1305 
1306 		sreq->SetATAPICommand(request->data_length);
1307 //		uint8* data = (uint8*) sreq->ccb()->cdb;
1308 //		for (int i = 0; i < 16; i += 8) {
1309 //			TRACE("  %02x %02x %02x %02x %02x %02x %02x %02x\n", data[i], data[i+1], data[i+2], data[i+3], data[i+4], data[i+5], data[i+6], data[i+7]);
1310 //		}
1311 		ExecuteSataRequest(sreq, isWrite);
1312 		return;
1313 	}
1314 
1315 	if (request->cdb[0] == SCSI_OP_REQUEST_SENSE) {
1316 		panic("ahci: SCSI_OP_REQUEST_SENSE not yet supported\n");
1317 		return;
1318 	}
1319 
1320 	if (!fDevicePresent) {
1321 		TRACE("no device present on port %d\n", fIndex);
1322 		request->subsys_status = SCSI_DEV_NOT_THERE;
1323 		gSCSI->finished(request, 1);
1324 		return;
1325 	}
1326 
1327 	request->subsys_status = SCSI_REQ_CMP;
1328 
1329 	switch (request->cdb[0]) {
1330 		case SCSI_OP_TEST_UNIT_READY:
1331 			ScsiTestUnitReady(request);
1332 			break;
1333 		case SCSI_OP_INQUIRY:
1334 			ScsiInquiry(request);
1335 			break;
1336 		case SCSI_OP_READ_CAPACITY:
1337 			ScsiReadCapacity(request);
1338 			break;
1339 		case SCSI_OP_SERVICE_ACTION_IN:
1340 			if ((request->cdb[1] & 0x1f) == SCSI_SAI_READ_CAPACITY_16)
1341 				ScsiReadCapacity16(request);
1342 			else {
1343 				request->subsys_status = SCSI_REQ_INVALID;
1344 				gSCSI->finished(request, 1);
1345 			}
1346 			break;
1347 		case SCSI_OP_SYNCHRONIZE_CACHE:
1348 			ScsiSynchronizeCache(request);
1349 			break;
1350 		case SCSI_OP_READ_6:
1351 		case SCSI_OP_WRITE_6:
1352 		{
1353 			const scsi_cmd_rw_6* cmd = (const scsi_cmd_rw_6*)request->cdb;
1354 			uint32 position = ((uint32)cmd->high_lba << 16)
1355 				| ((uint32)cmd->mid_lba << 8) | (uint32)cmd->low_lba;
1356 			size_t length = cmd->length != 0 ? cmd->length : 256;
1357 			bool isWrite = request->cdb[0] == SCSI_OP_WRITE_6;
1358 			ScsiReadWrite(request, position, length, isWrite);
1359 			break;
1360 		}
1361 		case SCSI_OP_READ_10:
1362 		case SCSI_OP_WRITE_10:
1363 		{
1364 			const scsi_cmd_rw_10* cmd = (const scsi_cmd_rw_10*)request->cdb;
1365 			uint32 position = B_BENDIAN_TO_HOST_INT32(cmd->lba);
1366 			size_t length = B_BENDIAN_TO_HOST_INT16(cmd->length);
1367 			bool isWrite = request->cdb[0] == SCSI_OP_WRITE_10;
1368 			if (length) {
1369 				ScsiReadWrite(request, position, length, isWrite);
1370 			} else {
1371 				ERROR("AHCIPort::ScsiExecuteRequest error: transfer without "
1372 					"data!\n");
1373 				request->subsys_status = SCSI_REQ_INVALID;
1374 				gSCSI->finished(request, 1);
1375 			}
1376 			break;
1377 		}
1378 		case SCSI_OP_READ_12:
1379 		case SCSI_OP_WRITE_12:
1380 		{
1381 			const scsi_cmd_rw_12* cmd = (const scsi_cmd_rw_12*)request->cdb;
1382 			uint32 position = B_BENDIAN_TO_HOST_INT32(cmd->lba);
1383 			size_t length = B_BENDIAN_TO_HOST_INT32(cmd->length);
1384 			bool isWrite = request->cdb[0] == SCSI_OP_WRITE_12;
1385 			if (length) {
1386 				ScsiReadWrite(request, position, length, isWrite);
1387 			} else {
1388 				ERROR("AHCIPort::ScsiExecuteRequest error: transfer without "
1389 					"data!\n");
1390 				request->subsys_status = SCSI_REQ_INVALID;
1391 				gSCSI->finished(request, 1);
1392 			}
1393 			break;
1394 		}
1395 		case SCSI_OP_READ_16:
1396 		case SCSI_OP_WRITE_16:
1397 		{
1398 			const scsi_cmd_rw_16* cmd = (const scsi_cmd_rw_16*)request->cdb;
1399 			uint64 position = B_BENDIAN_TO_HOST_INT64(cmd->lba);
1400 			size_t length = B_BENDIAN_TO_HOST_INT32(cmd->length);
1401 			bool isWrite = request->cdb[0] == SCSI_OP_WRITE_16;
1402 			if (length) {
1403 				ScsiReadWrite(request, position, length, isWrite);
1404 			} else {
1405 				ERROR("AHCIPort::ScsiExecuteRequest error: transfer without "
1406 					"data!\n");
1407 				request->subsys_status = SCSI_REQ_INVALID;
1408 				gSCSI->finished(request, 1);
1409 			}
1410 			break;
1411 		}
1412 		case SCSI_OP_UNMAP:
1413 		{
1414 			const scsi_cmd_unmap* cmd = (const scsi_cmd_unmap*)request->cdb;
1415 
1416 			if (!fTrimSupported) {
1417 				ERROR("%s port %d: unsupported request opcode 0x%02x\n",
1418 					__func__, fIndex, request->cdb[0]);
1419 				request->subsys_status = SCSI_REQ_ABORTED;
1420 				gSCSI->finished(request, 1);
1421 				break;
1422 			}
1423 
1424 			scsi_unmap_parameter_list* unmapBlocks
1425 				= (scsi_unmap_parameter_list*)request->data;
1426 			if (unmapBlocks == NULL
1427 				|| (uint16)B_BENDIAN_TO_HOST_INT16(cmd->length)
1428 					!= request->data_length
1429 				|| (uint16)B_BENDIAN_TO_HOST_INT16(unmapBlocks->data_length)
1430 					!= request->data_length
1431 						- offsetof(scsi_unmap_parameter_list, block_data_length)
1432 				|| (uint16)B_BENDIAN_TO_HOST_INT16(
1433 						unmapBlocks->block_data_length)
1434 					!= request->data_length
1435 						- offsetof(scsi_unmap_parameter_list, blocks)) {
1436 				ERROR("%s port %d: invalid unmap parameter data length\n",
1437 					__func__, fIndex);
1438 				request->subsys_status = SCSI_REQ_ABORTED;
1439 				gSCSI->finished(request, 1);
1440 			} else {
1441 				ScsiUnmap(request, unmapBlocks);
1442 			}
1443 			break;
1444 		}
1445 		default:
1446 			ERROR("AHCIPort::ScsiExecuteRequest port %d unsupported request "
1447 				"opcode 0x%02x\n", fIndex, request->cdb[0]);
1448 			request->subsys_status = SCSI_REQ_ABORTED;
1449 			gSCSI->finished(request, 1);
1450 	}
1451 }
1452 
1453 
1454 uchar
1455 AHCIPort::ScsiAbortRequest(scsi_ccb* request)
1456 {
1457 	return SCSI_REQ_CMP;
1458 }
1459 
1460 
1461 uchar
1462 AHCIPort::ScsiTerminateRequest(scsi_ccb* request)
1463 {
1464 	return SCSI_REQ_CMP;
1465 }
1466 
1467 
1468 uchar
1469 AHCIPort::ScsiResetDevice()
1470 {
1471 	return SCSI_REQ_CMP;
1472 }
1473 
1474 
1475 void
1476 AHCIPort::ScsiGetRestrictions(bool* isATAPI, bool* noAutoSense,
1477 	uint32* maxBlocks)
1478 {
1479 	*isATAPI = fIsATAPI;
1480 	*noAutoSense = fIsATAPI; // emulated auto sense for ATA, but not ATAPI
1481 	*maxBlocks = fUse48BitCommands ? 65536 : 256;
1482 	TRACE("AHCIPort::ScsiGetRestrictions port %d: isATAPI %d, noAutoSense %d, "
1483 		"maxBlocks %" B_PRIu32 "\n", fIndex, *isATAPI, *noAutoSense,
1484 		*maxBlocks);
1485 }
1486 
1487 
1488 bool
1489 AHCIPort::Enable()
1490 {
1491 	// Spec v1.3.1, §10.3.1 Start (PxCMD.ST)
1492 	TRACE("%s: port %d\n", __func__, fIndex);
1493 
1494 	if ((fRegs->cmd & PORT_CMD_ST) != 0) {
1495 		ERROR("%s: Starting port already running!\n", __func__);
1496 		return false;
1497 	}
1498 
1499 	if ((fRegs->cmd & PORT_CMD_FRE) == 0) {
1500 		ERROR("%s: Unable to start port without FRE enabled!\n", __func__);
1501 		return false;
1502 	}
1503 
1504 	// Clear DMA engine and wait for completion
1505 	if (wait_until_clear(&fRegs->cmd, PORT_CMD_CR, 500000) < B_OK) {
1506 		ERROR("%s: port %d error DMA engine still running\n", __func__,
1507 			fIndex);
1508 		return false;
1509 	}
1510 	// Start port
1511 	fRegs->cmd |= PORT_CMD_ST;
1512 	FlushPostedWrites();
1513 	return true;
1514 }
1515 
1516 
1517 bool
1518 AHCIPort::Disable()
1519 {
1520 	TRACE("%s: port %d\n", __func__, fIndex);
1521 
1522 	if ((fRegs->cmd & PORT_CMD_ST) == 0) {
1523 		// Port already disabled, carry on.
1524 		TRACE("%s: port %d attempting to disable stopped port.\n",
1525 			__func__, fIndex);
1526 	} else {
1527 		// Disable port
1528 		fRegs->cmd &= ~PORT_CMD_ST;
1529 		FlushPostedWrites();
1530 	}
1531 
1532 	// Spec v1.3.1, §10.4.2 Port Reset - assume hung after 500 mil.
1533 	// Clear DMA engine and wait for completion
1534 	if (wait_until_clear(&fRegs->cmd, PORT_CMD_CR, 500000) < B_OK) {
1535 		ERROR("%s: port %d error DMA engine still running\n", __func__,
1536 			fIndex);
1537 		return false;
1538 	}
1539 
1540 	return true;
1541 }
1542 
1543 
1544 void
1545 AHCIPort::_ClearErrorRegister()
1546 {
1547 	// clear error bits
1548 	fRegs->serr = fRegs->serr;
1549 	FlushPostedWrites();
1550 }
1551