1136849Sscottl/*
2149871Sscottl * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
3136849Sscottl * All rights reserved.
4136849Sscottl *
5136849Sscottl * Redistribution and use in source and binary forms, with or without
6136849Sscottl * modification, are permitted provided that the following conditions
7136849Sscottl * are met:
8136849Sscottl * 1. Redistributions of source code must retain the above copyright
9136849Sscottl *    notice, this list of conditions and the following disclaimer.
10136849Sscottl * 2. Redistributions in binary form must reproduce the above copyright
11136849Sscottl *    notice, this list of conditions and the following disclaimer in the
12136849Sscottl *    documentation and/or other materials provided with the distribution.
13136849Sscottl *
14136849Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15136849Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16136849Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17136849Sscottl * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18136849Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19136849Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20136849Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21136849Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22136849Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23136849Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24136849Sscottl * SUCH DAMAGE.
25142988Sscottl *
26142988Sscottl * $FreeBSD: releng/10.2/sys/dev/hptmv/command.h 190809 2009-04-07 16:38:25Z delphij $
27136849Sscottl */
28136849Sscottl#ifndef _COMMAND_H_
29136849Sscottl#define _COMMAND_H_
30136849Sscottl
31136849Sscottl/***************************************************************************
32136849Sscottl * Description: Command
33136849Sscottl ***************************************************************************/
34136849Sscottltypedef struct _AtaCommand
35136849Sscottl{
36136849Sscottl	LBA_T            Lba;          /* Current Logic Disk command: LBA   */
37136849Sscottl	USHORT           nSectors;     /* sector count. May great than 0x80 */
38136849Sscottl	UCHAR            Command;      /* IDE_COMMAND_READ, _WRITE, _VERIFY */
39136849Sscottl	UCHAR            QueueTag;
40136849Sscottl} AtaComm, *PAtaComm;
41136849Sscottl
42136849Sscottltypedef struct _PassthroughCmd {
43136849Sscottl	BYTE     bFeaturesReg;     /* feature register */
44136849Sscottl	BYTE     bSectorCountReg;  /* IDE sector count register. */
45190809Sdelphij	BYTE     bLbaLowReg; /* IDE sector number register. */
46190809Sdelphij	BYTE     bLbaMidReg;       /* IDE low order cylinder value. */
47190809Sdelphij	BYTE     bLbaHighReg;      /* IDE high order cylinder value. */
48136849Sscottl	BYTE     bDriveHeadReg;    /* IDE drive/head register. */
49136849Sscottl	BYTE     bCommandReg;      /* Actual IDE command. Checked for validity by driver. */
50136849Sscottl	BYTE     nSectors;         /* data transfer */
51136849Sscottl	ADDRESS  pDataBuffer;      /* data buffer */
52136849Sscottl}
53136849SscottlPassthroughCmd;
54136849Sscottl
55136849Sscottl/* control commands */
56136849Sscottl#define CTRL_CMD_REBUILD 1
57136849Sscottl#define CTRL_CMD_VERIFY  2
58136849Sscottl#define CTRL_CMD_INIT    3
59136849Sscottl
60136849Sscottl/*
61136849Sscottl * RAID5 rebuild/verify
62136849Sscottl *   Rebuild/verify one stripe line.
63136849Sscottl *   The caller needn't supply a buffer for rebuild.
64136849Sscottl *   RebuildSectors member will be updated if its previous location is the
65136849Sscottl *   begin of this stripe line.
66136849Sscottl */
67136849Sscottltypedef struct _R5ControlCmd {
68136849Sscottl	LBA_T  StripeLine;   /* _physical_ stripe line on array */
69136849Sscottl	USHORT Offset;       /* internal use, don't set */
70136849Sscottl	UCHAR  Command;      /* CTRL_CMD_XXX */
71136849Sscottl	UCHAR  reserve1;
72136849Sscottl}
73136849SscottlR5ControlCmd, *PR5ControlCmd;
74136849Sscottl
75136849Sscottl/*
76136849Sscottl * RAID1 rebuild/verify
77136849Sscottl *   Rebuild/verify specified sectors.
78136849Sscottl *   The caller must supply a valid buffer and a physical SG table (or a
79136849Sscottl *   pfnBuildSgl routine).
80136849Sscottl *   For rebuild/initialize, the buffer size should be nSectors<<9;
81136849Sscottl *   For verify, the buffer size should be (nSectors*2)<<9.
82136849Sscottl *   RebuildSectors member will be updated if its previous value equals Lba.
83136849Sscottl */
84136849Sscottltypedef struct _R1ControlCmd {
85136849Sscottl	LBA_T  Lba;
86136849Sscottl	USHORT nSectors;
87136849Sscottl	UCHAR  Command;      /* CTRL_CMD_XXX */
88136849Sscottl	UCHAR  reserve1;
89136849Sscottl	ADDRESS Buffer;  /* buffer logical address */
90136849Sscottl#ifdef _MACOSX_
91136849Sscottl	ADDRESS PhysicalAddress;
92136849Sscottl#endif
93136849Sscottl}
94136849SscottlR1ControlCmd, *PR1ControlCmd;
95136849Sscottl
96136849Sscottltypedef struct _Command
97136849Sscottl{
98136849Sscottl	PVDevice pVDevice;
99136849Sscottl	union{
100136849Sscottl		/* Ide Command */
101136849Sscottl		AtaComm Ide;
102136849Sscottl		PassthroughCmd Passthrough;
103136849Sscottl		/* Atapi Command */
104136849Sscottl		UCHAR Atapi[12];
105136849Sscottl		/* Control command */
106136849Sscottl		R5ControlCmd R5Control;
107136849Sscottl		R1ControlCmd R1Control;
108136849Sscottl	} uCmd;
109136849Sscottl
110136849Sscottl	USHORT	cf_physical_sg: 1;
111136849Sscottl	USHORT	cf_data_in: 1;
112136849Sscottl	USHORT	cf_data_out: 1;
113136849Sscottl	USHORT	cf_atapi: 1;
114136849Sscottl	USHORT	cf_ide_passthrough: 1;
115136849Sscottl	USHORT  cf_control: 1;
116136849Sscottl
117136849Sscottl	/* return status */
118136849Sscottl	UCHAR	Result;
119136849Sscottl	/* retry count */
120136849Sscottl	UCHAR   RetryCount;
121136849Sscottl
122136849Sscottl	/* S/G table address, if already prepared */
123136849Sscottl	FPSCAT_GATH pSgTable;
124136849Sscottl
125136849Sscottl	/* called if pSgTable is invalid. */
126136849Sscottl	int (* HPTLIBAPI pfnBuildSgl)(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSgTable, int logical);
127136849Sscottl
128136849Sscottl	/* called when this command is finished */
129136849Sscottl	void (* HPTLIBAPI pfnCompletion)(_VBUS_ARG PCommand pCmd);
130136849Sscottl
131136849Sscottl	/* pointer to origional command */
132136849Sscottl	void *pOrgCommand;
133136849Sscottl
134136849Sscottl
135136849Sscottl	/* scratch data area */
136136849Sscottl	union {
137136849Sscottl		struct {
138136849Sscottl			LBA_T      StartLBA;
139136849Sscottl			UCHAR      FirstMember;    /* the sequence number of the first member */
140136849Sscottl			UCHAR      LastMember;     /* the sequence number of the last member */
141136849Sscottl			USHORT     LastSectors;    /* the number of sectors for the last member */
142136849Sscottl			USHORT     FirstSectors;   /* the number of sectors for the first member */
143136849Sscottl			USHORT     FirstOffset;    /* the offset from the StartLBA for the first member */
144136849Sscottl			USHORT     AllMemberBlocks;/* the number of sectors for all member */
145136849Sscottl			USHORT     WaitInterrupt;  /* bit map the members who wait interrupt */
146136849Sscottl			UCHAR      InSameLine;     /* if the start and end on the same line */
147136849Sscottl			UCHAR      pad1;
148136849Sscottl		} array;
149136849Sscottl		struct {
150136849Sscottl			LBA_T      StartLBA;
151136849Sscottl			USHORT     FirstSectors;   /* the number of sectors for the first member */
152136849Sscottl			USHORT     FirstOffset;    /* the offset from the StartLBA for the first member */
153136849Sscottl			USHORT     WaitInterrupt;  /* bit map the members who wait interrupt */
154136849Sscottl			USHORT     r5_gap;         /* see raid5.c */
155136849Sscottl			UCHAR      ParDiskNo;      /* parity for startLba */
156136849Sscottl			UCHAR      BadDiskNo;
157136849Sscottl			UCHAR      FirstMember;
158136849Sscottl			UCHAR      pad1;
159136849Sscottl		} r5;
160136849Sscottl		struct {
161136849Sscottl			PCommand pCmd1;
162136849Sscottl			PCommand pCmd2;
163136849Sscottl		} r5split;
164136849Sscottl#ifdef _RAID5N_
165136849Sscottl		struct {
166136849Sscottl			ULONG dummy[2]; /* uScratch.wait shall be moved out uScratch.
167136849Sscottl							   now just fix it thisway */
168136849Sscottl			struct range_lock *range_lock;
169136849Sscottl			struct stripe *stripes[5];
170136849Sscottl			UCHAR nstripes;
171136849Sscottl			UCHAR finished_stripes;
172136849Sscottl			USHORT pad2;
173136849Sscottl			/* for direct-read: */
174136849Sscottl			struct {
175136849Sscottl				UCHAR  cmds;
176136849Sscottl				UCHAR  finished;
177136849Sscottl				UCHAR  first;
178136849Sscottl				UCHAR  parity;
179136849Sscottl				LBA_T  base;
180136849Sscottl				USHORT firstoffset;
181136849Sscottl				USHORT firstsectors;
182136849Sscottl			} dr;
183136849Sscottl		} r5n2;
184136849Sscottl#endif
185136849Sscottl		struct {
186136849Sscottl			ULONG WordsLeft;
187136849Sscottl			FPSCAT_GATH pPIOSg;
188136849Sscottl			void (* HPTLIBAPI pfnOrgDone)(_VBUS_ARG PCommand pCmd);
189136849Sscottl#ifdef SUPPORT_HPT584
190136849Sscottl			UCHAR cmd;
191136849Sscottl#endif
192136849Sscottl		} disk;
193136849Sscottl		struct {
194136849Sscottl			PCommand pNext;
195136849Sscottl			void (* HPTLIBAPI WaitEntry)(_VBUS_ARG PCommand pCmd);
196136849Sscottl		} wait;
197136849Sscottl
198136849Sscottl		struct {
199136849Sscottl			PVOID prdAddr;
200136849Sscottl			ULONG cmd_priv;
201136849Sscottl			USHORT responseFlags;
202136849Sscottl			UCHAR  bIdeStatus;
203136849Sscottl			UCHAR  errorRegister;
204136849Sscottl		} sata_param;
205136849Sscottl	} uScratch;
206136849Sscottl} Command;
207136849Sscottl
208136849Sscottl/***************************************************************************
209136849Sscottl * command return value
210136849Sscottl ***************************************************************************/
211136849Sscottl#define   RETURN_PENDING             0
212136849Sscottl#define   RETURN_SUCCESS             1
213136849Sscottl#define   RETURN_BAD_DEVICE          2
214136849Sscottl#define   RETURN_BAD_PARAMETER       3
215136849Sscottl#define   RETURN_WRITE_NO_DRQ        4
216136849Sscottl#define   RETURN_DEVICE_BUSY         5
217136849Sscottl#define   RETURN_INVALID_REQUEST     6
218136849Sscottl#define   RETURN_SELECTION_TIMEOUT   7
219136849Sscottl#define   RETURN_IDE_ERROR           8
220136849Sscottl#define   RETURN_NEED_LOGICAL_SG     9
221136849Sscottl#define   RETURN_NEED_PHYSICAL_SG    10
222136849Sscottl#define   RETURN_RETRY               11
223136849Sscottl#define   RETURN_DATA_ERROR          12
224136849Sscottl#define   RETURN_BUS_RESET           13
225136849Sscottl#define   RETURN_BAD_TRANSFER_LENGTH 14
226136849Sscottl
227136849Sscottltypedef void (* HPTLIBAPI DPC_PROC)(_VBUS_ARG void *);
228136849Sscottltypedef struct _dpc_routine {
229136849Sscottl	DPC_PROC proc;
230136849Sscottl	void *arg;
231136849Sscottl}
232136849SscottlDPC_ROUTINE;
233136849Sscottl
234136849Sscottl/*
235136849Sscottl * MAX_QUEUE_COMM is defined in platform related compiler.h
236136849Sscottl * to specify the maximum requests allowed (for each VBus) from system.
237136849Sscottl *
238136849Sscottl * Maximum command blocks needed for each VBus:
239136849Sscottl *   Each OS command requests 1+MAX_MEMBERS*2 command blocks (RAID1/0 case)
240136849Sscottl *   This space is allocated by platform dependent part, either static or
241136849Sscottl *   dynamic, continuous or non-continous.
242136849Sscottl *   The code only needs _vbus_(pFreeCommands) to be set.
243136849Sscottl *
244136849Sscottl * PendingRoutines[] size:
245136849Sscottl *   Each command may invoke CallAfterReturn once.
246136849Sscottl *
247136849Sscottl * IdleRoutines[] size:
248136849Sscottl *   Each command may invoke CallWhenIdle once.
249136849Sscottl */
250190809Sdelphij#define MAX_COMMAND_BLOCKS_FOR_EACH_VBUS (MAX_QUEUE_COMM * (1+MAX_MEMBERS*2) + 1)
251136849Sscottl#define MAX_PENDING_ROUTINES  (MAX_COMMAND_BLOCKS_FOR_EACH_VBUS+1)
252136849Sscottl#define MAX_IDLE_ROUTINES     (MAX_COMMAND_BLOCKS_FOR_EACH_VBUS+1)
253136849Sscottl
254136849Sscottl#define mWaitingForIdle(pVBus) ((pVBus)->IdleRoutinesFirst!=(pVBus)->IdleRoutinesLast)
255136849Sscottl
256136849SscottlPCommand HPTLIBAPI AllocateCommand(_VBUS_ARG0);
257136849Sscottlvoid FASTCALL FreeCommand(_VBUS_ARG PCommand pCmd);
258136849Sscottl
259136849Sscottlvoid FASTCALL CallAfterReturn(_VBUS_ARG DPC_PROC proc, void *arg);
260136849Sscottlvoid HPTLIBAPI CheckPendingCall(_VBUS_ARG0);
261136849Sscottlvoid FASTCALL CallWhenIdle(_VBUS_ARG DPC_PROC proc, void *arg);
262136849Sscottlvoid HPTLIBAPI CheckIdleCall(_VBUS_ARG0);
263136849Sscottl
264136849Sscottlvoid HPTLIBAPI AddToWaitingList(PCommand *ppList, PCommand pCmd);
265136849Sscottlvoid HPTLIBAPI DoWaitingList(_VBUS_ARG PCommand *ppList);
266136849Sscottl
267136849Sscottl#endif
268