summaryrefslogtreecommitdiffstats
path: root/sys/dev/hptmv/command.h
blob: dbc0bd67ce7dcdf443f75b4c65d2a7e486349838 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
/*
 * Copyright (c) 2003-2004 HighPoint Technologies, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD$
 */
#ifndef _COMMAND_H_
#define _COMMAND_H_

/***************************************************************************
 * Description: Command
 ***************************************************************************/
typedef struct _AtaCommand
{
	LBA_T            Lba;          /* Current Logic Disk command: LBA   */
	USHORT           nSectors;     /* sector count. May great than 0x80 */	
	UCHAR            Command;      /* IDE_COMMAND_READ, _WRITE, _VERIFY */
	UCHAR            QueueTag;
} AtaComm, *PAtaComm;

typedef struct _PassthroughCmd {
	BYTE     bFeaturesReg;     /* feature register */
	BYTE     bSectorCountReg;  /* IDE sector count register. */
	BYTE     bSectorNumberReg; /* IDE sector number register. */
	BYTE     bCylLowReg;       /* IDE low order cylinder value. */
	BYTE     bCylHighReg;      /* IDE high order cylinder value. */
	BYTE     bDriveHeadReg;    /* IDE drive/head register. */
	BYTE     bCommandReg;      /* Actual IDE command. Checked for validity by driver. */
	BYTE     nSectors;         /* data transfer */
	ADDRESS  pDataBuffer;      /* data buffer */
}
PassthroughCmd;

/* control commands */
#define CTRL_CMD_REBUILD 1
#define CTRL_CMD_VERIFY  2
#define CTRL_CMD_INIT    3

/* 
 * RAID5 rebuild/verify
 *   Rebuild/verify one stripe line.
 *   The caller needn't supply a buffer for rebuild.
 *   RebuildSectors member will be updated if its previous location is the 
 *   begin of this stripe line.
 */
typedef struct _R5ControlCmd {
	LBA_T  StripeLine;   /* _physical_ stripe line on array */
	USHORT Offset;       /* internal use, don't set */
	UCHAR  Command;      /* CTRL_CMD_XXX */
	UCHAR  reserve1;
}
R5ControlCmd, *PR5ControlCmd;

/* 
 * RAID1 rebuild/verify 
 *   Rebuild/verify specified sectors.
 *   The caller must supply a valid buffer and a physical SG table (or a
 *   pfnBuildSgl routine).
 *   For rebuild/initialize, the buffer size should be nSectors<<9;
 *   For verify, the buffer size should be (nSectors*2)<<9.
 *   RebuildSectors member will be updated if its previous value equals Lba.
 */
typedef struct _R1ControlCmd {
	LBA_T  Lba;
	USHORT nSectors;
	UCHAR  Command;      /* CTRL_CMD_XXX */
	UCHAR  reserve1;
	ADDRESS Buffer;  /* buffer logical address */
#ifdef _MACOSX_
	ADDRESS PhysicalAddress;
#endif
}
R1ControlCmd, *PR1ControlCmd;

typedef struct _Command
{
	PVDevice pVDevice;
	union{
		/* Ide Command */
		AtaComm Ide;
		PassthroughCmd Passthrough;
		/* Atapi Command */
		UCHAR Atapi[12];
		/* Control command */
		R5ControlCmd R5Control;
		R1ControlCmd R1Control;
	} uCmd;
	
	USHORT	cf_physical_sg: 1;
	USHORT	cf_data_in: 1;
	USHORT	cf_data_out: 1;
	USHORT	cf_atapi: 1;
	USHORT	cf_ide_passthrough: 1;
	USHORT  cf_control: 1;

	/* return status */
	UCHAR	Result;
	/* retry count */
	UCHAR   RetryCount;

	/* S/G table address, if already prepared */
	FPSCAT_GATH pSgTable;
	
	/* called if pSgTable is invalid. */
	int (* HPTLIBAPI pfnBuildSgl)(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSgTable, int logical);
	
	/* called when this command is finished */
	void (* HPTLIBAPI pfnCompletion)(_VBUS_ARG PCommand pCmd);
	
	/* pointer to origional command */
	void *pOrgCommand;


	/* scratch data area */
	union {
		struct {
			LBA_T      StartLBA;
			UCHAR      FirstMember;    /* the sequence number of the first member */
			UCHAR      LastMember;     /* the sequence number of the last member */
			USHORT     LastSectors;    /* the number of sectors for the last member */
			USHORT     FirstSectors;   /* the number of sectors for the first member */
			USHORT     FirstOffset;    /* the offset from the StartLBA for the first member */
			USHORT     AllMemberBlocks;/* the number of sectors for all member */
			USHORT     WaitInterrupt;  /* bit map the members who wait interrupt */
			UCHAR      InSameLine;     /* if the start and end on the same line */
			UCHAR      pad1;
		} array;
		struct {
			LBA_T      StartLBA;
			USHORT     FirstSectors;   /* the number of sectors for the first member */
			USHORT     FirstOffset;    /* the offset from the StartLBA for the first member */
			USHORT     WaitInterrupt;  /* bit map the members who wait interrupt */
			USHORT     r5_gap;         /* see raid5.c */
			UCHAR      ParDiskNo;      /* parity for startLba */
			UCHAR      BadDiskNo;
			UCHAR      FirstMember;
			UCHAR      pad1;
		} r5;
		struct {
			PCommand pCmd1;
			PCommand pCmd2;
		} r5split;
#ifdef _RAID5N_
		struct {
			ULONG dummy[2]; /* uScratch.wait shall be moved out uScratch.
							   now just fix it thisway */
			struct range_lock *range_lock;
			struct stripe *stripes[5]; 
			UCHAR nstripes;
			UCHAR finished_stripes;
			USHORT pad2;
			/* for direct-read: */
			struct {
				UCHAR  cmds;
				UCHAR  finished;
				UCHAR  first;
				UCHAR  parity;
				LBA_T  base;
				USHORT firstoffset;
				USHORT firstsectors;
			} dr;
		} r5n2;
#endif
		struct {
			ULONG WordsLeft;
			FPSCAT_GATH pPIOSg;
			void (* HPTLIBAPI pfnOrgDone)(_VBUS_ARG PCommand pCmd);
#ifdef SUPPORT_HPT584
			UCHAR cmd;
#endif
		} disk;
		struct {
			PCommand pNext;
			void (* HPTLIBAPI WaitEntry)(_VBUS_ARG PCommand pCmd);
		} wait;
		
		struct {
			PVOID prdAddr;
			ULONG cmd_priv;
			USHORT responseFlags;
			UCHAR  bIdeStatus;
			UCHAR  errorRegister;
		} sata_param;
	} uScratch;
} Command;

