[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference hydra::axp-developer

Title:Alpha Developer Support
Notice:[email protected], 800-332-4786
Moderator:HYDRA::SYSTEM
Created:Mon Jun 06 1994
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:3722
Total number of notes:11359

3347.0. "magma" by HYDRA::TALATINIAN () Tue Mar 18 1997 13:56

    Company Name :  magma
    Contact Name :  Bruce Schoenleber
    Phone        :  
    Fax          :  
    Email        :  [email protected]
    Date/Time in :  18-MAR-1997 13:55:02
    Entered by   :  John Talatinian
    SPE center   :  MRO

    Category     :  UNIX
    OS Version   :  
    System H/W   :  


    Brief Description of Problem:
    -----------------------------

From: [email protected] (Bruce)
Message-Id: <[email protected]>
To: [email protected]
Subject: configure_driver returns EINVAL (errno 22)
Cc: [email protected]


Hello,

  My PIN # is 120495.  I am having difficulty in going from
the ldbl_stanza_resolver() and ldbl_ctlr_configure() interfaces
to the new configure_driver() paradigm.  I did a straight
conversion from the old to the new, using the sample none driver
verbatim.  I continue to get EINVAL back from the call to
configure_driver.  

  Will you be kind enough to open a support call for me and assign
someone to give me a hand.

Thankyou very much,
Bruce Schoenleber

T.RTitleUserPersonal
Name
DateLines
3347.1magmaHYDRA::TALATINIANTue Mar 18 1997 14:0116
Bruce,

  Please provide me with the following information, and I will look into this.

   System type
   OS & version
   phone number to reach you
   sample code of what doesn't work.

thanks,

John Talatinian
Software Partners Eng. Group
Digital Equipment Corp.


3347.2magmaHYDRA::TALATINIANTue Mar 18 1997 15:461086
From: [email protected] (Bruce)
Message-Id: <[email protected]>
To: [email protected]
Subject: Re: configure_driver returns EINVAL (errno 22)

Hi John,

 Thanks for the quick response, here are the vitals:

Target systems are all alpha pci machines.  In house we are
currently using an AlphaStation 200 4/166.

OS is Digital UNIX 4.0B

Phone number is (619) 457-0750

This is the sysconfigtab snippet:

ma:
  Subsystem_Description = Magma PCI Serial card driver
  Module_Type = Dynamic
  Module_Path = /subsys/ma.mod
  Module_Config_Name = ma
  Device_Char_Major = ANY
  PCI_Option = PCI_SE_Rev - 0x210, Vendor_Id - 0x11c9, Device_Id - 0x10, Driver_
Name - ma, Type - C, Adpt_Config - N


The following is the driver code for the autoconfiguration.  The stuff
inside the "#ifdef OLDWAY" works.  The problem is at the point
where configure_driver() is called, it returns with errno == 22.
Btw: This is a pci serial port mux.

Thanks for the help,
Bruce Schoenleber

-------------- maconfig.c--------------------------------
#ifndef lint
static char sid2[] = "%W% Magma PCI DU common driver %G%";
#endif


extern int nodev(), nulldev(); 

/* auto configuration routines */
static   int   maprobe (struct pci_config_hdr *, struct controller *);
static   int   maattach (struct controller *);
static   int   madettach (struct bus*, struct controller *);
int   ma_configure (cfg_op_t, cfg_attr_t *, size_t, cfg_attr_t *, size_t);

struct controller *mainfo[MAXBOARDS];
ihandler_id_t *ma_id_t[MAXBOARDS]; 

/* driver/device attributes */

static int cmajnum = -1; 
static int begunit = 0;
static int numunit = 0;
static int maversion = 19;
static int ma_is_dynamic = 0; 
static int ma_config = FALSE;  /* State flags indicating driver configured */
dev_t ma_devno = NODEV; /* No major number assigned yet. */

static unsigned char mcfgname[CFG_ATTR_NAME_SZ] = ""; 
static unsigned char modtype[300] = "";
static unsigned char devcmajor[300] = "";
static unsigned char subsysdscr[300] = "";
static unsigned char modpath[300] = "";
static unsigned char modconf[MAXBOARDS][300] = {"","","","","",""};
static unsigned char pci_optiondata[300] = "";

cfg_subsys_attr_t ma_attributes[] = { 
   {"Module_Config_Name",
         CFG_ATTR_STRTYPE, CFG_OP_CONFIGURE | CFG_OP_QUERY,
         (caddr_t)mcfgname,2,CFG_ATTR_NAME_SZ,0
   },
   {"PCI_Option",
         CFG_ATTR_STRTYPE, CFG_OP_CONFIGURE | CFG_OP_QUERY,
         (caddr_t)pci_optiondata,0,300,0
   },
   {"Module_Type",
         CFG_ATTR_STRTYPE, CFG_OP_CONFIGURE | CFG_OP_QUERY,
         (caddr_t)modtype,2,300,0
   },
   {"Device_Char_Major",
         CFG_ATTR_STRTYPE, CFG_OP_CONFIGURE | CFG_OP_QUERY,
         (caddr_t)devcmajor,0,300,0
   },
   {"Subsystem_Description",
         CFG_ATTR_STRTYPE, CFG_OP_CONFIGURE | CFG_OP_QUERY,
         (caddr_t)subsysdscr,0,300,0
   },
   {"Module_Path",
         CFG_ATTR_STRTYPE, CFG_OP_CONFIGURE | CFG_OP_QUERY,
         (caddr_t)modpath,0,300,0
   },
   {"Module_Config1",
         CFG_ATTR_STRTYPE, CFG_OP_CONFIGURE | CFG_OP_QUERY,
         (caddr_t)modconf[0],0,300,0
   },
   {"Module_Config2",
         CFG_ATTR_STRTYPE, CFG_OP_CONFIGURE | CFG_OP_QUERY,
         (caddr_t)modconf[1],0,300,0
   },
   {"Module_Config3",
         CFG_ATTR_STRTYPE, CFG_OP_CONFIGURE | CFG_OP_QUERY,
         (caddr_t)modconf[2],0,300,0
   },
   {"Module_Config4",
         CFG_ATTR_STRTYPE, CFG_OP_CONFIGURE | CFG_OP_QUERY,
         (caddr_t)modconf[3],0,300,0
   },
   {"Module_Config5",
         CFG_ATTR_STRTYPE, CFG_OP_CONFIGURE | CFG_OP_QUERY,
         (caddr_t)modconf[4],0,300,0
   },
   {"Module_Config6",
         CFG_ATTR_STRTYPE, CFG_OP_CONFIGURE | CFG_OP_QUERY,
         (caddr_t)modconf[5],0,300,0
   },
   {"majnum",
         CFG_ATTR_INTTYPE, CFG_OP_QUERY,
         (caddr_t)&cmajnum,0,99,0
   },
   {"begunit",
         CFG_ATTR_INTTYPE, CFG_OP_QUERY,
         (caddr_t)&begunit,0,8,0
   },
   {"numunit",
         CFG_ATTR_INTTYPE, CFG_OP_QUERY,
         (caddr_t)&numunit,0,8,0
   },
   {"version",
         CFG_ATTR_INTTYPE, CFG_OP_QUERY,
         (caddr_t)&maversion,0,9999999,0
   },
   {"",0,0,0,0,0,0}
};


#define MABUSNAME    "pci" /* This is a PCI driver */
#define MAJOR_INSTANCE 1

#ifdef OLDWAY
struct pci_option ma_option_snippet [] = {
   {0x210, MA_VENDOR_ID, MA_PCI16DMA, 0, 0, 0,
      0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, "ma", 'C', 0},
   {0x210, MA_VENDOR_ID, MA_PCI4DMA, 0, 0, 0,
      0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, "ma", 'C', 0},
   {0x210, MA_VENDOR_ID, MA_PCI16, 0, 0, 0,
      0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, "ma", 'C', 0},
   {0x210, PCI_VID_INVALID, 0, 0, 0, 0, 0,
      0, 0, 1, 1, 0, 0, 0,0,0,0, "", '', 0} /* Null terminator in the table */
};
#endif

struct driver madriver = {
   maprobe,               /* probe */
   0,                     /* slave */
   maattach,              /* cattach */
   0,			              /* dattach */
   0,                     /* go */
   0,                     /* addr_list */
   0,                     /* dev_name */
   0,                     /* dev_list */
   "ma",                  /* ctlr_name */
   mainfo,                /* ctlr_list */
   0,                     /* xclu */
   0,                     /* addr1_size */
   0,                     /* addr1_atype */
   0,                     /* addr2_size */
   0,                     /* addr2_atype */
   madettach,             /* ctlr_unattach */
   0                      /* dev_unattach */
};


struct dsent ma_cdevsw= {
   maopen,                 /* d_open */
   maclose,                /* d_close */
	nodev,						/* d_stratagy */
   maread,                 /* d_read */
   mawrite,                /* d_write */
   maioctl,                /* d_ioctl */
	nodev,						/* d_dump */
	nodev,						/* d_psize */
   nodev,                  /* d_stop */
   nodev,                  /* d_reset */
   maselect,               /* d_select */
	nodev,						/* d_mmap */
	nodev,						/* d_segmap */
   NULL,                   /* d_ttys */
   DEV_FUNNEL_NULL,        /* d_funnel */
   0,                      /* d_bflags */
   0								/* d_cflags */
};
 

#ifdef MADEBUG
cfg_attr_t cfg_buf[64];
#endif
               

int
ma_configure (cfg_op_t op, cfg_attr_t *indata, size_t indata_size,
               cfg_attr_t *outdata, size_t outdata_size)
{

   dev_t   devno = NODEV;
   int i, status;

   switch (op)
   {
      default:
         maprintf("ma_configure: Unkown operation\n",0);
         return ENOTSUP;

      case CFG_OP_RECONFIGURE:
         maprintf("ma_configure: reconfigure operation\n",0);
         return ESUCCESS;

      case CFG_OP_QUERY:
         maprintf("ma_configure: query, operation\n",0);
         return ESUCCESS;

      case CFG_OP_UNCONFIGURE:
         maprintf("ma_configure: unconfig\n",0);
         if (madaemonflag) return(EBUSY);

         i = devsw_del (mcfgname, 1);
         if (i) return(ESRCH);
         if (unconfigure_driver(MABUSNAME, LDBL_WILDNUM,
                  &madriver, MABUSNAME, LDBL_WILDNUM) != 0)
            return(ESRCH);
         return (ESUCCESS);

      case  CFG_OP_CONFIGURE:
#ifdef MADEBUG
         printf("\nma_configure: Config request\n");
         bcopy(indata, cfg_buf[0].name,
         indata_size*(sizeof(cfg_attr_t)));
         for( i=0; i < indata_size; i++)
         {
            printf("%s: ",cfg_buf[i].name);
            switch(cfg_buf[i].type)
            {
               case CFG_ATTR_STRTYPE:
                  printf("%s\n",cfg_buf[i].attr.str.val);
                  break;
               default:
                  switch(cfg_buf[i].status)
                  {
                     case CFG_ATTR_EEXISTS:
                        printf("**Attribute does not exist\n");
                        break;
                     case CFG_ATTR_EOP:
                        printf("**Attribute does not support operation\n");
                        break;
                     case CFG_ATTR_ESUBSYS:
                        printf("**Subsystem Failure\n");
                        break;
                     case CFG_ATTR_ESMALL:
                        printf("**Attribute size/value too small\n");
                        break;
                     case CFG_ATTR_ELARGE:
                        printf("**Attribute size/value too large\n");
                        break;
                     case CFG_ATTR_ETYPE:
                        printf("**Attribute invalid type\n");
                        break;
                     case CFG_ATTR_EINDEX:
                        printf("**Attribute invalid index\n");
                        break;
                     case CFG_ATTR_EMEM:
                        printf("**Attribute memory allocation error\n");
                        break;
                     default:
                        printf("**Unknown attribute: ");
                        printf("%x\n", cfg_buf[i].status);
                        break;
                  }
                  break;
            }
         }
#endif MADEBUG

			if (ma_config) return (EINVAL); /* already configured */

			maprintf("ma: config name is %s\n",mcfgname);
         if(strcmp(mcfgname,"")==0)
				strcpy(mcfgname, "ma");

			if (cfgmgr_get_state(mcfgname,&ma_is_dynamic) !=
ESUCCESS)
				return(EINVAL);

         if (ma_is_dynamic == SUBSYSTEM_DYNAMICALLY_CONFIGURED) { 

				maprintf("ma: Dynamic configuration\n",0);

				if ((status = register_config()) != ESUCCESS)
					return(status);

				if ((status = configure_driver(mcfgname,
DRIVER_WILDNUM,
								DRIVER_WILDNAME,
&madriver)) != ESUCCESS) {
               	maprintf("ma_configure, config driver failed, status %d",
								status);
						return(status);
				}

				if ((status = register_majornum()) != ESUCCESS)
					return(status);

				return(status);

			} else { /* static configuration */
				maprintf("ma: Static configuration\n",0);
				return(EINVAL);
			}
#ifdef OLDWAY
         if (ma_is_dynamic == SUBSYSTEM_DYNAMICALLY_CONFIGURED)
         { 
 
            if(strcmp(mcfgname,"")==0)
            {
               maprintf("ma_configure, null config name.",0);
               return(ENODEV);
            }

            if (ldbl_stanza_resolver(mcfgname, MABUSNAME, &madriver,
                              (caddr_t *)ma_option_snippet) != 0)
                  return(EINVAL);

            if (ldbl_ctlr_configure(MABUSNAME, LDBL_WILDNUM, 
                              mcfgname, &madriver, 0))
                  return(EINVAL);

            /*
            ** The above call should have called  
            ** the driver's probe interface for  
            ** each instance of the controller. 
            ** If there were no controllers found
            ** then fail the driver configure   
            ** operation.   
            */

            if (nboards == 0)
            {
               maprintf("ma_configure: no controllers found.",0);
               return(ENODEV);
            }
         } 

         if(strcmp(devcmajor,"")!=0)
         { 
            if((strcmp(devcmajor,"-1")==0) ||
                  (strcmp(devcmajor,"?")==0) ||
                  (strcmp(devcmajor,"any")==0) ||
                  (strcmp(devcmajor,"ANY")==0))
               devno = NODEV;
            else
            { 
               devno = atoi(devcmajor);
               devno = makedev(devno,0);
            }
         }
         else 
            return EINVAL; 

         if ((devno = cdevsw_add(devno, &ma_cdevsw)) == NODEV) {
            printf("ma_configure: cdevsw add failed --Nodev--\n");
            return ENODEV;
         }

         ma_devno = devno;
         cmajnum = major(devno); 
         begunit = 0; 
         numunit = nboards; 
         ma_config = TRUE; 
#endif OLD
         break;
   } /* switch (op) */

#ifdef MADEBUG
   printf("ma_configure: succeeded, major num %d\n", cmajnum);
#endif
   return ESUCCESS;
}

static int
register_config()
{
	struct controller_config ctlr, *ctlrp;
	struct device_config dev, *devp;
	int status;

	ctlrp = &ctlr;
	devp = &dev;

	ctlrp->revision = CTLR_CONFIG_REVISION;
	ctlrp->devdriver = &madriver;
	strcpy(ctlrp->subsystem_name, mcfgname);
	strcpy(ctlrp->bus_name, MABUSNAME);
	if ((status = create_controller_struct(ctlrp)) != ESUCCESS) {
		maprintf("ma: create controller struct failed status
%d\n",status);
		return(status);
	}

	devp->revision = DEVICE_CONFIG_REVISION;
	devp->controller_num = 0 /*LDBL_WILDNUM*/; /* ldbl_wildnum gets einval */
	strcpy(devp->device_type, "tty");
	strcpy(devp->device_name, "ma");
	strcpy(devp->controller_name, "ma");
	if ((status = create_device_struct(devp)) != ESUCCESS) {
		maprintf("ma: create device struct failed status %d\n",status);
	}
	return(status);
}

static int
register_majornum()
{
	if (nboards == 0)
		return(ENODEV);

	if ((cmajnum = devsw_add(mcfgname, MAJOR_INSTANCE, cmajnum, &ma_cdevsw))
==
				ENODEV) {
		maprintf("ma: Failed to get major number.\n",0);
		return (ENODEV);
	}
	maprintf("ma: Major number is %d\n",cmajnum);
   ma_devno = cmajnum;
   begunit = 0; 
   numunit = nboards; 
   ma_config = TRUE; 
	return(ESUCCESS);
}

static int
maprobe (struct pci_config_hdr *pci, struct controller *ctlr)
{
   u_int boardno;
   register u_short btype, clock;
   register ma_board_t *maboard;
#ifdef MADEBUG
   printf("maprobe: round %d\n",nboards);
#endif

   if (!(pci->command & CMD_MEM_SPACE) || !(pci->command & CMD_BUS_MASTER)) {
      printf("maprobe%d at pci%d not configured by PCI POST code.\n",
                  ctlr->ctlr_num, ctlr->bus_num);
      return(0);
   }

   if (nboards++ > MAXBOARDS)
   {
      printf("maprobe: failed\n");
      return(0);
   } 
   
   boardno = ctlr->ctlr_num; 
   if (nboards && (boardno < nboards))
   {
      if (ma_board[boardno] == NULL)
         ma_board[boardno] = (ma_board_t *)
            MALLOC(maboard, ma_board_t *, sizeof(ma_board_t),
                     M_DEVBUF, M_NOWAIT);
      else
      {
         printf("maprobe: board %d already attached", boardno);
         nboards--;
         return(-1);
      }
      if (ma_board[boardno] == NULL)
      {
         printf("maprobe: board %d failed, enomem\n", boardno);
         nboards--;
         return(-1);
      }
   }
   else
   {
      printf("maprobe: board %d failed, enodev\n", boardno);
      nboards--;
      return(-1);
   }

#ifdef MADEBUG
   printf("maprobe: board struct @ 0x%lx\n",maboard);
#endif
   bzero((char *)maboard, sizeof(ma_board_t));
   maboard->b_attach_flags |= SOFT_STATE_ALLOCATED;
   maboard->b_boardno = boardno;
   maboard->b_ctlr = ctlr;

   /*
   ** get the board info.  Bus dependent!
   */
   btype = -1;
   maboard->b_pci_cfg_hdr = pci;
#ifdef OLDBOARDS
   maboard->b_baseaddr = pci->bar0;
#else
   maboard->b_plx = pci->bar0;
   maboard->b_baseaddr = pci->bar2;
#ifdef MADEBUG
   printf("maprobe: PLX @ 0x%lx, CD2400 starts @ 0x%lx\n",
         maboard->b_plx, maboard->b_baseaddr);
#endif
#endif
   /*
   ** first grab the vendor id and veryify that is is ours.
   ** then grab the device type.
   ** Note that the PCI_VID and PCI_DID are from the pci.h system
   ** header file.
   */
   btype = (u_short) read_io_port(pci->config_base + PCI_VID, 2, 0);
   mb();
   if (btype != MA_VENDOR_ID) {
         printf("maprobe: non-Magma vendor Id. 0x%x\n", btype);
         goto probe_fail;
   }
   btype = (u_short) read_io_port(pci->config_base + PCI_DID, 2, 0);
   mb();
   

   /*
   ** Board specific setup.  This could be done in the attach
   ** routine, but the intent is to keep all PCI configuration
   ** stuff here.
   */

   switch (btype) {
      default:
         printf("maprobe: unrecognized board type %d\n", btype);
         goto probe_fail;
      case MA_PCI16DMA:
      case MA_PCI4DMA:
         /* these two are the old style boards and all have 30Mhz clocks */
         maboard->b_clock = 30000000;
         break;
      case MA_PCI16:
         /* On the new boards, we use the PCI revid field for the clock */
         clock = (u_short) read_io_port(pci->config_base + PCI_REVID, 2, 0);
         maboard->b_clock = (u_int) clock * 1000000;
         maprintf("maprobe: clock speed is %d\n",clock);
         break;
   }
   

   maboard->b_type = (u_int) btype;
   maboard->b_slot = ctlr->slot;
   maboard->b_bus = ctlr->bus_num;
   maboard->b_bname = ctlr->bus_name;
   

   return (1);  

probe_fail:
   bzero((char *)maboard, sizeof(ma_board_t)); /* paranoia */
   FREE (maboard, M_DEVBUF);
   ma_board[boardno] = NULL;
   nboards--;
   return (0);
}

STATIC int
maattach (struct controller *ctlr)
{
   ma_board_t *maboard;
   u_int boardno, port, i;
   ihandler_t handler;        
   struct handler_intr_info info;  
   u_char reg;
   maline_t *mal;
   permset_t *set;

   boardno = ctlr->ctlr_num; 
   if ((maboard = ma_board[boardno]) == NULL)
   {
      printf("maattach: bad board number\n");
      goto attach_fail;
   }

   if (maboard->b_ctlr != ctlr)
   {
      printf("maattach: bad board pointer\n");
      goto attach_fail;
   }

   if ( ! mabaudset )
      mainitbaud();
      
   /* set up interrupt handler */
   handler.ih_bus = ctlr->bus_hd; 
   info.configuration_st = (caddr_t)ctlr; 
   info.config_type = CONTROLLER_CONFIG_TYPE; 
   info.intr = maintr; 
   info.param = (caddr_t)boardno; 
   handler.ih_bus_info = (char *)&info; 
   ma_id_t[boardno] = handler_add(&handler); 
   if (ma_id_t[boardno] == NULL)
   {
      printf("maattach: handler_add failed\n");
      goto attach_fail;
   }
   if (handler_enable(ma_id_t[boardno]) != 0)
   { 
      printf("maattach: handler_enable failed\n");
      handler_del(ma_id_t[boardno]);
      goto attach_fail;
   }
   maboard->b_ihandl = ma_id_t[boardno]; 
   maboard->b_attach_flags |= INTERRUPT_ADDED;

   /* Initialize MUTEX; we will use this MUTEX later on
   ** to lock our instance structure
   **/

   simple_lock_init(&maboard->b_lock); 

   maboard->b_attach_flags |= MUTEX_ADDED;
   reg = (u_char)maboard->b_type;
   /*
   ** Multiple board support.
   */
   switch (reg)
   {
      default:
         printf("ma%d: board type %d not recognized\n",ctlr->ctlr_num, reg);
         goto attach_fail;
      case MA_PCI16:
      case MA_PCI16DMA:
         maboard->b_intr   = cd2400_intr;
         maboard->b_nsports = 16;
         maboard->b_npports =  0;
         maboard->b_2400s = 4;
         maboard->b_1400s = 0;
         maboard->b_iackr  = (NULL);
         maboard->b_iackt  = (NULL);
         maboard->b_iackm  = (NULL);
         if (reg == MA_PCI16DMA) {
            maboard->b_iack24 =
               (u_long)(maboard->b_baseaddr + INTR_ACK_16PCIDMA);
            maboard->b_chips[0] =
               (u_long)maboard->b_baseaddr + BASE_16PCI1DMA;
            maboard->b_chips[1] =
               (u_long)maboard->b_baseaddr + BASE_16PCI2DMA;
            maboard->b_chips[2] =
               (u_long)maboard->b_baseaddr + BASE_16PCI3DMA;
            maboard->b_chips[3] =
               (u_long)maboard->b_baseaddr + BASE_16PCI4DMA;
         } else { /* MAPCI16 */
            maboard->b_iack24 =
               (u_long)(maboard->b_baseaddr + (INTR_ACK_16PCIDMA<<2));
            maboard->b_chips[0] =
               (u_long)maboard->b_baseaddr + (BASE_16PCI1DMA<<2);
            maboard->b_chips[1] =
               (u_long)maboard->b_baseaddr + (BASE_16PCI2DMA<<2);
            maboard->b_chips[2] =
               (u_long)maboard->b_baseaddr + (BASE_16PCI3DMA<<2);
            maboard->b_chips[3] =
               (u_long)maboard->b_baseaddr + (BASE_16PCI4DMA<<2);
         }
         break;
      case MA_PCI4DMA:
         maboard->b_nsports = 4;
         maboard->b_npports =  0;
         maboard->b_2400s = 1;
         maboard->b_1400s = 0;
         maboard->b_iackr  = (NULL);
         maboard->b_iackt  = (NULL);
         maboard->b_iackm  = (NULL);
         maboard->b_iack24  = (u_long)(maboard->b_baseaddr + INTR_ACK_16PCIDMA);
         maboard->b_intr   = cd2400_intr;
         maboard->b_chips[0] =
               (u_long)maboard->b_baseaddr + BASE_16PCI1DMA;
         maboard->b_chips[1] = 0;
         maboard->b_chips[2] = 0;
         maboard->b_chips[3] = 0;

         break;
      case MA_PCI8:
#ifdef NOTDONE
         maboard->b_nsports = 8;
         maboard->b_npports =  0;
         maboard->b_2400s = 0;
         maboard->b_1400s = 2;
         maboard->b_iackr  = (u_long)(maboard->b_baseaddr + INTR_ACKR_8PCI);
         maboard->b_iackt  = (u_long)(maboard->b_baseaddr + INTR_ACKT_8PCI);
         maboard->b_iackm  = (u_long)(maboard->b_baseaddr + INTR_ACKM_8PCI);
         maboard->b_iack24  = (NULL);
         maboard->b_intr   = cd1400_intr;
         maboard->b_chips[0] =
               (u_long)maboard->b_baseaddr + BASE_8PCI1;
         maboard->b_chips[1] =
               (u_long)maboard->b_baseaddr + BASE_8PCI2;
         maboard->b_chips[2] = 0;
         maboard->b_chips[3] = 0;
#endif
         break;
   }

   if (maboard->b_nsports)
   {
      if ((MALLOC(maboard->b_malinebase, maline_t *,
            sizeof(maline_t) * maboard->b_nsports,
            M_DEVBUF, M_NOWAIT)) == NULL)
      {
         printf("ma%d: could not allocate line structures\n",boardno);
         goto attach_fail;
      }
      maboard->b_attach_flags |= MHLINE_ADDED;
      if ((MALLOC(maboard->b_psetbase, permset_t *,
            sizeof(permset_t) * maboard->b_nsports,
            M_DEVBUF, M_NOWAIT)) == NULL)
      {
         printf("ma%d: could not allocate permset structures\n",boardno);
         goto attach_fail;
      }
      maboard->b_attach_flags |= PERMSET_ADDED;
      (void) bzero((caddr_t)maboard->b_malinebase,
                        sizeof(maline_t) * maboard->b_nsports);
      (void) bzero((caddr_t)maboard->b_psetbase,
                        sizeof(permset_t) * maboard->b_nsports);
   }

   /*
   ** now do chip specific setup
   */
   if (maboard->b_type == MA_PCI16) {
      i = (u_int) read_io_port(maboard->b_plx+0x68L, 4, 0);
#ifdef MADEBUG
      printf("ma: plx ICR is 0x%x\n",i);
#endif
      i |= 0x0800;
      write_io_port(maboard->b_plx+0x68L, 4, 0, i);
   }

#ifdef MADEBUG
      printf("ma: attaching %d ports\n",maboard->b_nsports);
#endif

   /* set up line structures */
   mal = maboard->b_malinebase;
   set = maboard->b_psetbase;
   for (port = 0; port < maboard->b_nsports; port++, mal++, set++)
   {
      trace(0x3bad000000000000, (u_long) port);
      trace(0x3bad000000000001, (u_long) mal);
      mal->board = boardno;
      mal->unit = port;
      mal->permset = set;
      mal->clock = maboard->b_clock;
      mal->l_lock = &maboard->b_lock;

      switch (maboard->b_type)
      {
         default:  /* this should not be possible if we got this far! */
            maprintf("ma%d: Fatal err, the sky has fallen twice!", boardno);
            goto attach_fail;

         case MA_PCI16:      
         case MA_PCI16DMA:      
         case MA_PCI4DMA:      
         {
            register u_long cd24;
            trace(0x3bad000000000002, (u_long) mal);
            mal->l_open = cd2400_open;
            mal->l_close = cd2400_close;
            mal->l_param = cd2400_param;
            mal->l_start = cd2400_start;
            mal->l_endbreak = cd2400_endbreak;
            mal->l_mctl = cd2400_mctl;
            mal->chip = CD_2400;
            if ( port < 4 )
               mal->cd2400 = maboard->b_chips[0];
            else if ( port < 8 )
               mal->cd2400 = maboard->b_chips[1];
            else if ( port < 12 )
               mal->cd2400 = maboard->b_chips[2];
            else if ( port < 16 )
               mal->cd2400 = maboard->b_chips[3];

            /* allocate the dma buffers */
            mal->l_rab = (u_int *) kalloc(MADMASIZE);
            mal->l_rbb = (u_int *) kalloc(MADMASIZE);
            mal->l_tab = (u_int *) kalloc(MADMASIZE);
            mal->l_tbb = (u_int *) kalloc(MADMASIZE);
            if ( (mal->l_rab == (u_int *)NULL ) ||
               ( mal->l_rbb == (u_int *)NULL )  ||
               ( mal->l_tab == (u_int *)NULL )  ||
               ( mal->l_tbb == (u_int *)NULL ) )
            {
               maprintf("ma%d: could not allocate dma buffers\n",boardno);
               goto attach_fail;
            }
            if (dma_map_alloc(MADMASIZE,
                  maboard->b_ctlr, &mal->l_dma_hndl_ra, 0) == 0) {
               maprintf("ma%d: could not allocate dma map\n",boardno);
               goto attach_fail;
            }
            if (dma_map_alloc(MADMASIZE,
                  maboard->b_ctlr, &mal->l_dma_hndl_rb, 0) == 0) {
               maprintf("ma%d: could not allocate dma map\n",boardno);
               goto attach_fail;
            }
            if (dma_map_alloc(MADMASIZE,
                  maboard->b_ctlr, &mal->l_dma_hndl_ta, 0) == 0) {
               maprintf("ma%d: could not allocate dma map\n",boardno);
               goto attach_fail;
            }
            if (dma_map_alloc(MADMASIZE,
                  maboard->b_ctlr, &mal->l_dma_hndl_tb, 0) == 0) {
               maprintf("ma%d: could not allocate dma map\n",boardno);
               goto attach_fail;
            }



            cd24 = mal->cd2400;
            trace(0x3bad000000000003, (u_long) cd24);
            trace(0x3bad0000000000f3, (u_long) (gfrcr));
            /* Initialize the cd2400 if 1st port of chip */
            if ((port % 4) == 0)
            {
#ifdef MADEBUGXXXX
               reg = (u_char) read_io_port(cd24+gfrcr, 1, 0);
               mb();
               trace(0x3bad000000000004, (u_long) reg);
#endif
               /* clear gfcr */
               write_io_port(cd24+gfrcr, 1, 0, 0);
               mb();

               /* reset chip */
               write_io_port(cd24+ccr, 1, 0, CCR_RSTALL);
               mb();
               trace(0x3bad000000000005, (u_long) port);

               /* it takes ~500 mics to reset, give it 2X that */
               DELAY ( 1000 ); /* wait for gfrcr to be non-zero */
               for ( i = 0; i < 10; i++ )
               {
                  reg = (u_char) read_io_port(cd24+gfrcr, 1, 0);
                  mb();
                  if (reg) break;
                  maprintf ( ".",mal);
                  DELAY (1000); /* wait for gfrcr to be non-0 */
               }
               reg = (u_char) read_io_port(cd24+gfrcr, 1, 0);
               mb();
               trace(0x3bad000000000006, (u_long) reg);
               if (reg == 0)
               {
                  printf ("ma: failed to reset\n");
                  trace(0x3bad000000000007, (u_long) reg);
                  goto attach_fail;
               }
            }
      
            mal->revision = reg;
 
            trace(0x3bad000000000008, (u_long) port);
            cd2400_config(mal);
            break;
         } /* cases ma_pci4dma and ma_pci16dma */

#ifdef NOTDONE
         case MA_PCI8:      
         {
            register u_long cd14;
            trace(0x3bad000000000009, (u_long) mal);
            mal->l_open = cd1400_open;
            mal->l_close = cd1400_close;
            mal->l_param = cd1400_param;
            mal->l_start = cd1400_start;
            mal->l_endbreak = cd1400_endbreak;
            mal->l_mctl = cd1400_mctl;
            mal->chip = CD_1400;
            if ( port < 4 )
               mal->cd1400 = maboard->b_chips[0];
            else if ( port < 8 )
               mal->cd1400 = maboard->b_chips[1];
            else if ( port < 12 )
               mal->cd1400 = maboard->b_chips[2];
            else if ( port < 16 )
               mal->cd1400 = maboard->b_chips[3];

            cd14 = mal->cd1400;
            /* Initialize the cd1400 if 1st port of chip */
            if ((port % 4) == 0)
            {
               write_io_port(cd14+GFRCR, 1, 0, 0); /* clear GFRCR */
               mb();

               /* reset chip */
               write_io_port(cd14+CCR, 1, 0, CCR_FULL_RESET);
               mb();

               /* it takes ~500 mics to reset, give it 2X that */
               DELAY ( 1000 ); /* wait for gfrcr to be non-zero */
               for ( i = 0; i < 10; i++ )
               {
                  reg = (u_char) read_io_port(cd14+GFRCR, 1, 0);
                  mb();
                  if (reg) break;
                  maprintf ( ".",mal);
                  DELAY (1000); /* wait for gfrcr to be non-0 */
               }
               reg = (u_char) read_io_port(cd14+GFRCR, 1, 0);
               mb();
               if (reg == 0)
               {
                  maprintf ("ma%d: failed to reset\n", boardno);
                  return(-1);
               }

               /* set chip id in [R,T,M]ICR global registers */
               switch (port) {
                  case 0:
                     write_io_port(cd14+RICR, 1, 0, 0x01);
                     mb();
                     write_io_port(cd14+TICR, 1, 0, 0x02);
                     mb();
                     write_io_port(cd14+MICR, 1, 0, 0x03);
                     break;
                  case 4:
                     write_io_port(cd14+RICR, 1, 0, 0x11);
                     mb();
                     write_io_port(cd14+TICR, 1, 0, 0x12);
                     mb();
                     write_io_port(cd14+MICR, 1, 0, 0x13);
                     break;
                  case 8:
                     write_io_port(cd14+RICR, 1, 0, 0x21);
                     mb();
                     write_io_port(cd14+TICR, 1, 0, 0x22);
                     mb();
                     write_io_port(cd14+MICR, 1, 0, 0x23);
                     break;
                  case 12:
                     write_io_port(cd14+RICR, 1, 0, 0x31);
                     mb();
                     write_io_port(cd14+TICR, 1, 0, 0x32);
                     mb();
                     write_io_port(cd14+MICR, 1, 0, 0x33);
                     break;
               }
               mb();
            }

            reg = (u_char) read_io_port(cd14+GFRCR, 1, 0);
            mb();
            mal->revision = reg;
            cd1400_config (mal); /* configure the port */
         } /* case ma_pci8 */
#endif NOTDONE

      }
      trace(0x3bad00000000000a, (u_long) port);
   } /* for port */

#ifdef MADEBUG
   printf("\nma: %s revision 0x%x\n",
               maboard->b_malinebase->chip == CD_1400 ? "CD1400" : "CD2400",
               maboard->b_malinebase->revision);
#endif

   return (0);

attach_fail:
   printf("MAGMA: could not attach board %d",boardno);
   (void)madettach(NULL, ctlr);
   return (-1);
}

static int
madettach (struct bus *bus, struct controller *ctlr)
{
   u_int instance, port;
   register ma_board_t *maboard;
   register maline_t *mal;


   instance = ctlr->ctlr_num;
   if (instance < 0 || instance > nboards)
      return (ENODEV);

   maprintf("ma%d: is being detached.", instance);
   nboards--;

   maboard = (ma_board_t *) ma_board[instance];

   if (maboard == NULL) {
      maprintf("ma%d: detach: could not get state", instance);
      return (ENODEV);
   }

   if (maboard->b_attach_flags & SERIAL_PORT_MUTEXES) {
      /* reset the chips to quiesce interrupts */
      switch (maboard->b_type) {
         default:
            maprintf("ma: madetach, bad board type %d\n", maboard->b_type);
            break;
         case MA_PCI16:
            /* Clear plx interrupt enable */
            port = (u_int) read_io_port(maboard->b_plx+0x68L, 4, 0);
            port &= ~0x0800;
            write_io_port(maboard->b_plx+0x68L, 4, 0, port);
            /* No break */
         case MA_PCI16DMA:
         case MA_PCI4DMA:
            for (port = 0; port < maboard->b_2400s; port++) {
               write_io_port(maboard->b_chips[port]+ccr, 1, 0, CCR_RSTALL);
               mb();
            }
            break;
      }

      maboard->b_attach_flags &= ~SERIAL_PORT_MUTEXES;
   }

#if 0
   if (maboard->b_attach_flags & HANDLE_ADDED) {
      ddi_dma_free (maboard->dvma.dvma_handle);
      maboard->dvma.dvma_handle = NULL;
      maboard->b_attach_flags &= ~HANDLE_ADDED;
   }

   if (maboard->b_attach_flags & SYNC_ADDED)
      delete_sync(maboard);

   if (maboard->b_attach_flags & DVMA_ADDED) {
      FREE (maboard->ma_dvma.dvma_address, M_DEVBUF);
      maboard->ma_dvma.dvma_address = NULL;

      maboard->b_attach_flags &= ~DVMA_ADDED;
   }
#endif

   if (maboard->b_attach_flags & PERMSET_ADDED) {
      FREE (maboard->b_psetbase, M_DEVBUF);
      maboard->b_psetbase = NULL;
      maboard->b_attach_flags &= ~PERMSET_ADDED;
   }

   if (maboard->b_attach_flags & MHLINE_ADDED) {
      FREE (maboard->b_malinebase, M_DEVBUF);
      maboard->b_malinebase = NULL;
      maboard->b_attach_flags &= ~MHLINE_ADDED;
   }


   if (maboard->b_attach_flags & MUTEX_ADDED) {
      simple_lock_terminate(&maboard->b_lock);
      maboard->b_attach_flags &= ~MUTEX_ADDED;
   }

   if (maboard->b_attach_flags & INTERRUPT_ADDED) {
      if (handler_disable(maboard->b_ihandl) != 0)
         return(ENXIO);
      (void)handler_del(maboard->b_ihandl);
      ma_id_t[instance] = maboard->b_ihandl = NULL;
      maboard->b_attach_flags &= ~INTERRUPT_ADDED;
   }

   if (maboard->b_attach_flags & SOFT_STATE_ALLOCATED) {
      /* remove this board from our polling board array */
      for( port = 0; port < nboards; port++ ) {
         if( ma_board[port] == maboard ) {
            ma_board[port] = NULL;
            break;
         }
      }
      bzero((char *)maboard, sizeof(ma_board_t));
      FREE (maboard, M_DEVBUF);
   }

   return ( 0 );
}

3347.3poke from Bruce...HYDRA::KENYONThe Foundation of Science...FictionFri Mar 21 1997 14:5111
From:   SMTP%"[email protected]"
To:     [email protected]
CC:
Subj:   Re: configure_driver returns EINVAL (errno 22)

Hello John,

  Has there been any progress?  How about dropping
me a line just to let me kow you are there?
-bruce

3347.4my reply...HYDRA::KENYONThe Foundation of Science...FictionFri Mar 21 1997 14:5219
From:   HYDRA::AXPDEVELOPER "[email protected]"
To:     SMTP%"[email protected]"
CC:     AXPDEVELOPER
Subj:   Re: configure_driver returns EINVAL (errno 22)

Bruce,

Device drivers are not an area where we have direct experience/expertise.
That was the reason for John's delay -- he was trying to find a person
in engineering to handle your request.

I have located an engineering resource, and will make sure John knows to
follow up on your behalf.

Sorry for the delay.

Jeff Kenyon
Software Partners Engineering

3347.5request for driver help sent...HYDRA::KENYONThe Foundation of Science...FictionFri Mar 21 1997 14:5816
From:   HYDRA::AXPDEVELOPER "[email protected]"
To:     DECWET::VOBA
CC:     AXPDEVELOPER
Subj:   RE: Alpha Developer note #3347...

Can you take a look at note 3347 in the AXP-DEVELOPER conference?  This
SHOULD be up your alley if I understand the arrangement.

I have not "met" you, and don't have your name properly (so I won't try
to guess it).  could you send it to me?  Also -- is this the type of
problem you can help us with?

thanks,

-jeff

3347.6DECWET::VOBAFri Mar 21 1997 15:544
    Re .5, sorry but i can't help with UNIX questions.  Our core competency
    is Windows NT kernel driver and hardware options.
    
    --svb
3347.7HYDRA::SCHAFERMark Schafer, SPE MROFri Apr 04 1997 15:404
    this call was closed after Navin Modi investigated and learned that
    Karl Ebner had helped the partner.
    
    \Mark
3347.8Issue resolved, Call closedHYDRA::MODIFri Apr 04 1997 15:4510
    I escalated the issue to Mark Parenti in ZK. He assigned to the
    Karl Ebner (wasted::ebner) in UNIX device driver development group.
    
    Karl informed that he had already provided resolution to MAGNA for this
    particular issue.
    
    I confirmed with Bruce@MAGNA and he confirmed that the reported issue
    was resolved.
    
    -Navin
3347.9closedHYDRA::MODIFri Apr 04 1997 15:481
    .7 and .8 notes collision.7 and .8 :   notes collison..