xref: /freebsd/sys/dev/hptmv/command.h (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
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