/***************************************************************************
 * command return value
 ***************************************************************************/
#define   RETURN_PENDING             0
#define   RETURN_SUCCESS             1
#define   RETURN_BAD_DEVICE          2
#define   RETURN_BAD_PARAMETER       3
#define   RETURN_WRITE_NO_DRQ        4
#define   RETURN_DEVICE_BUSY         5
#define   RETURN_INVALID_REQUEST     6
#define   RETURN_SELECTION_TIMEOUT   7
#define   RETURN_IDE_ERROR           8
#define   RETURN_NEED_LOGICAL_SG     9
#define   RETURN_NEED_PHYSICAL_SG    10
#define   RETURN_RETRY               11
#define   RETURN_DATA_ERROR          12
#define   RETURN_BUS_RESET           13
#define   RETURN_BAD_TRANSFER_LENGTH 14

typedef void (* HPTLIBAPI DPC_PROC)(_VBUS_ARG void *);
typedef struct _dpc_routine {
	DPC_PROC proc;
	void *arg;
}
DPC_ROUTINE;

/*
 * MAX_QUEUE_COMM is defined in platform related compiler.h
 * to specify the maximum requests allowed (for each VBus) from system.
 *
 * Maximum command blocks needed for each VBus:
 *   Each OS command requests 1+MAX_MEMBERS*2 command blocks (RAID1/0 case)
 *   This space is allocated by platform dependent part, either static or 
 *   dynamic, continuous or non-continous.
 *   The code only needs _vbus_(pFreeCommands) to be set.
 *
 * PendingRoutines[] size:
 *   Each command may invoke CallAfterReturn once.
 *
 * IdleRoutines[] size:
 *   Each command may invoke CallWhenIdle once.
 */
#define MAX_COMMAND_BLOCKS_FOR_EACH_VBUS (MAX_QUEUE_COMM * (1+MAX_MEMBERS*2))
#define MAX_PENDING_ROUTINES  (MAX_COMMAND_BLOCKS_FOR_EACH_VBUS+1)
#define MAX_IDLE_ROUTINES     (MAX_COMMAND_BLOCKS_FOR_EACH_VBUS+1)

#define mWaitingForIdle(pVBus) ((pVBus)->IdleRoutinesFirst!=(pVBus)->IdleRoutinesLast)

PCommand HPTLIBAPI AllocateCommand(_VBUS_ARG0);
void FASTCALL FreeCommand(_VBUS_ARG PCommand pCmd);

void FASTCALL CallAfterReturn(_VBUS_ARG DPC_PROC proc, void *arg);
void HPTLIBAPI CheckPendingCall(_VBUS_ARG0);
void FASTCALL CallWhenIdle(_VBUS_ARG DPC_PROC proc, void *arg);
void HPTLIBAPI CheckIdleCall(_VBUS_ARG0);

void HPTLIBAPI AddToWaitingList(PCommand *ppList, PCommand pCmd);
void HPTLIBAPI DoWaitingList(_VBUS_ARG PCommand *ppList);

#endif
OpenPOWER on IntegriCloud