command.h revision 136849
1136849Sscottl/*
2136849Sscottl * Copyright (c) 2003-2004 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.
25136849Sscottl */
26136849Sscottl#ifndef _COMMAND_H_
27136849Sscottl#define _COMMAND_H_
28136849Sscottl
29136849Sscottl/***************************************************************************
30136849Sscottl * Description: Command
31136849Sscottl ***************************************************************************/
32136849Sscottltypedef struct _AtaCommand
33136849Sscottl{
34136849Sscottl	LBA_T            Lba;          /* Current Logic Disk command: LBA   */
35136849Sscottl	USHORT           nSectors;     /* sector count. May great than 0x80 */
36136849Sscottl	UCHAR            Command;      /* IDE_COMMAND_READ, _WRITE, _VERIFY */
37136849Sscottl	UCHAR            QueueTag;
38136849Sscottl} AtaComm, *PAtaComm;
39136849Sscottl
40136849Sscottltypedef struct _PassthroughCmd {
41136849Sscottl	BYTE     bFeaturesReg;     /* feature register */
42136849Sscottl	BYTE     bSectorCountReg;  /* IDE sector count register. */
43136849Sscottl	BYTE     bSectorNumberReg; /* IDE sector number register. */
44136849Sscottl	BYTE     bCylLowReg;       /* IDE low order cylinder value. */
45136849Sscottl	BYTE     bCylHighReg;      /* IDE high order cylinder value. */
46136849Sscottl	BYTE     bDriveHeadReg;    /* IDE drive/head register. */
47136849Sscottl	BYTE     bCommandReg;      /* Actual IDE command. Checked for validity by driver. */
48136849Sscottl	BYTE     nSectors;         /* data transfer */
49136849Sscottl	ADDRESS  pDataBuffer;      /* data buffer */
50136849Sscottl}
51136849SscottlPassthroughCmd;
52136849Sscottl
53136849Sscottl/* control commands */
54136849Sscottl#define CTRL_CMD_REBUILD 1
55136849Sscottl#define CTRL_CMD_VERIFY  2
56136849Sscottl#define CTRL_CMD_INIT    3
57136849Sscottl
58136849Sscottl/*
59136849Sscottl * RAID5 rebuild/verify
60136849Sscottl *   Rebuild/verify one stripe line.
61136849Sscottl *   The caller needn't supply a buffer for rebuild.
62136849Sscottl *   RebuildSectors member will be updated if its previous location is the
63136849Sscottl *   begin of this stripe line.
64136849Sscottl */
65136849Sscottltypedef struct _R5ControlCmd {
66136849Sscottl	LBA_T  StripeLine;   /* _physical_ stripe line on array */
67136849Sscottl	USHORT Offset;       /* internal use, don't set */
68136849Sscottl	UCHAR  Command;      /* CTRL_CMD_XXX */
69136849Sscottl	UCHAR  reserve1;
70136849Sscottl}
71136849SscottlR5ControlCmd, *PR5ControlCmd;
72136849Sscottl
73136849Sscottl/*
74136849Sscottl * RAID1 rebuild/verify
75136849Sscottl *   Rebuild/verify specified sectors.
76136849Sscottl *   The caller must supply a valid buffer and a physical SG table (or a
77136849Sscottl *   pfnBuildSgl routine).
78136849Sscottl *   For rebuild/initialize, the buffer size should be nSectors<<9;
79136849Sscottl *   For verify, the buffer size should be (nSectors*2)<<9.
80136849Sscottl *   RebuildSectors member will be updated if its previous value equals Lba.
81136849Sscottl */
82136849Sscottltypedef struct _R1ControlCmd {
83136849Sscottl	LBA_T  Lba;
84136849Sscottl	USHORT nSectors;
85136849Sscottl	UCHAR  Command;      /* CTRL_CMD_XXX */
86136849Sscottl	UCHAR  reserve1;
87136849Sscottl	ADDRESS Buffer;  /* buffer logical address */
88136849Sscottl#ifdef _MACOSX_
89136849Sscottl	ADDRESS PhysicalAddress;
90136849Sscottl#endif
91136849Sscottl}
92136849SscottlR1ControlCmd, *PR1ControlCmd;
93136849Sscottl
94136849Sscottltypedef struct _Command
95136849Sscottl{
96136849Sscottl	PVDevice pVDevice;
97136849Sscottl	union{
98136849Sscottl		/* Ide Command */
99136849Sscottl		AtaComm Ide;
100136849Sscottl		PassthroughCmd Passthrough;
101136849Sscottl		/* Atapi Command */
102136849Sscottl		UCHAR Atapi[12];
103136849Sscottl		/* Control command */
104136849Sscottl		R5ControlCmd R5Control;
105136849Sscottl		R1ControlCmd R1Control;
106136849Sscottl	} uCmd;
107136849Sscottl
108136849Sscottl	USHORT	cf_physical_sg: 1;
109136849Sscottl	USHORT	cf_data_in: 1;
110136849Sscottl	USHORT	cf_data_out: 1;
111136849Sscottl	USHORT	cf_atapi: 1;
112136849Sscottl	USHORT	cf_ide_passthrough: 1;
113136849Sscottl	USHORT  cf_control: 1;
114136849Sscottl
115136849Sscottl	/* return status */
116136849Sscottl	UCHAR	Result;
117136849Sscottl	/* retry count */
118136849Sscottl	UCHAR   RetryCount;
119136849Sscottl
120136849Sscottl	/* S/G table address, if already prepared */
121136849Sscottl	FPSCAT_GATH pSgTable;
122136849Sscottl
123136849Sscottl	/* called if pSgTable is invalid. */
124136849Sscottl	int (* HPTLIBAPI pfnBuildSgl)(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSgTable, int logical);
125136849Sscottl
126136849Sscottl	/* called when this command is finished */
127136849Sscottl	void (* HPTLIBAPI pfnCompletion)(_VBUS_ARG PCommand pCmd);
128136849Sscottl
129136849Sscottl	/* pointer to origional command */
130136849Sscottl	void *pOrgCommand;
131136849Sscottl
132136849Sscottl
133136849Sscottl	/* scratch data area */
134136849Sscottl	union {
135136849Sscottl		struct {
136136849Sscottl			LBA_T      StartLBA;
137136849Sscottl			UCHAR      FirstMember;    /* the sequence number of the first member */
138136849Sscottl			UCHAR      LastMember;     /* the sequence number of the last member */
139136849Sscottl			USHORT     LastSectors;    /* the number of sectors for the last member */
140136849Sscottl			USHORT     FirstSectors;   /* the number of sectors for the first member */
141136849Sscottl			USHORT     FirstOffset;    /* the offset from the StartLBA for the first member */
142136849Sscottl			USHORT     AllMemberBlocks;/* the number of sectors for all member */
143136849Sscottl			USHORT     WaitInterrupt;  /* bit map the members who wait interrupt */
144136849Sscottl			UCHAR      InSameLine;     /* if the start and end on the same line */
145136849Sscottl			UCHAR      pad1;
146136849Sscottl		} array;
147136849Sscottl		struct {
148136849Sscottl			LBA_T      StartLBA;
149136849Sscottl			USHORT     FirstSectors;   /* the number of sectors for the first member */
150136849Sscottl			USHORT     FirstOffset;    /* the offset from the StartLBA for the first member */
151136849Sscottl			USHORT     WaitInterrupt;  /* bit map the members who wait interrupt */
152136849Sscottl			USHORT     r5_gap;         /* see raid5.c */
153136849Sscottl			UCHAR      ParDiskNo;      /* parity for startLba */
154136849Sscottl			UCHAR      BadDiskNo;
155136849Sscottl			UCHAR      FirstMember;
156136849Sscottl			UCHAR      pad1;
157136849Sscottl		} r5;
158136849Sscottl		struct {
159136849Sscottl			PCommand pCmd1;
160136849Sscottl			PCommand pCmd2;
161136849Sscottl		} r5split;
162136849Sscottl#ifdef _RAID5N_
163136849Sscottl		struct {
164136849Sscottl			ULONG dummy[2]; /* uScratch.wait shall be moved out uScratch.
165136849Sscottl							   now just fix it thisway */
166136849Sscottl			struct range_lock *range_lock;
167136849Sscottl			struct stripe *stripes[5];
168136849Sscottl			UCHAR nstripes;
169136849Sscottl			UCHAR finished_stripes;
170136849Sscottl			USHORT pad2;
171136849Sscottl			/* for direct-read: */
172136849Sscottl			struct {
173136849Sscottl				UCHAR  cmds;
174136849Sscottl				UCHAR  finished;
175136849Sscottl				UCHAR  first;
176136849Sscottl				UCHAR  parity;
177136849Sscottl				LBA_T  base;
178136849Sscottl				USHORT firstoffset;
179136849Sscottl				USHORT firstsectors;
180136849Sscottl			} dr;
181136849Sscottl		} r5n2;
182136849Sscottl#endif
183136849Sscottl		struct {
184136849Sscottl			ULONG WordsLeft;
185136849Sscottl			FPSCAT_GATH pPIOSg;
186136849Sscottl			void (* HPTLIBAPI pfnOrgDone)(_VBUS_ARG PCommand pCmd);
187136849Sscottl#ifdef SUPPORT_HPT584
188136849Sscottl			UCHAR cmd;
189136849Sscottl#endif
190136849Sscottl		} disk;
191136849Sscottl		struct {
192136849Sscottl			PCommand pNext;
193136849Sscottl			void (* HPTLIBAPI WaitEntry)(_VBUS_ARG PCommand pCmd);
194136849Sscottl		} wait;
195136849Sscottl
196136849Sscottl		struct {
197136849Sscottl			PVOID prdAddr;
198136849Sscottl			ULONG cmd_priv;
199136849Sscottl			USHORT responseFlags;
200136849Sscottl			UCHAR  bIdeStatus;
201136849Sscottl			UCHAR  errorRegister;
202136849Sscottl		} sata_param;
203136849Sscottl	} uScratch;
204136849Sscottl} Command;
205136849Sscottl
206136849Sscottl/***************************************************************************
207136849Sscottl * command return value
208136849Sscottl ***************************************************************************/
209136849Sscottl#define   RETURN_PENDING             0
210136849Sscottl#define   RETURN_SUCCESS             1
211136849Sscottl#define   RETURN_BAD_DEVICE          2
212136849Sscottl#define   RETURN_BAD_PARAMETER       3
213136849Sscottl#define   RETURN_WRITE_NO_DRQ        4
214136849Sscottl#define   RETURN_DEVICE_BUSY         5
215136849Sscottl#define   RETURN_INVALID_REQUEST     6
216136849Sscottl#define   RETURN_SELECTION_TIMEOUT   7
217136849Sscottl#define   RETURN_IDE_ERROR           8
218136849Sscottl#define   RETURN_NEED_LOGICAL_SG     9
219136849Sscottl#define   RETURN_NEED_PHYSICAL_SG    10
220136849Sscottl#define   RETURN_RETRY               11
221136849Sscottl#define   RETURN_DATA_ERROR          12
222136849Sscottl#define   RETURN_BUS_RESET           13
223136849Sscottl#define   RETURN_BAD_TRANSFER_LENGTH 14
224136849Sscottl
225136849Sscottltypedef void (* HPTLIBAPI DPC_PROC)(_VBUS_ARG void *);
226136849Sscottltypedef struct _dpc_routine {
227136849Sscottl	DPC_PROC proc;
228136849Sscottl	void *arg;
229136849Sscottl}
230136849SscottlDPC_ROUTINE;
231136849Sscottl
232136849Sscottl/*
233136849Sscottl * MAX_QUEUE_COMM is defined in platform related compiler.h
234136849Sscottl * to specify the maximum requests allowed (for each VBus) from system.
235136849Sscottl *
236136849Sscottl * Maximum command blocks needed for each VBus:
237136849Sscottl *   Each OS command requests 1+MAX_MEMBERS*2 command blocks (RAID1/0 case)
238136849Sscottl *   This space is allocated by platform dependent part, either static or
239136849Sscottl *   dynamic, continuous or non-continous.
240136849Sscottl *   The code only needs _vbus_(pFreeCommands) to be set.
241136849Sscottl *
242136849Sscottl * PendingRoutines[] size:
243136849Sscottl *   Each command may invoke CallAfterReturn once.
244136849Sscottl *
245136849Sscottl * IdleRoutines[] size:
246136849Sscottl *   Each command may invoke CallWhenIdle once.
247136849Sscottl */
248136849Sscottl#define MAX_COMMAND_BLOCKS_FOR_EACH_VBUS (MAX_QUEUE_COMM * (1+MAX_MEMBERS*2))
249136849Sscottl#define MAX_PENDING_ROUTINES  (MAX_COMMAND_BLOCKS_FOR_EACH_VBUS+1)
250136849Sscottl#define MAX_IDLE_ROUTINES     (MAX_COMMAND_BLOCKS_FOR_EACH_VBUS+1)
251136849Sscottl
252136849Sscottl#define mWaitingForIdle(pVBus) ((pVBus)->IdleRoutinesFirst!=(pVBus)->IdleRoutinesLast)
253136849Sscottl
254136849SscottlPCommand HPTLIBAPI AllocateCommand(_VBUS_ARG0);
255136849Sscottlvoid FASTCALL FreeCommand(_VBUS_ARG PCommand pCmd);
256136849Sscottl
257136849Sscottlvoid FASTCALL CallAfterReturn(_VBUS_ARG DPC_PROC proc, void *arg);
258136849Sscottlvoid HPTLIBAPI CheckPendingCall(_VBUS_ARG0);
259136849Sscottlvoid FASTCALL CallWhenIdle(_VBUS_ARG DPC_PROC proc, void *arg);
260136849Sscottlvoid HPTLIBAPI CheckIdleCall(_VBUS_ARG0);
261136849Sscottl
262136849Sscottlvoid HPTLIBAPI AddToWaitingList(PCommand *ppList, PCommand pCmd);
263136849Sscottlvoid HPTLIBAPI DoWaitingList(_VBUS_ARG PCommand *ppList);
264136849Sscottl
265136849Sscottl#endif
266