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