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