268 lines
8.7 KiB
C
268 lines
8.7 KiB
C
/*-
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*
|
|
* Copyright (c) 2004-2005 HighPoint Technologies, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*/
|
|
#ifndef _COMMAND_H_
|
|
#define _COMMAND_H_
|
|
|
|
/***************************************************************************
|
|
* Description: Command
|
|
***************************************************************************/
|
|
typedef struct _AtaCommand
|
|
{
|
|
LBA_T Lba; /* Current Logic Disk command: LBA */
|
|
USHORT nSectors; /* sector count. May great than 0x80 */
|
|
UCHAR Command; /* IDE_COMMAND_READ, _WRITE, _VERIFY */
|
|
UCHAR QueueTag;
|
|
} AtaComm, *PAtaComm;
|
|
|
|
typedef struct _PassthroughCmd {
|
|
BYTE bFeaturesReg; /* feature register */
|
|
BYTE bSectorCountReg; /* IDE sector count register. */
|
|
BYTE bLbaLowReg; /* IDE sector number register. */
|
|
BYTE bLbaMidReg; /* IDE low order cylinder value. */
|
|
BYTE bLbaHighReg; /* IDE high order cylinder value. */
|
|
BYTE bDriveHeadReg; /* IDE drive/head register. */
|
|
BYTE bCommandReg; /* Actual IDE command. Checked for validity by driver. */
|
|
BYTE nSectors; /* data transfer */
|
|
ADDRESS pDataBuffer; /* data buffer */
|
|
}
|
|
PassthroughCmd;
|
|
|
|
/* control commands */
|
|
#define CTRL_CMD_REBUILD 1
|
|
#define CTRL_CMD_VERIFY 2
|
|
#define CTRL_CMD_INIT 3
|
|
|
|
/*
|
|
* RAID5 rebuild/verify
|
|
* Rebuild/verify one stripe line.
|
|
* The caller needn't supply a buffer for rebuild.
|
|
* RebuildSectors member will be updated if its previous location is the
|
|
* begin of this stripe line.
|
|
*/
|
|
typedef struct _R5ControlCmd {
|
|
LBA_T StripeLine; /* _physical_ stripe line on array */
|
|
USHORT Offset; /* internal use, don't set */
|
|
UCHAR Command; /* CTRL_CMD_XXX */
|
|
UCHAR reserve1;
|
|
}
|
|
R5ControlCmd, *PR5ControlCmd;
|
|
|
|
/*
|
|
* RAID1 rebuild/verify
|
|
* Rebuild/verify specified sectors.
|
|
* The caller must supply a valid buffer and a physical SG table (or a
|
|
* pfnBuildSgl routine).
|
|
* For rebuild/initialize, the buffer size should be nSectors<<9;
|
|
* For verify, the buffer size should be (nSectors*2)<<9.
|
|
* RebuildSectors member will be updated if its previous value equals Lba.
|
|
*/
|
|
typedef struct _R1ControlCmd {
|
|
LBA_T Lba;
|
|
USHORT nSectors;
|
|
UCHAR Command; /* CTRL_CMD_XXX */
|
|
UCHAR reserve1;
|
|
ADDRESS Buffer; /* buffer logical address */
|
|
#ifdef _MACOSX_
|
|
ADDRESS PhysicalAddress;
|
|
#endif
|
|
}
|
|
R1ControlCmd, *PR1ControlCmd;
|
|
|
|
typedef struct _Command
|
|
{
|
|
PVDevice pVDevice;
|
|
union{
|
|
/* Ide Command */
|
|
AtaComm Ide;
|
|
PassthroughCmd Passthrough;
|
|
/* Atapi Command */
|
|
UCHAR Atapi[12];
|
|
/* Control command */
|
|
R5ControlCmd R5Control;
|
|
R1ControlCmd R1Control;
|
|
} uCmd;
|
|
|
|
USHORT cf_physical_sg: 1;
|
|
USHORT cf_data_in: 1;
|
|
USHORT cf_data_out: 1;
|
|
USHORT cf_atapi: 1;
|
|
USHORT cf_ide_passthrough: 1;
|
|
USHORT cf_control: 1;
|
|
|
|
/* return status */
|
|
UCHAR Result;
|
|
/* retry count */
|
|
UCHAR RetryCount;
|
|
|
|
/* S/G table address, if already prepared */
|
|
FPSCAT_GATH pSgTable;
|
|
|
|
/* called if pSgTable is invalid. */
|
|
int (* HPTLIBAPI pfnBuildSgl)(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSgTable, int logical);
|
|
|
|
/* called when this command is finished */
|
|
void (* HPTLIBAPI pfnCompletion)(_VBUS_ARG PCommand pCmd);
|
|
|
|
/* pointer to original command */
|
|
void *pOrgCommand;
|
|
|
|
|
|
/* scratch data area */
|
|
union {
|
|
struct {
|
|
LBA_T StartLBA;
|
|
UCHAR FirstMember; /* the sequence number of the first member */
|
|
UCHAR LastMember; /* the sequence number of the last member */
|
|
USHORT LastSectors; /* the number of sectors for the last member */
|
|
USHORT FirstSectors; /* the number of sectors for the first member */
|
|
USHORT FirstOffset; /* the offset from the StartLBA for the first member */
|
|
USHORT AllMemberBlocks;/* the number of sectors for all member */
|
|
USHORT WaitInterrupt; /* bit map the members who wait interrupt */
|
|
UCHAR InSameLine; /* if the start and end on the same line */
|
|
UCHAR pad1;
|
|
} array;
|
|
struct {
|
|
LBA_T StartLBA;
|
|
USHORT FirstSectors; /* the number of sectors for the first member */
|
|
USHORT FirstOffset; /* the offset from the StartLBA for the first member */
|
|
USHORT WaitInterrupt; /* bit map the members who wait interrupt */
|
|
USHORT r5_gap; /* see raid5.c */
|
|
UCHAR ParDiskNo; /* parity for startLba */
|
|
UCHAR BadDiskNo;
|
|
UCHAR FirstMember;
|
|
UCHAR pad1;
|
|
} r5;
|
|
struct {
|
|
PCommand pCmd1;
|
|
PCommand pCmd2;
|
|
} r5split;
|
|
#ifdef _RAID5N_
|
|
struct {
|
|
ULONG dummy[2]; /* uScratch.wait shall be moved out uScratch.
|
|
now just fix it thisway */
|
|
struct range_lock *range_lock;
|
|
struct stripe *stripes[5];
|
|
UCHAR nstripes;
|
|
UCHAR finished_stripes;
|
|
USHORT pad2;
|
|
/* for direct-read: */
|
|
struct {
|
|
UCHAR cmds;
|
|
UCHAR finished;
|
|
UCHAR first;
|
|
UCHAR parity;
|
|
LBA_T base;
|
|
USHORT firstoffset;
|
|
USHORT firstsectors;
|
|
} dr;
|
|
} r5n2;
|
|
#endif
|
|
struct {
|
|
ULONG WordsLeft;
|
|
FPSCAT_GATH pPIOSg;
|
|
void (* HPTLIBAPI pfnOrgDone)(_VBUS_ARG PCommand pCmd);
|
|
#ifdef SUPPORT_HPT584
|
|
UCHAR cmd;
|
|
#endif
|
|
} disk;
|
|
struct {
|
|
PCommand pNext;
|
|
void (* HPTLIBAPI WaitEntry)(_VBUS_ARG PCommand pCmd);
|
|
} wait;
|
|
|
|
struct {
|
|
PVOID prdAddr;
|
|
ULONG cmd_priv;
|
|
USHORT responseFlags;
|
|
UCHAR bIdeStatus;
|
|
UCHAR errorRegister;
|
|
} sata_param;
|
|
} uScratch;
|
|
} Command;
|
|
|
|
/***************************************************************************
|
|
* command return value
|
|
***************************************************************************/
|
|
#define RETURN_PENDING 0
|
|
#define RETURN_SUCCESS 1
|
|
#define RETURN_BAD_DEVICE 2
|
|
#define RETURN_BAD_PARAMETER 3
|
|
#define RETURN_WRITE_NO_DRQ 4
|
|
#define RETURN_DEVICE_BUSY 5
|
|
#define RETURN_INVALID_REQUEST 6
|
|
#define RETURN_SELECTION_TIMEOUT 7
|
|
#define RETURN_IDE_ERROR 8
|
|
#define RETURN_NEED_LOGICAL_SG 9
|
|
#define RETURN_NEED_PHYSICAL_SG 10
|
|
#define RETURN_RETRY 11
|
|
#define RETURN_DATA_ERROR 12
|
|
#define RETURN_BUS_RESET 13
|
|
#define RETURN_BAD_TRANSFER_LENGTH 14
|
|
|
|
typedef void (* HPTLIBAPI DPC_PROC)(_VBUS_ARG void *);
|
|
typedef struct _dpc_routine {
|
|
DPC_PROC proc;
|
|
void *arg;
|
|
}
|
|
DPC_ROUTINE;
|
|
|
|
/*
|
|
* MAX_QUEUE_COMM is defined in platform related compiler.h
|
|
* to specify the maximum requests allowed (for each VBus) from system.
|
|
*
|
|
* Maximum command blocks needed for each VBus:
|
|
* Each OS command requests 1+MAX_MEMBERS*2 command blocks (RAID1/0 case)
|
|
* This space is allocated by platform dependent part, either static or
|
|
* dynamic, continuous or non-continuous.
|
|
* The code only needs _vbus_(pFreeCommands) to be set.
|
|
*
|
|
* PendingRoutines[] size:
|
|
* Each command may invoke CallAfterReturn once.
|
|
*
|
|
* IdleRoutines[] size:
|
|
* Each command may invoke CallWhenIdle once.
|
|
*/
|
|
#define MAX_COMMAND_BLOCKS_FOR_EACH_VBUS (MAX_QUEUE_COMM * (1+MAX_MEMBERS*2) + 1)
|
|
#define MAX_PENDING_ROUTINES (MAX_COMMAND_BLOCKS_FOR_EACH_VBUS+1)
|
|
#define MAX_IDLE_ROUTINES (MAX_COMMAND_BLOCKS_FOR_EACH_VBUS+1)
|
|
|
|
#define mWaitingForIdle(pVBus) ((pVBus)->IdleRoutinesFirst!=(pVBus)->IdleRoutinesLast)
|
|
|
|
PCommand HPTLIBAPI AllocateCommand(_VBUS_ARG0);
|
|
void FASTCALL FreeCommand(_VBUS_ARG PCommand pCmd);
|
|
|
|
void FASTCALL CallAfterReturn(_VBUS_ARG DPC_PROC proc, void *arg);
|
|
void HPTLIBAPI CheckPendingCall(_VBUS_ARG0);
|
|
void FASTCALL CallWhenIdle(_VBUS_ARG DPC_PROC proc, void *arg);
|
|
void HPTLIBAPI CheckIdleCall(_VBUS_ARG0);
|
|
|
|
void HPTLIBAPI AddToWaitingList(PCommand *ppList, PCommand pCmd);
|
|
void HPTLIBAPI DoWaitingList(_VBUS_ARG PCommand *ppList);
|
|
|
|
#endif
|