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