186d7f5d3SJohn Marino /* 286d7f5d3SJohn Marino * Copyright (c) 2004-2005 HighPoint Technologies, Inc. 386d7f5d3SJohn Marino * All rights reserved. 486d7f5d3SJohn Marino * 586d7f5d3SJohn Marino * Redistribution and use in source and binary forms, with or without 686d7f5d3SJohn Marino * modification, are permitted provided that the following conditions 786d7f5d3SJohn Marino * are met: 886d7f5d3SJohn Marino * 1. Redistributions of source code must retain the above copyright 986d7f5d3SJohn Marino * notice, this list of conditions and the following disclaimer. 1086d7f5d3SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright 1186d7f5d3SJohn Marino * notice, this list of conditions and the following disclaimer in the 1286d7f5d3SJohn Marino * documentation and/or other materials provided with the distribution. 1386d7f5d3SJohn Marino * 1486d7f5d3SJohn Marino * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1586d7f5d3SJohn Marino * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1686d7f5d3SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1786d7f5d3SJohn Marino * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1886d7f5d3SJohn Marino * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1986d7f5d3SJohn Marino * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2086d7f5d3SJohn Marino * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2186d7f5d3SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2286d7f5d3SJohn Marino * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2386d7f5d3SJohn Marino * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2486d7f5d3SJohn Marino * SUCH DAMAGE. 2586d7f5d3SJohn Marino * 2686d7f5d3SJohn Marino * $FreeBSD: src/sys/dev/hptmv/command.h,v 1.4 2009/04/07 16:38:25 delphij Exp $ 2786d7f5d3SJohn Marino */ 2886d7f5d3SJohn Marino #ifndef _COMMAND_H_ 2986d7f5d3SJohn Marino #define _COMMAND_H_ 3086d7f5d3SJohn Marino 3186d7f5d3SJohn Marino /*************************************************************************** 3286d7f5d3SJohn Marino * Description: Command 3386d7f5d3SJohn Marino ***************************************************************************/ 3486d7f5d3SJohn Marino typedef struct _AtaCommand 3586d7f5d3SJohn Marino { 3686d7f5d3SJohn Marino LBA_T Lba; /* Current Logic Disk command: LBA */ 3786d7f5d3SJohn Marino USHORT nSectors; /* sector count. May great than 0x80 */ 3886d7f5d3SJohn Marino UCHAR Command; /* IDE_COMMAND_READ, _WRITE, _VERIFY */ 3986d7f5d3SJohn Marino UCHAR QueueTag; 4086d7f5d3SJohn Marino } AtaComm, *PAtaComm; 4186d7f5d3SJohn Marino 4286d7f5d3SJohn Marino typedef struct _PassthroughCmd { 4386d7f5d3SJohn Marino BYTE bFeaturesReg; /* feature register */ 4486d7f5d3SJohn Marino BYTE bSectorCountReg; /* IDE sector count register. */ 4586d7f5d3SJohn Marino BYTE bLbaLowReg; /* IDE sector number register. */ 4686d7f5d3SJohn Marino BYTE bLbaMidReg; /* IDE low order cylinder value. */ 4786d7f5d3SJohn Marino BYTE bLbaHighReg; /* IDE high order cylinder value. */ 4886d7f5d3SJohn Marino BYTE bDriveHeadReg; /* IDE drive/head register. */ 4986d7f5d3SJohn Marino BYTE bCommandReg; /* Actual IDE command. Checked for validity by driver. */ 5086d7f5d3SJohn Marino BYTE nSectors; /* data transfer */ 5186d7f5d3SJohn Marino ADDRESS pDataBuffer; /* data buffer */ 5286d7f5d3SJohn Marino } 5386d7f5d3SJohn Marino PassthroughCmd; 5486d7f5d3SJohn Marino 5586d7f5d3SJohn Marino /* control commands */ 5686d7f5d3SJohn Marino #define CTRL_CMD_REBUILD 1 5786d7f5d3SJohn Marino #define CTRL_CMD_VERIFY 2 5886d7f5d3SJohn Marino #define CTRL_CMD_INIT 3 5986d7f5d3SJohn Marino 6086d7f5d3SJohn Marino /* 6186d7f5d3SJohn Marino * RAID5 rebuild/verify 6286d7f5d3SJohn Marino * Rebuild/verify one stripe line. 6386d7f5d3SJohn Marino * The caller needn't supply a buffer for rebuild. 6486d7f5d3SJohn Marino * RebuildSectors member will be updated if its previous location is the 6586d7f5d3SJohn Marino * begin of this stripe line. 6686d7f5d3SJohn Marino */ 6786d7f5d3SJohn Marino typedef struct _R5ControlCmd { 6886d7f5d3SJohn Marino LBA_T StripeLine; /* _physical_ stripe line on array */ 6986d7f5d3SJohn Marino USHORT Offset; /* internal use, don't set */ 7086d7f5d3SJohn Marino UCHAR Command; /* CTRL_CMD_XXX */ 7186d7f5d3SJohn Marino UCHAR reserve1; 7286d7f5d3SJohn Marino } 7386d7f5d3SJohn Marino R5ControlCmd, *PR5ControlCmd; 7486d7f5d3SJohn Marino 7586d7f5d3SJohn Marino /* 7686d7f5d3SJohn Marino * RAID1 rebuild/verify 7786d7f5d3SJohn Marino * Rebuild/verify specified sectors. 7886d7f5d3SJohn Marino * The caller must supply a valid buffer and a physical SG table (or a 7986d7f5d3SJohn Marino * pfnBuildSgl routine). 8086d7f5d3SJohn Marino * For rebuild/initialize, the buffer size should be nSectors<<9; 8186d7f5d3SJohn Marino * For verify, the buffer size should be (nSectors*2)<<9. 8286d7f5d3SJohn Marino * RebuildSectors member will be updated if its previous value equals Lba. 8386d7f5d3SJohn Marino */ 8486d7f5d3SJohn Marino typedef struct _R1ControlCmd { 8586d7f5d3SJohn Marino LBA_T Lba; 8686d7f5d3SJohn Marino USHORT nSectors; 8786d7f5d3SJohn Marino UCHAR Command; /* CTRL_CMD_XXX */ 8886d7f5d3SJohn Marino UCHAR reserve1; 8986d7f5d3SJohn Marino ADDRESS Buffer; /* buffer logical address */ 9086d7f5d3SJohn Marino #ifdef _MACOSX_ 9186d7f5d3SJohn Marino ADDRESS PhysicalAddress; 9286d7f5d3SJohn Marino #endif 9386d7f5d3SJohn Marino } 9486d7f5d3SJohn Marino R1ControlCmd, *PR1ControlCmd; 9586d7f5d3SJohn Marino 9686d7f5d3SJohn Marino typedef struct _Command 9786d7f5d3SJohn Marino { 9886d7f5d3SJohn Marino PVDevice pVDevice; 9986d7f5d3SJohn Marino union{ 10086d7f5d3SJohn Marino /* Ide Command */ 10186d7f5d3SJohn Marino AtaComm Ide; 10286d7f5d3SJohn Marino PassthroughCmd Passthrough; 10386d7f5d3SJohn Marino /* Atapi Command */ 10486d7f5d3SJohn Marino UCHAR Atapi[12]; 10586d7f5d3SJohn Marino /* Control command */ 10686d7f5d3SJohn Marino R5ControlCmd R5Control; 10786d7f5d3SJohn Marino R1ControlCmd R1Control; 10886d7f5d3SJohn Marino } uCmd; 10986d7f5d3SJohn Marino 11086d7f5d3SJohn Marino USHORT cf_physical_sg: 1; 11186d7f5d3SJohn Marino USHORT cf_data_in: 1; 11286d7f5d3SJohn Marino USHORT cf_data_out: 1; 11386d7f5d3SJohn Marino USHORT cf_atapi: 1; 11486d7f5d3SJohn Marino USHORT cf_ide_passthrough: 1; 11586d7f5d3SJohn Marino USHORT cf_control: 1; 11686d7f5d3SJohn Marino 11786d7f5d3SJohn Marino /* return status */ 11886d7f5d3SJohn Marino UCHAR Result; 11986d7f5d3SJohn Marino /* retry count */ 12086d7f5d3SJohn Marino UCHAR RetryCount; 12186d7f5d3SJohn Marino 12286d7f5d3SJohn Marino /* S/G table address, if already prepared */ 12386d7f5d3SJohn Marino FPSCAT_GATH pSgTable; 12486d7f5d3SJohn Marino 12586d7f5d3SJohn Marino /* called if pSgTable is invalid. */ 12686d7f5d3SJohn Marino int (* HPTLIBAPI pfnBuildSgl)(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSgTable, int logical); 12786d7f5d3SJohn Marino 12886d7f5d3SJohn Marino /* called when this command is finished */ 12986d7f5d3SJohn Marino void (* HPTLIBAPI pfnCompletion)(_VBUS_ARG PCommand pCmd); 13086d7f5d3SJohn Marino 13186d7f5d3SJohn Marino /* pointer to origional command */ 13286d7f5d3SJohn Marino void *pOrgCommand; 13386d7f5d3SJohn Marino 13486d7f5d3SJohn Marino 13586d7f5d3SJohn Marino /* scratch data area */ 13686d7f5d3SJohn Marino union { 13786d7f5d3SJohn Marino struct { 13886d7f5d3SJohn Marino LBA_T StartLBA; 13986d7f5d3SJohn Marino UCHAR FirstMember; /* the sequence number of the first member */ 14086d7f5d3SJohn Marino UCHAR LastMember; /* the sequence number of the last member */ 14186d7f5d3SJohn Marino USHORT LastSectors; /* the number of sectors for the last member */ 14286d7f5d3SJohn Marino USHORT FirstSectors; /* the number of sectors for the first member */ 14386d7f5d3SJohn Marino USHORT FirstOffset; /* the offset from the StartLBA for the first member */ 14486d7f5d3SJohn Marino USHORT AllMemberBlocks;/* the number of sectors for all member */ 14586d7f5d3SJohn Marino USHORT WaitInterrupt; /* bit map the members who wait interrupt */ 14686d7f5d3SJohn Marino UCHAR InSameLine; /* if the start and end on the same line */ 14786d7f5d3SJohn Marino UCHAR pad1; 14886d7f5d3SJohn Marino } array; 14986d7f5d3SJohn Marino struct { 15086d7f5d3SJohn Marino LBA_T StartLBA; 15186d7f5d3SJohn Marino USHORT FirstSectors; /* the number of sectors for the first member */ 15286d7f5d3SJohn Marino USHORT FirstOffset; /* the offset from the StartLBA for the first member */ 15386d7f5d3SJohn Marino USHORT WaitInterrupt; /* bit map the members who wait interrupt */ 15486d7f5d3SJohn Marino USHORT r5_gap; /* see raid5.c */ 15586d7f5d3SJohn Marino UCHAR ParDiskNo; /* parity for startLba */ 15686d7f5d3SJohn Marino UCHAR BadDiskNo; 15786d7f5d3SJohn Marino UCHAR FirstMember; 15886d7f5d3SJohn Marino UCHAR pad1; 15986d7f5d3SJohn Marino } r5; 16086d7f5d3SJohn Marino struct { 16186d7f5d3SJohn Marino PCommand pCmd1; 16286d7f5d3SJohn Marino PCommand pCmd2; 16386d7f5d3SJohn Marino } r5split; 16486d7f5d3SJohn Marino #ifdef _RAID5N_ 16586d7f5d3SJohn Marino struct { 16686d7f5d3SJohn Marino ULONG dummy[2]; /* uScratch.wait shall be moved out uScratch. 16786d7f5d3SJohn Marino now just fix it thisway */ 16886d7f5d3SJohn Marino struct range_lock *range_lock; 16986d7f5d3SJohn Marino struct stripe *stripes[5]; 17086d7f5d3SJohn Marino UCHAR nstripes; 17186d7f5d3SJohn Marino UCHAR finished_stripes; 17286d7f5d3SJohn Marino USHORT pad2; 17386d7f5d3SJohn Marino /* for direct-read: */ 17486d7f5d3SJohn Marino struct { 17586d7f5d3SJohn Marino UCHAR cmds; 17686d7f5d3SJohn Marino UCHAR finished; 17786d7f5d3SJohn Marino UCHAR first; 17886d7f5d3SJohn Marino UCHAR parity; 17986d7f5d3SJohn Marino LBA_T base; 18086d7f5d3SJohn Marino USHORT firstoffset; 18186d7f5d3SJohn Marino USHORT firstsectors; 18286d7f5d3SJohn Marino } dr; 18386d7f5d3SJohn Marino } r5n2; 18486d7f5d3SJohn Marino #endif 18586d7f5d3SJohn Marino struct { 18686d7f5d3SJohn Marino ULONG WordsLeft; 18786d7f5d3SJohn Marino FPSCAT_GATH pPIOSg; 18886d7f5d3SJohn Marino void (* HPTLIBAPI pfnOrgDone)(_VBUS_ARG PCommand pCmd); 18986d7f5d3SJohn Marino #ifdef SUPPORT_HPT584 19086d7f5d3SJohn Marino UCHAR cmd; 19186d7f5d3SJohn Marino #endif 19286d7f5d3SJohn Marino } disk; 19386d7f5d3SJohn Marino struct { 19486d7f5d3SJohn Marino PCommand pNext; 19586d7f5d3SJohn Marino void (* HPTLIBAPI WaitEntry)(_VBUS_ARG PCommand pCmd); 19686d7f5d3SJohn Marino } wait; 19786d7f5d3SJohn Marino 19886d7f5d3SJohn Marino struct { 19986d7f5d3SJohn Marino PVOID prdAddr; 20086d7f5d3SJohn Marino ULONG cmd_priv; 20186d7f5d3SJohn Marino USHORT responseFlags; 20286d7f5d3SJohn Marino UCHAR bIdeStatus; 20386d7f5d3SJohn Marino UCHAR errorRegister; 20486d7f5d3SJohn Marino } sata_param; 20586d7f5d3SJohn Marino } uScratch; 20686d7f5d3SJohn Marino } Command; 20786d7f5d3SJohn Marino 20886d7f5d3SJohn Marino /*************************************************************************** 20986d7f5d3SJohn Marino * command return value 21086d7f5d3SJohn Marino ***************************************************************************/ 21186d7f5d3SJohn Marino #define RETURN_PENDING 0 21286d7f5d3SJohn Marino #define RETURN_SUCCESS 1 21386d7f5d3SJohn Marino #define RETURN_BAD_DEVICE 2 21486d7f5d3SJohn Marino #define RETURN_BAD_PARAMETER 3 21586d7f5d3SJohn Marino #define RETURN_WRITE_NO_DRQ 4 21686d7f5d3SJohn Marino #define RETURN_DEVICE_BUSY 5 21786d7f5d3SJohn Marino #define RETURN_INVALID_REQUEST 6 21886d7f5d3SJohn Marino #define RETURN_SELECTION_TIMEOUT 7 21986d7f5d3SJohn Marino #define RETURN_IDE_ERROR 8 22086d7f5d3SJohn Marino #define RETURN_NEED_LOGICAL_SG 9 22186d7f5d3SJohn Marino #define RETURN_NEED_PHYSICAL_SG 10 22286d7f5d3SJohn Marino #define RETURN_RETRY 11 22386d7f5d3SJohn Marino #define RETURN_DATA_ERROR 12 22486d7f5d3SJohn Marino #define RETURN_BUS_RESET 13 22586d7f5d3SJohn Marino #define RETURN_BAD_TRANSFER_LENGTH 14 22686d7f5d3SJohn Marino 22786d7f5d3SJohn Marino typedef void (* HPTLIBAPI DPC_PROC)(_VBUS_ARG void *); 22886d7f5d3SJohn Marino typedef struct _dpc_routine { 22986d7f5d3SJohn Marino DPC_PROC proc; 23086d7f5d3SJohn Marino void *arg; 23186d7f5d3SJohn Marino } 23286d7f5d3SJohn Marino DPC_ROUTINE; 23386d7f5d3SJohn Marino 23486d7f5d3SJohn Marino /* 23586d7f5d3SJohn Marino * MAX_QUEUE_COMM is defined in platform related compiler.h 23686d7f5d3SJohn Marino * to specify the maximum requests allowed (for each VBus) from system. 23786d7f5d3SJohn Marino * 23886d7f5d3SJohn Marino * Maximum command blocks needed for each VBus: 23986d7f5d3SJohn Marino * Each OS command requests 1+MAX_MEMBERS*2 command blocks (RAID1/0 case) 24086d7f5d3SJohn Marino * This space is allocated by platform dependent part, either static or 24186d7f5d3SJohn Marino * dynamic, continuous or non-continous. 24286d7f5d3SJohn Marino * The code only needs _vbus_(pFreeCommands) to be set. 24386d7f5d3SJohn Marino * 24486d7f5d3SJohn Marino * PendingRoutines[] size: 24586d7f5d3SJohn Marino * Each command may invoke CallAfterReturn once. 24686d7f5d3SJohn Marino * 24786d7f5d3SJohn Marino * IdleRoutines[] size: 24886d7f5d3SJohn Marino * Each command may invoke CallWhenIdle once. 24986d7f5d3SJohn Marino */ 25086d7f5d3SJohn Marino #define MAX_COMMAND_BLOCKS_FOR_EACH_VBUS (MAX_QUEUE_COMM * (1+MAX_MEMBERS*2) + 1) 25186d7f5d3SJohn Marino #define MAX_PENDING_ROUTINES (MAX_COMMAND_BLOCKS_FOR_EACH_VBUS+1) 25286d7f5d3SJohn Marino #define MAX_IDLE_ROUTINES (MAX_COMMAND_BLOCKS_FOR_EACH_VBUS+1) 25386d7f5d3SJohn Marino 25486d7f5d3SJohn Marino #define mWaitingForIdle(pVBus) ((pVBus)->IdleRoutinesFirst!=(pVBus)->IdleRoutinesLast) 25586d7f5d3SJohn Marino 25686d7f5d3SJohn Marino PCommand HPTLIBAPI AllocateCommand(_VBUS_ARG0); 25786d7f5d3SJohn Marino void FASTCALL FreeCommand(_VBUS_ARG PCommand pCmd); 25886d7f5d3SJohn Marino 25986d7f5d3SJohn Marino void FASTCALL CallAfterReturn(_VBUS_ARG DPC_PROC proc, void *arg); 26086d7f5d3SJohn Marino void HPTLIBAPI CheckPendingCall(_VBUS_ARG0); 26186d7f5d3SJohn Marino void FASTCALL CallWhenIdle(_VBUS_ARG DPC_PROC proc, void *arg); 26286d7f5d3SJohn Marino void HPTLIBAPI CheckIdleCall(_VBUS_ARG0); 26386d7f5d3SJohn Marino 26486d7f5d3SJohn Marino void HPTLIBAPI AddToWaitingList(PCommand *ppList, PCommand pCmd); 26586d7f5d3SJohn Marino void HPTLIBAPI DoWaitingList(_VBUS_ARG PCommand *ppList); 26686d7f5d3SJohn Marino 26786d7f5d3SJohn Marino #endif 268