Coherent4.2.10/conf/hai/src/biosdisk.c

#include <kernel/typed.h>
#include <sys/hdioctl.h>
#include <sys/haiscsi.h>
#include <sys/scsiwork.h>

/*
 * First, what to do with disks not supported by the BIOS.
 * Answer:  support them with a default geometry. This mimics the
 * Adaptec controller's logic which is simplest so far. In the future,
 * may need to set it up so that the Seagate/Future Domain geometry is 
 * supported.
 */

#define BLK_PER_GIG	2097152	/* One gigabyte in blocks. */
#define SMDRV_HDS	64	/* Small drive # heads */
#define SMDRV_SPT	32	/* Small drive # sectors */
#define LGDRV_HDS	255	/* Large drive # heads */
#define LGDRV_SPT	63	/* Large drive # sectors */

extern _drv_parm_t	_sd_drv_parm[];

/*
 * loadbiosparms()
 *
 * Load the bios parameters for a scsi drive into the drive parms table.
 */

#if __USE_PROTO__
void loadbiosparms(int biosnum, int s_id)
#else
void 
loadbiosparms(biosnum, s_id)
int  	biosnum;
int 	s_id;
#endif
{
    FIFO		*ffp;
    typed_space 	*tp;
    extern typed_space	boot_gift;
    
    /*
     * Attempt to load the parameters for the drive from the bootgift.
     * Recent "advances" in disk technology force this on us although
     * it probably should have been done this way from the word go.
     * Piggy left us the parameters in the T_BIOS_DISK entries in the boot
     * gift.
     */
      
    if (biosnum >= 0 &&
	biosnum <= 1 &&
	(ffp = fifo_open (&boot_gift, 0)) != F_NULL) {

	/*
	 * Look through the entire boot gift for our entry.
	 */

	for ( ; (tp = fifo_read(ffp)) != 0; ) {
	    BIOS_DISK * bdp = (BIOS_DISK *)tp->ts_data;

	    /*
	     * If we found a disk drive and it's ours load the parameters.
	     */

	    if (tp->ts_type == T_BIOS_DISK && bdp->dp_drive == biosnum) {
		_sd_drv_parm[s_id].ncyl = bdp->dp_cylinders;
		_sd_drv_parm[s_id].nhead = bdp->dp_heads;
		_sd_drv_parm[s_id].nspt = bdp->dp_sectors;

		break;
	    } /* if */
	} /* for */
	fifo_close(ffp);
    } /* if */
} /* loadbiosparms() */

/*
 *  haihdgeta()     --  Get disk driver paramters.
 *
 *  This function is provided to support the HDGETA/HDSETA I/O Controls
 *  so you don't need the old Adaptec SCSI driver to set up the partition
 *  table on initial setup.  There is a catch-22 with this.  You need
 *  to know the drive's geometry in order to set up the partition table
 *  but cannot get the drive's geometry until you have set up the partition
 *  table.  We solve this by using the drive's size and then dividing
 *  down based upon SDS_HDS heads and SDS_SPT sectors per track.  Every
 *  host adapter will want to do this differently.  The Adaptec solution
 *  is the best that I've seen so far. (It allows you to use Huge (1.0
 *  GB) disks under DOS without trouble.
 */

#if __USE_PROTO__
void haihdgeta(int target, hdparm_t *hdp, unsigned int diskcap)
#else
void
haihdgeta(target, hdp, diskcap)
int 		target;
hdparm_t	*hdp;
unsigned int	diskcap;
#endif
{
	memset(hdp, 0, sizeof(hdparm_t));
	*((unsigned short *) hdp->rwccp) = 0xffff;
	*((unsigned short *) hdp->wpcc) = 0xffff;
	if (_sd_drv_parm[target]. ncyl != 0) {
		*((unsigned short *) hdp->ncyl) = _sd_drv_parm[target].ncyl;
		*((unsigned short *) hdp->landc) = _sd_drv_parm[target].ncyl;
		
		hdp->nhead = _sd_drv_parm[target].nhead;
		if (hdp->nhead > 8)
			hdp->ctrl |= 8;
		hdp->nspt = _sd_drv_parm[target].nspt;
	} else {
		if (diskcap < BLK_PER_GIG) {
			_sd_drv_parm[target].nhead = SMDRV_HDS;
			_sd_drv_parm[target].nspt = SMDRV_SPT;
		} else {
			_sd_drv_parm[target].nhead = LGDRV_HDS;
			_sd_drv_parm[target].nspt = LGDRV_SPT;
		}
		_sd_drv_parm[target].ncyl = diskcap / (_sd_drv_parm[target].nhead * _sd_drv_parm[target].nspt);
		
		*((unsigned short *) hdp->ncyl) = _sd_drv_parm[target].ncyl;
		*((unsigned short *) hdp->landc) = _sd_drv_parm[target].ncyl;
		
		hdp->nhead = _sd_drv_parm[target].nhead;
		if (hdp->nhead > 8)
			hdp->ctrl |= 8;
		hdp->nspt = _sd_drv_parm[target].nspt;
	}
}		/* haihdgeta() */

/***********************************************************************
 *  haihdseta()     --  Set disk parameters in accordance with HDSETA
 *                      I/O Control.
 *
 *  Set the disk paramters accordingly for a request from the fdisk
 *  program.  This call really doesn't do anything on the adaptec or
 *  in the SCSI driver in general because SCSI Disks use Logical Block
 *  addressing rather than Cylinder/Head/Track addressing found with
 *  less intelligent Disk drive types.  What this will do is allow
 *  the fdisk program to work so a user can format his disk and install
 *  Coherent on it (A Good Thing).  This boils down to a fancy way to
 *  patch SDS_HDS and SDS_SPT.
 */

#if __USE_PROTO__
void haihdseta(int target, hdparm_t *hdp)
#else
void
haihdseta(target, hdp)
int 		target;
hdparm_t	*hdp;
#endif
{
	_sd_drv_parm[target].ncyl =  *((unsigned short *) hdp->ncyl);
	_sd_drv_parm[target].nhead = hdp->nhead;
	_sd_drv_parm[target].nspt =  hdp->nspt;
}	/* haihdseta() */

/* End of file */