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