xref: /netbsd-src/sys/dev/raidframe/rf_disks.c (revision dc306354b0b29af51801a7632f1e95265a68cd81)
1 /*	$NetBSD: rf_disks.c,v 1.2 1998/12/03 15:06:25 oster Exp $	*/
2 /*
3  * Copyright (c) 1995 Carnegie-Mellon University.
4  * All rights reserved.
5  *
6  * Author: Mark Holland
7  *
8  * Permission to use, copy, modify and distribute this software and
9  * its documentation is hereby granted, provided that both the copyright
10  * notice and this permission notice appear in all copies of the
11  * software, derivative works or modified versions, and any portions
12  * thereof, and that both notices appear in supporting documentation.
13  *
14  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
16  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17  *
18  * Carnegie Mellon requests users of this software to return to
19  *
20  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
21  *  School of Computer Science
22  *  Carnegie Mellon University
23  *  Pittsburgh PA 15213-3890
24  *
25  * any improvements or extensions that they make and grant Carnegie the
26  * rights to redistribute these changes.
27  */
28 
29 /***************************************************************
30  * rf_disks.c -- code to perform operations on the actual disks
31  ***************************************************************/
32 
33 /* :
34  * Log: rf_disks.c,v
35  * Revision 1.32  1996/07/27 18:40:24  jimz
36  * cleanup sweep
37  *
38  * Revision 1.31  1996/07/22  19:52:16  jimz
39  * switched node params to RF_DagParam_t, a union of
40  * a 64-bit int and a void *, for better portability
41  * attempted hpux port, but failed partway through for
42  * lack of a single C compiler capable of compiling all
43  * source files
44  *
45  * Revision 1.30  1996/07/19  16:11:21  jimz
46  * pass devname to DoReadCapacity
47  *
48  * Revision 1.29  1996/07/18  22:57:14  jimz
49  * port simulator to AIX
50  *
51  * Revision 1.28  1996/07/10  22:28:38  jimz
52  * get rid of obsolete row statuses (dead,degraded2)
53  *
54  * Revision 1.27  1996/06/10  12:06:14  jimz
55  * don't do any SCSI op stuff in simulator at all
56  *
57  * Revision 1.26  1996/06/10  11:55:47  jimz
58  * Straightened out some per-array/not-per-array distinctions, fixed
59  * a couple bugs related to confusion. Added shutdown lists. Removed
60  * layout shutdown function (now subsumed by shutdown lists).
61  *
62  * Revision 1.25  1996/06/09  02:36:46  jimz
63  * lots of little crufty cleanup- fixup whitespace
64  * issues, comment #ifdefs, improve typing in some
65  * places (esp size-related)
66  *
67  * Revision 1.24  1996/06/07  21:33:04  jimz
68  * begin using consistent types for sector numbers,
69  * stripe numbers, row+col numbers, recon unit numbers
70  *
71  * Revision 1.23  1996/06/03  23:28:26  jimz
72  * more bugfixes
73  * check in tree to sync for IPDS runs with current bugfixes
74  * there still may be a problem with threads in the script test
75  * getting I/Os stuck- not trivially reproducible (runs ~50 times
76  * in a row without getting stuck)
77  *
78  * Revision 1.22  1996/06/02  17:31:48  jimz
79  * Moved a lot of global stuff into array structure, where it belongs.
80  * Fixed up paritylogging, pss modules in this manner. Some general
81  * code cleanup. Removed lots of dead code, some dead files.
82  *
83  * Revision 1.21  1996/05/30  23:22:16  jimz
84  * bugfixes of serialization, timing problems
85  * more cleanup
86  *
87  * Revision 1.20  1996/05/30  11:29:41  jimz
88  * Numerous bug fixes. Stripe lock release code disagreed with the taking code
89  * about when stripes should be locked (I made it consistent: no parity, no lock)
90  * There was a lot of extra serialization of I/Os which I've removed- a lot of
91  * it was to calculate values for the cache code, which is no longer with us.
92  * More types, function, macro cleanup. Added code to properly quiesce the array
93  * on shutdown. Made a lot of stuff array-specific which was (bogusly) general
94  * before. Fixed memory allocation, freeing bugs.
95  *
96  * Revision 1.19  1996/05/27  18:56:37  jimz
97  * more code cleanup
98  * better typing
99  * compiles in all 3 environments
100  *
101  * Revision 1.18  1996/05/24  22:17:04  jimz
102  * continue code + namespace cleanup
103  * typed a bunch of flags
104  *
105  * Revision 1.17  1996/05/24  01:59:45  jimz
106  * another checkpoint in code cleanup for release
107  * time to sync kernel tree
108  *
109  * Revision 1.16  1996/05/23  21:46:35  jimz
110  * checkpoint in code cleanup (release prep)
111  * lots of types, function names have been fixed
112  *
113  * Revision 1.15  1996/05/23  00:33:23  jimz
114  * code cleanup: move all debug decls to rf_options.c, all extern
115  * debug decls to rf_options.h, all debug vars preceded by rf_
116  *
117  * Revision 1.14  1996/05/18  19:51:34  jimz
118  * major code cleanup- fix syntax, make some types consistent,
119  * add prototypes, clean out dead code, et cetera
120  *
121  * Revision 1.13  1996/05/02  14:57:43  jimz
122  * initialize sectorMask
123  *
124  * Revision 1.12  1995/12/01  15:57:04  root
125  * added copyright info
126  *
127  */
128 
129 #include "rf_types.h"
130 #include "rf_raid.h"
131 #include "rf_alloclist.h"
132 #include "rf_utils.h"
133 #include "rf_configure.h"
134 #include "rf_general.h"
135 #if !defined(__NetBSD__)
136 #include "rf_camlayer.h"
137 #endif
138 #include "rf_options.h"
139 #include "rf_sys.h"
140 
141 #if defined(__NetBSD__) && defined(_KERNEL)
142 #include <sys/types.h>
143 #include <sys/param.h>
144 #include <sys/systm.h>
145 #include <sys/proc.h>
146 #include <sys/ioctl.h>
147 #include <sys/fcntl.h>
148 #include <sys/vnode.h>
149 
150 int raidlookup __P((char *, struct proc *p, struct vnode **));
151 #endif
152 
153 #ifdef SIMULATE
154 static char disk_db_file_name[120], disk_type_name[120];
155 static double init_offset;
156 #endif /* SIMULATE  */
157 
158 #define DPRINTF6(a,b,c,d,e,f) if (rf_diskDebug) printf(a,b,c,d,e,f)
159 #define DPRINTF7(a,b,c,d,e,f,g) if (rf_diskDebug) printf(a,b,c,d,e,f,g)
160 
161 #include "rf_ccmn.h"
162 
163 /****************************************************************************************
164  *
165  * initialize the disks comprising the array
166  *
167  * We want the spare disks to have regular row,col numbers so that we can easily
168  * substitue a spare for a failed disk.  But, the driver code assumes throughout
169  * that the array contains numRow by numCol _non-spare_ disks, so it's not clear
170  * how to fit in the spares.  This is an unfortunate holdover from raidSim.  The
171  * quick and dirty fix is to make row zero bigger than the rest, and put all the
172  * spares in it.  This probably needs to get changed eventually.
173  *
174  ***************************************************************************************/
175 int rf_ConfigureDisks(
176   RF_ShutdownList_t  **listp,
177   RF_Raid_t           *raidPtr,
178   RF_Config_t         *cfgPtr)
179 {
180   RF_RaidDisk_t **disks;
181   RF_SectorCount_t min_numblks = (RF_SectorCount_t)0x7FFFFFFFFFFFLL;
182   RF_RowCol_t r, c;
183   int bs, ret;
184   unsigned i, count, foundone=0, numFailuresThisRow;
185   RF_DiskOp_t *rdcap_op = NULL, *tur_op = NULL;
186   int num_rows_done,num_cols_done;
187 
188 #if defined(__NetBSD__) && defined(_KERNEL)
189 	struct proc *proc = 0;
190 #endif
191 #ifndef SIMULATE
192 #ifndef __NetBSD__
193   ret = rf_SCSI_AllocReadCapacity(&rdcap_op);
194   if (ret)
195     goto fail;
196   ret = rf_SCSI_AllocTUR(&tur_op);
197   if (ret)
198     goto fail;
199 #endif /* !__NetBSD__ */
200 #endif /* !SIMULATE */
201 
202   num_rows_done = 0;
203   num_cols_done = 0;
204 
205 
206   RF_CallocAndAdd(disks, raidPtr->numRow, sizeof(RF_RaidDisk_t *), (RF_RaidDisk_t **), raidPtr->cleanupList);
207   if (disks == NULL) {
208     ret = ENOMEM;
209     goto fail;
210   }
211   raidPtr->Disks = disks;
212 
213 #if defined(__NetBSD__) && defined(_KERNEL)
214 
215   proc = raidPtr->proc; /* Blah XXX */
216 
217   /* get space for the device-specific stuff... */
218   RF_CallocAndAdd(raidPtr->raid_cinfo, raidPtr->numRow,
219 		  sizeof(struct raidcinfo *), (struct raidcinfo **),
220 		  raidPtr->cleanupList);
221   if (raidPtr->raid_cinfo == NULL) {
222 	  ret = ENOMEM;
223 	  goto fail;
224   }
225 #endif
226 
227   for (r=0; r<raidPtr->numRow; r++) {
228     numFailuresThisRow = 0;
229     RF_CallocAndAdd(disks[r], raidPtr->numCol + ((r==0) ? raidPtr->numSpare : 0), sizeof(RF_RaidDisk_t), (RF_RaidDisk_t *), raidPtr->cleanupList);
230     if (disks[r] == NULL) {
231       ret = ENOMEM;
232       goto fail;
233     }
234 
235     /* get more space for device specific stuff.. */
236     RF_CallocAndAdd(raidPtr->raid_cinfo[r],
237 		    raidPtr->numCol + ((r==0) ? raidPtr->numSpare : 0),
238 		    sizeof(struct raidcinfo), (struct raidcinfo *),
239 		    raidPtr->cleanupList);
240     if (raidPtr->raid_cinfo[r] == NULL) {
241       ret = ENOMEM;
242       goto fail;
243     }
244 
245 
246     for (c=0; c<raidPtr->numCol; c++) {
247       ret = rf_ConfigureDisk(raidPtr,&cfgPtr->devnames[r][c][0],
248 			     &disks[r][c], rdcap_op, tur_op,
249 			     cfgPtr->devs[r][c],r,c);
250       if (ret)
251         goto fail;
252       if (disks[r][c].status != rf_ds_optimal) {
253         numFailuresThisRow++;
254       }
255       else {
256         if (disks[r][c].numBlocks < min_numblks)
257           min_numblks = disks[r][c].numBlocks;
258         DPRINTF7("Disk at row %d col %d: dev %s numBlocks %ld blockSize %d (%ld MB)\n",
259           r,c,disks[r][c].devname,
260 		 (long int) disks[r][c].numBlocks,
261 		 disks[r][c].blockSize,
262 		 (long int) disks[r][c].numBlocks * disks[r][c].blockSize / 1024 / 1024);
263       }
264       num_cols_done++;
265     }
266     /* XXX fix for n-fault tolerant */
267     if (numFailuresThisRow > 0)
268       raidPtr->status[r] = rf_rs_degraded;
269     num_rows_done++;
270   }
271 #ifndef SIMULATE
272 #if defined(__NetBSD__) && defined(_KERNEL)
273   /* we do nothing */
274 #else
275   rf_SCSI_FreeDiskOp(rdcap_op, 1); rdcap_op = NULL;
276   rf_SCSI_FreeDiskOp(tur_op, 0);   tur_op   = NULL;
277 #endif
278 #endif /* !SIMULATE */
279   /* all disks must be the same size & have the same block size, bs must be a power of 2 */
280   bs = 0;
281   for (foundone=r=0; !foundone && r<raidPtr->numRow; r++) {
282     for (c=0; !foundone && c<raidPtr->numCol; c++) {
283       if (disks[r][c].status == rf_ds_optimal) {
284         bs = disks[r][c].blockSize;
285         foundone = 1;
286       }
287     }
288   }
289   if (!foundone) {
290     RF_ERRORMSG("RAIDFRAME: Did not find any live disks in the array.\n");
291     ret = EINVAL;
292     goto fail;
293   }
294   for (count=0,i=1; i; i<<=1) if (bs & i)
295     count++;
296   if (count != 1) {
297     RF_ERRORMSG1("Error: block size on disks (%d) must be a power of 2\n",bs);
298     ret = EINVAL;
299     goto fail;
300   }
301   for (r=0; r<raidPtr->numRow; r++) {
302     for (c=0; c<raidPtr->numCol; c++) {
303       if (disks[r][c].status == rf_ds_optimal) {
304 	if (disks[r][c].blockSize != bs) {
305 	  RF_ERRORMSG2("Error: block size of disk at r %d c %d different from disk at r 0 c 0\n",r,c);
306 	  ret = EINVAL;
307 	  goto fail;
308 	}
309 	if (disks[r][c].numBlocks != min_numblks) {
310 	  RF_ERRORMSG3("WARNING: truncating disk at r %d c %d to %d blocks\n",
311 		       r,c,(int) min_numblks);
312 	  disks[r][c].numBlocks = min_numblks;
313 	}
314       }
315     }
316   }
317 
318   raidPtr->sectorsPerDisk = min_numblks;
319   raidPtr->logBytesPerSector = ffs(bs) - 1;
320   raidPtr->bytesPerSector = bs;
321   raidPtr->sectorMask = bs-1;
322   return(0);
323 
324 fail:
325 
326 #ifndef SIMULATE
327 #if defined(__NetBSD__) && defined(_KERNEL)
328 
329   for(r=0;r<raidPtr->numRow;r++) {
330 	  for(c=0;c<raidPtr->numCol;c++) {
331 		  /* Cleanup.. */
332 #ifdef DEBUG
333 		  printf("Cleaning up row: %d col: %d\n",r,c);
334 #endif
335 		  if (raidPtr->raid_cinfo[r][c].ci_vp) {
336 			  (void)vn_close(raidPtr->raid_cinfo[r][c].ci_vp,
337 					 FREAD|FWRITE, proc->p_ucred, proc);
338 		  }
339 	  }
340   }
341   /* Space allocated for raid_vpp will get cleaned up at some other point */
342   /* XXX Need more #ifdefs in the above... */
343 
344 #else
345 
346   if (rdcap_op) rf_SCSI_FreeDiskOp(rdcap_op, 1);
347   if (tur_op)   rf_SCSI_FreeDiskOp(tur_op, 0);
348 
349 #endif
350 #endif /* !SIMULATE */
351   return(ret);
352 }
353 
354 
355 /****************************************************************************************
356  * set up the data structures describing the spare disks in the array
357  * recall from the above comment that the spare disk descriptors are stored
358  * in row zero, which is specially expanded to hold them.
359  ***************************************************************************************/
360 int rf_ConfigureSpareDisks(
361   RF_ShutdownList_t  **listp,
362   RF_Raid_t           *raidPtr,
363   RF_Config_t         *cfgPtr)
364 {
365   char buf[256];
366   int r,c,i, ret;
367   RF_DiskOp_t *rdcap_op = NULL, *tur_op = NULL;
368   unsigned bs;
369   RF_RaidDisk_t *disks;
370   int num_spares_done;
371 
372 #if defined(__NetBSD__) && defined(_KERNEL)
373 	struct proc *proc;
374 #endif
375 
376 #ifndef SIMULATE
377 #ifndef __NetBSD__
378   ret = rf_SCSI_AllocReadCapacity(&rdcap_op);
379   if (ret)
380     goto fail;
381   ret = rf_SCSI_AllocTUR(&tur_op);
382   if (ret)
383     goto fail;
384 #endif /* !__NetBSD__ */
385 #endif /* !SIMULATE */
386 
387   num_spares_done = 0;
388 
389 #if defined(__NetBSD__) && defined(_KERNEL)
390   proc = raidPtr->proc;
391   /* The space for the spares should have already been
392      allocated by ConfigureDisks() */
393 #endif
394 
395   disks = &raidPtr->Disks[0][raidPtr->numCol];
396   for (i=0; i<raidPtr->numSpare; i++) {
397     ret = rf_ConfigureDisk(raidPtr,&cfgPtr->spare_names[i][0],
398 			   &disks[i], rdcap_op, tur_op,
399 			   cfgPtr->spare_devs[i],0,raidPtr->numCol+i);
400     if (ret)
401       goto fail;
402     if (disks[i].status != rf_ds_optimal) {
403       RF_ERRORMSG1("Warning: spare disk %s failed TUR\n",buf);
404     } else {
405       disks[i].status = rf_ds_spare;      /* change status to spare */
406       DPRINTF6("Spare Disk %d: dev %s numBlocks %ld blockSize %d (%ld MB)\n",i,
407 	       disks[i].devname,
408 	       (long int) disks[i].numBlocks,disks[i].blockSize,
409 	       (long int) disks[i].numBlocks * disks[i].blockSize / 1024 / 1024);
410     }
411     num_spares_done++;
412   }
413 #ifndef SIMULATE
414 #if defined(__NetBSD__) && (_KERNEL)
415 
416 #else
417   rf_SCSI_FreeDiskOp(rdcap_op, 1); rdcap_op = NULL;
418   rf_SCSI_FreeDiskOp(tur_op, 0);   tur_op   = NULL;
419 #endif
420 #endif /* !SIMULATE */
421 
422   /* check sizes and block sizes on spare disks */
423   bs = 1 << raidPtr->logBytesPerSector;
424   for (i=0; i<raidPtr->numSpare; i++) {
425     if (disks[i].blockSize != bs) {
426       RF_ERRORMSG3("Block size of %d on spare disk %s is not the same as on other disks (%d)\n",disks[i].blockSize, disks[i].devname, bs);
427       ret = EINVAL;
428       goto fail;
429     }
430     if (disks[i].numBlocks < raidPtr->sectorsPerDisk) {
431 	    RF_ERRORMSG3("Spare disk %s (%d blocks) is too small to serve as a spare (need %ld blocks)\n",
432 		disks[i].devname, disks[i].blockSize, (long int)raidPtr->sectorsPerDisk);
433       ret = EINVAL;
434       goto fail;
435     } else if (disks[i].numBlocks > raidPtr->sectorsPerDisk) {
436 	    RF_ERRORMSG2("Warning: truncating spare disk %s to %ld blocks\n",disks[i].devname, (long int) raidPtr->sectorsPerDisk);
437 
438       disks[i].numBlocks = raidPtr->sectorsPerDisk;
439     }
440   }
441 
442   return(0);
443 
444 fail:
445 #ifndef SIMULATE
446 #if defined(__NetBSD__) && defined(_KERNEL)
447 
448   /* Release the hold on the main components.  We've failed to allocate a
449      spare, and since we're failing, we need to free things.. */
450 
451   for(r=0;r<raidPtr->numRow;r++) {
452 	  for(c=0;c<raidPtr->numCol;c++) {
453 		  /* Cleanup.. */
454 #ifdef DEBUG
455 		  printf("Cleaning up row: %d col: %d\n",r,c);
456 #endif
457 		  if (raidPtr->raid_cinfo[r][c].ci_vp) {
458 			  (void)vn_close(raidPtr->raid_cinfo[r][c].ci_vp,
459 					 FREAD|FWRITE, proc->p_ucred, proc);
460 		  }
461 	  }
462   }
463 
464   for(i=0;i<raidPtr->numSpare;i++) {
465 	  /* Cleanup.. */
466 #ifdef DEBUG
467 	  printf("Cleaning up spare: %d\n",i);
468 #endif
469 	  if (raidPtr->raid_cinfo[0][raidPtr->numCol+i].ci_vp) {
470 		  (void)vn_close(raidPtr->raid_cinfo[0][raidPtr->numCol+i].ci_vp,
471 				 FREAD|FWRITE, proc->p_ucred, proc);
472 	  }
473   }
474 
475 #else
476 
477   if (rdcap_op) rf_SCSI_FreeDiskOp(rdcap_op, 1);
478   if (tur_op)   rf_SCSI_FreeDiskOp(tur_op, 0);
479 
480 #endif
481 
482 #endif /* !SIMULATE */
483   return(ret);
484 }
485 
486 
487 
488 /* configure a single disk in the array */
489 int rf_ConfigureDisk(raidPtr, buf, diskPtr, rdcap_op, tur_op, dev, row, col)
490   RF_Raid_t      *raidPtr;  /* We need this down here too!! GO */
491   char           *buf;
492   RF_RaidDisk_t  *diskPtr;
493   RF_DiskOp_t    *rdcap_op;
494   RF_DiskOp_t    *tur_op;
495   dev_t           dev;      /* device number used only in kernel */
496   RF_RowCol_t     row;
497   RF_RowCol_t     col;
498 {
499   char *p;
500 #ifdef SIMULATE
501   double	init_offset;
502 #else /* SIMULATE  */
503 #if defined(__NetBSD__) && defined(_KERNEL)
504   int retcode;
505 #else
506   int busid, targid, lun, retcode;
507 #endif
508 #endif /* SIMULATE  */
509 
510 #if defined(__NetBSD__) && defined(_KERNEL)
511 	struct partinfo dpart;
512 	struct vnode *vp;
513 	struct vattr va;
514 	struct proc *proc;
515 	int error;
516 #endif
517 
518 retcode = 0;
519   p = rf_find_non_white(buf);
520   if (p[strlen(p)-1] == '\n') {
521     /* strip off the newline */
522     p[strlen(p)-1] = '\0';
523   }
524   (void) strcpy(diskPtr->devname, p);
525 
526 #ifdef SIMULATE
527 
528   init_offset = 0.0;
529   rf_InitDisk(&diskPtr->diskState, disk_db_file_name,diskPtr->devname,0,0,init_offset,row,col);
530   rf_GeometryDoReadCapacity(&diskPtr->diskState, &diskPtr->numBlocks, &diskPtr->blockSize);
531   diskPtr->numBlocks = diskPtr->numBlocks * rf_sizePercentage / 100;
532 
533   /* we allow the user to specify that only a fraction of the disks should be used
534    * this is just for debug:  it speeds up the parity scan
535    */
536 
537 #else /* SIMULATE */
538 #ifndef __NetBSD__
539   /* get bus, target, lun */
540   retcode = rf_extract_ids(p, &busid, &targid, &lun);
541   if (retcode)
542     return(retcode);
543 
544   /* required in kernel, nop at user level */
545   retcode = rf_SCSI_OpenUnit(dev);
546   if (retcode)
547     return(retcode);
548 
549   diskPtr->dev = dev;
550   if (rf_SCSI_DoTUR(tur_op, (u_char)busid, (u_char)targid, (u_char)lun, dev)) {
551     RF_ERRORMSG1("Disk %s failed TUR.  Marked as dead.\n",diskPtr->devname);
552     diskPtr->status = rf_ds_failed;
553   } else {
554     diskPtr->status = rf_ds_optimal;
555     retcode = rf_SCSI_DoReadCapacity(raidPtr,rdcap_op, busid, targid, lun, dev,
556       &diskPtr->numBlocks, &diskPtr->blockSize, diskPtr->devname);
557     if (retcode)
558       return(retcode);
559 
560     /* we allow the user to specify that only a fraction of the disks should be used
561      * this is just for debug:  it speeds up the parity scan
562      */
563     diskPtr->numBlocks = diskPtr->numBlocks * rf_sizePercentage / 100;
564   }
565 #endif
566 #if defined(__NetBSD__) && defined(_KERNEL)
567 
568   proc = raidPtr->proc;  /* XXX Yes, this is not nice.. */
569 
570   /* Let's start by claiming the component is fine and well... */
571   /* XXX not the case if the disk is toast.. */
572   diskPtr->status = rf_ds_optimal;
573 
574 
575   raidPtr->raid_cinfo[row][col].ci_vp = NULL;
576   raidPtr->raid_cinfo[row][col].ci_dev = NULL;
577 
578   error = raidlookup(diskPtr->devname, proc, &vp);
579   if (error) {
580 	  printf("raidlookup on device: %s failed!\n",diskPtr->devname);
581 	  if (error == ENXIO) {
582 		  /* XXX the component isn't there... must be dead :-( */
583 		  diskPtr->status = rf_ds_failed;
584 	  } else {
585 		  return(error);
586 	  }
587   }
588 
589   if (diskPtr->status == rf_ds_optimal) {
590 
591 	  if ((error = VOP_GETATTR(vp, &va, proc->p_ucred, proc)) != 0) {
592 		  return(error);
593 	  }
594 
595 	  error = VOP_IOCTL(vp, DIOCGPART, (caddr_t)&dpart,
596 			    FREAD, proc->p_ucred, proc);
597 	  if (error) {
598 		  return(error);
599 	  }
600 
601 
602 	  diskPtr->blockSize = dpart.disklab->d_secsize;
603 
604 	  diskPtr->numBlocks = dpart.part->p_size - rf_protectedSectors;
605 
606 	  raidPtr->raid_cinfo[row][col].ci_vp = vp;
607 	  raidPtr->raid_cinfo[row][col].ci_dev = va.va_rdev;
608 
609 #if 0
610 	  diskPtr->dev = dev;
611 #endif
612 
613 	  diskPtr->dev = va.va_rdev; /* XXX or the above? */
614 
615 	  /* we allow the user to specify that only a fraction of the disks should be used
616 	   * this is just for debug:  it speeds up the parity scan
617 	   */
618 	  diskPtr->numBlocks = diskPtr->numBlocks * rf_sizePercentage / 100;
619 
620   }
621 
622 #endif /* !__NetBSD__ */
623 #endif /* SIMULATE */
624 
625   return(0);
626 }
627 
628 #ifdef SIMULATE
629 
630 void rf_default_disk_names()
631 {
632     sprintf(disk_db_file_name,"disk.db");
633     sprintf(disk_type_name,"HP2247");
634 }
635 
636 void rf_set_disk_db_name(s)
637  char  *s;
638 {
639     strcpy(disk_db_file_name,s);
640 }
641 
642 void rf_set_disk_type_name(s)
643  char  *s;
644 {
645     strcpy(disk_type_name,s);
646 }
647 
648 #endif /* SIMULATE */
649