/* Device.c - Device support routines */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* |_o_o|\\ Copyright (c) 1987 The Software Distillery.  All Rights Reserved */
/* |. o.| || This program may not be distributed without the permission of   */
/* | .  | || the author.                                           BBS:      */
/* | o  | ||   John Toebes    Dave Baker                     (919)-471-6436  */
/* |  . |//                                                                  */
/* ======                                                                    */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include "handler.h"
#include <devices/trackdisk.h>

typedef struct FileSysStartupMsg *FSSM;

int GetDevice (global, myfssmsg)
GLOBAL global;    
FSSM myfssmsg;
{
FSSM  fssmsg;
ULONG *tmpdskenv;
int   devnum;
char  *defaultdev = TD_NAME;

   BUG(("devname:%s\n",global->devname));
   BUG(("Global->node = %08lx Global->node->dn_Startup = %08lx\n",global->node, BADDR(global->node->dn_Startup)));

   /* Did they give us any information in the device list ? */
   if (((fssmsg = (FSSM)BADDR(global->node->dn_Startup)) == NULL) ||
        (fssmsg->fssm_Device == NULL))
      {
      /* No information about what we are mounting.  Figure out what it is */
      /* we want by guessing from a default naming convention              */

      /* Make sure we have a 4 character name followed by a : only */
      if (global->devname[4] != ':')
         {
         BUG(("Name is not the right length\n"));
         return(NULL);
         }

      devnum = global->devname[3] - '0';
      if ((devnum < 0) || (devnum > 3))
         {
         BUG(("Device number %ld out of range\n", devnum));
         return(NULL);
         }

      /* Initialize the device information */
      global->unitnum = myfssmsg->fssm_Unit = devnum;

      /* what trackdisk.device looks like */
      myfssmsg->fssm_Device          = (ULONG)defaultdev;
      myfssmsg->fssm_Flags           = 0;
      global->dskenv.de_sizeblock    = 128;
      global->dskenv.de_blkspertrk   = 11;
      global->dskenv.de_reservedblks = 2;
      global->dskenv.de_numblks      = 1760;
      global->dskenv.de_lowcyl       = 0;
      global->dskenv.de_uppercyl     = 79;
      global->dskenv.de_numbufs      = 5;
      global->dskenv.de_membuftype   = (MEMF_CHIP|MEMF_CLEAR);

      BUG(("GetDevice-fssm_Device:%s\n", myfssmsg->fssm_Device));
      BUG(("GetDevice-fssm_Unit:%ld\n",   myfssmsg->fssm_Unit)); 
      BUG(("GetDevice-fssm_Flags:%lx\n", myfssmsg->fssm_Flags));
      }

   else
      {
      /* They gave us all the device information in the mountlist */
      myfssmsg->fssm_Device  = (ULONG)BADDR(fssmsg->fssm_Device);
      global->unitnum        =
      myfssmsg->fssm_Unit    = fssmsg->fssm_Unit;
      myfssmsg->fssm_Flags   = (ULONG)BADDR(fssmsg->fssm_Flags);
  
      BUG(("fssm:%lx\n", fssmsg));
      BUG(("fssm_Device:%s\n",    fssmsg->fssm_Device));
      BUG(("fssm_Unit:%ld\n",      fssmsg->fssm_Unit)); 
      BUG(("fssm_Flags:%lx\n",    fssmsg->fssm_Flags));
      BUG(("fssm_Environ:%lx\n",  fssmsg->fssm_Environ));
  
      tmpdskenv = (ULONG *)BADDR(fssmsg->fssm_Environ);

      BUG(("dskenv tablesize:%lx\n",    tmpdskenv[DE_TABLESIZE]   ));
      BUG(("dskenv sizeblock:%lx\n",    tmpdskenv[DE_SIZEBLOCK]   ));
      BUG(("dskenv secorg:%lx\n",       tmpdskenv[DE_SECORG]      ));
      BUG(("dskenv numheads:%lx\n",     tmpdskenv[DE_NUMHEADS]    ));
      BUG(("dskenv secsperblk:%lx\n",   tmpdskenv[DE_SECSPERBLK]  ));
      BUG(("dskenv blkspertrack:%lx\n", tmpdskenv[DE_BLKSPERTRACK]));
      BUG(("dskenv reservedblks:%lx\n", tmpdskenv[DE_RESERVEDBLKS]));
      BUG(("dskenv prefac:%lx\n",       tmpdskenv[DE_PREFAC]      ));
      BUG(("dskenv interleave:%lx\n",   tmpdskenv[DE_INTERLEAVE]  ));
      BUG(("dskenv lowcyl:%lx\n",       tmpdskenv[DE_LOWCYL]      ));
      BUG(("dskenv uppercyl:%lx\n",     tmpdskenv[DE_UPPERCYL]    ));
      BUG(("dskenv numbuffers:%lx\n",   tmpdskenv[DE_NUMBUFFERS]  ));
      BUG(("dskenv membuftype:%lx\n",   tmpdskenv[DE_MEMBUFTYPE]  ));
   
      global->dskenv.de_sizeblock    = tmpdskenv[DE_SIZEBLOCK];
      global->dskenv.de_blkspertrk   =  tmpdskenv[DE_BLKSPERTRACK];
      global->dskenv.de_reservedblks = tmpdskenv[DE_RESERVEDBLKS];
      global->dskenv.de_numblks      =
          ((((tmpdskenv[DE_UPPERCYL]-tmpdskenv[DE_LOWCYL])+1)*
             (tmpdskenv[DE_BLKSPERTRACK]))*(tmpdskenv[DE_NUMHEADS]));

      global->dskenv.de_lowcyl       = tmpdskenv[DE_LOWCYL];
      global->dskenv.de_uppercyl     = tmpdskenv[DE_UPPERCYL];
      global->dskenv.de_numbufs      = tmpdskenv[DE_NUMBUFFERS];
      global->dskenv.de_membuftype   = tmpdskenv[DE_MEMBUFTYPE];
   
      }

   /* Figure out where the root block is supposed to be */
   global->Root = (global->dskenv.de_numblks / 2);
   return(-1);
}



