home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / AHDI / SYQUEST / SQHDX / SECT.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  10.5 KB  |  485 lines

  1. /* sect.c */
  2.  
  3.  
  4. #include "obdefs.h"
  5. #include "osbind.h"
  6. #include "defs.h"
  7. #include "part.h"
  8. #include "hdx.h"
  9. #include "addr.h"
  10. #include "error.h"
  11.  
  12. #define    ZBUFSIZ    0x4000        /* about 16k == 32 sectors */
  13. #define    ZCOUNT    (ZBUFSIZ/0x200)    /* ZCOUNT = 32 */
  14.  
  15. extern long ostack;        /* old stack pointer */
  16. extern UWORD errcode();        /* function to return error code */
  17.  
  18.  
  19. /*
  20.  * Logical-to-dev+partition mapping table.
  21.  */
  22. int nlogdevs;            /* # logical devices */
  23. LOGMAP logmap[MAXLOGDEVS];    /* logical dev map */
  24. int livedevs[MAXPHYSDEVS];    /* live devs flags; 1: device is alive */
  25.  
  26.  
  27. /*
  28.  * Rebuild logical-to-physical mapping
  29.  * by reading and interpreting the root
  30.  * blocks for all physical devs.
  31.  *
  32.  */
  33. rescan(flag)
  34. int flag;    /* 0: don't report medium change error; */
  35.         /* non-0: report medium change error; */
  36. {
  37.     int dev;
  38.     char buf[512];
  39.     int partno, ret;
  40.     PART partinfo[NPARTS];
  41.  
  42.     /* disable all logical and physical devs */
  43.     for (dev = 0; dev < MAXLOGDEVS; ++dev)
  44.     logmap[dev].lm_physdev = -1;
  45.  
  46.     for (dev = 0; dev < MAXPHYSDEVS; ++dev)
  47.     livedevs[dev] = 0;
  48.  
  49.     /*
  50.      * Scan all physical devs
  51.      * and pick up partition structures.
  52.      */
  53.     nlogdevs = 0;
  54.     for (dev = 0; dev < MAXPHYSDEVS; ++dev)
  55.     {
  56.         if ((ret = getroot(dev, buf)) < 0) {
  57.         continue;
  58.     } else {        /* ret >= 0 */
  59.         if (ret > 0) {
  60.             if (flag) {    /* if non-0, report error if medium changed */
  61.                 if (tsterr(ret) == OK)
  62.                     return ERROR;
  63.             }
  64.             if ((ret = getroot(dev, buf))) {    /* try again */
  65.             if (ret > 0 && flag && tsterr(ret) == OK)
  66.             return ERROR;
  67.             continue;
  68.         }
  69.         }
  70.         livedevs[dev] = 1;
  71.         gpart(buf, &partinfo[0]);
  72.         for (partno = 0; partno < NPARTS; ++partno) {
  73.             if (partinfo[partno].p_flg & P_EXISTS &&
  74.             partinfo[partno].p_siz != (SECTOR)0 &&
  75.             partinfo[partno].p_id[0] == 'G' &&
  76.             partinfo[partno].p_id[1] == 'E' &&
  77.             partinfo[partno].p_id[2] == 'M')
  78.             {
  79.             if (nlogdevs >= MAXLOGDEVS)
  80.                 return err(manyldev);
  81.  
  82.             logmap[nlogdevs].lm_physdev = dev;
  83.             logmap[nlogdevs].lm_partno = partno;
  84.             logmap[nlogdevs].lm_start = partinfo[partno].p_st;
  85.             logmap[nlogdevs].lm_siz = partinfo[partno].p_siz;
  86.             ++nlogdevs;
  87.             }
  88.         }
  89.     }
  90.     }
  91.     return OK;
  92. }
  93.  
  94.  
  95. /*
  96.  * From a PHYSICAL device unit (0->7)
  97.  * and a partition number (0->3), figure
  98.  * out the LOGICAL disk number ('C'->'P').
  99.  *
  100.  * return the LOGICAL disk number or
  101.  * ERROR if the PHYSICAL device doesn't exist.
  102.  *
  103.  */
  104. phys2log(pdev, pno)
  105. int  pdev;    /* physical device unit */
  106. int  pno;    /* partition number (0 -> 3) */
  107. {
  108.     int logdev;        /* index to step through partitions of a phys unit */
  109.  
  110.     for (logdev = 0; logdev < MAXLOGDEVS; logdev++) {
  111.         if (logmap[logdev].lm_physdev == pdev &&
  112.             logmap[logdev].lm_partno == pno)
  113.             return ('C'+logdev);
  114.     }
  115.     return ERROR;
  116. }
  117.  
  118.  
  119. /*
  120.  * Map block on logical device to
  121.  * block on physical device;
  122.  * return ERROR if the logical device
  123.  * doesn't exist.
  124.  */
  125. log2phys(adev, ablk)
  126. int *adev;
  127. SECTOR *ablk;
  128. {
  129.     int dev;
  130.     char xbuf[256];
  131.     
  132.     dev = *adev;
  133.     if (dev >= 0 && dev <= 7)
  134.     return OK;
  135.  
  136.     dev = toupper(dev);
  137.     if (dev >= 'C' && dev <= 'P')
  138.     {
  139.     dev -= 'C';
  140.     *adev = logmap[dev].lm_physdev;
  141.     *ablk = logmap[dev].lm_start + *ablk;
  142.     return OK;
  143.     }
  144.  
  145.     return ERROR;
  146. }
  147.  
  148.  
  149.  
  150. /*
  151.  * Return physical starting block# of a partition
  152.  *
  153.  */
  154. SECTOR 
  155. logstart(ldev)
  156. int ldev;    /* logical device */
  157. {
  158.     ldev = toupper(ldev);
  159.     if (ldev >= 'C' && ldev <= 'P') {
  160.         ldev -= 'C';
  161.         return (logmap[ldev].lm_start);
  162.     }
  163.     return ERROR;
  164. }
  165.  
  166.  
  167.  
  168. /*
  169.  * Return physical starting block# of a partition's data block.
  170.  *
  171.  */
  172. SECTOR 
  173. logend(ldev)
  174. int ldev;    /* logical device */
  175. {
  176.     ldev = toupper(ldev);
  177.     if (ldev >= 'C' && ldev <= 'P') {
  178.         ldev -= 'C';
  179.         return (logmap[ldev].lm_start+logmap[ldev].lm_siz-1);
  180.     }
  181.     return ERROR;
  182. }
  183.  
  184.  
  185. #define    MFM 17        /* sectors per track for MFM */
  186. #define    RLL 26        /* sectors per track for RLL */
  187.  
  188.  
  189. /*
  190.  * Check if dev's root block is intact.
  191.  * Return number of sectors per track on disk.
  192.  *
  193.  */
  194. chkroot(dev, bs)
  195. int dev;
  196. char *bs;
  197. {
  198.     extern long get3bytes();
  199.     SETMODE *mb;
  200.     int i, ret;
  201.     int cyl, head;
  202.     SECTOR size, msiz;    /* size of media */
  203.     char buf[512], sendata[16];
  204.     long dmaptr, tmpptr;
  205.     char *dmahigh=0xffff8609,
  206.          *dmamid=0xffff860b,
  207.          *dmalow=0xffff860d;
  208.     
  209.     size = ((RSECT *)(bs + 0x200 - sizeof(RSECT)))->hd_siz;
  210.     
  211.     ostack = Super(NULL);
  212.     
  213.     /* Get format parameters/ disk size from media */
  214.     ret = md_sense(dev, sendata);
  215.     delay();
  216.     Super(ostack);
  217.     
  218.     if (ret != 0) {
  219.         return ERROR;
  220.     }
  221.     
  222.     /* check what kind of sense data it returned  */
  223.     /* If full SCSI, will return number of blocks */
  224.     /* on disk at byte 5, 6 and 7.  If Adaptec,   */
  225.     /* will return 0 for number of blocks on disk */
  226.     /* on SCSI. */
  227.     
  228.     if (!(msiz = get3bytes(sendata+5))) {    /* no disk size returned? */
  229.         /* Yup, ie., it's adaptec's.  Interpret as SETMODE structure */
  230.         mb = (SETMODE *)sendata;
  231.     /* get number of cylinders */
  232.     cyl = mb->smd_cc[0];
  233.     cyl <<= 8;
  234.     cyl |= mb->smd_cc[1];
  235.     
  236.     /* get number of heads */
  237.     head = mb->smd_dhc;
  238.     
  239.     msiz = (SECTOR)head * (SECTOR)cyl * MFM;
  240.     
  241.     for (i = 0; i < 20; i++) {
  242.         if ((ret = rdsects(dev, 1, buf, msiz+i)) == OK) {
  243.         
  244.         /* find out whether data has been transferred, by
  245.               checking if dma pointer has been moved.      */
  246.  
  247.            ostack = Super(NULL);    /* get into Supervisor mode */
  248.            
  249.         dmaptr = *dmahigh;
  250.         dmaptr &= 0x0000003f;
  251.         dmaptr <<= 16;
  252.         tmpptr = *dmamid;
  253.         tmpptr &= 0x000000ff;
  254.         tmpptr <<= 8;
  255.         dmaptr |= tmpptr;
  256.         tmpptr = *dmalow;
  257.         tmpptr &= 0x000000ff;
  258.         dmaptr |= tmpptr;
  259.         
  260.             delay();
  261.             Super(ostack);        /* back to user mode */
  262.             
  263.         if (dmaptr != buf)
  264.             break;
  265.         } else {            /* rdsects return an error */
  266.         if (tsterr(ret) == OK) {
  267.                 break;
  268.         }
  269.             }
  270.         }
  271.     
  272.     if (ret == MDMCHGD)        /* check if error occurred */
  273.         return (ret);
  274.        
  275.     /* Determine if media is MFM or RLL */
  276.     if (i < 20)
  277.         msiz = (SECTOR)head * (SECTOR)cyl * RLL;
  278.     }
  279.         
  280.     if (size != msiz)
  281.         ret = ERROR;
  282.     else 
  283.         ret = OK;
  284.         
  285.     return (ret);
  286. }
  287.  
  288.  
  289. /*
  290.  * Chkparm()
  291.  *    Check if given logical device has the asssumed parameters.
  292.  * Assumptions are:
  293.  *    - 512 bytes/sector
  294.  *    - 2 sectors/cluster
  295.  *    - 1 reserved sector
  296.  *    - 2 FATs
  297.  *
  298.  * Input:
  299.  *    ldev - logical device number ('C' -> 'P').
  300.  *
  301.  * Return:
  302.  *    OK - parameters of partition match the assumptions
  303.  *    ERROR - something went wrong.
  304.  *
  305.  * Comment:
  306.  *    Number of FATs is assumed to be 2.  Cannot check this 
  307.  * because previous version of HDX did not put that in the boot
  308.  * sector.
  309.  */
  310. chkparm(ldev)
  311. int ldev;
  312. {
  313.     char bs[512];        /* boot sector */
  314.     BOOT *boot;            /* boot structure */
  315.     UWORD bps, res, siz;    /* bytes/sector, num reserved sectors, ldev size */
  316.     int ret;
  317.  
  318.     if ((ret = rdsects(ldev, 1, bs, (SECTOR)0)) != 0) {
  319.         if (tsterr(ret) != OK)
  320.             err(bootread);
  321.         ret = ERROR;
  322.         goto parmend;
  323.     }    
  324.  
  325.     boot = (BOOT *)bs;
  326.     gw((UWORD *)&boot->b_bps, &bps);    /* what is number bytes/sector? */
  327.     gw((UWORD *)&boot->b_res, &res);    /* what is num of reserved sectors? */
  328.     gw((UWORD *)&boot->b_nsects, &siz);    /* what is size of partition */
  329.     if (bps != 512            /* bytes per sector == 512 ? */
  330.     || res != 1) {            /* num sectors reserved == 1 ? */
  331.     ret = ERROR;            /* Nope, different from assumptions */
  332.     goto parmend;
  333.     }
  334.     
  335.     /* Check if sectors per cluster make sense */
  336.     if ((siz >= 0x8000L && boot->b_spc != 4) ||
  337.         (siz < 0x8000L && boot->b_spc != 2)) {
  338.         ret = ERROR;
  339.         goto parmend;
  340.     }
  341.     
  342.     ret = OK;                /* If yes, return OK */
  343.  
  344. parmend:
  345.     return ret;
  346. }
  347.  
  348.  
  349. /*
  350.  * Get dev's root block.
  351.  *
  352.  */
  353. getroot(dev, buf)
  354. int dev;
  355. char *buf;
  356. {
  357.     return rdsects(dev, 1, buf, (SECTOR)0);
  358. }
  359.  
  360.  
  361. /*
  362.  * Put dev's root block.
  363.  *
  364.  */
  365. putroot(dev, buf)
  366. int dev;
  367. char *buf;
  368. {
  369.     return wrsects(dev, 1, buf, (SECTOR)0);
  370. }
  371.  
  372.  
  373. /*
  374.  *  Read sector(s) from dev.
  375.  *
  376.  *  Input:
  377.  *    dev - device number (logical or physical).
  378.  *    num - number of sectors to read.
  379.  *    buf - buffer to write data read.
  380.  *    sect - starting sector number to read from.
  381.  *
  382.  *  Return:
  383.  *    errnum - 0: if read is successful.
  384.  *         an error code: if read is unsuccessful.
  385.  */
  386. rdsects(dev, num, buf, sect)
  387. int dev;            /* device number (logical or physical) */
  388. UWORD num;            /* number of sectors to read */
  389. char *buf;
  390. SECTOR sect;            /* starting sector to read from */
  391. {
  392.     int errnum;
  393.  
  394.     if (log2phys(&dev, §) < 0)
  395.     return ERROR;
  396.  
  397.     ostack = Super(NULL);
  398.     errnum = hread(sect, num, buf, (UWORD)dev);
  399.     delay();
  400.     Super(ostack);
  401.  
  402.     if (errnum > 0) {
  403.         errnum = errcode(dev);
  404.     }
  405.         
  406.     return errnum;        /* return the error code */
  407. }
  408.  
  409.  
  410. /*
  411.  *  Write sector(s) to dev.
  412.  *
  413.  *  Input:
  414.  *    dev - device number (logical or physical).
  415.  *    num - number of sectors to write.
  416.  *    buf - buffer with data to be written.
  417.  *    sect - starting sector number to write to.
  418.  *
  419.  *  Return:
  420.  *    errnum - 0: if write is successful.
  421.  *         an error code: if write is unsuccessful.
  422.  */
  423. wrsects(dev, num, buf, sect)
  424. int dev;            /* device number (logical or physical */
  425. UWORD num;            /* number of sectors to write */
  426. char *buf;            /* buffer with data to be written */
  427. SECTOR sect;            /* starting sector to write to */
  428. {
  429.     int errnum;
  430.  
  431.     if (log2phys(&dev, §) < 0)
  432.     return ERROR;
  433.  
  434.     ostack = Super(NULL);
  435.     errnum = hwrite(sect, num, buf, (UWORD)dev);
  436.     delay();
  437.     Super(ostack);
  438.  
  439.     if (errnum > 0) {
  440.         errnum = errcode(dev);
  441.     }
  442.  
  443.     return errnum;
  444. }
  445.  
  446.  
  447. /*
  448.  * Zero range of sectors on dev.
  449.  *
  450.  */
  451. zerosect(dev, start, count)
  452. int dev;
  453. SECTOR start;
  454. UWORD count;
  455. {
  456.     char *zbuf;
  457.     int  v;
  458.     UWORD i;
  459.  
  460.     if ((zbuf = (char *)mymalloc(ZBUFSIZ)) <= 0)
  461.         return err(nomemory);
  462.         
  463.     if (log2phys(&dev, &start) < 0) {
  464.         free(zbuf);
  465.     return ERROR;
  466.     }
  467.  
  468.     fillbuf(zbuf, (long)ZBUFSIZ, 0L);
  469.  
  470.     while (count)
  471.     {
  472.         if (count > ZCOUNT)
  473.             i = ZCOUNT;
  474.         else i = count;
  475.  
  476.     if ((v = wrsects(dev, i, zbuf, start)) != 0)
  477.         break;
  478.     start += i;
  479.     count -= i;
  480.     }
  481.     free(zbuf);
  482.     
  483.     return v;
  484. }
  485.