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