Deleted Added
full compact
ioctl.c (169823) ioctl.c (190809)
1/*
2 * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*
2 * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/dev/hptmv/ioctl.c 169823 2007-05-21 09:26:47Z mjacob $
26 * $FreeBSD: head/sys/dev/hptmv/ioctl.c 190809 2009-04-07 16:38:25Z delphij $
27 */
28/*
29 * ioctl.c ioctl interface implementation
30 */
31#include <sys/param.h>
32#include <sys/systm.h>
33#include <sys/kernel.h>
34#include <sys/malloc.h>
35
36#if (__FreeBSD_version < 500000)
37#include <sys/proc.h>
38#include <sys/kthread.h>
39#include <sys/wait.h>
40#include <sys/sysproto.h>
41#endif
42
43#ifndef __KERNEL__
44#define __KERNEL__
45#endif
46
47#include <dev/hptmv/global.h>
48#include <dev/hptmv/hptintf.h>
49#include <dev/hptmv/osbsd.h>
50#include <dev/hptmv/access601.h>
51
52#pragma pack(1)
53
54typedef struct _HPT_REBUILD_PARAM
55{
56 DEVICEID idMirror;
57 DWORD Lba;
58 UCHAR nSector;
59} HPT_REBUILD_PARAM, *PHPT_REBUILD_PARAM;
60
61#pragma pack()
62
63#define MAX_EVENTS 10
64static HPT_EVENT hpt_event_queue[MAX_EVENTS];
65static int event_queue_head=0, event_queue_tail=0;
66
67static int hpt_get_event(PHPT_EVENT pEvent);
68static int hpt_set_array_state(DEVICEID idArray, DWORD state);
69static intrmask_t lock_driver_idle(IAL_ADAPTER_T *pAdapter);
70static void HPTLIBAPI thread_io_done(_VBUS_ARG PCommand pCmd);
71static int HPTLIBAPI R1ControlSgl(_VBUS_ARG PCommand pCmd,
72 FPSCAT_GATH pSgTable, int logical);
73
74static void
75get_disk_location(PDevice pDev, int *controller, int *channel)
76{
77 IAL_ADAPTER_T *pAdapTemp;
78 int i, j;
79
80 *controller = *channel = 0;
81
82 for (i=1, pAdapTemp = gIal_Adapter; pAdapTemp; pAdapTemp = pAdapTemp->next, i++) {
83 for (j=0; j<MV_SATA_CHANNELS_NUM; j++) {
84 if (pDev == &pAdapTemp->VDevices[j].u.disk) {
85 *controller = i;
86 *channel = j;
87 return;
88 }
89 }
90 }
91}
92
93static int
94event_queue_add(PHPT_EVENT pEvent)
95{
96 int p;
97 p = (event_queue_tail + 1) % MAX_EVENTS;
98 if (p==event_queue_head)
99 {
100 return -1;
101 }
102 hpt_event_queue[event_queue_tail] = *pEvent;
103 event_queue_tail = p;
104 return 0;
105}
106
107static int
108event_queue_remove(PHPT_EVENT pEvent)
109{
110 if (event_queue_head != event_queue_tail)
111 {
112 *pEvent = hpt_event_queue[event_queue_head];
113 event_queue_head++;
114 event_queue_head %= MAX_EVENTS;
115 return 0;
116 }
117 return -1;
118}
119
120void HPTLIBAPI
121ioctl_ReportEvent(UCHAR event, PVOID param)
122{
123 HPT_EVENT e;
124 ZeroMemory(&e, sizeof(e));
125 e.EventType = event;
126 switch(event)
127 {
128 case ET_INITIALIZE_ABORTED:
129 case ET_INITIALIZE_FAILED:
130 memcpy(e.Data, ((PVDevice)param)->u.array.ArrayName, MAX_ARRAY_NAME);
131 case ET_INITIALIZE_STARTED:
132 case ET_INITIALIZE_FINISHED:
133
134 case ET_REBUILD_STARTED:
135 case ET_REBUILD_ABORTED:
136 case ET_REBUILD_FAILED:
137 case ET_REBUILD_FINISHED:
138
139 case ET_VERIFY_STARTED:
140 case ET_VERIFY_ABORTED:
141 case ET_VERIFY_FAILED:
142 case ET_VERIFY_FINISHED:
143 case ET_VERIFY_DATA_ERROR:
144
145 case ET_SPARE_TOOK_OVER:
146 case ET_DEVICE_REMOVED:
147 case ET_DEVICE_PLUGGED:
148 case ET_DEVICE_ERROR:
149 e.DeviceID = VDEV_TO_ID((PVDevice)param);
150 break;
151
152 default:
153 break;
154 }
155 event_queue_add(&e);
156 if (event==ET_DEVICE_REMOVED) {
157 int controller, channel;
158 get_disk_location(&((PVDevice)param)->u.disk, &controller, &channel);
159 hpt_printk(("Device removed: controller %d channel %d\n", controller, channel));
160 }
161}
162
163static int
164hpt_delete_array(_VBUS_ARG DEVICEID id, DWORD options)
165{
166 PVDevice pArray = ID_TO_VDEV(id);
167 BOOLEAN del_block0 = (options & DAF_KEEP_DATA_IF_POSSIBLE)?0:1;
168 int i;
169 PVDevice pa;
170
171 if ((id==0) || check_VDevice_valid(pArray))
172 return -1;
173
174 if(!mIsArray(pArray)) return -1;
175
176 if (pArray->u.array.rf_rebuilding || pArray->u.array.rf_verifying ||
177 pArray->u.array.rf_initializing)
178 return -1;
179
180 for(i=0; i<pArray->u.array.bArnMember; i++) {
181 pa = pArray->u.array.pMember[i];
182 if (pa && mIsArray(pa)) {
183 if (pa->u.array.rf_rebuilding || pa->u.array.rf_verifying ||
184 pa->u.array.rf_initializing)
185 return -1;
186 }
187 }
188
189 if (pArray->pVBus!=_vbus_p) { HPT_ASSERT(0); return -1;}
190 fDeleteArray(_VBUS_P pArray, del_block0);
191 return 0;
192
193}
194
195/* just to prevent driver from sending more commands */
196static void HPTLIBAPI nothing(_VBUS_ARG void *notused){}
197
198intrmask_t
199lock_driver_idle(IAL_ADAPTER_T *pAdapter)
200{
201 intrmask_t oldspl;
202 _VBUS_INST(&pAdapter->VBus)
203 oldspl = lock_driver();
204 while (pAdapter->outstandingCommands) {
205 KdPrint(("outstandingCommands is %d, wait..\n", pAdapter->outstandingCommands));
206 if (!mWaitingForIdle(_VBUS_P0)) CallWhenIdle(_VBUS_P nothing, 0);
207 unlock_driver(oldspl);
208/*Schedule out*/
209#if (__FreeBSD_version < 500000)
210 YIELD_THREAD;
211#else
27 */
28/*
29 * ioctl.c ioctl interface implementation
30 */
31#include <sys/param.h>
32#include <sys/systm.h>
33#include <sys/kernel.h>
34#include <sys/malloc.h>
35
36#if (__FreeBSD_version < 500000)
37#include <sys/proc.h>
38#include <sys/kthread.h>
39#include <sys/wait.h>
40#include <sys/sysproto.h>
41#endif
42
43#ifndef __KERNEL__
44#define __KERNEL__
45#endif
46
47#include <dev/hptmv/global.h>
48#include <dev/hptmv/hptintf.h>
49#include <dev/hptmv/osbsd.h>
50#include <dev/hptmv/access601.h>
51
52#pragma pack(1)
53
54typedef struct _HPT_REBUILD_PARAM
55{
56 DEVICEID idMirror;
57 DWORD Lba;
58 UCHAR nSector;
59} HPT_REBUILD_PARAM, *PHPT_REBUILD_PARAM;
60
61#pragma pack()
62
63#define MAX_EVENTS 10
64static HPT_EVENT hpt_event_queue[MAX_EVENTS];
65static int event_queue_head=0, event_queue_tail=0;
66
67static int hpt_get_event(PHPT_EVENT pEvent);
68static int hpt_set_array_state(DEVICEID idArray, DWORD state);
69static intrmask_t lock_driver_idle(IAL_ADAPTER_T *pAdapter);
70static void HPTLIBAPI thread_io_done(_VBUS_ARG PCommand pCmd);
71static int HPTLIBAPI R1ControlSgl(_VBUS_ARG PCommand pCmd,
72 FPSCAT_GATH pSgTable, int logical);
73
74static void
75get_disk_location(PDevice pDev, int *controller, int *channel)
76{
77 IAL_ADAPTER_T *pAdapTemp;
78 int i, j;
79
80 *controller = *channel = 0;
81
82 for (i=1, pAdapTemp = gIal_Adapter; pAdapTemp; pAdapTemp = pAdapTemp->next, i++) {
83 for (j=0; j<MV_SATA_CHANNELS_NUM; j++) {
84 if (pDev == &pAdapTemp->VDevices[j].u.disk) {
85 *controller = i;
86 *channel = j;
87 return;
88 }
89 }
90 }
91}
92
93static int
94event_queue_add(PHPT_EVENT pEvent)
95{
96 int p;
97 p = (event_queue_tail + 1) % MAX_EVENTS;
98 if (p==event_queue_head)
99 {
100 return -1;
101 }
102 hpt_event_queue[event_queue_tail] = *pEvent;
103 event_queue_tail = p;
104 return 0;
105}
106
107static int
108event_queue_remove(PHPT_EVENT pEvent)
109{
110 if (event_queue_head != event_queue_tail)
111 {
112 *pEvent = hpt_event_queue[event_queue_head];
113 event_queue_head++;
114 event_queue_head %= MAX_EVENTS;
115 return 0;
116 }
117 return -1;
118}
119
120void HPTLIBAPI
121ioctl_ReportEvent(UCHAR event, PVOID param)
122{
123 HPT_EVENT e;
124 ZeroMemory(&e, sizeof(e));
125 e.EventType = event;
126 switch(event)
127 {
128 case ET_INITIALIZE_ABORTED:
129 case ET_INITIALIZE_FAILED:
130 memcpy(e.Data, ((PVDevice)param)->u.array.ArrayName, MAX_ARRAY_NAME);
131 case ET_INITIALIZE_STARTED:
132 case ET_INITIALIZE_FINISHED:
133
134 case ET_REBUILD_STARTED:
135 case ET_REBUILD_ABORTED:
136 case ET_REBUILD_FAILED:
137 case ET_REBUILD_FINISHED:
138
139 case ET_VERIFY_STARTED:
140 case ET_VERIFY_ABORTED:
141 case ET_VERIFY_FAILED:
142 case ET_VERIFY_FINISHED:
143 case ET_VERIFY_DATA_ERROR:
144
145 case ET_SPARE_TOOK_OVER:
146 case ET_DEVICE_REMOVED:
147 case ET_DEVICE_PLUGGED:
148 case ET_DEVICE_ERROR:
149 e.DeviceID = VDEV_TO_ID((PVDevice)param);
150 break;
151
152 default:
153 break;
154 }
155 event_queue_add(&e);
156 if (event==ET_DEVICE_REMOVED) {
157 int controller, channel;
158 get_disk_location(&((PVDevice)param)->u.disk, &controller, &channel);
159 hpt_printk(("Device removed: controller %d channel %d\n", controller, channel));
160 }
161}
162
163static int
164hpt_delete_array(_VBUS_ARG DEVICEID id, DWORD options)
165{
166 PVDevice pArray = ID_TO_VDEV(id);
167 BOOLEAN del_block0 = (options & DAF_KEEP_DATA_IF_POSSIBLE)?0:1;
168 int i;
169 PVDevice pa;
170
171 if ((id==0) || check_VDevice_valid(pArray))
172 return -1;
173
174 if(!mIsArray(pArray)) return -1;
175
176 if (pArray->u.array.rf_rebuilding || pArray->u.array.rf_verifying ||
177 pArray->u.array.rf_initializing)
178 return -1;
179
180 for(i=0; i<pArray->u.array.bArnMember; i++) {
181 pa = pArray->u.array.pMember[i];
182 if (pa && mIsArray(pa)) {
183 if (pa->u.array.rf_rebuilding || pa->u.array.rf_verifying ||
184 pa->u.array.rf_initializing)
185 return -1;
186 }
187 }
188
189 if (pArray->pVBus!=_vbus_p) { HPT_ASSERT(0); return -1;}
190 fDeleteArray(_VBUS_P pArray, del_block0);
191 return 0;
192
193}
194
195/* just to prevent driver from sending more commands */
196static void HPTLIBAPI nothing(_VBUS_ARG void *notused){}
197
198intrmask_t
199lock_driver_idle(IAL_ADAPTER_T *pAdapter)
200{
201 intrmask_t oldspl;
202 _VBUS_INST(&pAdapter->VBus)
203 oldspl = lock_driver();
204 while (pAdapter->outstandingCommands) {
205 KdPrint(("outstandingCommands is %d, wait..\n", pAdapter->outstandingCommands));
206 if (!mWaitingForIdle(_VBUS_P0)) CallWhenIdle(_VBUS_P nothing, 0);
207 unlock_driver(oldspl);
208/*Schedule out*/
209#if (__FreeBSD_version < 500000)
210 YIELD_THREAD;
211#else
212#if (__FreeBSD_version > 700033)
212 pause("switch", 1);
213 pause("switch", 1);
214#else
215 tsleep(lock_driver_idle, PPAUSE, "switch", 1);
213#endif
216#endif
217#endif
214 oldspl = lock_driver();
215 }
216 CheckIdleCall(_VBUS_P0);
217 return oldspl;
218}
219
220int Kernel_DeviceIoControl(_VBUS_ARG
221 DWORD dwIoControlCode, /* operation control code */
222 PVOID lpInBuffer, /* input data buffer */
223 DWORD nInBufferSize, /* size of input data buffer */
224 PVOID lpOutBuffer, /* output data buffer */
225 DWORD nOutBufferSize, /* size of output data buffer */
226 PDWORD lpBytesReturned /* byte count */
227 )
228{
229 IAL_ADAPTER_T *pAdapter;
230
231 switch(dwIoControlCode) {
232 case HPT_IOCTL_DELETE_ARRAY:
233 {
234 DEVICEID idArray;
235 int iSuccess;
236 int i;
237 PVDevice pArray;
238 PVBus _vbus_p;
239 struct cam_periph *periph = NULL;
240
241 if (nInBufferSize!=sizeof(DEVICEID)+sizeof(DWORD)) return -1;
242 if (nOutBufferSize!=sizeof(int)) return -1;
243 idArray = *(DEVICEID *)lpInBuffer;
244
245 pArray = ID_TO_VDEV(idArray);
246
247 if((idArray == 0) || check_VDevice_valid(pArray))
248 return -1;
249
250 if(!mIsArray(pArray))
251 return -1;
252
253 _vbus_p=pArray->pVBus;
254 pAdapter = (IAL_ADAPTER_T *)_vbus_p->OsExt;
255
256 for(i = 0; i < MAX_VDEVICE_PER_VBUS; i++) {
257 if(pArray == _vbus_p->pVDevice[i])
258 {
259 periph = hpt_get_periph(pAdapter->mvSataAdapter.adapterId, i);
260 if (periph != NULL && periph->refcount >= 1)
261 {
262 hpt_printk(("Can not delete a mounted device.\n"));
263 return -1;
264 }
265 }
266 /* the Mounted Disk isn't delete */
267 }
268
269 iSuccess = hpt_delete_array(_VBUS_P idArray, *(DWORD*)((DEVICEID *)lpInBuffer+1));
270
271 *(int*)lpOutBuffer = iSuccess;
272
273 if(iSuccess != 0)
274 return -1;
275 break;
276 }
277
278 case HPT_IOCTL_GET_EVENT:
279 {
280 PHPT_EVENT pInfo;
281
282 if (nInBufferSize!=0) return -1;
283 if (nOutBufferSize!=sizeof(HPT_EVENT)) return -1;
284
285 pInfo = (PHPT_EVENT)lpOutBuffer;
286
287 if (hpt_get_event(pInfo)!=0)
288 return -1;
289 }
290 break;
291
292 case HPT_IOCTL_SET_ARRAY_STATE:
293 {
294 DEVICEID idArray;
295 DWORD state;
296
297 if (nInBufferSize!=sizeof(HPT_SET_STATE_PARAM)) return -1;
298 if (nOutBufferSize!=0) return -1;
299
300 idArray = ((PHPT_SET_STATE_PARAM)lpInBuffer)->idArray;
301 state = ((PHPT_SET_STATE_PARAM)lpInBuffer)->state;
302
303 if(hpt_set_array_state(idArray, state)!=0)
304 return -1;
305 }
306 break;
307
308 case HPT_IOCTL_RESCAN_DEVICES:
309 {
310 if (nInBufferSize!=0) return -1;
311 if (nOutBufferSize!=0) return -1;
312
313#ifndef FOR_DEMO
314 /* stop buzzer if user perform rescan */
315 for (pAdapter=gIal_Adapter; pAdapter; pAdapter=pAdapter->next) {
316 if (pAdapter->beeping) {
317 pAdapter->beeping = 0;
318 BeepOff(pAdapter->mvSataAdapter.adapterIoBaseAddress);
319 }
320 }
321#endif
322 }
323 break;
324
325 default:
326 {
327 PVDevice pVDev;
328#ifdef SUPPORT_ARRAY
329 intrmask_t oldspl;
330#endif
331 switch(dwIoControlCode) {
332 /* read-only ioctl functions can be called directly. */
333 case HPT_IOCTL_GET_VERSION:
334 case HPT_IOCTL_GET_CONTROLLER_IDS:
335 case HPT_IOCTL_GET_CONTROLLER_COUNT:
336 case HPT_IOCTL_GET_CONTROLLER_INFO:
337 case HPT_IOCTL_GET_CHANNEL_INFO:
338 case HPT_IOCTL_GET_LOGICAL_DEVICES:
339 case HPT_IOCTL_GET_DEVICE_INFO:
218 oldspl = lock_driver();
219 }
220 CheckIdleCall(_VBUS_P0);
221 return oldspl;
222}
223
224int Kernel_DeviceIoControl(_VBUS_ARG
225 DWORD dwIoControlCode, /* operation control code */
226 PVOID lpInBuffer, /* input data buffer */
227 DWORD nInBufferSize, /* size of input data buffer */
228 PVOID lpOutBuffer, /* output data buffer */
229 DWORD nOutBufferSize, /* size of output data buffer */
230 PDWORD lpBytesReturned /* byte count */
231 )
232{
233 IAL_ADAPTER_T *pAdapter;
234
235 switch(dwIoControlCode) {
236 case HPT_IOCTL_DELETE_ARRAY:
237 {
238 DEVICEID idArray;
239 int iSuccess;
240 int i;
241 PVDevice pArray;
242 PVBus _vbus_p;
243 struct cam_periph *periph = NULL;
244
245 if (nInBufferSize!=sizeof(DEVICEID)+sizeof(DWORD)) return -1;
246 if (nOutBufferSize!=sizeof(int)) return -1;
247 idArray = *(DEVICEID *)lpInBuffer;
248
249 pArray = ID_TO_VDEV(idArray);
250
251 if((idArray == 0) || check_VDevice_valid(pArray))
252 return -1;
253
254 if(!mIsArray(pArray))
255 return -1;
256
257 _vbus_p=pArray->pVBus;
258 pAdapter = (IAL_ADAPTER_T *)_vbus_p->OsExt;
259
260 for(i = 0; i < MAX_VDEVICE_PER_VBUS; i++) {
261 if(pArray == _vbus_p->pVDevice[i])
262 {
263 periph = hpt_get_periph(pAdapter->mvSataAdapter.adapterId, i);
264 if (periph != NULL && periph->refcount >= 1)
265 {
266 hpt_printk(("Can not delete a mounted device.\n"));
267 return -1;
268 }
269 }
270 /* the Mounted Disk isn't delete */
271 }
272
273 iSuccess = hpt_delete_array(_VBUS_P idArray, *(DWORD*)((DEVICEID *)lpInBuffer+1));
274
275 *(int*)lpOutBuffer = iSuccess;
276
277 if(iSuccess != 0)
278 return -1;
279 break;
280 }
281
282 case HPT_IOCTL_GET_EVENT:
283 {
284 PHPT_EVENT pInfo;
285
286 if (nInBufferSize!=0) return -1;
287 if (nOutBufferSize!=sizeof(HPT_EVENT)) return -1;
288
289 pInfo = (PHPT_EVENT)lpOutBuffer;
290
291 if (hpt_get_event(pInfo)!=0)
292 return -1;
293 }
294 break;
295
296 case HPT_IOCTL_SET_ARRAY_STATE:
297 {
298 DEVICEID idArray;
299 DWORD state;
300
301 if (nInBufferSize!=sizeof(HPT_SET_STATE_PARAM)) return -1;
302 if (nOutBufferSize!=0) return -1;
303
304 idArray = ((PHPT_SET_STATE_PARAM)lpInBuffer)->idArray;
305 state = ((PHPT_SET_STATE_PARAM)lpInBuffer)->state;
306
307 if(hpt_set_array_state(idArray, state)!=0)
308 return -1;
309 }
310 break;
311
312 case HPT_IOCTL_RESCAN_DEVICES:
313 {
314 if (nInBufferSize!=0) return -1;
315 if (nOutBufferSize!=0) return -1;
316
317#ifndef FOR_DEMO
318 /* stop buzzer if user perform rescan */
319 for (pAdapter=gIal_Adapter; pAdapter; pAdapter=pAdapter->next) {
320 if (pAdapter->beeping) {
321 pAdapter->beeping = 0;
322 BeepOff(pAdapter->mvSataAdapter.adapterIoBaseAddress);
323 }
324 }
325#endif
326 }
327 break;
328
329 default:
330 {
331 PVDevice pVDev;
332#ifdef SUPPORT_ARRAY
333 intrmask_t oldspl;
334#endif
335 switch(dwIoControlCode) {
336 /* read-only ioctl functions can be called directly. */
337 case HPT_IOCTL_GET_VERSION:
338 case HPT_IOCTL_GET_CONTROLLER_IDS:
339 case HPT_IOCTL_GET_CONTROLLER_COUNT:
340 case HPT_IOCTL_GET_CONTROLLER_INFO:
341 case HPT_IOCTL_GET_CHANNEL_INFO:
342 case HPT_IOCTL_GET_LOGICAL_DEVICES:
343 case HPT_IOCTL_GET_DEVICE_INFO:
344 case HPT_IOCTL_GET_DEVICE_INFO_V2:
340 case HPT_IOCTL_GET_EVENT:
341 case HPT_IOCTL_GET_DRIVER_CAPABILITIES:
342 if(hpt_default_ioctl(_VBUS_P dwIoControlCode, lpInBuffer, nInBufferSize,
343 lpOutBuffer, nOutBufferSize, lpBytesReturned) == -1) return -1;
344 break;
345
346 default:
347 /*
348 * GUI always use /proc/scsi/hptmv/0, so the _vbus_p param will be
349 * wrong for second controller.
350 */
351 switch(dwIoControlCode) {
352 case HPT_IOCTL_CREATE_ARRAY:
353 pVDev = ID_TO_VDEV(((PCREATE_ARRAY_PARAMS)lpInBuffer)->Members[0]); break;
345 case HPT_IOCTL_GET_EVENT:
346 case HPT_IOCTL_GET_DRIVER_CAPABILITIES:
347 if(hpt_default_ioctl(_VBUS_P dwIoControlCode, lpInBuffer, nInBufferSize,
348 lpOutBuffer, nOutBufferSize, lpBytesReturned) == -1) return -1;
349 break;
350
351 default:
352 /*
353 * GUI always use /proc/scsi/hptmv/0, so the _vbus_p param will be
354 * wrong for second controller.
355 */
356 switch(dwIoControlCode) {
357 case HPT_IOCTL_CREATE_ARRAY:
358 pVDev = ID_TO_VDEV(((PCREATE_ARRAY_PARAMS)lpInBuffer)->Members[0]); break;
359 case HPT_IOCTL_CREATE_ARRAY_V2:
360 pVDev = ID_TO_VDEV(((PCREATE_ARRAY_PARAMS_V2)lpInBuffer)->Members[0]); break;
354 case HPT_IOCTL_SET_ARRAY_INFO:
355 pVDev = ID_TO_VDEV(((PHPT_SET_ARRAY_INFO)lpInBuffer)->idArray); break;
356 case HPT_IOCTL_SET_DEVICE_INFO:
357 pVDev = ID_TO_VDEV(((PHPT_SET_DEVICE_INFO)lpInBuffer)->idDisk); break;
361 case HPT_IOCTL_SET_ARRAY_INFO:
362 pVDev = ID_TO_VDEV(((PHPT_SET_ARRAY_INFO)lpInBuffer)->idArray); break;
363 case HPT_IOCTL_SET_DEVICE_INFO:
364 pVDev = ID_TO_VDEV(((PHPT_SET_DEVICE_INFO)lpInBuffer)->idDisk); break;
365 case HPT_IOCTL_SET_DEVICE_INFO_V2:
366 pVDev = ID_TO_VDEV(((PHPT_SET_DEVICE_INFO_V2)lpInBuffer)->idDisk); break;
358 case HPT_IOCTL_SET_BOOT_MARK:
359 case HPT_IOCTL_ADD_SPARE_DISK:
360 case HPT_IOCTL_REMOVE_SPARE_DISK:
361 pVDev = ID_TO_VDEV(*(DEVICEID *)lpInBuffer); break;
362 case HPT_IOCTL_ADD_DISK_TO_ARRAY:
363 pVDev = ID_TO_VDEV(((PHPT_ADD_DISK_TO_ARRAY)lpInBuffer)->idArray); break;
364 default:
365 pVDev = 0;
366 }
367
368 if (pVDev && !check_VDevice_valid(pVDev)){
369 _vbus_p = pVDev->pVBus;
370
371 pAdapter = (IAL_ADAPTER_T *)_vbus_p->OsExt;
372 /*
373 * create_array, and other functions can't be executed while channel is
374 * perform I/O commands. Wait until driver is idle.
375 */
376 oldspl = lock_driver_idle(pAdapter);
377 if (hpt_default_ioctl(_VBUS_P dwIoControlCode, lpInBuffer, nInBufferSize,
378 lpOutBuffer, nOutBufferSize, lpBytesReturned) == -1) {
379 unlock_driver(oldspl);
380 return -1;
381 }
382 unlock_driver(oldspl);
383 }
384 else
385 return -1;
386 break;
387 }
388
389#ifdef SUPPORT_ARRAY
390 switch(dwIoControlCode)
391 {
392 case HPT_IOCTL_CREATE_ARRAY:
393 {
394 pAdapter=(IAL_ADAPTER_T *)(ID_TO_VDEV(*(DEVICEID *)lpOutBuffer))->pVBus->OsExt;
395 oldspl = lock_driver();
396 if(((PCREATE_ARRAY_PARAMS)lpInBuffer)->CreateFlags & CAF_CREATE_AND_DUPLICATE)
397 {
398 (ID_TO_VDEV(*(DEVICEID *)lpOutBuffer))->u.array.rf_auto_rebuild = 0;
399 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, ID_TO_VDEV(*(DEVICEID *)lpOutBuffer), DUPLICATE);
400 }
401 else if(((PCREATE_ARRAY_PARAMS)lpInBuffer)->CreateFlags & CAF_CREATE_R5_ZERO_INIT)
402 {
403 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, ID_TO_VDEV(*(DEVICEID *)lpOutBuffer), INITIALIZE);
404 }
405 else if(((PCREATE_ARRAY_PARAMS)lpInBuffer)->CreateFlags & CAF_CREATE_R5_BUILD_PARITY)
406 {
407 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, ID_TO_VDEV(*(DEVICEID *)lpOutBuffer), REBUILD_PARITY);
408 }
409 unlock_driver(oldspl);
410 break;
411 }
412
367 case HPT_IOCTL_SET_BOOT_MARK:
368 case HPT_IOCTL_ADD_SPARE_DISK:
369 case HPT_IOCTL_REMOVE_SPARE_DISK:
370 pVDev = ID_TO_VDEV(*(DEVICEID *)lpInBuffer); break;
371 case HPT_IOCTL_ADD_DISK_TO_ARRAY:
372 pVDev = ID_TO_VDEV(((PHPT_ADD_DISK_TO_ARRAY)lpInBuffer)->idArray); break;
373 default:
374 pVDev = 0;
375 }
376
377 if (pVDev && !check_VDevice_valid(pVDev)){
378 _vbus_p = pVDev->pVBus;
379
380 pAdapter = (IAL_ADAPTER_T *)_vbus_p->OsExt;
381 /*
382 * create_array, and other functions can't be executed while channel is
383 * perform I/O commands. Wait until driver is idle.
384 */
385 oldspl = lock_driver_idle(pAdapter);
386 if (hpt_default_ioctl(_VBUS_P dwIoControlCode, lpInBuffer, nInBufferSize,
387 lpOutBuffer, nOutBufferSize, lpBytesReturned) == -1) {
388 unlock_driver(oldspl);
389 return -1;
390 }
391 unlock_driver(oldspl);
392 }
393 else
394 return -1;
395 break;
396 }
397
398#ifdef SUPPORT_ARRAY
399 switch(dwIoControlCode)
400 {
401 case HPT_IOCTL_CREATE_ARRAY:
402 {
403 pAdapter=(IAL_ADAPTER_T *)(ID_TO_VDEV(*(DEVICEID *)lpOutBuffer))->pVBus->OsExt;
404 oldspl = lock_driver();
405 if(((PCREATE_ARRAY_PARAMS)lpInBuffer)->CreateFlags & CAF_CREATE_AND_DUPLICATE)
406 {
407 (ID_TO_VDEV(*(DEVICEID *)lpOutBuffer))->u.array.rf_auto_rebuild = 0;
408 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, ID_TO_VDEV(*(DEVICEID *)lpOutBuffer), DUPLICATE);
409 }
410 else if(((PCREATE_ARRAY_PARAMS)lpInBuffer)->CreateFlags & CAF_CREATE_R5_ZERO_INIT)
411 {
412 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, ID_TO_VDEV(*(DEVICEID *)lpOutBuffer), INITIALIZE);
413 }
414 else if(((PCREATE_ARRAY_PARAMS)lpInBuffer)->CreateFlags & CAF_CREATE_R5_BUILD_PARITY)
415 {
416 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, ID_TO_VDEV(*(DEVICEID *)lpOutBuffer), REBUILD_PARITY);
417 }
418 unlock_driver(oldspl);
419 break;
420 }
421
422
423 case HPT_IOCTL_CREATE_ARRAY_V2:
424 {
425 pAdapter=(IAL_ADAPTER_T *)(ID_TO_VDEV(*(DEVICEID *)lpOutBuffer))->pVBus->OsExt;
426 oldspl = lock_driver();
427 if(((PCREATE_ARRAY_PARAMS_V2)lpInBuffer)->CreateFlags & CAF_CREATE_AND_DUPLICATE) {
428 (ID_TO_VDEV(*(DEVICEID *)lpOutBuffer))->u.array.rf_auto_rebuild = 0;
429 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, ID_TO_VDEV(*(DEVICEID *)lpOutBuffer), DUPLICATE);
430 } else if(((PCREATE_ARRAY_PARAMS_V2)lpInBuffer)->CreateFlags & CAF_CREATE_R5_ZERO_INIT) {
431 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, ID_TO_VDEV(*(DEVICEID *)lpOutBuffer), INITIALIZE);
432 } else if(((PCREATE_ARRAY_PARAMS_V2)lpInBuffer)->CreateFlags & CAF_CREATE_R5_BUILD_PARITY) {
433 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, ID_TO_VDEV(*(DEVICEID *)lpOutBuffer), REBUILD_PARITY);
434 }
435 unlock_driver(oldspl);
436 break;
437 }
413 case HPT_IOCTL_ADD_DISK_TO_ARRAY:
414 {
415 PVDevice pArray = ID_TO_VDEV(((PHPT_ADD_DISK_TO_ARRAY)lpInBuffer)->idArray);
416 pAdapter=(IAL_ADAPTER_T *)pArray->pVBus->OsExt;
417 if(pArray->u.array.rf_rebuilding == 0)
418 {
419 DWORD timeout = 0;
420 oldspl = lock_driver();
421 pArray->u.array.rf_auto_rebuild = 0;
422 pArray->u.array.rf_abort_rebuild = 0;
423 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pArray, DUPLICATE);
424 unlock_driver(oldspl);
425 while (!pArray->u.array.rf_rebuilding)
426 {
438 case HPT_IOCTL_ADD_DISK_TO_ARRAY:
439 {
440 PVDevice pArray = ID_TO_VDEV(((PHPT_ADD_DISK_TO_ARRAY)lpInBuffer)->idArray);
441 pAdapter=(IAL_ADAPTER_T *)pArray->pVBus->OsExt;
442 if(pArray->u.array.rf_rebuilding == 0)
443 {
444 DWORD timeout = 0;
445 oldspl = lock_driver();
446 pArray->u.array.rf_auto_rebuild = 0;
447 pArray->u.array.rf_abort_rebuild = 0;
448 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pArray, DUPLICATE);
449 unlock_driver(oldspl);
450 while (!pArray->u.array.rf_rebuilding)
451 {
452#if (__FreeBSD_version > 700033)
427 pause("pause", 1);
453 pause("pause", 1);
454#else
455 tsleep((caddr_t)Kernel_DeviceIoControl, PPAUSE, "pause", 1);
456#endif
428 if ( timeout >= hz*3)
429 break;
430 timeout ++;
431 }
432 }
433 break;
434 }
435 }
436#endif
437 return 0;
438 }
439 }
440
441 if (lpBytesReturned)
442 *lpBytesReturned = nOutBufferSize;
443 return 0;
444}
445
446static int
447hpt_get_event(PHPT_EVENT pEvent)
448{
449 intrmask_t oldspl = lock_driver();
450 int ret = event_queue_remove(pEvent);
451 unlock_driver(oldspl);
452 return ret;
453}
454
455static int
456hpt_set_array_state(DEVICEID idArray, DWORD state)
457{
458 IAL_ADAPTER_T *pAdapter;
459 PVDevice pVDevice = ID_TO_VDEV(idArray);
460 int i;
461 DWORD timeout = 0;
462 intrmask_t oldspl;
463
464 if(idArray == 0 || check_VDevice_valid(pVDevice)) return -1;
465 if(!mIsArray(pVDevice))
466 return -1;
467 if(!pVDevice->vf_online || pVDevice->u.array.rf_broken) return -1;
468
469 pAdapter=(IAL_ADAPTER_T *)pVDevice->pVBus->OsExt;
470
471 switch(state)
472 {
473 case MIRROR_REBUILD_START:
474 {
475 if (pVDevice->u.array.rf_rebuilding ||
476 pVDevice->u.array.rf_verifying ||
477 pVDevice->u.array.rf_initializing)
478 return -1;
479
480 oldspl = lock_driver();
481
482 pVDevice->u.array.rf_auto_rebuild = 0;
483 pVDevice->u.array.rf_abort_rebuild = 0;
484
485 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice,
486 (UCHAR)((pVDevice->u.array.CriticalMembers || pVDevice->VDeviceType == VD_RAID_1)? DUPLICATE : REBUILD_PARITY));
487
488 unlock_driver(oldspl);
489
490 while (!pVDevice->u.array.rf_rebuilding)
491 {
457 if ( timeout >= hz*3)
458 break;
459 timeout ++;
460 }
461 }
462 break;
463 }
464 }
465#endif
466 return 0;
467 }
468 }
469
470 if (lpBytesReturned)
471 *lpBytesReturned = nOutBufferSize;
472 return 0;
473}
474
475static int
476hpt_get_event(PHPT_EVENT pEvent)
477{
478 intrmask_t oldspl = lock_driver();
479 int ret = event_queue_remove(pEvent);
480 unlock_driver(oldspl);
481 return ret;
482}
483
484static int
485hpt_set_array_state(DEVICEID idArray, DWORD state)
486{
487 IAL_ADAPTER_T *pAdapter;
488 PVDevice pVDevice = ID_TO_VDEV(idArray);
489 int i;
490 DWORD timeout = 0;
491 intrmask_t oldspl;
492
493 if(idArray == 0 || check_VDevice_valid(pVDevice)) return -1;
494 if(!mIsArray(pVDevice))
495 return -1;
496 if(!pVDevice->vf_online || pVDevice->u.array.rf_broken) return -1;
497
498 pAdapter=(IAL_ADAPTER_T *)pVDevice->pVBus->OsExt;
499
500 switch(state)
501 {
502 case MIRROR_REBUILD_START:
503 {
504 if (pVDevice->u.array.rf_rebuilding ||
505 pVDevice->u.array.rf_verifying ||
506 pVDevice->u.array.rf_initializing)
507 return -1;
508
509 oldspl = lock_driver();
510
511 pVDevice->u.array.rf_auto_rebuild = 0;
512 pVDevice->u.array.rf_abort_rebuild = 0;
513
514 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice,
515 (UCHAR)((pVDevice->u.array.CriticalMembers || pVDevice->VDeviceType == VD_RAID_1)? DUPLICATE : REBUILD_PARITY));
516
517 unlock_driver(oldspl);
518
519 while (!pVDevice->u.array.rf_rebuilding)
520 {
521#if (__FreeBSD_version > 700033)
492 pause("pause", 1);
522 pause("pause", 1);
523#else
524 tsleep((caddr_t)hpt_set_array_state, PPAUSE, "pause", 1);
525#endif
493 if ( timeout >= hz*20)
494 break;
495 timeout ++;
496 }
497 }
498
499 break;
500
501 case MIRROR_REBUILD_ABORT:
502 {
503 for(i = 0; i < pVDevice->u.array.bArnMember; i++) {
504 if(pVDevice->u.array.pMember[i] != 0 && pVDevice->u.array.pMember[i]->VDeviceType == VD_RAID_1)
505 hpt_set_array_state(VDEV_TO_ID(pVDevice->u.array.pMember[i]), state);
506 }
507
508 if(pVDevice->u.array.rf_rebuilding != 1)
509 return -1;
510
511 oldspl = lock_driver();
512 pVDevice->u.array.rf_abort_rebuild = 1;
513 unlock_driver(oldspl);
514
515 while (pVDevice->u.array.rf_abort_rebuild)
516 {
526 if ( timeout >= hz*20)
527 break;
528 timeout ++;
529 }
530 }
531
532 break;
533
534 case MIRROR_REBUILD_ABORT:
535 {
536 for(i = 0; i < pVDevice->u.array.bArnMember; i++) {
537 if(pVDevice->u.array.pMember[i] != 0 && pVDevice->u.array.pMember[i]->VDeviceType == VD_RAID_1)
538 hpt_set_array_state(VDEV_TO_ID(pVDevice->u.array.pMember[i]), state);
539 }
540
541 if(pVDevice->u.array.rf_rebuilding != 1)
542 return -1;
543
544 oldspl = lock_driver();
545 pVDevice->u.array.rf_abort_rebuild = 1;
546 unlock_driver(oldspl);
547
548 while (pVDevice->u.array.rf_abort_rebuild)
549 {
550#if (__FreeBSD_version > 700033)
517 pause("pause", 1);
551 pause("pause", 1);
552#else
553 tsleep((caddr_t)hpt_set_array_state, PPAUSE, "pause", 1);
554#endif
518 if ( timeout >= hz*20)
519 break;
520 timeout ++;
521 }
522 }
523 break;
524
525 case AS_VERIFY_START:
526 {
527 /*if(pVDevice->u.array.rf_verifying)
528 return -1;*/
529 if (pVDevice->u.array.rf_rebuilding ||
530 pVDevice->u.array.rf_verifying ||
531 pVDevice->u.array.rf_initializing)
532 return -1;
533
534 oldspl = lock_driver();
535 pVDevice->u.array.RebuildSectors = 0;
536 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice, VERIFY);
537 unlock_driver(oldspl);
538
539 while (!pVDevice->u.array.rf_verifying)
540 {
555 if ( timeout >= hz*20)
556 break;
557 timeout ++;
558 }
559 }
560 break;
561
562 case AS_VERIFY_START:
563 {
564 /*if(pVDevice->u.array.rf_verifying)
565 return -1;*/
566 if (pVDevice->u.array.rf_rebuilding ||
567 pVDevice->u.array.rf_verifying ||
568 pVDevice->u.array.rf_initializing)
569 return -1;
570
571 oldspl = lock_driver();
572 pVDevice->u.array.RebuildSectors = 0;
573 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice, VERIFY);
574 unlock_driver(oldspl);
575
576 while (!pVDevice->u.array.rf_verifying)
577 {
578#if (__FreeBSD_version > 700033)
541 pause("pause", 1);
579 pause("pause", 1);
580#else
581 tsleep((caddr_t)hpt_set_array_state, PPAUSE, "pause", 1);
582#endif
542 if ( timeout >= hz*20)
543 break;
544 timeout ++;
545 }
546 }
547 break;
548
549 case AS_VERIFY_ABORT:
550 {
551 if(pVDevice->u.array.rf_verifying != 1)
552 return -1;
553
554 oldspl = lock_driver();
555 pVDevice->u.array.rf_abort_rebuild = 1;
556 unlock_driver(oldspl);
557
558 while (pVDevice->u.array.rf_abort_rebuild)
559 {
583 if ( timeout >= hz*20)
584 break;
585 timeout ++;
586 }
587 }
588 break;
589
590 case AS_VERIFY_ABORT:
591 {
592 if(pVDevice->u.array.rf_verifying != 1)
593 return -1;
594
595 oldspl = lock_driver();
596 pVDevice->u.array.rf_abort_rebuild = 1;
597 unlock_driver(oldspl);
598
599 while (pVDevice->u.array.rf_abort_rebuild)
600 {
601#if (__FreeBSD_version > 700033)
560 pause("pause", 1);
602 pause("pause", 1);
603#else
604 tsleep((caddr_t)hpt_set_array_state, PPAUSE, "pause", 1);
605#endif
561 if ( timeout >= hz*80)
562 break;
563 timeout ++;
564 }
565 }
566 break;
567
568 case AS_INITIALIZE_START:
569 {
570 if (pVDevice->u.array.rf_rebuilding ||
571 pVDevice->u.array.rf_verifying ||
572 pVDevice->u.array.rf_initializing)
573 return -1;
574
575 oldspl = lock_driver();
576 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice, VERIFY);
577 unlock_driver(oldspl);
578
579 while (!pVDevice->u.array.rf_initializing)
580 {
606 if ( timeout >= hz*80)
607 break;
608 timeout ++;
609 }
610 }
611 break;
612
613 case AS_INITIALIZE_START:
614 {
615 if (pVDevice->u.array.rf_rebuilding ||
616 pVDevice->u.array.rf_verifying ||
617 pVDevice->u.array.rf_initializing)
618 return -1;
619
620 oldspl = lock_driver();
621 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pVDevice, VERIFY);
622 unlock_driver(oldspl);
623
624 while (!pVDevice->u.array.rf_initializing)
625 {
626#if (__FreeBSD_version > 700033)
581 pause("pause", 1);
627 pause("pause", 1);
628#else
629 tsleep((caddr_t)hpt_set_array_state, PPAUSE, "pause", 1);
630#endif
582 if ( timeout >= hz*80)
583 break;
584 timeout ++;
585 }
586 }
587 break;
588
589 case AS_INITIALIZE_ABORT:
590 {
591 if(pVDevice->u.array.rf_initializing != 1)
592 return -1;
593
594 oldspl = lock_driver();
595 pVDevice->u.array.rf_abort_rebuild = 1;
596 unlock_driver(oldspl);
597
598 while (pVDevice->u.array.rf_abort_rebuild)
599 {
631 if ( timeout >= hz*80)
632 break;
633 timeout ++;
634 }
635 }
636 break;
637
638 case AS_INITIALIZE_ABORT:
639 {
640 if(pVDevice->u.array.rf_initializing != 1)
641 return -1;
642
643 oldspl = lock_driver();
644 pVDevice->u.array.rf_abort_rebuild = 1;
645 unlock_driver(oldspl);
646
647 while (pVDevice->u.array.rf_abort_rebuild)
648 {
649#if (__FreeBSD_version > 700033)
600 pause("pause", 1);
650 pause("pause", 1);
651#else
652 tsleep((caddr_t)hpt_set_array_state, PPAUSE, "pause", 1);
653#endif
601 if ( timeout >= hz*80)
602 break;
603 timeout ++;
604 }
605 }
606 break;
607
608 default:
609 return -1;
610 }
611
612 return 0;
613}
614
615int HPTLIBAPI
616R1ControlSgl(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSgTable, int logical)
617{
618 ULONG bufferSize = SECTOR_TO_BYTE(pCmd->uCmd.R1Control.nSectors);
619 if (pCmd->uCmd.R1Control.Command==CTRL_CMD_VERIFY)
620 bufferSize<<=1;
621 if (logical) {
622 pSgTable->dSgAddress = (ULONG_PTR)pCmd->uCmd.R1Control.Buffer;
623 pSgTable->wSgSize = (USHORT)bufferSize;
624 pSgTable->wSgFlag = SG_FLAG_EOT;
625 }
626 else {
627 /* build physical SG table for pCmd->uCmd.R1Control.Buffer */
628 ADDRESS dataPointer, v, nextpage, currvaddr, nextvaddr, currphypage, nextphypage;
629 ULONG length;
630 int idx = 0;
631
632 v = pCmd->uCmd.R1Control.Buffer;
633 dataPointer = (ADDRESS)fOsPhysicalAddress(v);
634
635 if ((ULONG_PTR)dataPointer & 0x1)
636 return FALSE;
637
638 #define ON64KBOUNDARY(x) (((ULONG_PTR)(x) & 0xFFFF) == 0)
639 #define NOTNEIGHBORPAGE(highvaddr, lowvaddr) ((ULONG_PTR)(highvaddr) - (ULONG_PTR)(lowvaddr) != PAGE_SIZE)
640
641 do {
642 if (idx >= MAX_SG_DESCRIPTORS) return FALSE;
643
644 pSgTable[idx].dSgAddress = fOsPhysicalAddress(v);
645 currvaddr = v;
646 currphypage = (ADDRESS)fOsPhysicalAddress((void*)trunc_page((ULONG_PTR)currvaddr));
647
648
649 do {
650 nextpage = (ADDRESS)trunc_page(((ULONG_PTR)currvaddr + PAGE_SIZE));
651 nextvaddr = (ADDRESS)MIN(((ULONG_PTR)v + bufferSize), (ULONG_PTR)(nextpage));
652
653 if (nextvaddr == (ADDRESS)((ULONG_PTR)v + bufferSize)) break;
654 nextphypage = (ADDRESS)fOsPhysicalAddress(nextpage);
655
656 if (NOTNEIGHBORPAGE(nextphypage, currphypage) || ON64KBOUNDARY(nextphypage)) {
657 nextvaddr = nextpage;
658 break;
659 }
660
661 currvaddr = nextvaddr;
662 currphypage = nextphypage;
663 }while (1);
664
665 length = (ULONG_PTR)nextvaddr - (ULONG_PTR)v;
666 v = nextvaddr;
667 bufferSize -= length;
668
669 pSgTable[idx].wSgSize = (USHORT)length;
670 pSgTable[idx].wSgFlag = (bufferSize)? 0 : SG_FLAG_EOT;
671 idx++;
672
673 }while (bufferSize);
674 }
675 return 1;
676}
677
678static int End_Job=0;
679void HPTLIBAPI
680thread_io_done(_VBUS_ARG PCommand pCmd)
681{
682 End_Job = 1;
683 wakeup((caddr_t)pCmd);
684}
685
686void
687hpt_rebuild_data_block(IAL_ADAPTER_T *pAdapter, PVDevice pArray, UCHAR flags)
688{
689 DWORD timeout = 0;
690 ULONG capacity = pArray->VDeviceCapacity / (pArray->u.array.bArnMember-1);
691 PCommand pCmd;
692 UINT result;
693 int needsync=0, retry=0, needdelete=0;
694 void *buffer = 0;
695 intrmask_t oldspl;
696
697 _VBUS_INST(&pAdapter->VBus)
698
699 if (pArray->u.array.rf_broken==1 ||
700 pArray->u.array.RebuildSectors>=capacity)
701 return;
702
703 oldspl = lock_driver();
704
705 switch(flags)
706 {
707 case DUPLICATE:
708 case REBUILD_PARITY:
709 if(pArray->u.array.rf_rebuilding == 0)
710 {
711 pArray->u.array.rf_rebuilding = 1;
712 hpt_printk(("Rebuilding started.\n"));
713 ioctl_ReportEvent(ET_REBUILD_STARTED, pArray);
714 }
715 break;
716
717 case INITIALIZE:
718 if(pArray->u.array.rf_initializing == 0)
719 {
720 pArray->u.array.rf_initializing = 1;
721 hpt_printk(("Initializing started.\n"));
722 ioctl_ReportEvent(ET_INITIALIZE_STARTED, pArray);
723 }
724 break;
725
726 case VERIFY:
727 if(pArray->u.array.rf_verifying == 0)
728 {
729 pArray->u.array.rf_verifying = 1;
730 hpt_printk(("Verifying started.\n"));
731 ioctl_ReportEvent(ET_VERIFY_STARTED, pArray);
732 }
733 break;
734 }
735
736retry_cmd:
737 pCmd = AllocateCommand(_VBUS_P0);
738 HPT_ASSERT(pCmd);
739 pCmd->cf_control = 1;
740 End_Job = 0;
741
742 if (pArray->VDeviceType==VD_RAID_1)
743 {
744 #define MAX_REBUILD_SECTORS 0x40
745
746 /* take care for discontinuous buffer in R1ControlSgl */
747 unlock_driver(oldspl);
748 buffer = malloc(SECTOR_TO_BYTE(MAX_REBUILD_SECTORS), M_DEVBUF, M_NOWAIT);
749 oldspl = lock_driver();
750 if(!buffer) {
751 FreeCommand(_VBUS_P pCmd);
752 hpt_printk(("can't allocate rebuild buffer\n"));
753 goto fail;
754 }
755 switch(flags)
756 {
757 case DUPLICATE:
758 pCmd->uCmd.R1Control.Command = CTRL_CMD_REBUILD;
759 pCmd->uCmd.R1Control.nSectors = MAX_REBUILD_SECTORS;
760 break;
761
762 case VERIFY:
763 pCmd->uCmd.R1Control.Command = CTRL_CMD_VERIFY;
764 pCmd->uCmd.R1Control.nSectors = MAX_REBUILD_SECTORS/2;
765 break;
766
767 case INITIALIZE:
768 pCmd->uCmd.R1Control.Command = CTRL_CMD_REBUILD;
769 pCmd->uCmd.R1Control.nSectors = MAX_REBUILD_SECTORS;
770 break;
771 }
772
773 pCmd->uCmd.R1Control.Lba = pArray->u.array.RebuildSectors;
774
775 if (capacity - pArray->u.array.RebuildSectors < pCmd->uCmd.R1Control.nSectors)
776 pCmd->uCmd.R1Control.nSectors = capacity - pArray->u.array.RebuildSectors;
777
778 pCmd->uCmd.R1Control.Buffer = buffer;
779 pCmd->pfnBuildSgl = R1ControlSgl;
780 }
781 else if (pArray->VDeviceType==VD_RAID_5)
782 {
783 switch(flags)
784 {
785 case DUPLICATE:
786 case REBUILD_PARITY:
787 pCmd->uCmd.R5Control.Command = CTRL_CMD_REBUILD; break;
788 case VERIFY:
789 pCmd->uCmd.R5Control.Command = CTRL_CMD_VERIFY; break;
790 case INITIALIZE:
791 pCmd->uCmd.R5Control.Command = CTRL_CMD_INIT; break;
792 }
793 pCmd->uCmd.R5Control.StripeLine=pArray->u.array.RebuildSectors>>pArray->u.array.bArBlockSizeShift;
794 }
795 else
796 HPT_ASSERT(0);
797
798 pCmd->pVDevice = pArray;
799 pCmd->pfnCompletion = thread_io_done;
800 pArray->pfnSendCommand(_VBUS_P pCmd);
801 CheckPendingCall(_VBUS_P0);
802
803 if (!End_Job) {
804 unlock_driver(oldspl);
805 while (!End_Job) {
806 tsleep((caddr_t)pCmd, PPAUSE, "pause", hz);
807 if (timeout++>60) break;
808 }
809 oldspl = lock_driver();
810 if (!End_Job) {
811 hpt_printk(("timeout, reset\n"));
812 fResetVBus(_VBUS_P0);
813 }
814 }
815
816 result = pCmd->Result;
817 FreeCommand(_VBUS_P pCmd);
818 unlock_driver(oldspl);
819 if (buffer) free(buffer, M_DEVBUF);
820 oldspl = lock_driver();
821 KdPrintI(("cmd finished %d", result));
822
823 switch(result)
824 {
825 case RETURN_SUCCESS:
826 if (!pArray->u.array.rf_abort_rebuild)
827 {
828 if(pArray->u.array.RebuildSectors < capacity)
829 {
830 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pArray, flags);
831 }
832 else
833 {
834 switch (flags)
835 {
836 case DUPLICATE:
837 case REBUILD_PARITY:
838 needsync = 1;
839 pArray->u.array.rf_rebuilding = 0;
840 pArray->u.array.rf_need_rebuild = 0;
841 pArray->u.array.CriticalMembers = 0;
842 pArray->u.array.RebuildSectors = MAX_LBA_T;
843 pArray->u.array.rf_duplicate_and_create = 0;
844 hpt_printk(("Rebuilding finished.\n"));
845 ioctl_ReportEvent(ET_REBUILD_FINISHED, pArray);
846 break;
847 case INITIALIZE:
848 needsync = 1;
849 pArray->u.array.rf_initializing = 0;
850 pArray->u.array.rf_need_rebuild = 0;
851 pArray->u.array.RebuildSectors = MAX_LBA_T;
852 hpt_printk(("Initializing finished.\n"));
853 ioctl_ReportEvent(ET_INITIALIZE_FINISHED, pArray);
854 break;
855 case VERIFY:
856 pArray->u.array.rf_verifying = 0;
857 hpt_printk(("Verifying finished.\n"));
858 ioctl_ReportEvent(ET_VERIFY_FINISHED, pArray);
859 break;
860 }
861 }
862 }
863 else
864 {
865 pArray->u.array.rf_abort_rebuild = 0;
866 if (pArray->u.array.rf_rebuilding)
867 {
868 hpt_printk(("Abort rebuilding.\n"));
869 pArray->u.array.rf_rebuilding = 0;
870 pArray->u.array.rf_duplicate_and_create = 0;
871 ioctl_ReportEvent(ET_REBUILD_ABORTED, pArray);
872 }
873 else if (pArray->u.array.rf_verifying)
874 {
875 hpt_printk(("Abort verifying.\n"));
876 pArray->u.array.rf_verifying = 0;
877 ioctl_ReportEvent(ET_VERIFY_ABORTED, pArray);
878 }
879 else if (pArray->u.array.rf_initializing)
880 {
881 hpt_printk(("Abort initializing.\n"));
882 pArray->u.array.rf_initializing = 0;
883 ioctl_ReportEvent(ET_INITIALIZE_ABORTED, pArray);
884 }
885 needdelete=1;
886 }
887 break;
888
889 case RETURN_DATA_ERROR:
890 if (flags==VERIFY)
891 {
892 needsync = 1;
893 pArray->u.array.rf_verifying = 0;
894 pArray->u.array.rf_need_rebuild = 1;
895 hpt_printk(("Verifying failed: found inconsistency\n"));
896 ioctl_ReportEvent(ET_VERIFY_DATA_ERROR, pArray);
897 ioctl_ReportEvent(ET_VERIFY_FAILED, pArray);
898
899 if (!pArray->vf_online || pArray->u.array.rf_broken) break;
900
901 pArray->u.array.rf_auto_rebuild = 0;
902 pArray->u.array.rf_abort_rebuild = 0;
903 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pArray,
904 (pArray->VDeviceType == VD_RAID_1) ? DUPLICATE : REBUILD_PARITY);
905 }
906 break;
907
908 default:
909 hpt_printk(("command failed with error %d\n", result));
910 if (++retry<3)
911 {
912 hpt_printk(("retry (%d)\n", retry));
913 goto retry_cmd;
914 }
915fail:
916 pArray->u.array.rf_abort_rebuild = 0;
917 switch (flags)
918 {
919 case DUPLICATE:
920 case REBUILD_PARITY:
921 needsync = 1;
922 pArray->u.array.rf_rebuilding = 0;
923 pArray->u.array.rf_duplicate_and_create = 0;
924 hpt_printk(((flags==DUPLICATE)? "Duplicating failed.\n":"Rebuilding failed.\n"));
925 ioctl_ReportEvent(ET_REBUILD_FAILED, pArray);
926 break;
927
928 case INITIALIZE:
929 needsync = 1;
930 pArray->u.array.rf_initializing = 0;
931 hpt_printk(("Initializing failed.\n"));
932 ioctl_ReportEvent(ET_INITIALIZE_FAILED, pArray);
933 break;
934
935 case VERIFY:
936 needsync = 1;
937 pArray->u.array.rf_verifying = 0;
938 hpt_printk(("Verifying failed.\n"));
939 ioctl_ReportEvent(ET_VERIFY_FAILED, pArray);
940 break;
941 }
942 needdelete=1;
943 }
944
945 while (pAdapter->outstandingCommands)
946 {
947 KdPrintI(("currcmds is %d, wait..\n", pAdapter->outstandingCommands));
948 /* put this to have driver stop processing system commands quickly */
949 if (!mWaitingForIdle(_VBUS_P0)) CallWhenIdle(_VBUS_P nothing, 0);
950 unlock_driver(oldspl);
951 /*Schedule out*/
952#if (__FreeBSD_version < 500000)
953 YIELD_THREAD;
954#else
654 if ( timeout >= hz*80)
655 break;
656 timeout ++;
657 }
658 }
659 break;
660
661 default:
662 return -1;
663 }
664
665 return 0;
666}
667
668int HPTLIBAPI
669R1ControlSgl(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSgTable, int logical)
670{
671 ULONG bufferSize = SECTOR_TO_BYTE(pCmd->uCmd.R1Control.nSectors);
672 if (pCmd->uCmd.R1Control.Command==CTRL_CMD_VERIFY)
673 bufferSize<<=1;
674 if (logical) {
675 pSgTable->dSgAddress = (ULONG_PTR)pCmd->uCmd.R1Control.Buffer;
676 pSgTable->wSgSize = (USHORT)bufferSize;
677 pSgTable->wSgFlag = SG_FLAG_EOT;
678 }
679 else {
680 /* build physical SG table for pCmd->uCmd.R1Control.Buffer */
681 ADDRESS dataPointer, v, nextpage, currvaddr, nextvaddr, currphypage, nextphypage;
682 ULONG length;
683 int idx = 0;
684
685 v = pCmd->uCmd.R1Control.Buffer;
686 dataPointer = (ADDRESS)fOsPhysicalAddress(v);
687
688 if ((ULONG_PTR)dataPointer & 0x1)
689 return FALSE;
690
691 #define ON64KBOUNDARY(x) (((ULONG_PTR)(x) & 0xFFFF) == 0)
692 #define NOTNEIGHBORPAGE(highvaddr, lowvaddr) ((ULONG_PTR)(highvaddr) - (ULONG_PTR)(lowvaddr) != PAGE_SIZE)
693
694 do {
695 if (idx >= MAX_SG_DESCRIPTORS) return FALSE;
696
697 pSgTable[idx].dSgAddress = fOsPhysicalAddress(v);
698 currvaddr = v;
699 currphypage = (ADDRESS)fOsPhysicalAddress((void*)trunc_page((ULONG_PTR)currvaddr));
700
701
702 do {
703 nextpage = (ADDRESS)trunc_page(((ULONG_PTR)currvaddr + PAGE_SIZE));
704 nextvaddr = (ADDRESS)MIN(((ULONG_PTR)v + bufferSize), (ULONG_PTR)(nextpage));
705
706 if (nextvaddr == (ADDRESS)((ULONG_PTR)v + bufferSize)) break;
707 nextphypage = (ADDRESS)fOsPhysicalAddress(nextpage);
708
709 if (NOTNEIGHBORPAGE(nextphypage, currphypage) || ON64KBOUNDARY(nextphypage)) {
710 nextvaddr = nextpage;
711 break;
712 }
713
714 currvaddr = nextvaddr;
715 currphypage = nextphypage;
716 }while (1);
717
718 length = (ULONG_PTR)nextvaddr - (ULONG_PTR)v;
719 v = nextvaddr;
720 bufferSize -= length;
721
722 pSgTable[idx].wSgSize = (USHORT)length;
723 pSgTable[idx].wSgFlag = (bufferSize)? 0 : SG_FLAG_EOT;
724 idx++;
725
726 }while (bufferSize);
727 }
728 return 1;
729}
730
731static int End_Job=0;
732void HPTLIBAPI
733thread_io_done(_VBUS_ARG PCommand pCmd)
734{
735 End_Job = 1;
736 wakeup((caddr_t)pCmd);
737}
738
739void
740hpt_rebuild_data_block(IAL_ADAPTER_T *pAdapter, PVDevice pArray, UCHAR flags)
741{
742 DWORD timeout = 0;
743 ULONG capacity = pArray->VDeviceCapacity / (pArray->u.array.bArnMember-1);
744 PCommand pCmd;
745 UINT result;
746 int needsync=0, retry=0, needdelete=0;
747 void *buffer = 0;
748 intrmask_t oldspl;
749
750 _VBUS_INST(&pAdapter->VBus)
751
752 if (pArray->u.array.rf_broken==1 ||
753 pArray->u.array.RebuildSectors>=capacity)
754 return;
755
756 oldspl = lock_driver();
757
758 switch(flags)
759 {
760 case DUPLICATE:
761 case REBUILD_PARITY:
762 if(pArray->u.array.rf_rebuilding == 0)
763 {
764 pArray->u.array.rf_rebuilding = 1;
765 hpt_printk(("Rebuilding started.\n"));
766 ioctl_ReportEvent(ET_REBUILD_STARTED, pArray);
767 }
768 break;
769
770 case INITIALIZE:
771 if(pArray->u.array.rf_initializing == 0)
772 {
773 pArray->u.array.rf_initializing = 1;
774 hpt_printk(("Initializing started.\n"));
775 ioctl_ReportEvent(ET_INITIALIZE_STARTED, pArray);
776 }
777 break;
778
779 case VERIFY:
780 if(pArray->u.array.rf_verifying == 0)
781 {
782 pArray->u.array.rf_verifying = 1;
783 hpt_printk(("Verifying started.\n"));
784 ioctl_ReportEvent(ET_VERIFY_STARTED, pArray);
785 }
786 break;
787 }
788
789retry_cmd:
790 pCmd = AllocateCommand(_VBUS_P0);
791 HPT_ASSERT(pCmd);
792 pCmd->cf_control = 1;
793 End_Job = 0;
794
795 if (pArray->VDeviceType==VD_RAID_1)
796 {
797 #define MAX_REBUILD_SECTORS 0x40
798
799 /* take care for discontinuous buffer in R1ControlSgl */
800 unlock_driver(oldspl);
801 buffer = malloc(SECTOR_TO_BYTE(MAX_REBUILD_SECTORS), M_DEVBUF, M_NOWAIT);
802 oldspl = lock_driver();
803 if(!buffer) {
804 FreeCommand(_VBUS_P pCmd);
805 hpt_printk(("can't allocate rebuild buffer\n"));
806 goto fail;
807 }
808 switch(flags)
809 {
810 case DUPLICATE:
811 pCmd->uCmd.R1Control.Command = CTRL_CMD_REBUILD;
812 pCmd->uCmd.R1Control.nSectors = MAX_REBUILD_SECTORS;
813 break;
814
815 case VERIFY:
816 pCmd->uCmd.R1Control.Command = CTRL_CMD_VERIFY;
817 pCmd->uCmd.R1Control.nSectors = MAX_REBUILD_SECTORS/2;
818 break;
819
820 case INITIALIZE:
821 pCmd->uCmd.R1Control.Command = CTRL_CMD_REBUILD;
822 pCmd->uCmd.R1Control.nSectors = MAX_REBUILD_SECTORS;
823 break;
824 }
825
826 pCmd->uCmd.R1Control.Lba = pArray->u.array.RebuildSectors;
827
828 if (capacity - pArray->u.array.RebuildSectors < pCmd->uCmd.R1Control.nSectors)
829 pCmd->uCmd.R1Control.nSectors = capacity - pArray->u.array.RebuildSectors;
830
831 pCmd->uCmd.R1Control.Buffer = buffer;
832 pCmd->pfnBuildSgl = R1ControlSgl;
833 }
834 else if (pArray->VDeviceType==VD_RAID_5)
835 {
836 switch(flags)
837 {
838 case DUPLICATE:
839 case REBUILD_PARITY:
840 pCmd->uCmd.R5Control.Command = CTRL_CMD_REBUILD; break;
841 case VERIFY:
842 pCmd->uCmd.R5Control.Command = CTRL_CMD_VERIFY; break;
843 case INITIALIZE:
844 pCmd->uCmd.R5Control.Command = CTRL_CMD_INIT; break;
845 }
846 pCmd->uCmd.R5Control.StripeLine=pArray->u.array.RebuildSectors>>pArray->u.array.bArBlockSizeShift;
847 }
848 else
849 HPT_ASSERT(0);
850
851 pCmd->pVDevice = pArray;
852 pCmd->pfnCompletion = thread_io_done;
853 pArray->pfnSendCommand(_VBUS_P pCmd);
854 CheckPendingCall(_VBUS_P0);
855
856 if (!End_Job) {
857 unlock_driver(oldspl);
858 while (!End_Job) {
859 tsleep((caddr_t)pCmd, PPAUSE, "pause", hz);
860 if (timeout++>60) break;
861 }
862 oldspl = lock_driver();
863 if (!End_Job) {
864 hpt_printk(("timeout, reset\n"));
865 fResetVBus(_VBUS_P0);
866 }
867 }
868
869 result = pCmd->Result;
870 FreeCommand(_VBUS_P pCmd);
871 unlock_driver(oldspl);
872 if (buffer) free(buffer, M_DEVBUF);
873 oldspl = lock_driver();
874 KdPrintI(("cmd finished %d", result));
875
876 switch(result)
877 {
878 case RETURN_SUCCESS:
879 if (!pArray->u.array.rf_abort_rebuild)
880 {
881 if(pArray->u.array.RebuildSectors < capacity)
882 {
883 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pArray, flags);
884 }
885 else
886 {
887 switch (flags)
888 {
889 case DUPLICATE:
890 case REBUILD_PARITY:
891 needsync = 1;
892 pArray->u.array.rf_rebuilding = 0;
893 pArray->u.array.rf_need_rebuild = 0;
894 pArray->u.array.CriticalMembers = 0;
895 pArray->u.array.RebuildSectors = MAX_LBA_T;
896 pArray->u.array.rf_duplicate_and_create = 0;
897 hpt_printk(("Rebuilding finished.\n"));
898 ioctl_ReportEvent(ET_REBUILD_FINISHED, pArray);
899 break;
900 case INITIALIZE:
901 needsync = 1;
902 pArray->u.array.rf_initializing = 0;
903 pArray->u.array.rf_need_rebuild = 0;
904 pArray->u.array.RebuildSectors = MAX_LBA_T;
905 hpt_printk(("Initializing finished.\n"));
906 ioctl_ReportEvent(ET_INITIALIZE_FINISHED, pArray);
907 break;
908 case VERIFY:
909 pArray->u.array.rf_verifying = 0;
910 hpt_printk(("Verifying finished.\n"));
911 ioctl_ReportEvent(ET_VERIFY_FINISHED, pArray);
912 break;
913 }
914 }
915 }
916 else
917 {
918 pArray->u.array.rf_abort_rebuild = 0;
919 if (pArray->u.array.rf_rebuilding)
920 {
921 hpt_printk(("Abort rebuilding.\n"));
922 pArray->u.array.rf_rebuilding = 0;
923 pArray->u.array.rf_duplicate_and_create = 0;
924 ioctl_ReportEvent(ET_REBUILD_ABORTED, pArray);
925 }
926 else if (pArray->u.array.rf_verifying)
927 {
928 hpt_printk(("Abort verifying.\n"));
929 pArray->u.array.rf_verifying = 0;
930 ioctl_ReportEvent(ET_VERIFY_ABORTED, pArray);
931 }
932 else if (pArray->u.array.rf_initializing)
933 {
934 hpt_printk(("Abort initializing.\n"));
935 pArray->u.array.rf_initializing = 0;
936 ioctl_ReportEvent(ET_INITIALIZE_ABORTED, pArray);
937 }
938 needdelete=1;
939 }
940 break;
941
942 case RETURN_DATA_ERROR:
943 if (flags==VERIFY)
944 {
945 needsync = 1;
946 pArray->u.array.rf_verifying = 0;
947 pArray->u.array.rf_need_rebuild = 1;
948 hpt_printk(("Verifying failed: found inconsistency\n"));
949 ioctl_ReportEvent(ET_VERIFY_DATA_ERROR, pArray);
950 ioctl_ReportEvent(ET_VERIFY_FAILED, pArray);
951
952 if (!pArray->vf_online || pArray->u.array.rf_broken) break;
953
954 pArray->u.array.rf_auto_rebuild = 0;
955 pArray->u.array.rf_abort_rebuild = 0;
956 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pArray,
957 (pArray->VDeviceType == VD_RAID_1) ? DUPLICATE : REBUILD_PARITY);
958 }
959 break;
960
961 default:
962 hpt_printk(("command failed with error %d\n", result));
963 if (++retry<3)
964 {
965 hpt_printk(("retry (%d)\n", retry));
966 goto retry_cmd;
967 }
968fail:
969 pArray->u.array.rf_abort_rebuild = 0;
970 switch (flags)
971 {
972 case DUPLICATE:
973 case REBUILD_PARITY:
974 needsync = 1;
975 pArray->u.array.rf_rebuilding = 0;
976 pArray->u.array.rf_duplicate_and_create = 0;
977 hpt_printk(((flags==DUPLICATE)? "Duplicating failed.\n":"Rebuilding failed.\n"));
978 ioctl_ReportEvent(ET_REBUILD_FAILED, pArray);
979 break;
980
981 case INITIALIZE:
982 needsync = 1;
983 pArray->u.array.rf_initializing = 0;
984 hpt_printk(("Initializing failed.\n"));
985 ioctl_ReportEvent(ET_INITIALIZE_FAILED, pArray);
986 break;
987
988 case VERIFY:
989 needsync = 1;
990 pArray->u.array.rf_verifying = 0;
991 hpt_printk(("Verifying failed.\n"));
992 ioctl_ReportEvent(ET_VERIFY_FAILED, pArray);
993 break;
994 }
995 needdelete=1;
996 }
997
998 while (pAdapter->outstandingCommands)
999 {
1000 KdPrintI(("currcmds is %d, wait..\n", pAdapter->outstandingCommands));
1001 /* put this to have driver stop processing system commands quickly */
1002 if (!mWaitingForIdle(_VBUS_P0)) CallWhenIdle(_VBUS_P nothing, 0);
1003 unlock_driver(oldspl);
1004 /*Schedule out*/
1005#if (__FreeBSD_version < 500000)
1006 YIELD_THREAD;
1007#else
1008#if (__FreeBSD_version > 700033)
955 pause("switch", 1);
1009 pause("switch", 1);
1010#else
1011 tsleep(hpt_rebuild_data_block, PPAUSE, "switch", 1);
956#endif
1012#endif
1013#endif
957 oldspl = lock_driver();
958 }
959
960 if (needsync) SyncArrayInfo(pArray);
961 if(needdelete && (pArray->u.array.rf_duplicate_must_done || (flags == INITIALIZE)))
962 fDeleteArray(_VBUS_P pArray, TRUE);
963
964 Check_Idle_Call(pAdapter);
965 unlock_driver(oldspl);
966}
1014 oldspl = lock_driver();
1015 }
1016
1017 if (needsync) SyncArrayInfo(pArray);
1018 if(needdelete && (pArray->u.array.rf_duplicate_must_done || (flags == INITIALIZE)))
1019 fDeleteArray(_VBUS_P pArray, TRUE);
1020
1021 Check_Idle_Call(pAdapter);
1022 unlock_driver(oldspl);
1023}