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