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