dpartCbio.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:23k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* dpartCbio.c - generic disk partition manager */
  2. /* Copyright 1999-2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01s,14jan02,jkf  SPR#72533,dpartDevCreate failed with BLK_DEV, & doc edits.
  8. 01r,12dec01,jkf  fixing diab build warnings.
  9. 01q,09dec01,jkf  SPR#71637, fix for SPR#68387 caused ready changed bugs.
  10. 01p,09nov01,jkf  SPR#71633, dont set errno when DevCreate is called w/BLK_DEV
  11. 01o,20sep01,jkf  SPR#69031, common code for both AE & 5.x.
  12. 01n,01aug01,jyo  Fixed SPR#69411: Change in media's readyChanged bit is not
  13.                  being propogated appropriately to the layers above.
  14. 01m,14jun01,jyo  SPR#67729: Updating blkSubDev, cbioSubDev and isDriver in
  15.                  dpartDevCreate().
  16. 01l,19apr00,dat  doc fixup
  17. 01k,29feb00,jkf  T3 changes, cleanup.
  18. 01j,15sep99,jkf  changes for new CBIO API.
  19. 01i,24aug99,jkf  changed docs
  20. 01h,31jul99,jkf  increased max partitions to 24 (c-z) in header, 
  21.                  changed docs, defaulted the debug global to 0. SPR#28277.
  22. 01g,31jul99,jkf  T2 merge, tidiness & spelling.
  23. 01f,07dec98,lrn  minor fixes for partition table creation
  24. 01e,25oct98,lrn  fixed re-reading subDev geometry on RESET
  25. 01d,15sep98,lrn  some doc cleanups
  26. 01c,10sep98,lrn  added cbioDevVerify for cache-less configs
  27. 01b,02jul98,lrn  tested, doc review
  28. 01a,15jun98,lrn  written, preliminary
  29. */
  30. /*
  31. DESCRIPTION
  32. This module implements a generic partition manager using the CBIO
  33. API (see cbioLib)  It supports creating a separate file system 
  34. device for each of its partitions.
  35. This partition manager depends upon an external library to decode a
  36. particular disk partition table format, and report the resulting
  37. partition layout information back to this module.  This module is
  38. responsible for maintaining the partition logic during operation.
  39. When using this module with the dcacheCbio module, it is recommened
  40. this module be the master CBIO device.   This module should be above 
  41. the cache CBIO module layer.   This is because the cache layer is 
  42. optimized to fuction efficently atop a single physical disk drive.
  43. One should call dcacheDevCreate before dpartDevCreate.
  44. An implementation of the de-facto standard partition table format
  45. which is created by the MSDOS FDISK program is provided with the
  46. usrFdiskPartLib module, which should be used to handle PC-style
  47. partitioned hard or removable drives.
  48. EXAMPLE
  49. The following code will initialize a disk which is expected to have up
  50. to 4 partitions:
  51. .CS
  52.   usrPartDiskFsInit( BLK_DEV * blkDevId )
  53.     {
  54.     const char * devNames[] = { "/sd0a", "/sd0b", "/sd0c", "/sd0d" };
  55.     CBIO_DEV_ID cbioCache;
  56.     CBIO_DEV_ID cbioParts;
  57.     /@ create a disk cache atop the entire BLK_DEV @/
  58.     cbioCache = dcacheDevCreate ( blkDevId, NULL, 0, "/sd0" );
  59.     if (NULL == cbioCache)
  60.         {
  61.         return (ERROR);
  62.         }
  63.     /@ create a partition manager with a FDISK style decoder @/
  64.     cbioParts = dpartDevCreate( cbioCache, 4, usrFdiskPartRead );
  65.     if (NULL == cbioParts)
  66.         {
  67.         return (ERROR);
  68.         }
  69.     /@ create file systems atop each partition @/
  70.     dosFsDevCreate( devNames[0], dpartPartGet(cbioParts,0), 0x10, NONE);
  71.     dosFsDevCreate( devNames[1], dpartPartGet(cbioParts,1), 0x10, NONE);
  72.     dosFsDevCreate( devNames[2], dpartPartGet(cbioParts,2), 0x10, NONE);
  73.     dosFsDevCreate( devNames[3], dpartPartGet(cbioParts,3), 0x10, NONE);
  74.     }
  75. .CE
  76. Because this module complies with the CBIO programming interface on both 
  77. its upper and lower layers, it is both an optional and a stackable module.
  78. SEE ALSO:
  79. dcacheLib, dosFsLib, usrFdiskPartLib
  80. INTERNAL
  81. */
  82. /* includes */
  83. #include "vxWorks.h"
  84. #include "private/dosFsVerP.h"
  85. #include "stdlib.h"
  86. #include "semLib.h"
  87. #include "ioLib.h"
  88. #include "string.h"
  89. #include "stdio.h"
  90. #include "errno.h"
  91. #include "assert.h"
  92. /* START - CBIO private header */
  93. #define CBIO_DEV_EXTRA struct dpartCtrl
  94. #include "private/cbioLibP.h"
  95. /* END - CBIO private header */
  96. #include "dpartCbio.h"
  97. /* Implementation dependent data structures */
  98. typedef struct dpartCtrl
  99.     {
  100.     CBIO_DEV_ID subDev; /* lower level CBIO device handle */
  101.     int nPart ; /* Actual # of partitions on the disk */
  102.     FUNCPTR pPartDecodeFunc;/* Extern. partition decoder */
  103.     PART_TABLE_ENTRY /* partition table */
  104. table [ PART_MAX_ENTRIES ];
  105.     
  106.     CBIO_DEV /* per-partition virtual devices */
  107. vDev [ PART_MAX_ENTRIES ];
  108.     CBIO_DEV_ID masterDev; /* master handle CBIO */
  109.     } DPART_CTRL ;
  110. /* custom use of CBIO fields */
  111. #define cbioPartIndx cbioPriv0
  112. extern void logMsg( const char *fmt, ... );
  113. int dpartDebug = 0;
  114. int dpartSemOptions = (SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE) ;
  115. #define INFO_MSG logMsg
  116. #define DEBUG_MSG if(dpartDebug) logMsg
  117. /* declarations */
  118. LOCAL STATUS dpartBlkRW
  119.     (
  120.     CBIO_DEV_ID dev,
  121.     block_t startBlock,
  122.     block_t numBlocks,
  123.     addr_t buffer,
  124.     CBIO_RW rw,
  125.     cookie_t *pCookie
  126.     );
  127. LOCAL STATUS dpartBytesRW
  128.     (
  129.     CBIO_DEV_ID  dev,
  130.     block_t startBlock,
  131.     off_t offset,
  132.     addr_t buffer,
  133.     size_t nBytes,
  134.     CBIO_RW rw,
  135.     cookie_t *pCookie
  136.     );
  137. LOCAL STATUS dpartBlkCopy
  138.     (
  139.     CBIO_DEV_ID  dev,
  140.     block_t srcBlock,
  141.     block_t dstBlock,
  142.     block_t numBlocks
  143.     );
  144. LOCAL STATUS dpartIoctl
  145.     (
  146.     CBIO_DEV_ID dev,
  147.     UINT32 command,
  148.     addr_t arg
  149.     );
  150. /* CBIO_FUNCS, one per cbio driver */
  151. LOCAL CBIO_FUNCS cbioFuncs = {(FUNCPTR) dpartBlkRW,
  152.       (FUNCPTR) dpartBytesRW,
  153.       (FUNCPTR) dpartBlkCopy,
  154.       (FUNCPTR) dpartIoctl};
  155. /*******************************************************************************
  156. *
  157. * dpartPartTableFill - Fill in partition geometry
  158. *
  159. * Call external function to decode partitions, and fill the partition
  160. * geometry table accordingly.
  161. *
  162. * RETURNS: OK or ERROR if the partition decode function failed for any reason
  163. */
  164. LOCAL STATUS dpartPartTableFill( DPART_CTRL * pDc )
  165.     {
  166.     STATUS ret;
  167.     int pn ;
  168.     CBIO_DEV_ID  masterDev, subDev ;
  169.     masterDev = pDc->masterDev;
  170.     subDev = pDc->subDev;
  171.     if((OK != cbioDevVerify( masterDev )) ||
  172.        (OK != cbioDevVerify( subDev )))
  173. {
  174. return ERROR;
  175. }
  176.     bzero( (char *) &pDc->table, sizeof( pDc->table ) );
  177.     /* First, call out the external decode function */
  178.     ret = pDc->pPartDecodeFunc( pDc->subDev, &pDc->table, pDc->nPart ) ;
  179.     if( ret == ERROR )
  180. return ERROR ;
  181.     /*
  182.      * re-configure device geometry in case it has been replaced
  183.      */
  184.     masterDev->cbioParams.nBlocks = subDev->cbioParams.nBlocks ;
  185.     masterDev->cbioParams.bytesPerBlk = subDev->cbioParams.bytesPerBlk ;
  186.     masterDev->cbioParams.blocksPerTrack= subDev->cbioParams.blocksPerTrack ;
  187.     masterDev->cbioParams.nHeads = subDev->cbioParams.nHeads ;
  188.     masterDev->cbioMode = subDev->cbioMode ;
  189.     /*
  190.      * check sanity of the resulting partition table:
  191.      */
  192.     for( pn = 0; pn < pDc->nPart; pn ++ )
  193. {
  194. if( pDc->table[pn].spare != 0 || 
  195.     (pDc->table[pn].offset + pDc->table[pn].nBlocks) >
  196. pDc->subDev->cbioParams.nBlocks )
  197. {
  198. DEBUG_MSG("dpartCbio: error: "
  199. "partition spills over disk size: %d blocksn",
  200. pDc->table[pn].offset + pDc->table[pn].nBlocks -
  201. pDc->subDev->cbioParams.nBlocks );
  202. return ERROR;
  203. }
  204. }
  205.     DEBUG_MSG("dpartCbio: partition table decoded:n");
  206.     for( pn = 0; pn < pDc->nPart; pn ++ )
  207. {
  208. DEBUG_MSG("  part %d: offset %d nBlocks %d (next free block %d) n",
  209. pn, pDc->table[pn].offset, pDc->table[pn].nBlocks,
  210. pDc->table[pn].offset + pDc->table[pn].nBlocks);
  211. pDc->vDev[ pn ].cbioParams.nBlocks = pDc->table[pn].nBlocks ;
  212. pDc->vDev[ pn ].cbioParams.blockOffset  = pDc->table[pn].offset ;
  213.      pDc->vDev[ pn ].cbioParams.bytesPerBlk = 
  214. subDev->cbioParams.bytesPerBlk ;
  215.      pDc->vDev[ pn ].cbioParams.blocksPerTrack = 
  216. subDev->cbioParams.blocksPerTrack ;
  217.      pDc->vDev[ pn ].cbioParams.nHeads = 
  218. subDev->cbioParams.nHeads ;
  219.      pDc->vDev[ pn ].cbioMode = subDev->cbioMode ;
  220. CBIO_READYCHANGED (&(pDc->vDev[ pn ])) = TRUE;
  221. }
  222.     DEBUG_MSG("dpartCbio: end of partitions, total device blocks %dn",
  223. pDc->subDev->cbioParams.nBlocks );
  224.     return OK ;
  225.     }
  226. /*******************************************************************************
  227. *
  228. * dpartBlkRW - Read/Write blocks
  229. *
  230. * This routine transfers between a user buffer and the lower layer CBIO
  231. * It is optimized for block transfers.  
  232. *
  233. * RETURNS OK or ERROR and may otherwise set errno.
  234. */
  235. LOCAL STATUS dpartBlkRW
  236.     (
  237.     CBIO_DEV_ID dev, /* CBIO handle */
  238.     block_t startBlock, /* starting block */
  239.     block_t numBlocks, /* nbr of blocks */
  240.     addr_t buffer, /* data buffer */
  241.     CBIO_RW rw, /* data direction */
  242.     cookie_t *pCookie /* passed thru */
  243.     )
  244.     {
  245.     CBIO_DEV * pDev = (void *) dev ;
  246.     STATUS retStat ;
  247.     if(TRUE == cbioRdyChgdGet (dev))
  248. {
  249. errno = S_ioLib_DISK_NOT_PRESENT ;
  250. return ERROR;
  251. }
  252.     if( (startBlock) > pDev->cbioParams.nBlocks ||
  253.      (startBlock+numBlocks) > pDev->cbioParams.nBlocks )
  254. return ERROR;
  255.     startBlock += pDev->cbioParams.blockOffset;
  256.     if( semTake( pDev->cbioMutex, WAIT_FOREVER) == ERROR )
  257. return ERROR;
  258.     retStat = pDev->pDc->subDev->pFuncs->cbioDevBlkRW(
  259. pDev->pDc->subDev,
  260. startBlock,
  261. numBlocks,
  262. buffer,
  263. rw,
  264. pCookie );
  265.     if( retStat == ERROR )
  266. if( TRUE == cbioRdyChgdGet (dev->pDc->subDev))
  267.     CBIO_READYCHANGED (dev) = TRUE;
  268.     semGive( pDev->cbioMutex );
  269.     return (retStat);
  270.     }
  271. /*******************************************************************************
  272. *
  273. * dpartBytesRW - Read/Write bytes
  274. *
  275. * This routine transfers between a user buffer and the lower layer CBIO
  276. * It is optimized for byte transfers.  
  277. *
  278. * dev - the CBIO handle of the device being accessed (from creation routine)
  279. * startBlock - the starting block of the transfer operation
  280. * offset - offset in bytes from the beginning of the starting block
  281. * buffer - address of the memory buffer used for the transfer
  282. * nBytes - number of bytes to transfer
  283. * rw - indicates the direction of transfer up or down (READ/WRITE)
  284. * *pCookie - pointer to cookie used by upper layer such as dosFsLib(),
  285. * it should be preserved.
  286. * RETURNS OK or ERROR and may otherwise set errno.
  287. */
  288. LOCAL STATUS dpartBytesRW
  289.     (
  290.     CBIO_DEV_ID  dev,
  291.     block_t startBlock,
  292.     off_t offset,
  293.     addr_t buffer,
  294.     size_t nBytes,
  295.     CBIO_RW rw,
  296.     cookie_t *pCookie
  297.     )
  298.     {
  299.     CBIO_DEV *  pDev = dev ;
  300.     STATUS retStat ;
  301.     if(TRUE == cbioRdyChgdGet (dev))
  302. {
  303. errno = S_ioLib_DISK_NOT_PRESENT ;
  304. return ERROR;
  305. }
  306.     if( startBlock >= pDev->cbioParams.nBlocks )
  307. return ERROR;
  308.     /* verify that all bytes are within one block range */
  309.     if (((offset + nBytes) > pDev->cbioParams.bytesPerBlk ) ||
  310. (offset <0) || (nBytes <=0))
  311. return ERROR;
  312.     /* apply offset */
  313.     startBlock += pDev->cbioParams.blockOffset;
  314.     if( semTake( pDev->cbioMutex, WAIT_FOREVER) == ERROR )
  315. return ERROR;
  316.     retStat = pDev->pDc->subDev->pFuncs->cbioDevBytesRW(
  317. pDev->pDc->subDev,
  318. startBlock,
  319. offset,
  320. buffer,
  321. nBytes,
  322. rw,
  323. pCookie );
  324.     if( retStat == ERROR )
  325. if( TRUE == cbioRdyChgdGet (dev->pDc->subDev))
  326.     CBIO_READYCHANGED (dev) = TRUE;
  327.     semGive( pDev->cbioMutex );
  328.     return ( retStat );
  329.     }
  330. /*******************************************************************************
  331. *
  332. * dpartBlkCopy - Copy sectors 
  333. *
  334. * This routine makes copies of one or more blocks on the lower layer CBIO.
  335. * It is optimized for block copies on the subordinate layer.  
  336. * dev - the CBIO handle of the device being accessed (from creation routine)
  337. * srcBlock - source start block of the copy
  338. * dstBlock - destination start block of the copy
  339. * num_block - number of blocks to copy
  340. *
  341. * RETURNS OK or ERROR and may otherwise set errno.
  342. */
  343. LOCAL STATUS dpartBlkCopy
  344.     (
  345.     CBIO_DEV_ID  dev,
  346.     block_t srcBlock,
  347.     block_t dstBlock,
  348.     block_t numBlocks
  349.     )
  350.     {
  351.     CBIO_DEV *pDev = (void *) dev ;
  352.     STATUS retStat ;
  353.     if(TRUE == cbioRdyChgdGet (dev))
  354. {
  355. errno = S_ioLib_DISK_NOT_PRESENT ;
  356. return ERROR;
  357. }
  358.     if( (srcBlock) > pDev->cbioParams.nBlocks ||
  359.         (dstBlock) > pDev->cbioParams.nBlocks )
  360. return ERROR;
  361.     if( (srcBlock+numBlocks) > pDev->cbioParams.nBlocks ||
  362.         (dstBlock+numBlocks) > pDev->cbioParams.nBlocks )
  363. return ERROR;
  364.     srcBlock += pDev->cbioParams.blockOffset;
  365.     dstBlock += pDev->cbioParams.blockOffset;
  366.     if( semTake( pDev->cbioMutex, WAIT_FOREVER) == ERROR )
  367. return ERROR;
  368.     retStat = pDev->pDc->subDev->pFuncs->cbioDevBlkCopy(
  369. pDev->pDc->subDev,
  370. srcBlock,
  371. dstBlock,
  372. numBlocks
  373. );
  374.     if( retStat == ERROR )
  375. if( TRUE == cbioRdyChgdGet (dev->pDc->subDev))
  376.     CBIO_READYCHANGED (dev) = TRUE;
  377.     semGive( pDev->cbioMutex );
  378.     return ( retStat);
  379.     }
  380. /*******************************************************************************
  381. *
  382. * dpartIoctl - Misc control operations 
  383. *
  384. * This performs the requested ioctl() operation.
  385. * CBIO modules can expect the following ioctl() codes from cbioLib.h:
  386. * CBIO_RESET - reset the CBIO device and the lower layer
  387. * CBIO_STATUS_CHK - check device status of CBIO device and lower layer
  388. * CBIO_DEVICE_LOCK - Prevent disk removal 
  389. * CBIO_DEVICE_UNLOCK - Allow disk removal
  390. * CBIO_DEVICE_EJECT - Unmount and eject device
  391. * CBIO_CACHE_FLUSH - Flush any dirty cached data
  392. * CBIO_CACHE_INVAL - Flush & Invalidate all cached data
  393. * CBIO_CACHE_NEWBLK - Allocate scratch block
  394. *
  395. * command - ioctl() command being issued
  396. * arg - specific to the particular ioctl() function requested or un-used.
  397. *
  398. * RETURNS OK or ERROR and may otherwise set errno.
  399. */
  400. LOCAL STATUS dpartIoctl
  401.     (
  402.     CBIO_DEV_ID dev,
  403.     UINT32 command,
  404.     addr_t arg
  405.     )
  406.     {
  407.     STATUS retStat = ERROR ;
  408.     if(OK != cbioDevVerify (dev))
  409. {
  410. INFO_MSG("dpartIoctl: invalid handlen");
  411. return ERROR;
  412. }
  413.     if( semTake( dev->cbioMutex, WAIT_FOREVER) == ERROR )
  414. return ERROR;
  415.     switch ( command )
  416. {
  417. case CBIO_RESET :
  418. /*
  419.  * if this is the first partition to issue RESET
  420.  * we need to RESET the lower level device too,
  421.  * otherwise, RESET only this partition.
  422.  */
  423. if((TRUE == cbioRdyChgdGet (dev->pDc->subDev)) ||
  424.    (TRUE == cbioRdyChgdGet (dev->pDc->masterDev)))
  425.     {
  426.     DEBUG_MSG("dpartCbio: resetting subordinaten");
  427.     retStat = dev->pDc->subDev->pFuncs->cbioDevIoctl(
  428. dev->pDc->subDev,
  429. command,
  430. arg );
  431.     /* and also fill  the partitions geometry now */
  432.     if( retStat == OK )
  433. {
  434. retStat = dpartPartTableFill( dev->pDc );
  435. }
  436.     if( retStat == OK )
  437. {
  438. CBIO_READYCHANGED (dev->pDc->masterDev) = FALSE;
  439. }
  440.     }
  441. else
  442.     {
  443.     /*
  444.      * if masterDev does not have readyChanged
  445.      * there is no need to reset subDev, its been
  446.      * already reset
  447.      */
  448.     retStat = OK;
  449.     }
  450. /* non-existent partitions will remain "removed" */
  451. if (retStat == OK && dev->cbioParams.nBlocks == 0)
  452.     {
  453.     errno = S_ioLib_DISK_NOT_PRESENT ;
  454.     retStat = ERROR ;
  455.     }
  456. if( retStat == OK )
  457.     CBIO_READYCHANGED(dev) = FALSE;
  458. break;
  459. /* NEWBLK is the only ioctl where block# is coded in arg */
  460. case CBIO_CACHE_NEWBLK:
  461.     arg += dev->cbioParams.blockOffset ;
  462.     /*FALLTHROUGH*/
  463. /* all other commands should be executed by the lower layer */
  464. case CBIO_STATUS_CHK : 
  465. case CBIO_DEVICE_LOCK :
  466. case CBIO_DEVICE_UNLOCK :
  467. case CBIO_DEVICE_EJECT :
  468.     /* check if master has readyChanged */
  469.     if((TRUE == cbioRdyChgdGet (dev->pDc->subDev)) ||
  470.        (TRUE == cbioRdyChgdGet (dev->pDc->masterDev)))
  471. {
  472. CBIO_READYCHANGED (dev) = TRUE;
  473. }
  474.     /*FALLTHROUGH*/
  475. case CBIO_CACHE_FLUSH :
  476. case CBIO_CACHE_INVAL :
  477. default:
  478.     if(TRUE == cbioRdyChgdGet (dev))
  479. {
  480. errno = S_ioLib_DISK_NOT_PRESENT ;
  481. retStat = ERROR ;
  482. }
  483.     else
  484. {
  485. if( command == (int)CBIO_DEVICE_LOCK )
  486.     semTake( dev->pDc->subDev->cbioMutex, WAIT_FOREVER) ;
  487. retStat = dev->pDc->subDev->pFuncs->cbioDevIoctl(
  488.     dev->pDc->subDev,
  489.     command,
  490.     arg );
  491. if( command == (int)CBIO_DEVICE_UNLOCK )
  492.     semGive( dev->pDc->subDev->cbioMutex) ;
  493. }
  494. } /* end of switch */
  495.     if( retStat == ERROR )
  496. if( TRUE == cbioRdyChgdGet (dev->pDc->subDev))
  497.     CBIO_READYCHANGED (dev) = TRUE;
  498.     semGive( dev->cbioMutex );
  499.     return( retStat );
  500.     }
  501. /*******************************************************************************
  502. *
  503. * dpartDevCreate - Initialize a partitioned disk
  504. *
  505. * To handle a partitioned disk, this function should be called,
  506. * with <subDev> as the handle returned from dcacheDevCreate(),
  507. * It is recommended that for efficient operation a single disk cache
  508. * be allocated for the entire disk and shared by its partitions.
  509. *
  510. * <nPart> is the maximum number of partitions which are expected
  511. * for the particular disk drive. Up to 24 (C-Z) partitions per disk 
  512. * are supported.
  513. *
  514. * PARTITION DECODE FUNCTION
  515. * An external partition table decode function is provided via the
  516. * <pPartDecodeFunc> argument, which implements a particular style and
  517. * format of partition tables, and fill in the results into a table
  518. * defined as Pn array of PART_TABLE_ENTRY types. See dpartCbio.h
  519. * for definition of PART_TABLE_ENTRY.
  520. * The prototype for this function is as follows:
  521. * .CS
  522. *     STATUS parDecodeFunc
  523. *  (
  524. *  CBIO_DEV_ID dev, /@ device from which to read blocks @/
  525. *  PART_TABLE_ENTRY *pPartTab, /@ table where to fill results @/
  526. *  int nPart /@ # of entries in <pPartTable> @/
  527. *  )
  528. * .CE
  529. *
  530. * RETURNS: CBIO_DEV_ID or NULL if error creating CBIO device.
  531. * SEE ALSO: dosFsDevCreate().
  532. * INTERNAL
  533. * during create, readyChanged bit is TRUE, so no accesses are allowed
  534. * until after a CBIO_RESET, at which time the actual partition table
  535. * will be brought in and applied.
  536. */
  537. CBIO_DEV_ID dpartDevCreate
  538.     (
  539.     CBIO_DEV_ID subDev, /* lower level CBIO device */
  540.     int nPart, /* # of partitions */
  541.     FUNCPTR pPartDecodeFunc /* function to decode partition table */
  542.     )
  543.     {
  544.     CBIO_DEV_ID cbio = subDev ;
  545.     CBIO_DEV_ID pDev = NULL ;
  546.     DPART_CTRL * pDc ;
  547.     int p ;
  548.     if( nPart > PART_MAX_ENTRIES || pPartDecodeFunc == NULL )
  549. {
  550. printErr ("%d is too many partitions, max limit %dn",
  551.   nPart, PART_MAX_ENTRIES);
  552. errno = EINVAL;
  553. return NULL;
  554. }
  555.     cbioLibInit(); /* just in case */
  556.     /* if this is a BLK_DEV, create a CBIO_DEV */
  557.     if (OK != cbioDevVerify( subDev ))
  558.         {
  559.         /* attempt to handle BLK_DEV subDev */
  560.         cbio = cbioWrapBlkDev ((BLK_DEV *) subDev);
  561.         if( NULL != cbio )
  562.             {
  563.             /* SPR#71633, clear the errno set in cbioDevVerify() */
  564.             errno = 0;
  565.             }
  566.         }
  567.     else
  568. {
  569. cbio = subDev;
  570. }
  571.     if( NULL == cbio )
  572. {
  573. DEBUG_MSG("dpartDevCreate: invalid handlen");
  574. return NULL;
  575. }
  576.     /* allocate our main DPART_CTRL structure */
  577.     pDc = KHEAP_ALLOC((sizeof(DPART_CTRL)));
  578.     if( pDc == NULL )
  579. {
  580. return( NULL );
  581. }
  582.     bzero( (char *) pDc, sizeof( DPART_CTRL) );
  583.     /* create the primary CBIO handle */
  584.     pDev = cbioDevCreate ( NULL, 0 );
  585.     if( pDev == NULL )
  586. {
  587. return( NULL );
  588. }
  589.     /* the primary CBIO handle is not for any actual I/O, just for show */
  590.     pDev->cbioDesc = "dpartCbio Partition Manager" ;
  591.     CBIO_READYCHANGED (pDev) = CBIO_READYCHANGED (cbio);
  592.     pDev->cbioParams.cbioRemovable = cbio->cbioParams.cbioRemovable ;
  593.     pDev->cbioParams.nBlocks = cbio->cbioParams.nBlocks ;
  594.     pDev->cbioParams.bytesPerBlk = cbio->cbioParams.bytesPerBlk ;
  595.     pDev->cbioParams.blocksPerTrack = cbio->cbioParams.blocksPerTrack ;
  596.     pDev->cbioParams.nHeads = cbio->cbioParams.nHeads ;
  597.     pDev->cbioMode = cbio->cbioMode ;
  598.     pDev->cbioParams.blockOffset = 0 ;
  599.     pDev->cbioParams.lastErrBlk = NONE ;
  600.     pDev->cbioParams.lastErrno = 0 ;
  601.     pDev->cbioPartIndx = NONE ; /* master device */
  602.     /* SPR#67729: Fill in the members subDev and isDriver appropriately */
  603.     pDev->blkSubDev = NULL;    /* Since lower layer is not BLKDEV  */
  604.     pDev->cbioSubDev = cbio;    /* Storing the reference to the sub Device  */
  605.     pDev->isDriver = FALSE;   /* == FALSE since this is a CBIO TO CBIO layer */
  606.     pDev->pDc = pDc ;  /* DPART_CTRL */
  607.     pDev->pFuncs  = &cbioFuncs;
  608.     /* setup main fields */
  609.     pDc->subDev = cbio ;
  610.     pDc->pPartDecodeFunc = pPartDecodeFunc ;
  611.     pDc->nPart = nPart ;
  612.     pDc->masterDev = pDev ;
  613.     /* Now initialize the partition virtual devs */
  614.     for(p = 0; p < PART_MAX_ENTRIES; p++ )
  615. {
  616. CBIO_DEV_ID tmpDev = & ( pDc->vDev[ p ] );
  617. /* inherit most fields from the primary handle */
  618. *tmpDev = *pDev ;
  619. tmpDev->cbioDesc        = "dpartCbio Partition Slave Device";
  620. tmpDev->cbioPartIndx    = p;   /* partition # */
  621. CBIO_READYCHANGED (tmpDev) = TRUE;
  622. /* semaphore can be just copied, it has to be init'ed */
  623.         tmpDev->cbioMutex = semMCreate (dpartSemOptions);
  624.         if (NULL == tmpDev->cbioMutex)
  625.     {
  626.     DEBUG_MSG("Error Creating the device semaphoren");
  627.     pDev = NULL;
  628.     break;
  629.     }
  630. #ifdef _WRS_DOSFS2_VXWORKS_AE
  631. /* init the handle */
  632. handleInit (&tmpDev->cbioHandle, handleTypeCbioHdl);
  633. #endif  /* _WRS_DOSFS2_VXWORKS_AE */
  634. /* these will be filled later from actual geometry */
  635. tmpDev->cbioParams.nBlocks = 0 ;
  636. tmpDev->cbioParams.blockOffset = 0 ;
  637. }
  638.     DEBUG_MSG("dpartDevCreate: handle dev %x subDev %xn", pDev, cbio );
  639.     /* return device handle */
  640.     return( pDev );
  641.     }
  642. /*******************************************************************************
  643. *
  644. * dpartPartGet - retrieve handle for a partition
  645. *
  646. * This function retrieves a CBIO handle into a particular partition
  647. * of a partitioned device. This handle is intended to be used with
  648. * dosFsDevCreate().
  649. *
  650. * RETURNS: CBIO_DEV_ID or NULL if partition is out of range, or
  651. * <masterHandle> is invalid.
  652. *
  653. * SEE ALSO: dosFsDevCreate()
  654. */
  655. CBIO_DEV_ID dpartPartGet
  656.     (
  657.     CBIO_DEV_ID masterHandle, /* CBIO handle of the master partition */
  658.     int partNum /* partition number from 0 to nPart */
  659.     )
  660.     {
  661.     if(OK != cbioDevVerify( masterHandle))
  662. {
  663. return NULL;
  664. }
  665.     if( partNum >= masterHandle->pDc->nPart )
  666. {
  667. errno = EINVAL;
  668. return NULL;
  669. }
  670.     return ( & masterHandle->pDc->vDev[ partNum ] );
  671.     }
  672. /*******************************************************************************
  673. *
  674. * dpartShow - show current parameters of the RAM disk device
  675. *
  676. * NOMANUAL
  677. */
  678. STATUS dpartShow( CBIO_DEV_ID dev, int verb )
  679.     {
  680.     DPART_CTRL * pDc ;
  681.     int pn ;
  682.     if( (OK != cbioDevVerify (dev)))
  683. {
  684. DEBUG_MSG("dpartShow: invalid handlen");
  685. return ERROR;
  686. }
  687.     pDc = dev->pDc ;
  688.     if( TRUE == cbioRdyChgdGet (dev))
  689. dev->pFuncs->cbioDevIoctl( dev, CBIO_RESET, 0);
  690.     if( dev->cbioPartIndx == (u_long)NONE )
  691. printf("  Device %#lx is Master handle, Partition Table:n",
  692. (u_long) dev);
  693.     else
  694. printf("  Device %#lx is partition %ld, Partition Table:n",
  695. (u_long) dev, dev->cbioPartIndx );
  696.     for( pn = 0; pn < pDc->nPart ; pn ++ )
  697. {
  698. printf("  #%ld: from %ld to %ld (%ld blocks)n",
  699. pDc->vDev[ pn ].cbioPartIndx,
  700. (block_t) pDc->vDev[ pn ].cbioParams.blockOffset,
  701. pDc->vDev[ pn ].cbioParams.nBlocks + 
  702. pDc->vDev[ pn ].cbioParams.blockOffset,
  703. pDc->vDev[ pn ].cbioParams.nBlocks );
  704. }
  705.     printf("  master dev %#lx, subordinate dev %#lx, with total %ld blocksn",
  706. (u_long) pDc->masterDev, (u_long) pDc->subDev,
  707. pDc->subDev->cbioParams.nBlocks );
  708.     return OK;
  709.     }
  710. /* End of File */