xref: /dflybsd-src/sys/dev/raid/hptmv/command.h (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
1*86d7f5d3SJohn Marino /*
2*86d7f5d3SJohn Marino  * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
3*86d7f5d3SJohn Marino  * All rights reserved.
4*86d7f5d3SJohn Marino  *
5*86d7f5d3SJohn Marino  * Redistribution and use in source and binary forms, with or without
6*86d7f5d3SJohn Marino  * modification, are permitted provided that the following conditions
7*86d7f5d3SJohn Marino  * are met:
8*86d7f5d3SJohn Marino  * 1. Redistributions of source code must retain the above copyright
9*86d7f5d3SJohn Marino  *    notice, this list of conditions and the following disclaimer.
10*86d7f5d3SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
11*86d7f5d3SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
12*86d7f5d3SJohn Marino  *    documentation and/or other materials provided with the distribution.
13*86d7f5d3SJohn Marino  *
14*86d7f5d3SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*86d7f5d3SJohn Marino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*86d7f5d3SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*86d7f5d3SJohn Marino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*86d7f5d3SJohn Marino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*86d7f5d3SJohn Marino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*86d7f5d3SJohn Marino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*86d7f5d3SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*86d7f5d3SJohn Marino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*86d7f5d3SJohn Marino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*86d7f5d3SJohn Marino  * SUCH DAMAGE.
25*86d7f5d3SJohn Marino  *
26*86d7f5d3SJohn Marino  * $FreeBSD: src/sys/dev/hptmv/command.h,v 1.4 2009/04/07 16:38:25 delphij Exp $
27*86d7f5d3SJohn Marino  */
28*86d7f5d3SJohn Marino #ifndef _COMMAND_H_
29*86d7f5d3SJohn Marino #define _COMMAND_H_
30*86d7f5d3SJohn Marino 
31*86d7f5d3SJohn Marino /***************************************************************************
32*86d7f5d3SJohn Marino  * Description: Command
33*86d7f5d3SJohn Marino  ***************************************************************************/
34*86d7f5d3SJohn Marino typedef struct _AtaCommand
35*86d7f5d3SJohn Marino {
36*86d7f5d3SJohn Marino 	LBA_T            Lba;          /* Current Logic Disk command: LBA   */
37*86d7f5d3SJohn Marino 	USHORT           nSectors;     /* sector count. May great than 0x80 */
38*86d7f5d3SJohn Marino 	UCHAR            Command;      /* IDE_COMMAND_READ, _WRITE, _VERIFY */
39*86d7f5d3SJohn Marino 	UCHAR            QueueTag;
40*86d7f5d3SJohn Marino } AtaComm, *PAtaComm;
41*86d7f5d3SJohn Marino 
42*86d7f5d3SJohn Marino typedef struct _PassthroughCmd {
43*86d7f5d3SJohn Marino 	BYTE     bFeaturesReg;     /* feature register */
44*86d7f5d3SJohn Marino 	BYTE     bSectorCountReg;  /* IDE sector count register. */
45*86d7f5d3SJohn Marino 	BYTE     bLbaLowReg; /* IDE sector number register. */
46*86d7f5d3SJohn Marino 	BYTE     bLbaMidReg;       /* IDE low order cylinder value. */
47*86d7f5d3SJohn Marino 	BYTE     bLbaHighReg;      /* IDE high order cylinder value. */
48*86d7f5d3SJohn Marino 	BYTE     bDriveHeadReg;    /* IDE drive/head register. */
49*86d7f5d3SJohn Marino 	BYTE     bCommandReg;      /* Actual IDE command. Checked for validity by driver. */
50*86d7f5d3SJohn Marino 	BYTE     nSectors;         /* data transfer */
51*86d7f5d3SJohn Marino 	ADDRESS  pDataBuffer;      /* data buffer */
52*86d7f5d3SJohn Marino }
53*86d7f5d3SJohn Marino PassthroughCmd;
54*86d7f5d3SJohn Marino 
55*86d7f5d3SJohn Marino /* control commands */
56*86d7f5d3SJohn Marino #define CTRL_CMD_REBUILD 1
57*86d7f5d3SJohn Marino #define CTRL_CMD_VERIFY  2
58*86d7f5d3SJohn Marino #define CTRL_CMD_INIT    3
59*86d7f5d3SJohn Marino 
60*86d7f5d3SJohn Marino /*
61*86d7f5d3SJohn Marino  * RAID5 rebuild/verify
62*86d7f5d3SJohn Marino  *   Rebuild/verify one stripe line.
63*86d7f5d3SJohn Marino  *   The caller needn't supply a buffer for rebuild.
64*86d7f5d3SJohn Marino  *   RebuildSectors member will be updated if its previous location is the
65*86d7f5d3SJohn Marino  *   begin of this stripe line.
66*86d7f5d3SJohn Marino  */
67*86d7f5d3SJohn Marino typedef struct _R5ControlCmd {
68*86d7f5d3SJohn Marino 	LBA_T  StripeLine;   /* _physical_ stripe line on array */
69*86d7f5d3SJohn Marino 	USHORT Offset;       /* internal use, don't set */
70*86d7f5d3SJohn Marino 	UCHAR  Command;      /* CTRL_CMD_XXX */
71*86d7f5d3SJohn Marino 	UCHAR  reserve1;
72*86d7f5d3SJohn Marino }
73*86d7f5d3SJohn Marino R5ControlCmd, *PR5ControlCmd;
74*86d7f5d3SJohn Marino 
75*86d7f5d3SJohn Marino /*
76*86d7f5d3SJohn Marino  * RAID1 rebuild/verify
77*86d7f5d3SJohn Marino  *   Rebuild/verify specified sectors.
78*86d7f5d3SJohn Marino  *   The caller must supply a valid buffer and a physical SG table (or a
79*86d7f5d3SJohn Marino  *   pfnBuildSgl routine).
80*86d7f5d3SJohn Marino  *   For rebuild/initialize, the buffer size should be nSectors<<9;
81*86d7f5d3SJohn Marino  *   For verify, the buffer size should be (nSectors*2)<<9.
82*86d7f5d3SJohn Marino  *   RebuildSectors member will be updated if its previous value equals Lba.
83*86d7f5d3SJohn Marino  */
84*86d7f5d3SJohn Marino typedef struct _R1ControlCmd {
85*86d7f5d3SJohn Marino 	LBA_T  Lba;
86*86d7f5d3SJohn Marino 	USHORT nSectors;
87*86d7f5d3SJohn Marino 	UCHAR  Command;      /* CTRL_CMD_XXX */
88*86d7f5d3SJohn Marino 	UCHAR  reserve1;
89*86d7f5d3SJohn Marino 	ADDRESS Buffer;  /* buffer logical address */
90*86d7f5d3SJohn Marino #ifdef _MACOSX_
91*86d7f5d3SJohn Marino 	ADDRESS PhysicalAddress;
92*86d7f5d3SJohn Marino #endif
93*86d7f5d3SJohn Marino }
94*86d7f5d3SJohn Marino R1ControlCmd, *PR1ControlCmd;
95*86d7f5d3SJohn Marino 
96*86d7f5d3SJohn Marino typedef struct _Command
97*86d7f5d3SJohn Marino {
98*86d7f5d3SJohn Marino 	PVDevice pVDevice;
99*86d7f5d3SJohn Marino 	union{
100*86d7f5d3SJohn Marino 		/* Ide Command */
101*86d7f5d3SJohn Marino 		AtaComm Ide;
102*86d7f5d3SJohn Marino 		PassthroughCmd Passthrough;
103*86d7f5d3SJohn Marino 		/* Atapi Command */
104*86d7f5d3SJohn Marino 		UCHAR Atapi[12];
105*86d7f5d3SJohn Marino 		/* Control command */
106*86d7f5d3SJohn Marino 		R5ControlCmd R5Control;
107*86d7f5d3SJohn Marino 		R1ControlCmd R1Control;
108*86d7f5d3SJohn Marino 	} uCmd;
109*86d7f5d3SJohn Marino 
110*86d7f5d3SJohn Marino 	USHORT	cf_physical_sg: 1;
111*86d7f5d3SJohn Marino 	USHORT	cf_data_in: 1;
112*86d7f5d3SJohn Marino 	USHORT	cf_data_out: 1;
113*86d7f5d3SJohn Marino 	USHORT	cf_atapi: 1;
114*86d7f5d3SJohn Marino 	USHORT	cf_ide_passthrough: 1;
115*86d7f5d3SJohn Marino 	USHORT  cf_control: 1;
116*86d7f5d3SJohn Marino 
117*86d7f5d3SJohn Marino 	/* return status */
118*86d7f5d3SJohn Marino 	UCHAR	Result;
119*86d7f5d3SJohn Marino 	/* retry count */
120*86d7f5d3SJohn Marino 	UCHAR   RetryCount;
121*86d7f5d3SJohn Marino 
122*86d7f5d3SJohn Marino 	/* S/G table address, if already prepared */
123*86d7f5d3SJohn Marino 	FPSCAT_GATH pSgTable;
124*86d7f5d3SJohn Marino 
125*86d7f5d3SJohn Marino 	/* called if pSgTable is invalid. */
126*86d7f5d3SJohn Marino 	int (* HPTLIBAPI pfnBuildSgl)(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSgTable, int logical);
127*86d7f5d3SJohn Marino 
128*86d7f5d3SJohn Marino 	/* called when this command is finished */
129*86d7f5d3SJohn Marino 	void (* HPTLIBAPI pfnCompletion)(_VBUS_ARG PCommand pCmd);
130*86d7f5d3SJohn Marino 
131*86d7f5d3SJohn Marino 	/* pointer to origional command */
132*86d7f5d3SJohn Marino 	void *pOrgCommand;
133*86d7f5d3SJohn Marino 
134*86d7f5d3SJohn Marino 
135*86d7f5d3SJohn Marino 	/* scratch data area */
136*86d7f5d3SJohn Marino 	union {
137*86d7f5d3SJohn Marino 		struct {
138*86d7f5d3SJohn Marino 			LBA_T      StartLBA;
139*86d7f5d3SJohn Marino 			UCHAR      FirstMember;    /* the sequence number of the first member */
140*86d7f5d3SJohn Marino 			UCHAR      LastMember;     /* the sequence number of the last member */
141*86d7f5d3SJohn Marino 			USHORT     LastSectors;    /* the number of sectors for the last member */
142*86d7f5d3SJohn Marino 			USHORT     FirstSectors;   /* the number of sectors for the first member */
143*86d7f5d3SJohn Marino 			USHORT     FirstOffset;    /* the offset from the StartLBA for the first member */
144*86d7f5d3SJohn Marino 			USHORT     AllMemberBlocks;/* the number of sectors for all member */
145*86d7f5d3SJohn Marino 			USHORT     WaitInterrupt;  /* bit map the members who wait interrupt */
146*86d7f5d3SJohn Marino 			UCHAR      InSameLine;     /* if the start and end on the same line */
147*86d7f5d3SJohn Marino 			UCHAR      pad1;
148*86d7f5d3SJohn Marino 		} array;
149*86d7f5d3SJohn Marino 		struct {
150*86d7f5d3SJohn Marino 			LBA_T      StartLBA;
151*86d7f5d3SJohn Marino 			USHORT     FirstSectors;   /* the number of sectors for the first member */
152*86d7f5d3SJohn Marino 			USHORT     FirstOffset;    /* the offset from the StartLBA for the first member */
153*86d7f5d3SJohn Marino 			USHORT     WaitInterrupt;  /* bit map the members who wait interrupt */
154*86d7f5d3SJohn Marino 			USHORT     r5_gap;         /* see raid5.c */
155*86d7f5d3SJohn Marino 			UCHAR      ParDiskNo;      /* parity for startLba */
156*86d7f5d3SJohn Marino 			UCHAR      BadDiskNo;
157*86d7f5d3SJohn Marino 			UCHAR      FirstMember;
158*86d7f5d3SJohn Marino 			UCHAR      pad1;
159*86d7f5d3SJohn Marino 		} r5;
160*86d7f5d3SJohn Marino 		struct {
161*86d7f5d3SJohn Marino 			PCommand pCmd1;
162*86d7f5d3SJohn Marino 			PCommand pCmd2;
163*86d7f5d3SJohn Marino 		} r5split;
164*86d7f5d3SJohn Marino #ifdef _RAID5N_
165*86d7f5d3SJohn Marino 		struct {
166*86d7f5d3SJohn Marino 			ULONG dummy[2]; /* uScratch.wait shall be moved out uScratch.
167*86d7f5d3SJohn Marino 							   now just fix it thisway */
168*86d7f5d3SJohn Marino 			struct range_lock *range_lock;
169*86d7f5d3SJohn Marino 			struct stripe *stripes[5];
170*86d7f5d3SJohn Marino 			UCHAR nstripes;
171*86d7f5d3SJohn Marino 			UCHAR finished_stripes;
172*86d7f5d3SJohn Marino 			USHORT pad2;
173*86d7f5d3SJohn Marino 			/* for direct-read: */
174*86d7f5d3SJohn Marino 			struct {
175*86d7f5d3SJohn Marino 				UCHAR  cmds;
176*86d7f5d3SJohn Marino 				UCHAR  finished;
177*86d7f5d3SJohn Marino 				UCHAR  first;
178*86d7f5d3SJohn Marino 				UCHAR  parity;
179*86d7f5d3SJohn Marino 				LBA_T  base;
180*86d7f5d3SJohn Marino 				USHORT firstoffset;
181*86d7f5d3SJohn Marino 				USHORT firstsectors;
182*86d7f5d3SJohn Marino 			} dr;
183*86d7f5d3SJohn Marino 		} r5n2;
184*86d7f5d3SJohn Marino #endif
185*86d7f5d3SJohn Marino 		struct {
186*86d7f5d3SJohn Marino 			ULONG WordsLeft;
187*86d7f5d3SJohn Marino 			FPSCAT_GATH pPIOSg;
188*86d7f5d3SJohn Marino 			void (* HPTLIBAPI pfnOrgDone)(_VBUS_ARG PCommand pCmd);
189*86d7f5d3SJohn Marino #ifdef SUPPORT_HPT584
190*86d7f5d3SJohn Marino 			UCHAR cmd;
191*86d7f5d3SJohn Marino #endif
192*86d7f5d3SJohn Marino 		} disk;
193*86d7f5d3SJohn Marino 		struct {
194*86d7f5d3SJohn Marino 			PCommand pNext;
195*86d7f5d3SJohn Marino 			void (* HPTLIBAPI WaitEntry)(_VBUS_ARG PCommand pCmd);
196*86d7f5d3SJohn Marino 		} wait;
197*86d7f5d3SJohn Marino 
198*86d7f5d3SJohn Marino 		struct {
199*86d7f5d3SJohn Marino 			PVOID prdAddr;
200*86d7f5d3SJohn Marino 			ULONG cmd_priv;
201*86d7f5d3SJohn Marino 			USHORT responseFlags;
202*86d7f5d3SJohn Marino 			UCHAR  bIdeStatus;
203*86d7f5d3SJohn Marino 			UCHAR  errorRegister;
204*86d7f5d3SJohn Marino 		} sata_param;
205*86d7f5d3SJohn Marino 	} uScratch;
206*86d7f5d3SJohn Marino } Command;
207*86d7f5d3SJohn Marino 
208*86d7f5d3SJohn Marino /***************************************************************************
209*86d7f5d3SJohn Marino  * command return value
210*86d7f5d3SJohn Marino  ***************************************************************************/
211*86d7f5d3SJohn Marino #define   RETURN_PENDING             0
212*86d7f5d3SJohn Marino #define   RETURN_SUCCESS             1
213*86d7f5d3SJohn Marino #define   RETURN_BAD_DEVICE          2
214*86d7f5d3SJohn Marino #define   RETURN_BAD_PARAMETER       3
215*86d7f5d3SJohn Marino #define   RETURN_WRITE_NO_DRQ        4
216*86d7f5d3SJohn Marino #define   RETURN_DEVICE_BUSY         5
217*86d7f5d3SJohn Marino #define   RETURN_INVALID_REQUEST     6
218*86d7f5d3SJohn Marino #define   RETURN_SELECTION_TIMEOUT   7
219*86d7f5d3SJohn Marino #define   RETURN_IDE_ERROR           8
220*86d7f5d3SJohn Marino #define   RETURN_NEED_LOGICAL_SG     9
221*86d7f5d3SJohn Marino #define   RETURN_NEED_PHYSICAL_SG    10
222*86d7f5d3SJohn Marino #define   RETURN_RETRY               11
223*86d7f5d3SJohn Marino #define   RETURN_DATA_ERROR          12
224*86d7f5d3SJohn Marino #define   RETURN_BUS_RESET           13
225*86d7f5d3SJohn Marino #define   RETURN_BAD_TRANSFER_LENGTH 14
226*86d7f5d3SJohn Marino 
227*86d7f5d3SJohn Marino typedef void (* HPTLIBAPI DPC_PROC)(_VBUS_ARG void *);
228*86d7f5d3SJohn Marino typedef struct _dpc_routine {
229*86d7f5d3SJohn Marino 	DPC_PROC proc;
230*86d7f5d3SJohn Marino 	void *arg;
231*86d7f5d3SJohn Marino }
232*86d7f5d3SJohn Marino DPC_ROUTINE;
233*86d7f5d3SJohn Marino 
234*86d7f5d3SJohn Marino /*
235*86d7f5d3SJohn Marino  * MAX_QUEUE_COMM is defined in platform related compiler.h
236*86d7f5d3SJohn Marino  * to specify the maximum requests allowed (for each VBus) from system.
237*86d7f5d3SJohn Marino  *
238*86d7f5d3SJohn Marino  * Maximum command blocks needed for each VBus:
239*86d7f5d3SJohn Marino  *   Each OS command requests 1+MAX_MEMBERS*2 command blocks (RAID1/0 case)
240*86d7f5d3SJohn Marino  *   This space is allocated by platform dependent part, either static or
241*86d7f5d3SJohn Marino  *   dynamic, continuous or non-continous.
242*86d7f5d3SJohn Marino  *   The code only needs _vbus_(pFreeCommands) to be set.
243*86d7f5d3SJohn Marino  *
244*86d7f5d3SJohn Marino  * PendingRoutines[] size:
245*86d7f5d3SJohn Marino  *   Each command may invoke CallAfterReturn once.
246*86d7f5d3SJohn Marino  *
247*86d7f5d3SJohn Marino  * IdleRoutines[] size:
248*86d7f5d3SJohn Marino  *   Each command may invoke CallWhenIdle once.
249*86d7f5d3SJohn Marino  */
250*86d7f5d3SJohn Marino #define MAX_COMMAND_BLOCKS_FOR_EACH_VBUS (MAX_QUEUE_COMM * (1+MAX_MEMBERS*2) + 1)
251*86d7f5d3SJohn Marino #define MAX_PENDING_ROUTINES  (MAX_COMMAND_BLOCKS_FOR_EACH_VBUS+1)
252*86d7f5d3SJohn Marino #define MAX_IDLE_ROUTINES     (MAX_COMMAND_BLOCKS_FOR_EACH_VBUS+1)
253*86d7f5d3SJohn Marino 
254*86d7f5d3SJohn Marino #define mWaitingForIdle(pVBus) ((pVBus)->IdleRoutinesFirst!=(pVBus)->IdleRoutinesLast)
255*86d7f5d3SJohn Marino 
256*86d7f5d3SJohn Marino PCommand HPTLIBAPI AllocateCommand(_VBUS_ARG0);
257*86d7f5d3SJohn Marino void FASTCALL FreeCommand(_VBUS_ARG PCommand pCmd);
258*86d7f5d3SJohn Marino 
259*86d7f5d3SJohn Marino void FASTCALL CallAfterReturn(_VBUS_ARG DPC_PROC proc, void *arg);
260*86d7f5d3SJohn Marino void HPTLIBAPI CheckPendingCall(_VBUS_ARG0);
261*86d7f5d3SJohn Marino void FASTCALL CallWhenIdle(_VBUS_ARG DPC_PROC proc, void *arg);
262*86d7f5d3SJohn Marino void HPTLIBAPI CheckIdleCall(_VBUS_ARG0);
263*86d7f5d3SJohn Marino 
264*86d7f5d3SJohn Marino void HPTLIBAPI AddToWaitingList(PCommand *ppList, PCommand pCmd);
265*86d7f5d3SJohn Marino void HPTLIBAPI DoWaitingList(_VBUS_ARG PCommand *ppList);
266*86d7f5d3SJohn Marino 
267*86d7f5d3SJohn Marino #endif
268