home *** CD-ROM | disk | FTP | other *** search
- /* sect.c */
-
-
- #include "obdefs.h"
- #include "osbind.h"
- #include "defs.h"
- #include "part.h"
- #include "hdx.h"
- #include "addr.h"
- #include "error.h"
-
- #define ZBUFSIZ 0x4000 /* about 16k == 32 sectors */
- #define ZCOUNT (ZBUFSIZ/0x200) /* ZCOUNT = 32 */
-
- extern long ostack; /* old stack pointer */
- extern UWORD errcode(); /* function to return error code */
-
-
- /*
- * Logical-to-dev+partition mapping table.
- */
- int nlogdevs; /* # logical devices */
- LOGMAP logmap[MAXLOGDEVS]; /* logical dev map */
- int livedevs[MAXPHYSDEVS]; /* live devs flags; 1: device is alive */
-
-
- /*
- * Rebuild logical-to-physical mapping
- * by reading and interpreting the root
- * blocks for all physical devs.
- *
- */
- rescan(flag)
- int flag; /* 0: don't report medium change error; */
- /* non-0: report medium change error; */
- {
- int dev;
- char buf[512];
- int partno, ret;
- PART partinfo[NPARTS];
-
- /* disable all logical and physical devs */
- for (dev = 0; dev < MAXLOGDEVS; ++dev)
- logmap[dev].lm_physdev = -1;
-
- for (dev = 0; dev < MAXPHYSDEVS; ++dev)
- livedevs[dev] = 0;
-
- /*
- * Scan all physical devs
- * and pick up partition structures.
- */
- nlogdevs = 0;
- for (dev = 0; dev < MAXPHYSDEVS; ++dev)
- {
- if ((ret = getroot(dev, buf)) < 0) {
- continue;
- } else { /* ret >= 0 */
- if (ret > 0) {
- if (flag) { /* if non-0, report error if medium changed */
- if (tsterr(ret) == OK)
- return ERROR;
- }
- if ((ret = getroot(dev, buf))) { /* try again */
- if (ret > 0 && flag && tsterr(ret) == OK)
- return ERROR;
- continue;
- }
- }
- livedevs[dev] = 1;
- gpart(buf, &partinfo[0]);
- for (partno = 0; partno < NPARTS; ++partno) {
- if (partinfo[partno].p_flg & P_EXISTS &&
- partinfo[partno].p_siz != (SECTOR)0 &&
- partinfo[partno].p_id[0] == 'G' &&
- partinfo[partno].p_id[1] == 'E' &&
- partinfo[partno].p_id[2] == 'M')
- {
- if (nlogdevs >= MAXLOGDEVS)
- return err(manyldev);
-
- logmap[nlogdevs].lm_physdev = dev;
- logmap[nlogdevs].lm_partno = partno;
- logmap[nlogdevs].lm_start = partinfo[partno].p_st;
- logmap[nlogdevs].lm_siz = partinfo[partno].p_siz;
- ++nlogdevs;
- }
- }
- }
- }
- return OK;
- }
-
-
- /*
- * From a PHYSICAL device unit (0->7)
- * and a partition number (0->3), figure
- * out the LOGICAL disk number ('C'->'P').
- *
- * return the LOGICAL disk number or
- * ERROR if the PHYSICAL device doesn't exist.
- *
- */
- phys2log(pdev, pno)
- int pdev; /* physical device unit */
- int pno; /* partition number (0 -> 3) */
- {
- int logdev; /* index to step through partitions of a phys unit */
-
- for (logdev = 0; logdev < MAXLOGDEVS; logdev++) {
- if (logmap[logdev].lm_physdev == pdev &&
- logmap[logdev].lm_partno == pno)
- return ('C'+logdev);
- }
- return ERROR;
- }
-
-
- /*
- * Map block on logical device to
- * block on physical device;
- * return ERROR if the logical device
- * doesn't exist.
- */
- log2phys(adev, ablk)
- int *adev;
- SECTOR *ablk;
- {
- int dev;
- char xbuf[256];
-
- dev = *adev;
- if (dev >= 0 && dev <= 7)
- return OK;
-
- dev = toupper(dev);
- if (dev >= 'C' && dev <= 'P')
- {
- dev -= 'C';
- *adev = logmap[dev].lm_physdev;
- *ablk = logmap[dev].lm_start + *ablk;
- return OK;
- }
-
- return ERROR;
- }
-
-
-
- /*
- * Return physical starting block# of a partition
- *
- */
- SECTOR
- logstart(ldev)
- int ldev; /* logical device */
- {
- ldev = toupper(ldev);
- if (ldev >= 'C' && ldev <= 'P') {
- ldev -= 'C';
- return (logmap[ldev].lm_start);
- }
- return ERROR;
- }
-
-
-
- /*
- * Return physical starting block# of a partition's data block.
- *
- */
- SECTOR
- logend(ldev)
- int ldev; /* logical device */
- {
- ldev = toupper(ldev);
- if (ldev >= 'C' && ldev <= 'P') {
- ldev -= 'C';
- return (logmap[ldev].lm_start+logmap[ldev].lm_siz-1);
- }
- return ERROR;
- }
-
-
- #define MFM 17 /* sectors per track for MFM */
- #define RLL 26 /* sectors per track for RLL */
-
-
- /*
- * Check if dev's root block is intact.
- * Return number of sectors per track on disk.
- *
- */
- chkroot(dev, bs)
- int dev;
- char *bs;
- {
- extern long get3bytes();
- SETMODE *mb;
- int i, ret;
- int cyl, head;
- SECTOR size, msiz; /* size of media */
- char buf[512], sendata[16];
- long dmaptr, tmpptr;
- char *dmahigh=0xffff8609,
- *dmamid=0xffff860b,
- *dmalow=0xffff860d;
-
- size = ((RSECT *)(bs + 0x200 - sizeof(RSECT)))->hd_siz;
-
- ostack = Super(NULL);
-
- /* Get format parameters/ disk size from media */
- ret = md_sense(dev, sendata);
- delay();
- Super(ostack);
-
- if (ret != 0) {
- return ERROR;
- }
-
- /* check what kind of sense data it returned */
- /* If full SCSI, will return number of blocks */
- /* on disk at byte 5, 6 and 7. If Adaptec, */
- /* will return 0 for number of blocks on disk */
- /* on SCSI. */
-
- if (!(msiz = get3bytes(sendata+5))) { /* no disk size returned? */
- /* Yup, ie., it's adaptec's. Interpret as SETMODE structure */
- mb = (SETMODE *)sendata;
- /* get number of cylinders */
- cyl = mb->smd_cc[0];
- cyl <<= 8;
- cyl |= mb->smd_cc[1];
-
- /* get number of heads */
- head = mb->smd_dhc;
-
- msiz = (SECTOR)head * (SECTOR)cyl * MFM;
-
- for (i = 0; i < 20; i++) {
- if ((ret = rdsects(dev, 1, buf, msiz+i)) == OK) {
-
- /* find out whether data has been transferred, by
- checking if dma pointer has been moved. */
-
- ostack = Super(NULL); /* get into Supervisor mode */
-
- dmaptr = *dmahigh;
- dmaptr &= 0x0000003f;
- dmaptr <<= 16;
- tmpptr = *dmamid;
- tmpptr &= 0x000000ff;
- tmpptr <<= 8;
- dmaptr |= tmpptr;
- tmpptr = *dmalow;
- tmpptr &= 0x000000ff;
- dmaptr |= tmpptr;
-
- delay();
- Super(ostack); /* back to user mode */
-
- if (dmaptr != buf)
- break;
- } else { /* rdsects return an error */
- if (tsterr(ret) == OK) {
- break;
- }
- }
- }
-
- if (ret == MDMCHGD) /* check if error occurred */
- return (ret);
-
- /* Determine if media is MFM or RLL */
- if (i < 20)
- msiz = (SECTOR)head * (SECTOR)cyl * RLL;
- }
-
- if (size != msiz)
- ret = ERROR;
- else
- ret = OK;
-
- return (ret);
- }
-
-
- /*
- * Chkparm()
- * Check if given logical device has the asssumed parameters.
- * Assumptions are:
- * - 512 bytes/sector
- * - 2 sectors/cluster
- * - 1 reserved sector
- * - 2 FATs
- *
- * Input:
- * ldev - logical device number ('C' -> 'P').
- *
- * Return:
- * OK - parameters of partition match the assumptions
- * ERROR - something went wrong.
- *
- * Comment:
- * Number of FATs is assumed to be 2. Cannot check this
- * because previous version of HDX did not put that in the boot
- * sector.
- */
- chkparm(ldev)
- int ldev;
- {
- char bs[512]; /* boot sector */
- BOOT *boot; /* boot structure */
- UWORD bps, res, siz; /* bytes/sector, num reserved sectors, ldev size */
- int ret;
-
- if ((ret = rdsects(ldev, 1, bs, (SECTOR)0)) != 0) {
- if (tsterr(ret) != OK)
- err(bootread);
- ret = ERROR;
- goto parmend;
- }
-
- boot = (BOOT *)bs;
- gw((UWORD *)&boot->b_bps, &bps); /* what is number bytes/sector? */
- gw((UWORD *)&boot->b_res, &res); /* what is num of reserved sectors? */
- gw((UWORD *)&boot->b_nsects, &siz); /* what is size of partition */
- if (bps != 512 /* bytes per sector == 512 ? */
- || res != 1) { /* num sectors reserved == 1 ? */
- ret = ERROR; /* Nope, different from assumptions */
- goto parmend;
- }
-
- /* Check if sectors per cluster make sense */
- if ((siz >= 0x8000L && boot->b_spc != 4) ||
- (siz < 0x8000L && boot->b_spc != 2)) {
- ret = ERROR;
- goto parmend;
- }
-
- ret = OK; /* If yes, return OK */
-
- parmend:
- return ret;
- }
-
-
- /*
- * Get dev's root block.
- *
- */
- getroot(dev, buf)
- int dev;
- char *buf;
- {
- return rdsects(dev, 1, buf, (SECTOR)0);
- }
-
-
- /*
- * Put dev's root block.
- *
- */
- putroot(dev, buf)
- int dev;
- char *buf;
- {
- return wrsects(dev, 1, buf, (SECTOR)0);
- }
-
-
- /*
- * Read sector(s) from dev.
- *
- * Input:
- * dev - device number (logical or physical).
- * num - number of sectors to read.
- * buf - buffer to write data read.
- * sect - starting sector number to read from.
- *
- * Return:
- * errnum - 0: if read is successful.
- * an error code: if read is unsuccessful.
- */
- rdsects(dev, num, buf, sect)
- int dev; /* device number (logical or physical) */
- UWORD num; /* number of sectors to read */
- char *buf;
- SECTOR sect; /* starting sector to read from */
- {
- int errnum;
-
- if (log2phys(&dev, §) < 0)
- return ERROR;
-
- ostack = Super(NULL);
- errnum = hread(sect, num, buf, (UWORD)dev);
- delay();
- Super(ostack);
-
- if (errnum > 0) {
- errnum = errcode(dev);
- }
-
- return errnum; /* return the error code */
- }
-
-
- /*
- * Write sector(s) to dev.
- *
- * Input:
- * dev - device number (logical or physical).
- * num - number of sectors to write.
- * buf - buffer with data to be written.
- * sect - starting sector number to write to.
- *
- * Return:
- * errnum - 0: if write is successful.
- * an error code: if write is unsuccessful.
- */
- wrsects(dev, num, buf, sect)
- int dev; /* device number (logical or physical */
- UWORD num; /* number of sectors to write */
- char *buf; /* buffer with data to be written */
- SECTOR sect; /* starting sector to write to */
- {
- int errnum;
-
- if (log2phys(&dev, §) < 0)
- return ERROR;
-
- ostack = Super(NULL);
- errnum = hwrite(sect, num, buf, (UWORD)dev);
- delay();
- Super(ostack);
-
- if (errnum > 0) {
- errnum = errcode(dev);
- }
-
- return errnum;
- }
-
-
- /*
- * Zero range of sectors on dev.
- *
- */
- zerosect(dev, start, count)
- int dev;
- SECTOR start;
- UWORD count;
- {
- char *zbuf;
- int v;
- UWORD i;
-
- if ((zbuf = (char *)mymalloc(ZBUFSIZ)) <= 0)
- return err(nomemory);
-
- if (log2phys(&dev, &start) < 0) {
- free(zbuf);
- return ERROR;
- }
-
- fillbuf(zbuf, (long)ZBUFSIZ, 0L);
-
- while (count)
- {
- if (count > ZCOUNT)
- i = ZCOUNT;
- else i = count;
-
- if ((v = wrsects(dev, i, zbuf, start)) != 0)
- break;
- start += i;
- count -= i;
- }
- free(zbuf);
-
- return v;
- }
-