xref: /dflybsd-src/sys/dev/raid/hptmv/command.h (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
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