1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD$
29 */
30
31#ifndef _VDEVICE_H_
32#define _VDEVICE_H_
33
34/***************************************************************************
35 * Description:  virtual device header
36 ***************************************************************************/
37
38typedef  struct _VDevice
39{
40	UCHAR        VDeviceType;
41	UCHAR        vf_bootmark: 1; 	/* is boot device? */
42	UCHAR		 vf_bootable: 1;    /* has active partition */
43	UCHAR        vf_online: 1; 		/* is usable? */
44	UCHAR        vf_cache_disk: 1;  /* Cache enabled */
45	UCHAR        vf_format_v2: 1;   /* old array block */
46	UCHAR        vf_freed: 1;       /* memory free */
47	UCHAR        reserve1;
48	UCHAR        bSerialNumber; 	/* valid if pParent!=0 */
49
50	PVDevice	 pParent;			/* parent array */
51	PVBus        pVBus;				/* vbus this device located. Must not be NULL. */
52
53	LBA_T        VDeviceCapacity;   /* number of blocks */
54
55	LBA_T        LockedLba;
56	USHORT       LockedSectors;
57	USHORT       ActiveRequests;
58	PCommand     LockWaitList;
59	void (* HPTLIBAPI QuiesceAction)(_VBUS_ARG void *arg);
60	void  *QuiesceArg;
61	void (* HPTLIBAPI flush_callback)(_VBUS_ARG void *arg);
62	void *flush_callback_arg;
63
64
65#if defined(_RAID5N_)
66	struct stripe **CacheEntry;
67	struct range_lock *range_lock;
68#endif
69
70	void (* HPTLIBAPI pfnSendCommand)(_VBUS_ARG PCommand pCmd);   /* call this to send a command to a VDevice */
71	void (* HPTLIBAPI pfnDeviceFailed)(_VBUS_ARG PVDevice pVDev); /* call this when a VDevice failed */
72
73	union {
74#ifdef SUPPORT_ARRAY
75		RaidArray array;
76#endif
77		Device disk;
78	} u;
79
80} VDevice;
81
82#define ARRAY_VDEV_SIZE (offsetof(VDevice, u) + sizeof(RaidArray))
83#define DISK_VDEV_SIZE  (offsetof(VDevice, u) + sizeof(Device))
84
85#define Map2pVDevice(pDev) ((PVDevice)((UINT_PTR)pDev - (UINT)(UINT_PTR)&((PVDevice)0)->u.disk))
86
87/*
88 * bUserDeviceMode
89 */
90#define MEMBER_NOT_SET_MODE  0x5F
91
92/*
93 * arrayType
94 */
95#define VD_SPARE             0
96#define VD_REMOVABLE         1
97#define VD_ATAPI             2
98#define VD_SINGLE_DISK       3
99
100#define VD_JBOD              4 /* JBOD */
101#define VD_RAID_0            5 /* RAID 0 stripe */
102#define VD_RAID_1            6 /* RAID 1 mirror */
103#define VD_RAID_3            7 /* RAID 3 */
104#define VD_RAID_5            8 /* RAID 5 */
105#define VD_MAX_TYPE 8
106
107#ifdef SUPPORT_ARRAY
108#define mIsArray(pVDev) (pVDev->VDeviceType>VD_SINGLE_DISK)
109#else
110#define mIsArray(pVDev) 0
111#endif
112
113extern void (* HPTLIBAPI pfnSendCommand[])(_VBUS_ARG PCommand pCmd);
114extern void (* HPTLIBAPI pfnDeviceFailed[])(_VBUS_ARG PVDevice pVDev);
115void HPTLIBAPI fOsDiskFailed(_VBUS_ARG PVDevice pVDev);
116void HPTLIBAPI fDeviceSendCommand(_VBUS_ARG PCommand pCmd);
117void HPTLIBAPI fSingleDiskFailed(_VBUS_ARG PVDevice pVDev);
118
119/***************************************************************************
120 * Description:  RAID Adapter
121 ***************************************************************************/
122
123typedef struct _VBus  {
124	/* pVDevice[] may be non-continuous */
125	PVDevice      pVDevice[MAX_VDEVICE_PER_VBUS];
126
127	UINT          nInstances;
128	PChipInstance pChipInstance[MAX_CHIP_IN_VBUS];
129
130	void *        OsExt; /* for OS private use */
131
132
133	int serial_mode;
134	int next_active;
135	int working_devs;
136
137
138
139	PCommand pFreeCommands;
140	DPC_ROUTINE PendingRoutines[MAX_PENDING_ROUTINES];
141	int PendingRoutinesFirst, PendingRoutinesLast;
142	DPC_ROUTINE IdleRoutines[MAX_IDLE_ROUTINES];
143	int IdleRoutinesFirst, IdleRoutinesLast;
144
145#ifdef SUPPORT_ARRAY
146	PVDevice pFreeArrayLink;
147	BYTE    _ArrayTables[MAX_ARRAY_PER_VBUS * ARRAY_VDEV_SIZE];
148#endif
149
150
151#ifdef _RAID5N_
152	struct r5_global_data r5;
153#endif
154
155} VBus;
156
157/*
158 * Array members must be on same VBus.
159 * The platform dependent part shall select one of the following strategy.
160 */
161#ifdef SET_VBUS_FOR_EACH_IRQ
162#define CHIP_ON_SAME_VBUS(pChip1, pChip2) ((pChip1)->bChipIntrNum==(pChip2)->bChipIntrNum)
163#elif defined(SET_VBUS_FOR_EACH_CONTROLLER)
164#define CHIP_ON_SAME_VBUS(pChip1, pChip2) \
165	((pChip1)->pci_bus==(pChip2)->pci_bus && (pChip1)->pci_dev==(pChip2)->pci_dev)
166#elif defined(SET_VBUS_FOR_EACH_FUNCTION)
167#define CHIP_ON_SAME_VBUS(pChip1, pChip2) \
168	((pChip1)->pci_bus==(pChip2)->pci_bus && (pChip1)->pci_dev==(pChip2)->pci_dev && (pChip1)->pci_func==(pChip2)->pci_func)
169#else
170#error You must set one vbus setting
171#endif
172
173#define FOR_EACH_CHANNEL_ON_VBUS(_pVBus, _pChan) \
174		for (_pChan=pChanStart; _pChan<pChanEnd; _pChan++) \
175			if (_pChan->pChipInstance->pVBus!=_pVBus) ; else
176
177#define FOR_EACH_DEV_ON_VBUS(pVBus, pVDev, i) \
178		for(i = 0; i < MAX_VDEVICE_PER_VBUS; i++) \
179			if ((pVDev=pVBus->pVDevice[i])==0) continue; else
180
181
182#define FOR_EACH_VBUS(pVBus) \
183	for(pVBus = gVBus; pVBus < &gVBus[MAX_VBUS]; pVBus++) \
184
185#define FOR_EACH_ARRAY_ON_ALL_VBUS(pVBus, pArray, i) \
186	for(pVBus = gVBus; pVBus < &gVBus[MAX_VBUS]; pVBus++) \
187		for(i = 0; i < MAX_ARRAY_PER_VBUS; i++) \
188			if ((pArray=((PVDevice)&pVBus->_ArrayTables[i*ARRAY_VDEV_SIZE]))->u.array.dArStamp==0) continue; else
189
190#define FOR_EACH_DEV_ON_ALL_VBUS(pVBus, pVDev, i) \
191	FOR_EACH_VBUS(pVBus) \
192		for(i = 0; i < MAX_VDEVICE_PER_VBUS; i++) \
193			if ((pVDev=pVBus->pVDevice[i])==0) continue; else
194
195/***************************************************************************
196 * Description:  the functions called by IDE layer
197 ***************************************************************************/
198#ifdef SUPPORT_ARRAY
199#define IdeRegisterDevice               fCheckArray
200#else
201void HPTLIBAPI IdeRegisterDevice(PDevice pDev);
202#endif
203
204/***************************************************************************
205 * Description:  the functions OS must provided
206 ***************************************************************************/
207
208void HPTLIBAPI OsSetDeviceTable(PDevice pDevice, PIDENTIFY_DATA pIdentify);
209
210/*
211 * allocate and free data structure
212 */
213PChannel fGetChannelTable(void);
214PDevice  fGetDeviceTable(void);
215#define  OsGetChannelTable(x, y)  fGetChannelTable()
216#define  OsGetDeviceTable(x, y)   fGetDeviceTable()
217void 	OsReturnTable(PDevice pDevice);
218/***************************************************************************
219 * Description:  the functions Prototype
220 ***************************************************************************/
221/*
222 * vdevice.c
223 */
224int Initialize(void);
225int InitializeAllChips(void);
226void InitializeVBus(PVBus pVBus);
227void fRegisterChip(PChipInstance pChip);
228void __fRegisterVDevices(PVBus pVBus);
229void fRegisterVDevices(void);
230void HPTLIBAPI UnregisterVDevice(PVDevice);
231void HPTLIBAPI fCheckBootable(PVDevice pVDev);
232void HPTLIBAPI fFlushVDev(PVDevice pVDev);
233void HPTLIBAPI fFlushVDevAsync(PVDevice pVDev, DPC_PROC done, void *arg);
234void HPTLIBAPI fShutdownVDev(PVDevice pVDev);
235void HPTLIBAPI fResetVBus(_VBUS_ARG0);
236void HPTLIBAPI fCompleteAllCommandsSynchronously(PVBus _vbus_p);
237
238#define RegisterVDevice(pVDev)
239#define OsRegisterDevice(pVDev)
240#define OsUnregisterDevice(pVDev)
241
242#ifdef SUPPORT_VBUS_CONFIG
243void VBus_Config(PVBus pVBus, char *str);
244#else
245#define VBus_Config(pVBus, str)
246#endif
247
248#pragma pack(1)
249struct fdisk_partition_table
250{
251	UCHAR 		bootid;   			/* bootable?  0=no, 128=yes  */
252	UCHAR 		beghead;  			/* beginning head number */
253	UCHAR 		begsect;  			/* beginning sector number */
254	UCHAR		begcyl;   			/* 10 bit nmbr, with high 2 bits put in begsect */
255	UCHAR		systid;   			/* Operating System type indicator code */
256	UCHAR 		endhead;  			/* ending head number */
257	UCHAR 		endsect;  			/* ending sector number */
258	UCHAR 		endcyl;   			/* also a 10 bit nmbr, with same high 2 bit trick */
259	ULONG   	relsect;            /* first sector relative to start of disk */
260	ULONG 		numsect;            /* number of sectors in partition */
261};
262
263typedef struct _Master_Boot_Record
264{
265	UCHAR   bootinst[446];   		/* space to hold actual boot code */
266	struct 	fdisk_partition_table parts[4];
267	USHORT  signature;       		/* set to 0xAA55 to indicate PC MBR format */
268}
269Master_Boot_Record, *PMaster_Boot_Record;
270
271#ifndef SUPPORT_ARRAY
272/* TODO: move it later */
273#ifdef __BIG_ENDIAN_BITFIELD
274typedef DWORD TIME_RECORD;
275#else
276typedef struct _TIME_RECORD {
277   UINT        seconds:6;      /* 0 - 59 */
278   UINT        minutes:6;      /* 0 - 59 */
279   UINT        month:4;        /* 1 - 12 */
280   UINT        hours:6;        /* 0 - 59 */
281   UINT        day:5;          /* 1 - 31 */
282   UINT        year:5;         /* 0=2000, 31=2031 */
283} TIME_RECORD;
284#endif
285#endif
286
287#pragma pack()
288#endif
289