1718cf2ccSPedro F. Giffuni /*- 2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 3718cf2ccSPedro F. Giffuni * 4d2bd3ab9SScott Long * Copyright (c) 2004-2005 HighPoint Technologies, Inc. 51713e81bSScott Long * All rights reserved. 61713e81bSScott Long * 71713e81bSScott Long * Redistribution and use in source and binary forms, with or without 81713e81bSScott Long * modification, are permitted provided that the following conditions 91713e81bSScott Long * are met: 101713e81bSScott Long * 1. Redistributions of source code must retain the above copyright 111713e81bSScott Long * notice, this list of conditions and the following disclaimer. 121713e81bSScott Long * 2. Redistributions in binary form must reproduce the above copyright 131713e81bSScott Long * notice, this list of conditions and the following disclaimer in the 141713e81bSScott Long * documentation and/or other materials provided with the distribution. 151713e81bSScott Long * 161713e81bSScott Long * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 171713e81bSScott Long * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 181713e81bSScott Long * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 191713e81bSScott Long * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 201713e81bSScott Long * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 211713e81bSScott Long * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 221713e81bSScott Long * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 231713e81bSScott Long * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 241713e81bSScott Long * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 251713e81bSScott Long * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 261713e81bSScott Long * SUCH DAMAGE. 271713e81bSScott Long */ 281713e81bSScott Long #ifndef _COMMAND_H_ 291713e81bSScott Long #define _COMMAND_H_ 301713e81bSScott Long 311713e81bSScott Long /*************************************************************************** 321713e81bSScott Long * Description: Command 331713e81bSScott Long ***************************************************************************/ 341713e81bSScott Long typedef struct _AtaCommand 351713e81bSScott Long { 361713e81bSScott Long LBA_T Lba; /* Current Logic Disk command: LBA */ 371713e81bSScott Long USHORT nSectors; /* sector count. May great than 0x80 */ 381713e81bSScott Long UCHAR Command; /* IDE_COMMAND_READ, _WRITE, _VERIFY */ 391713e81bSScott Long UCHAR QueueTag; 401713e81bSScott Long } AtaComm, *PAtaComm; 411713e81bSScott Long 421713e81bSScott Long typedef struct _PassthroughCmd { 431713e81bSScott Long BYTE bFeaturesReg; /* feature register */ 441713e81bSScott Long BYTE bSectorCountReg; /* IDE sector count register. */ 4564470755SXin LI BYTE bLbaLowReg; /* IDE sector number register. */ 4664470755SXin LI BYTE bLbaMidReg; /* IDE low order cylinder value. */ 4764470755SXin LI BYTE bLbaHighReg; /* IDE high order cylinder value. */ 481713e81bSScott Long BYTE bDriveHeadReg; /* IDE drive/head register. */ 491713e81bSScott Long BYTE bCommandReg; /* Actual IDE command. Checked for validity by driver. */ 501713e81bSScott Long BYTE nSectors; /* data transfer */ 511713e81bSScott Long ADDRESS pDataBuffer; /* data buffer */ 521713e81bSScott Long } 531713e81bSScott Long PassthroughCmd; 541713e81bSScott Long 551713e81bSScott Long /* control commands */ 561713e81bSScott Long #define CTRL_CMD_REBUILD 1 571713e81bSScott Long #define CTRL_CMD_VERIFY 2 581713e81bSScott Long #define CTRL_CMD_INIT 3 591713e81bSScott Long 601713e81bSScott Long /* 611713e81bSScott Long * RAID5 rebuild/verify 621713e81bSScott Long * Rebuild/verify one stripe line. 631713e81bSScott Long * The caller needn't supply a buffer for rebuild. 641713e81bSScott Long * RebuildSectors member will be updated if its previous location is the 651713e81bSScott Long * begin of this stripe line. 661713e81bSScott Long */ 671713e81bSScott Long typedef struct _R5ControlCmd { 681713e81bSScott Long LBA_T StripeLine; /* _physical_ stripe line on array */ 691713e81bSScott Long USHORT Offset; /* internal use, don't set */ 701713e81bSScott Long UCHAR Command; /* CTRL_CMD_XXX */ 711713e81bSScott Long UCHAR reserve1; 721713e81bSScott Long } 731713e81bSScott Long R5ControlCmd, *PR5ControlCmd; 741713e81bSScott Long 751713e81bSScott Long /* 761713e81bSScott Long * RAID1 rebuild/verify 771713e81bSScott Long * Rebuild/verify specified sectors. 781713e81bSScott Long * The caller must supply a valid buffer and a physical SG table (or a 791713e81bSScott Long * pfnBuildSgl routine). 801713e81bSScott Long * For rebuild/initialize, the buffer size should be nSectors<<9; 811713e81bSScott Long * For verify, the buffer size should be (nSectors*2)<<9. 821713e81bSScott Long * RebuildSectors member will be updated if its previous value equals Lba. 831713e81bSScott Long */ 841713e81bSScott Long typedef struct _R1ControlCmd { 851713e81bSScott Long LBA_T Lba; 861713e81bSScott Long USHORT nSectors; 871713e81bSScott Long UCHAR Command; /* CTRL_CMD_XXX */ 881713e81bSScott Long UCHAR reserve1; 891713e81bSScott Long ADDRESS Buffer; /* buffer logical address */ 901713e81bSScott Long #ifdef _MACOSX_ 911713e81bSScott Long ADDRESS PhysicalAddress; 921713e81bSScott Long #endif 931713e81bSScott Long } 941713e81bSScott Long R1ControlCmd, *PR1ControlCmd; 951713e81bSScott Long 961713e81bSScott Long typedef struct _Command 971713e81bSScott Long { 981713e81bSScott Long PVDevice pVDevice; 991713e81bSScott Long union{ 1001713e81bSScott Long /* Ide Command */ 1011713e81bSScott Long AtaComm Ide; 1021713e81bSScott Long PassthroughCmd Passthrough; 1031713e81bSScott Long /* Atapi Command */ 1041713e81bSScott Long UCHAR Atapi[12]; 1051713e81bSScott Long /* Control command */ 1061713e81bSScott Long R5ControlCmd R5Control; 1071713e81bSScott Long R1ControlCmd R1Control; 1081713e81bSScott Long } uCmd; 1091713e81bSScott Long 1101713e81bSScott Long USHORT cf_physical_sg: 1; 1111713e81bSScott Long USHORT cf_data_in: 1; 1121713e81bSScott Long USHORT cf_data_out: 1; 1131713e81bSScott Long USHORT cf_atapi: 1; 1141713e81bSScott Long USHORT cf_ide_passthrough: 1; 1151713e81bSScott Long USHORT cf_control: 1; 1161713e81bSScott Long 1171713e81bSScott Long /* return status */ 1181713e81bSScott Long UCHAR Result; 1191713e81bSScott Long /* retry count */ 1201713e81bSScott Long UCHAR RetryCount; 1211713e81bSScott Long 1221713e81bSScott Long /* S/G table address, if already prepared */ 1231713e81bSScott Long FPSCAT_GATH pSgTable; 1241713e81bSScott Long 1251713e81bSScott Long /* called if pSgTable is invalid. */ 1261713e81bSScott Long int (* HPTLIBAPI pfnBuildSgl)(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSgTable, int logical); 1271713e81bSScott Long 1281713e81bSScott Long /* called when this command is finished */ 1291713e81bSScott Long void (* HPTLIBAPI pfnCompletion)(_VBUS_ARG PCommand pCmd); 1301713e81bSScott Long 131453130d9SPedro F. Giffuni /* pointer to original command */ 1321713e81bSScott Long void *pOrgCommand; 1331713e81bSScott Long 1341713e81bSScott Long 1351713e81bSScott Long /* scratch data area */ 1361713e81bSScott Long union { 1371713e81bSScott Long struct { 1381713e81bSScott Long LBA_T StartLBA; 1391713e81bSScott Long UCHAR FirstMember; /* the sequence number of the first member */ 1401713e81bSScott Long UCHAR LastMember; /* the sequence number of the last member */ 1411713e81bSScott Long USHORT LastSectors; /* the number of sectors for the last member */ 1421713e81bSScott Long USHORT FirstSectors; /* the number of sectors for the first member */ 1431713e81bSScott Long USHORT FirstOffset; /* the offset from the StartLBA for the first member */ 1441713e81bSScott Long USHORT AllMemberBlocks;/* the number of sectors for all member */ 1451713e81bSScott Long USHORT WaitInterrupt; /* bit map the members who wait interrupt */ 1461713e81bSScott Long UCHAR InSameLine; /* if the start and end on the same line */ 1471713e81bSScott Long UCHAR pad1; 1481713e81bSScott Long } array; 1491713e81bSScott Long struct { 1501713e81bSScott Long LBA_T StartLBA; 1511713e81bSScott Long USHORT FirstSectors; /* the number of sectors for the first member */ 1521713e81bSScott Long USHORT FirstOffset; /* the offset from the StartLBA for the first member */ 1531713e81bSScott Long USHORT WaitInterrupt; /* bit map the members who wait interrupt */ 1541713e81bSScott Long USHORT r5_gap; /* see raid5.c */ 1551713e81bSScott Long UCHAR ParDiskNo; /* parity for startLba */ 1561713e81bSScott Long UCHAR BadDiskNo; 1571713e81bSScott Long UCHAR FirstMember; 1581713e81bSScott Long UCHAR pad1; 1591713e81bSScott Long } r5; 1601713e81bSScott Long struct { 1611713e81bSScott Long PCommand pCmd1; 1621713e81bSScott Long PCommand pCmd2; 1631713e81bSScott Long } r5split; 1641713e81bSScott Long #ifdef _RAID5N_ 1651713e81bSScott Long struct { 1661713e81bSScott Long ULONG dummy[2]; /* uScratch.wait shall be moved out uScratch. 1671713e81bSScott Long now just fix it thisway */ 1681713e81bSScott Long struct range_lock *range_lock; 1691713e81bSScott Long struct stripe *stripes[5]; 1701713e81bSScott Long UCHAR nstripes; 1711713e81bSScott Long UCHAR finished_stripes; 1721713e81bSScott Long USHORT pad2; 1731713e81bSScott Long /* for direct-read: */ 1741713e81bSScott Long struct { 1751713e81bSScott Long UCHAR cmds; 1761713e81bSScott Long UCHAR finished; 1771713e81bSScott Long UCHAR first; 1781713e81bSScott Long UCHAR parity; 1791713e81bSScott Long LBA_T base; 1801713e81bSScott Long USHORT firstoffset; 1811713e81bSScott Long USHORT firstsectors; 1821713e81bSScott Long } dr; 1831713e81bSScott Long } r5n2; 1841713e81bSScott Long #endif 1851713e81bSScott Long struct { 1861713e81bSScott Long ULONG WordsLeft; 1871713e81bSScott Long FPSCAT_GATH pPIOSg; 1881713e81bSScott Long void (* HPTLIBAPI pfnOrgDone)(_VBUS_ARG PCommand pCmd); 1891713e81bSScott Long #ifdef SUPPORT_HPT584 1901713e81bSScott Long UCHAR cmd; 1911713e81bSScott Long #endif 1921713e81bSScott Long } disk; 1931713e81bSScott Long struct { 1941713e81bSScott Long PCommand pNext; 1951713e81bSScott Long void (* HPTLIBAPI WaitEntry)(_VBUS_ARG PCommand pCmd); 1961713e81bSScott Long } wait; 1971713e81bSScott Long 1981713e81bSScott Long struct { 1991713e81bSScott Long PVOID prdAddr; 2001713e81bSScott Long ULONG cmd_priv; 2011713e81bSScott Long USHORT responseFlags; 2021713e81bSScott Long UCHAR bIdeStatus; 2031713e81bSScott Long UCHAR errorRegister; 2041713e81bSScott Long } sata_param; 2051713e81bSScott Long } uScratch; 2061713e81bSScott Long } Command; 2071713e81bSScott Long 2081713e81bSScott Long /*************************************************************************** 2091713e81bSScott Long * command return value 2101713e81bSScott Long ***************************************************************************/ 2111713e81bSScott Long #define RETURN_PENDING 0 2121713e81bSScott Long #define RETURN_SUCCESS 1 2131713e81bSScott Long #define RETURN_BAD_DEVICE 2 2141713e81bSScott Long #define RETURN_BAD_PARAMETER 3 2151713e81bSScott Long #define RETURN_WRITE_NO_DRQ 4 2161713e81bSScott Long #define RETURN_DEVICE_BUSY 5 2171713e81bSScott Long #define RETURN_INVALID_REQUEST 6 2181713e81bSScott Long #define RETURN_SELECTION_TIMEOUT 7 2191713e81bSScott Long #define RETURN_IDE_ERROR 8 2201713e81bSScott Long #define RETURN_NEED_LOGICAL_SG 9 2211713e81bSScott Long #define RETURN_NEED_PHYSICAL_SG 10 2221713e81bSScott Long #define RETURN_RETRY 11 2231713e81bSScott Long #define RETURN_DATA_ERROR 12 2241713e81bSScott Long #define RETURN_BUS_RESET 13 2251713e81bSScott Long #define RETURN_BAD_TRANSFER_LENGTH 14 2261713e81bSScott Long 2271713e81bSScott Long typedef void (* HPTLIBAPI DPC_PROC)(_VBUS_ARG void *); 2281713e81bSScott Long typedef struct _dpc_routine { 2291713e81bSScott Long DPC_PROC proc; 2301713e81bSScott Long void *arg; 2311713e81bSScott Long } 2321713e81bSScott Long DPC_ROUTINE; 2331713e81bSScott Long 2341713e81bSScott Long /* 2351713e81bSScott Long * MAX_QUEUE_COMM is defined in platform related compiler.h 2361713e81bSScott Long * to specify the maximum requests allowed (for each VBus) from system. 2371713e81bSScott Long * 2381713e81bSScott Long * Maximum command blocks needed for each VBus: 2391713e81bSScott Long * Each OS command requests 1+MAX_MEMBERS*2 command blocks (RAID1/0 case) 2401713e81bSScott Long * This space is allocated by platform dependent part, either static or 241bbb0ca45SGordon Bergling * dynamic, continuous or non-continuous. 2421713e81bSScott Long * The code only needs _vbus_(pFreeCommands) to be set. 2431713e81bSScott Long * 2441713e81bSScott Long * PendingRoutines[] size: 2451713e81bSScott Long * Each command may invoke CallAfterReturn once. 2461713e81bSScott Long * 2471713e81bSScott Long * IdleRoutines[] size: 2481713e81bSScott Long * Each command may invoke CallWhenIdle once. 2491713e81bSScott Long */ 25064470755SXin LI #define MAX_COMMAND_BLOCKS_FOR_EACH_VBUS (MAX_QUEUE_COMM * (1+MAX_MEMBERS*2) + 1) 2511713e81bSScott Long #define MAX_PENDING_ROUTINES (MAX_COMMAND_BLOCKS_FOR_EACH_VBUS+1) 2521713e81bSScott Long #define MAX_IDLE_ROUTINES (MAX_COMMAND_BLOCKS_FOR_EACH_VBUS+1) 2531713e81bSScott Long 2541713e81bSScott Long #define mWaitingForIdle(pVBus) ((pVBus)->IdleRoutinesFirst!=(pVBus)->IdleRoutinesLast) 2551713e81bSScott Long 2561713e81bSScott Long PCommand HPTLIBAPI AllocateCommand(_VBUS_ARG0); 2571713e81bSScott Long void FASTCALL FreeCommand(_VBUS_ARG PCommand pCmd); 2581713e81bSScott Long 2591713e81bSScott Long void FASTCALL CallAfterReturn(_VBUS_ARG DPC_PROC proc, void *arg); 2601713e81bSScott Long void HPTLIBAPI CheckPendingCall(_VBUS_ARG0); 2611713e81bSScott Long void FASTCALL CallWhenIdle(_VBUS_ARG DPC_PROC proc, void *arg); 2621713e81bSScott Long void HPTLIBAPI CheckIdleCall(_VBUS_ARG0); 2631713e81bSScott Long 2641713e81bSScott Long void HPTLIBAPI AddToWaitingList(PCommand *ppList, PCommand pCmd); 2651713e81bSScott Long void HPTLIBAPI DoWaitingList(_VBUS_ARG PCommand *ppList); 2661713e81bSScott Long 2671713e81bSScott Long #endif 268