1136849Sscottl/*
2149871Sscottl * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
3136849Sscottl * All rights reserved.
4136849Sscottl *
5136849Sscottl * Redistribution and use in source and binary forms, with or without
6136849Sscottl * modification, are permitted provided that the following conditions
7136849Sscottl * are met:
8136849Sscottl * 1. Redistributions of source code must retain the above copyright
9136849Sscottl *    notice, this list of conditions and the following disclaimer.
10136849Sscottl * 2. Redistributions in binary form must reproduce the above copyright
11136849Sscottl *    notice, this list of conditions and the following disclaimer in the
12136849Sscottl *    documentation and/or other materials provided with the distribution.
13136849Sscottl *
14136849Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15136849Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16136849Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17136849Sscottl * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18136849Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19136849Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20136849Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21136849Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22136849Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23136849Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24136849Sscottl * SUCH DAMAGE.
25142988Sscottl *
26142988Sscottl * $FreeBSD$
27136849Sscottl */
28136849Sscottl
29136849Sscottl#ifndef _VDEVICE_H_
30136849Sscottl#define _VDEVICE_H_
31136849Sscottl
32136849Sscottl/***************************************************************************
33136849Sscottl * Description:  virtual device header
34136849Sscottl ***************************************************************************/
35136849Sscottl
36136849Sscottltypedef  struct _VDevice
37136849Sscottl{
38190809Sdelphij	UCHAR        VDeviceType;
39190809Sdelphij	UCHAR        vf_bootmark: 1; 	/* is boot device? */
40190809Sdelphij	UCHAR		 vf_bootable: 1;    /* has active partition */
41190809Sdelphij	UCHAR        vf_online: 1; 		/* is usable? */
42190809Sdelphij	UCHAR        vf_cache_disk: 1;  /* Cache enabled */
43136849Sscottl	UCHAR        vf_format_v2: 1;   /* old array block */
44136849Sscottl	UCHAR        vf_freed: 1;       /* memory free */
45190809Sdelphij	UCHAR        reserve1;
46190809Sdelphij	UCHAR        bSerialNumber; 	/* valid if pParent!=0 */
47136849Sscottl
48190809Sdelphij	PVDevice	 pParent;			/* parent array */
49136849Sscottl	PVBus        pVBus;				/* vbus this device located. Must not be NULL. */
50136849Sscottl
51190809Sdelphij	LBA_T        VDeviceCapacity;   /* number of blocks */
52136849Sscottl
53136849Sscottl	LBA_T        LockedLba;
54136849Sscottl	USHORT       LockedSectors;
55136849Sscottl	USHORT       ActiveRequests;
56136849Sscottl	PCommand     LockWaitList;
57136849Sscottl	void (* HPTLIBAPI QuiesceAction)(_VBUS_ARG void *arg);
58136849Sscottl	void  *QuiesceArg;
59136849Sscottl	void (* HPTLIBAPI flush_callback)(_VBUS_ARG void *arg);
60136849Sscottl	void *flush_callback_arg;
61136849Sscottl
62190809Sdelphij
63136849Sscottl#if defined(_RAID5N_)
64136849Sscottl	struct stripe **CacheEntry;
65136849Sscottl	struct range_lock *range_lock;
66136849Sscottl#endif
67136849Sscottl
68190809Sdelphij	void (* HPTLIBAPI pfnSendCommand)(_VBUS_ARG PCommand pCmd);   /* call this to send a command to a VDevice */
69190809Sdelphij	void (* HPTLIBAPI pfnDeviceFailed)(_VBUS_ARG PVDevice pVDev); /* call this when a VDevice failed */
70190809Sdelphij
71136849Sscottl	union {
72136849Sscottl#ifdef SUPPORT_ARRAY
73136849Sscottl		RaidArray array;
74136849Sscottl#endif
75136849Sscottl		Device disk;
76136849Sscottl	} u;
77136849Sscottl
78136849Sscottl} VDevice;
79136849Sscottl
80136849Sscottl#define ARRAY_VDEV_SIZE ((UINT)(ULONG_PTR)&((PVDevice)0)->u+sizeof(RaidArray))
81136849Sscottl#define DISK_VDEV_SIZE  ((UINT)(ULONG_PTR)&((PVDevice)0)->u+sizeof(Device))
82136849Sscottl
83136849Sscottl#define Map2pVDevice(pDev) ((PVDevice)((UINT_PTR)pDev - (UINT)(UINT_PTR)&((PVDevice)0)->u.disk))
84136849Sscottl
85136849Sscottl/*
86136849Sscottl * bUserDeviceMode
87136849Sscottl */
88190809Sdelphij#define MEMBER_NOT_SET_MODE  0x5F
89136849Sscottl
90190809Sdelphij/*
91190809Sdelphij * arrayType
92136849Sscottl */
93136849Sscottl#define VD_SPARE             0
94136849Sscottl#define VD_REMOVABLE         1
95136849Sscottl#define VD_ATAPI             2
96136849Sscottl#define VD_SINGLE_DISK       3
97136849Sscottl
98136849Sscottl#define VD_JBOD              4 /* JBOD */
99136849Sscottl#define VD_RAID_0            5 /* RAID 0 stripe */
100136849Sscottl#define VD_RAID_1            6 /* RAID 1 mirror */
101136849Sscottl#define VD_RAID_3            7 /* RAID 3 */
102136849Sscottl#define VD_RAID_5            8 /* RAID 5 */
103136849Sscottl#define VD_MAX_TYPE 8
104136849Sscottl
105136849Sscottl#ifdef SUPPORT_ARRAY
106136849Sscottl#define mIsArray(pVDev) (pVDev->VDeviceType>VD_SINGLE_DISK)
107136849Sscottl#else
108136849Sscottl#define mIsArray(pVDev) 0
109136849Sscottl#endif
110136849Sscottl
111136849Sscottlextern void (* HPTLIBAPI pfnSendCommand[])(_VBUS_ARG PCommand pCmd);
112136849Sscottlextern void (* HPTLIBAPI pfnDeviceFailed[])(_VBUS_ARG PVDevice pVDev);
113136849Sscottlvoid HPTLIBAPI fOsDiskFailed(_VBUS_ARG PVDevice pVDev);
114136849Sscottlvoid HPTLIBAPI fDeviceSendCommand(_VBUS_ARG PCommand pCmd);
115136849Sscottlvoid HPTLIBAPI fSingleDiskFailed(_VBUS_ARG PVDevice pVDev);
116136849Sscottl
117136849Sscottl/***************************************************************************
118136849Sscottl * Description:  RAID Adapter
119136849Sscottl ***************************************************************************/
120136849Sscottl
121136849Sscottltypedef struct _VBus  {
122136849Sscottl	/* pVDevice[] may be non-continuous */
123190809Sdelphij	PVDevice      pVDevice[MAX_VDEVICE_PER_VBUS];
124136849Sscottl
125190809Sdelphij	UINT          nInstances;
126190809Sdelphij	PChipInstance pChipInstance[MAX_CHIP_IN_VBUS];
127136849Sscottl
128136849Sscottl	void *        OsExt; /* for OS private use */
129136849Sscottl
130136849Sscottl
131136849Sscottl	int serial_mode;
132136849Sscottl	int next_active;
133136849Sscottl	int working_devs;
134136849Sscottl
135136849Sscottl
136136849Sscottl
137136849Sscottl	PCommand pFreeCommands;
138136849Sscottl	DPC_ROUTINE PendingRoutines[MAX_PENDING_ROUTINES];
139136849Sscottl	int PendingRoutinesFirst, PendingRoutinesLast;
140136849Sscottl	DPC_ROUTINE IdleRoutines[MAX_IDLE_ROUTINES];
141136849Sscottl	int IdleRoutinesFirst, IdleRoutinesLast;
142136849Sscottl
143136849Sscottl#ifdef SUPPORT_ARRAY
144136849Sscottl	PVDevice pFreeArrayLink;
145136849Sscottl	BYTE    _ArrayTables[MAX_ARRAY_PER_VBUS * ARRAY_VDEV_SIZE];
146136849Sscottl#endif
147136849Sscottl
148136849Sscottl
149136849Sscottl#ifdef _RAID5N_
150136849Sscottl	struct r5_global_data r5;
151136849Sscottl#endif
152136849Sscottl
153136849Sscottl} VBus;
154136849Sscottl
155136849Sscottl/*
156136849Sscottl * Array members must be on same VBus.
157136849Sscottl * The platform dependent part shall select one of the following strategy.
158136849Sscottl */
159136849Sscottl#ifdef SET_VBUS_FOR_EACH_IRQ
160136849Sscottl#define CHIP_ON_SAME_VBUS(pChip1, pChip2) ((pChip1)->bChipIntrNum==(pChip2)->bChipIntrNum)
161136849Sscottl#elif defined(SET_VBUS_FOR_EACH_CONTROLLER)
162136849Sscottl#define CHIP_ON_SAME_VBUS(pChip1, pChip2) \
163136849Sscottl	((pChip1)->pci_bus==(pChip2)->pci_bus && (pChip1)->pci_dev==(pChip2)->pci_dev)
164136849Sscottl#elif defined(SET_VBUS_FOR_EACH_FUNCTION)
165136849Sscottl#define CHIP_ON_SAME_VBUS(pChip1, pChip2) \
166136849Sscottl	((pChip1)->pci_bus==(pChip2)->pci_bus && (pChip1)->pci_dev==(pChip2)->pci_dev && (pChip1)->pci_func==(pChip2)->pci_func)
167136849Sscottl#else
168136849Sscottl#error You must set one vbus setting
169136849Sscottl#endif
170136849Sscottl
171136849Sscottl#define FOR_EACH_CHANNEL_ON_VBUS(_pVBus, _pChan) \
172136849Sscottl		for (_pChan=pChanStart; _pChan<pChanEnd; _pChan++) \
173136849Sscottl			if (_pChan->pChipInstance->pVBus!=_pVBus) ; else
174136849Sscottl
175136849Sscottl#define FOR_EACH_DEV_ON_VBUS(pVBus, pVDev, i) \
176136849Sscottl		for(i = 0; i < MAX_VDEVICE_PER_VBUS; i++) \
177136849Sscottl			if ((pVDev=pVBus->pVDevice[i])==0) continue; else
178136849Sscottl
179190809Sdelphij
180190809Sdelphij#define FOR_EACH_VBUS(pVBus) \
181136849Sscottl	for(pVBus = gVBus; pVBus < &gVBus[MAX_VBUS]; pVBus++) \
182136849Sscottl
183136849Sscottl#define FOR_EACH_ARRAY_ON_ALL_VBUS(pVBus, pArray, i) \
184136849Sscottl	for(pVBus = gVBus; pVBus < &gVBus[MAX_VBUS]; pVBus++) \
185136849Sscottl		for(i = 0; i < MAX_ARRAY_PER_VBUS; i++) \
186136849Sscottl			if ((pArray=((PVDevice)&pVBus->_ArrayTables[i*ARRAY_VDEV_SIZE]))->u.array.dArStamp==0) continue; else
187136849Sscottl
188190809Sdelphij#define FOR_EACH_DEV_ON_ALL_VBUS(pVBus, pVDev, i) \
189190809Sdelphij	FOR_EACH_VBUS(pVBus) \
190190809Sdelphij		for(i = 0; i < MAX_VDEVICE_PER_VBUS; i++) \
191190809Sdelphij			if ((pVDev=pVBus->pVDevice[i])==0) continue; else
192190809Sdelphij
193136849Sscottl/***************************************************************************
194136849Sscottl * Description:  the functions called by IDE layer
195136849Sscottl ***************************************************************************/
196136849Sscottl#ifdef SUPPORT_ARRAY
197136849Sscottl#define IdeRegisterDevice               fCheckArray
198136849Sscottl#else
199136849Sscottlvoid HPTLIBAPI IdeRegisterDevice(PDevice pDev);
200136849Sscottl#endif
201136849Sscottl
202136849Sscottl/***************************************************************************
203190809Sdelphij * Description:  the functions OS must provided
204136849Sscottl ***************************************************************************/
205136849Sscottl
206190809Sdelphijvoid HPTLIBAPI OsSetDeviceTable(PDevice pDevice, PIDENTIFY_DATA pIdentify);
207136849Sscottl
208136849Sscottl/*
209136849Sscottl * allocate and free data structure
210136849Sscottl */
211136849SscottlPChannel fGetChannelTable(void);
212136849SscottlPDevice  fGetDeviceTable(void);
213136849Sscottl#define  OsGetChannelTable(x, y)  fGetChannelTable()
214136849Sscottl#define  OsGetDeviceTable(x, y)   fGetDeviceTable()
215136849Sscottlvoid 	OsReturnTable(PDevice pDevice);
216136849Sscottl/***************************************************************************
217136849Sscottl * Description:  the functions Prototype
218136849Sscottl ***************************************************************************/
219136849Sscottl/*
220136849Sscottl * vdevice.c
221136849Sscottl */
222136849Sscottlint Initialize(void);
223136849Sscottlint InitializeAllChips(void);
224136849Sscottlvoid InitializeVBus(PVBus pVBus);
225136849Sscottlvoid fRegisterChip(PChipInstance pChip);
226136849Sscottlvoid __fRegisterVDevices(PVBus pVBus);
227136849Sscottlvoid fRegisterVDevices(void);
228136849Sscottlvoid HPTLIBAPI UnregisterVDevice(PVDevice);
229136849Sscottlvoid HPTLIBAPI fCheckBootable(PVDevice pVDev);
230136849Sscottlvoid HPTLIBAPI fFlushVDev(PVDevice pVDev);
231136849Sscottlvoid HPTLIBAPI fFlushVDevAsync(PVDevice pVDev, DPC_PROC done, void *arg);
232136849Sscottlvoid HPTLIBAPI fShutdownVDev(PVDevice pVDev);
233136849Sscottlvoid HPTLIBAPI fResetVBus(_VBUS_ARG0);
234136849Sscottlvoid HPTLIBAPI fCompleteAllCommandsSynchronously(PVBus _vbus_p);
235136849Sscottl
236136849Sscottl#define RegisterVDevice(pVDev)
237136849Sscottl#define OsRegisterDevice(pVDev)
238136849Sscottl#define OsUnregisterDevice(pVDev)
239136849Sscottl
240136849Sscottl#ifdef SUPPORT_VBUS_CONFIG
241136849Sscottlvoid VBus_Config(PVBus pVBus, char *str);
242136849Sscottl#else
243136849Sscottl#define VBus_Config(pVBus, str)
244136849Sscottl#endif
245136849Sscottl
246136849Sscottl#pragma pack(1)
247190809Sdelphijstruct fdisk_partition_table
248136849Sscottl{
249136849Sscottl	UCHAR 		bootid;   			/* bootable?  0=no, 128=yes  */
250136849Sscottl	UCHAR 		beghead;  			/* beginning head number */
251136849Sscottl	UCHAR 		begsect;  			/* beginning sector number */
252190809Sdelphij	UCHAR		begcyl;   			/* 10 bit nmbr, with high 2 bits put in begsect */
253136849Sscottl	UCHAR		systid;   			/* Operating System type indicator code */
254136849Sscottl	UCHAR 		endhead;  			/* ending head number */
255136849Sscottl	UCHAR 		endsect;  			/* ending sector number */
256136849Sscottl	UCHAR 		endcyl;   			/* also a 10 bit nmbr, with same high 2 bit trick */
257149871Sscottl	ULONG   	relsect;            /* first sector relative to start of disk */
258149871Sscottl	ULONG 		numsect;            /* number of sectors in partition */
259136849Sscottl};
260136849Sscottl
261190809Sdelphijtypedef struct _Master_Boot_Record
262136849Sscottl{
263136849Sscottl	UCHAR   bootinst[446];   		/* space to hold actual boot code */
264136849Sscottl	struct 	fdisk_partition_table parts[4];
265136849Sscottl	USHORT  signature;       		/* set to 0xAA55 to indicate PC MBR format */
266136849Sscottl}
267136849SscottlMaster_Boot_Record, *PMaster_Boot_Record;
268136849Sscottl
269136849Sscottl#ifndef SUPPORT_ARRAY
270136849Sscottl/* TODO: move it later */
271136849Sscottl#ifdef __BIG_ENDIAN_BITFIELD
272136849Sscottltypedef DWORD TIME_RECORD;
273136849Sscottl#else
274136849Sscottltypedef struct _TIME_RECORD {
275136849Sscottl   UINT        seconds:6;      /* 0 - 59 */
276136849Sscottl   UINT        minutes:6;      /* 0 - 59 */
277136849Sscottl   UINT        month:4;        /* 1 - 12 */
278136849Sscottl   UINT        hours:6;        /* 0 - 59 */
279136849Sscottl   UINT        day:5;          /* 1 - 31 */
280136849Sscottl   UINT        year:5;         /* 0=2000, 31=2031 */
281136849Sscottl} TIME_RECORD;
282136849Sscottl#endif
283136849Sscottl#endif
284136849Sscottl
285190809Sdelphij#pragma pack()
286136849Sscottl#endif
287