1/*
2 * Copyright 2007-2008, Marcus Overhagen. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _AHCI_PORT_H
6#define _AHCI_PORT_H
7
8
9#include <ATAInfoBlock.h>
10
11#include "ahci_defs.h"
12
13
14class AHCIController;
15class sata_request;
16
17class AHCIPort {
18public:
19				AHCIPort(AHCIController *controller, int index);
20				~AHCIPort();
21
22	status_t	Init1();
23	status_t	Init2();
24	void		Uninit();
25
26	void		Interrupt();
27	void		InterruptErrorHandler(uint32 is);
28
29
30	void		ScsiExecuteRequest(scsi_ccb *request);
31	uchar		ScsiAbortRequest(scsi_ccb *request);
32	uchar		ScsiTerminateRequest(scsi_ccb *request);
33	uchar		ScsiResetDevice();
34	void		ScsiGetRestrictions(bool *isATAPI, bool *noAutoSense, uint32 *maxBlocks);
35
36private:
37	void		ScsiTestUnitReady(scsi_ccb *request);
38	void		ScsiInquiry(scsi_ccb *request);
39	void		ScsiVPDInquiry(scsi_ccb* request, ata_device_infoblock* ataData);
40
41	void		ScsiReadCapacity(scsi_ccb *request);
42	void		ScsiReadCapacity16(scsi_ccb *request);
43	void		ScsiReadWrite(scsi_ccb *request, uint64 lba, size_t sectorCount, bool isWrite);
44	void		ScsiSynchronizeCache(scsi_ccb *request);
45	void		ScsiUnmap(scsi_ccb* request,
46					struct scsi_unmap_parameter_list* unmapBlocks);
47
48	void		ExecuteSataRequest(sata_request *request, bool isWrite = false);
49
50	void		ResetDevice();
51	status_t	PortReset();
52	status_t	Probe();
53
54	bool		Enable();
55	bool		Disable();
56
57	void		FlushPostedWrites();
58	void		DumpD2HFis();
59	void		DumpHBAState();
60
61	void		StartTransfer();
62	status_t	WaitForTransfer(int *tfd, bigtime_t timeout);
63	void		FinishTransfer();
64
65	inline	void				_ClearErrorRegister();
66
67//	uint8 *		SetCommandFis(volatile command_list_entry *cmd, volatile fis *fis, const void *data, size_t dataSize);
68	status_t	FillPrdTable(volatile prd *prdTable, int *prdCount, int prdMax, const void *data, size_t dataSize);
69	status_t	FillPrdTable(volatile prd *prdTable, int *prdCount, int prdMax, const physical_entry *sgTable, int sgCount, size_t dataSize);
70
71private:
72	AHCIController*			fController;
73	int						fIndex;
74	volatile ahci_port *	fRegs;
75	area_id					fArea;
76	spinlock						fSpinlock;
77	volatile uint32					fCommandsActive;
78	sem_id							fRequestSem;
79	sem_id							fResponseSem;
80	bool							fDevicePresent;
81	bool							fUse48BitCommands;
82	uint32							fSectorSize;
83	uint32							fPhysicalSectorSize;
84	uint64							fSectorCount;
85	bool							fIsATAPI;
86	bool							fTestUnitReadyActive;
87	bool							fPortReset;
88	bool							fError;
89	bool							fTrimSupported;
90	bool							fTrimReturnsZeros;
91	uint32							fMaxTrimRangeBlocks;
92
93	volatile fis *					fFIS;
94	volatile command_list_entry *	fCommandList;
95	volatile command_table *		fCommandTable;
96	volatile prd *					fPRDTable;
97};
98
99
100inline void
101AHCIPort::FlushPostedWrites()
102{
103	volatile uint32 dummy = fRegs->cmd;
104	dummy = dummy;
105}
106
107
108#endif	// _AHCI_PORT_H
109