int InitDevice(global)
GLOBAL global;
{
   struct FileSysStartupMsg myfssmsg;
  
   BUG(("InitDevice:\n"));

   if (GetDevice(global,&myfssmsg) == NULL)
      {
      BUG(("GetDevice Failed \n"));
      return(0);
      }

   if ((global->devport = (struct MsgPort *)CreatePort("dskport",0))==NULL)
      {
      BUG(("CreatePort Failed\n"));
      return(0);        /* error in createport */
      }  

   BUG(("fssm_Device:%s\n", myfssmsg.fssm_Device));
   BUG(("fssm_Unit:%ld\n",   myfssmsg.fssm_Unit)); 
   BUG(("fssm_Flags:%lx\n", myfssmsg.fssm_Flags));
 
   BUG(("CreateExtIO\n"));

   /* make an io request block for communicating with the disk */
   if ((global->devreq = (struct IOExtTD *)
             CreateExtIO(global->devport, sizeof(struct IOExtTD)))==NULL)
      {
      BUG(("CreateExtIO Failed\n"));
      DeletePort(global->devport);
      return(0);
      }

   BUG(("OpenDevice\n"));
   /* open the device for access note using FileSysStartupMsg struct */ 
   /* however fields have been converted to C pointers by GetDevice  */
   if ((OpenDevice((char *)myfssmsg.fssm_Device, myfssmsg.fssm_Unit,
                  (struct IORequest *)(global->devreq), 
                  myfssmsg.fssm_Flags)) != NULL)
      {
      BUG(("OpenDevice Failed\n"));
      return(0);
      }


   BUG(("AddDskChngInt\n"));
   /* add the disk change interrupt trash */
   if (AddDskChngInt(global) == NULL)
      {
      BUG(("AddDskChngInt Failed\n")); 
      }

   BUG(("AllocBlkBuffs\n"));
   /* allocate the block buffers */
   if ((AllocBlkBuffs(global,global->dskenv.de_numbufs) == NULL))
      {
      BUG(("AllocBlkBuffs Failed\n"));
      return(0);
      }

   BUG(("DiskChange\n"));
   /* now get the disk change value */
   global->devreq->iotd_Req.io_Command = TD_CHANGENUM;
   DoIO((struct IORequest *)global->devreq);
   global->DiskChange = global->devreq->iotd_Req.io_Actual;

   return(1);  /* successful completion */
}



int TermDevice(global)
GLOBAL global;
{
   return(1);
}

 
