home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1035 / getput.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  7.7 KB  |  321 lines

  1. /***************************************************************
  2.  *
  3.  *    Read/Write routines to access the basic block info needed:
  4.  *        The Master Boot Block
  5.  *        The Partition Boot Block
  6.  *        The Bad Track Table
  7.  *        The Partition End Record Block
  8.  *      and    The contents of the CMOS RAM chip
  9.  *
  10.  ***************************************************************
  11.  *
  12.  *    Revision Control Information
  13.  *
  14.  *    By:        $Author: root $
  15.  *            $Revision: 1.2 $
  16.  *    Last modified:    $Date: 87/09/16 02:12:24 $
  17.  *    $Source: /u/src/microport/newfdisk/test/RCS/getput.c,v $
  18.  *
  19.  *    Release state:    $State: Exp $
  20.  *
  21.  ***************************************************************
  22.  *
  23.  * Modification Log
  24.  * ----------------
  25.  * $Log:    getput.c,v $
  26.  * Revision 1.2  87/09/16  02:12:24  root
  27.  * maintenance update
  28.  * 
  29.  * Revision 1.1  88/04/07  23:11:20  root
  30.  * Initial revision
  31.  * 
  32.  * 
  33.  ***************************************************************
  34.  */
  35.  
  36. #ifndef lint
  37.     static char rcsid[] =
  38.     "$Header: getput.c,v 1.2 87/09/16 02:12:24 root Exp $";
  39. #endif
  40.  
  41. #include <fcntl.h>
  42. #include <errno.h>
  43. #include <sys/param.h>
  44. #include <sys/types.h>
  45. #include <malloc.h>
  46. #include "cmos.h"        /* cmos layout */
  47. #include "mbb.h"        /* master boot block */
  48. #include "pbb.h"        /* partition boot block */
  49. #include "btt.h"        /* bad track table */
  50. #include "per.h"        /* partition end record */
  51.  
  52. #include "fdisk.h"
  53.  
  54. static int fds[2] = { -1, -1 };    /* fds for both hard disk drives */
  55.  
  56. static char *unitname[] = {    /* entire disk... */
  57.     "/dev/rdsk/0s10",
  58.     "/dev/rdsk/1s10"
  59. };
  60.  
  61. /*
  62. **    Open a file which corrosponds to the entire disk.
  63. **    All other operations require that this be done before they call
  64. **    any disk I/O routines!
  65. */
  66.  
  67. int openunit( unit )
  68. int unit;
  69. {
  70.     char dummyblock[512];
  71.  
  72.     if (unit < 0 || unit > 1)
  73.     return ERROR;
  74.  
  75.     if ( fds[unit] != -1 )
  76.     closeunit( unit );
  77.  
  78.     if ((fds[unit] = open(unitname[unit], O_RDWR)) == -1) {
  79.     fprintf(stderr, "Can't open %s, errno=%d\n", unitname[unit], errno);
  80.     exit(errno);
  81.     }
  82.  
  83.     /*
  84.     **    WHY is this needed???
  85.     */
  86.  
  87.     read(fds[unit],dummyblock,512);    /* dummy read to force wnsweep */
  88.     return OK;
  89. }
  90.  
  91. closeunit( unit )
  92. int unit;
  93. {
  94.     close( fds[unit] );
  95.     fds[unit] = -1;
  96.     return OK;
  97. }
  98.  
  99. /*
  100. **    Read the Master Boot Block (MBB) from the hard disk
  101. */
  102.  
  103. get_MBB( unit, mbbp )
  104. int unit;
  105. mbb_t *mbbp;
  106. {
  107.     if (read_sector(fds[unit],mbbp,0,0,1 )) {
  108.     fprintf(stderr, "read error: %s (c0,h0,s1), errno=%d\n",
  109.              unitname[unit], errno);
  110.     exit(errno);
  111.     }
  112. }
  113.  
  114. /*
  115. **    Write the Master Boot Block (MBB) to the hard disk
  116. */
  117.  
  118. put_MBB( unit, mbbp )
  119. int unit;
  120. mbb_t *mbbp;
  121. {
  122.     if (write_sector(fds[unit],mbbp,0,0,1 )) {
  123.     fprintf(stderr, "write error: %s (c0,h0,s1), errno=%d\n",
  124.         unitname[unit], errno);
  125.     exit(errno);
  126.     }
  127. }
  128.  
  129. #define BOOTDRTBLOFF    0x1ee
  130.  
  131. int get_PBB( unit, mbbp, pbbp );    /* Return OK if a valid PBB, */
  132. int unit;                /* FAIL if not a uport PBB */
  133. mbb_t *mbbp;
  134. pbb_t *pbbp;
  135. {
  136. int    dptdbg = 0;
  137.  
  138.     partition_t  *pn;
  139.     unsigned char  beginsec;
  140.     unsigned int   begincyl;
  141.  
  142.     /*
  143.      *  Get the active unix partition boot sector where a ROM compatible
  144.      *  drive parameter entry (and Unix boot code) may be written
  145.      */
  146.  
  147.     pn = (partition_t *) (mbbp + PTOFFSET);
  148.     for (i=0; i < 4; ++i, ++pn)        /* find active paratition */
  149.     if (pn->part_boot == 0x80 &&
  150.         ( pn->part_sys == 5 || pn->part_sys == 0x52 ) /* types 5 and 52 */
  151.        )                          /* are System5    */
  152.         break;
  153.     if (i < 4) {    /* we found the active Microport Unix partition */
  154.     begincyl = ((pn->part_start_s & 0xC0) << 2) | pn->part_start_c;
  155.     beginsec = pn->part_start_s & 0x3F;        /* why is this here? */
  156.  
  157.     read_sector(fds[unit],pbbp,begincyl,
  158.                    pn->part_start_h,
  159.                    pn->part_start_s & 0x1f);
  160.     if (VALID_PBB(pbbp))
  161.         return OK;
  162.     }
  163.     return FAIL;    /* indicate not uport boot sector */
  164. }
  165.  
  166. init_PBB( unit, mbbp, pbbp, driveinfo );
  167. int unit;        /* unit to write drive table on */
  168. mbb_t *mbbp;        /* this holds current partition table */
  169. pbb_t *pbbp;        /* 512 byte work space */
  170. i1010drtab *driveinfo;    /* and this the disk geometry */
  171. {
  172.     int    bsfd;
  173.     if ((bsfd=open("/etc/boot.hd", 0)) < 0) {
  174.     fprintf(stderr,"Can't open /etc/boot.hd\n");
  175.     fprintf(stderr,"System5 partition on Hard Disk %d isn't bootable\n",
  176.                 unit);
  177.     return;
  178.     }
  179.     if (dptdbg)
  180.     fprintf(stderr, "Reading /etc/boot.hd\n");
  181.     read(bsfd, pbbp, 512);
  182.     close(bsfds[unit]);
  183.  
  184.     R_CYLS(    ROMTABLE(pbbp) )    = driveinfo->dr_ncyl;
  185.     R_HEADS(   ROMTABLE(pbbp) )    = driveinfo->dr_nfhead;
  186.     if (driveinfo->dr_nfhead > 8)
  187.     R_HDFLAG(  ROMTABLE(pbbp) )    = MORETHAN8HEADS;
  188.     else
  189.     R_HDFLAG(  ROMTABLE(pbbp) )    = LESSTHAN8HEADS;
  190.     R_PRECOMP( ROMTABLE(pbbp) )    = driveinfo->dr_precomp;
  191.     R_LZ(      ROMTABLE(pbbp) )    = driveinfo->dr_lzone;
  192.     R_SPT(     ROMTABLE(pbbp) )    = driveinfo->dr_nsec;
  193.  
  194.     VALIDATE_PBB( pbbp );
  195.  
  196.     return OK;
  197. }
  198.  
  199. write_PBB( unit, mbbp, pbbp );
  200. int unit;        /* unit to write drive table on */
  201. mbb_t *mbbp;        /* this holds current partition table */
  202. pbb_t *pbbp;        /* filled in and valid pbb */
  203. {
  204.     partition_t  *pn;            /* partition table entry */
  205.     unsigned char  beginsec;
  206.     unsigned int   begincyl;
  207.  
  208.     /*
  209.      *  Find the Active Microport partition in the MBB and write the
  210.      *  Partition Boot Record to the beginning of it.
  211.      */
  212.  
  213.     pn = (partition_t *) (mbbp + PTOFFSET);    /* partition table */
  214.  
  215.     for (i=0; i < 4; ++i, ++pn)        /* find active paratition */
  216.     if (pn->part_boot == 0x80 &&
  217.         ( pn->part_sys == 5 || pn->part_sys == 0x52 )
  218.        )
  219.         break;
  220.     if (i < 4) {    /* we found the active Microport Unix partition */
  221.     begincyl = ((pn->part_start_s & 0xC0) << 2) | pn->part_start_c;
  222.     beginsec = pn->part_start_s & 0x3F;        /* why is this here? */
  223.  
  224.     if (dptdbg)
  225.         fprintf(stderr,"Update PBB at C %u, H %d, S %d for unit %d\n",
  226.         begincyl, pt->part_start_h & 0xff, pt->part_start_s & 0x1f, unit);
  227.  
  228.     write_sector(fds[unit],pbbp,begincyl, pn->part_start_h,
  229.                               pn->part_start_s & 0x1F);
  230.     }
  231. }
  232.  
  233.  
  234. get_CMOS( cmosp )
  235. struct cmos *cmosp;
  236. {
  237.     int    cmosfd;
  238.  
  239.     if ((cmosfd = open(CMOSDEV, 0)) == -1) {
  240.     perror("Opening cmos device");
  241.     exit(1);
  242.     }
  243.     if ( sizeof(struct cmos) != read(cmosfd, cmosp, sizeof(struct cmos))) {
  244.     perror("Reading cmos device");
  245.     exit(1);
  246.     }
  247.     close(cmosfd);
  248. }
  249.  
  250. put_CMOS( cmosp )
  251. struct cmos *cmosp;
  252. {
  253.     unsigned int  cksum, i;
  254.     unsigned char *c;
  255.     int    cmosfds[unit];
  256.  
  257.         /* calculate new checksum */
  258.     c = (unsigned char *) &cmos;
  259.     cksum = 0;
  260.     for(i=0x10; i<0x21; i++)
  261.     cksum += *(c+i);
  262.         /* Set new checksum */
  263.     *(c + 0x2e ) = cksum >> 8;    /* this is also known as cmos.cksum */
  264.     *(c + 0x2f ) = cksum ;
  265.  
  266.     if ((cmosfd = open(CMOSDEV, 1)) == -1) {
  267.     perror("Opening cmos device");
  268.     exit(1);
  269.     }
  270.     if ( sizeof(struct cmos) != write(cmosfd, cmosp, sizeof(struct cmos))) {
  271.     perror("writing cmos device");
  272.     exit(1);
  273.     }
  274.     close(cmosfd);
  275. }
  276.  
  277. /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!  YET TO DO  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  278. **    read end-of-partition record, if any.
  279. **    get drtabs, slice table, and pointer to first bad-track sector
  280. **
  281. **    fds[unit] = fd of open /dev/rdsk/0x?0 
  282. **    er = pointer to buffer to read the stuff into
  283. **    cyl, head, and sect are place on disk to read from
  284. */
  285.  
  286. read_PER( unit, perp, cyl, head, sector)
  287. int unit;
  288. char *perp;
  289. int cyl, head, sector;
  290. {
  291.     read_sector (fds[unit],perp,cyl,head,sector & 0x1f);
  292. }
  293.  
  294.     /* write updated partition end record back to disk */
  295.  
  296. write_PER()
  297. {
  298.     if (er) {
  299.     /* move drive table to buffer */
  300.     memcpy (er, (byte *) &drvtab, sizeof(struct i1010drtab));
  301.     write_sector (fds[unit],er,endcyl,pt->ehead,pt->esect & 0x1f );
  302.     }
  303. }
  304.  
  305.  
  306.     /* read bad track table from disk */
  307.  
  308. read_BT()
  309. {
  310.         read_sector (fds[unit],bad,endcyl,pt->ehead, (pt->esect&0x1f)-1);
  311. }
  312.  
  313.     /* write updated bad track table back to disk */
  314.  
  315. write_BT()
  316. {
  317.     if (bad)
  318.         write_sector (fds[unit],bad,endcyl,pt->ehead, (pt->esect&0x1f)-1);
  319. }
  320.  
  321.