1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 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 #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 original 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-continuous. 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