Ejemplo n.º 1
0
/* Set up the struct device associated with this card.  Called after
 * probing succeeds.
 */
__initfunc(int arc20020_found(struct device *dev,int ioaddr,int airq))
{
  struct arcnet_local *lp;
  
  /* reserve the irq */
  if (request_irq(airq,&arcnet_interrupt,0,"arcnet (COM20020)",dev))
    {
      BUGMSG(D_NORMAL,"Can't get IRQ %d!\n",airq);
      return -ENODEV;
    }
  dev->irq=airq;
  
  /* reserve the I/O region - guaranteed to work by check_region */
  request_region(ioaddr,ARCNET_TOTAL_SIZE,"arcnet (COM20020)");
  dev->base_addr=ioaddr;
  
  dev->mem_start=dev->mem_end=dev->rmem_start=dev->rmem_end=(long)NULL;

  /* Initialize the rest of the device structure. */

  dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
  if (dev->priv == NULL)
    {
      free_irq(airq,dev);
      release_region(ioaddr,ARCNET_TOTAL_SIZE);
      return -ENOMEM;
    }

  memset(dev->priv,0,sizeof(struct arcnet_local));
  lp=(struct arcnet_local *)(dev->priv);
  lp->card_type = ARC_20020;
  lp->card_type_str = "COM 20020";

  lp->arcnet_reset=arc20020_reset;
  lp->asetmask=arc20020_setmask;
  lp->astatus=arc20020_status;
  lp->acommand=arc20020_command;
  lp->en_dis_able_TX=arc20020_en_dis_able_TX;
  lp->openclose_device=arc20020_openclose;
  lp->prepare_tx=arc20020_prepare_tx;
  lp->inthandler=arc20020_inthandler;

  dev->set_multicast_list = arc20020_set_mc_list;

  /* Fill in the fields of the device structure with generic
   * values.
   */
  arcnet_setup(dev);

  /* And now fill particular fields with arcnet values */
  dev->mtu=1500; /* completely arbitrary - agrees with ether, though */
  dev->hard_header_len=sizeof(struct ClientData);
  lp->sequence=1;
  lp->recbuf=0;

  BUGMSG(D_DURING,"ClientData header size is %d.\n",
	 sizeof(struct ClientData));
  BUGMSG(D_DURING,"HardHeader size is %d.\n",
	 sizeof(struct archdr));

  /* get and check the station ID from offset 1 in shmem */
  lp->timeout = dev->dev_addr[3] & 3; dev->dev_addr[3]=0;
  lp->backplane =dev->dev_addr[1] & 1; dev->dev_addr[1]=0;
  lp->setup = (dev->dev_addr[2] & 7) << 1; dev->dev_addr[2]=0;

  if (dev->dev_addr[0])
    lp->stationid=dev->dev_addr[0];
  else
    lp->stationid=inb(ioaddr+8);            /* FIX ME - We should check that
					       this is valid before using it */
  lp->config = 0x21 | (lp->timeout << 3) | (lp->backplane << 2);
  /* Default 0x38 + register: Node ID */
  SETCONF;
  outb(lp->stationid, ioaddr+7);

  REGSETUP;
  SETCONF;
  outb(lp->setup, ioaddr+7);

  if (!lp->stationid)
    BUGMSG(D_NORMAL,"WARNING!  Station address 00 is reserved "
	   "for broadcasts!\n");
  else if (lp->stationid==255)
    BUGMSG(D_NORMAL,"WARNING!  Station address FF may confuse "
	   "DOS networking programs!\n");
  dev->dev_addr[0]=lp->stationid;

  BUGMSG(D_NORMAL,"ARCnet COM20020: station %02Xh found at %03lXh, IRQ %d.\n",
	 lp->stationid, dev->base_addr,dev->irq);

  if (lp->backplane)
    BUGMSG (D_NORMAL, "Using backplane mode.\n");

  if (lp->timeout != 3)
    BUGMSG (D_NORMAL, "Using Extended Timeout value of %d.\n",lp->timeout);
  if (lp->setup)
    {
      BUGMSG (D_NORMAL, "Using CKP %d - Data rate %s.\n",
	      lp->setup >>1,clockrates[lp->setup >> 1] );
    }
Ejemplo n.º 2
0
/* Set up the struct device associated with this card.  Called after
 * probing succeeds.
 */
__initfunc(int arcrimi_found(struct device *dev,int node,int airq, u_long shmem))
{
  struct arcnet_local *lp;
  u_long first_mirror,last_mirror;
  int mirror_size;

  /* reserve the irq */
  if (request_irq(airq,&arcnet_interrupt,0,"arcnet (RIM I)",dev))
    {
      BUGMSG(D_NORMAL,"Can't get IRQ %d!\n",airq);
      return -ENODEV;
    }
  dev->irq=airq;

  dev->base_addr=0;
  writeb(TESTvalue,shmem);
  writeb(node,shmem+1);	/* actually the node ID */

  /* find the real shared memory start/end points, including mirrors */
#define BUFFER_SIZE (512)
#define MIRROR_SIZE (BUFFER_SIZE*4)

  /* guess the actual size of one "memory mirror" - the number of
   * bytes between copies of the shared memory.  On most cards, it's
   * 2k (or there are no mirrors at all) but on some, it's 4k.
   */
  mirror_size=MIRROR_SIZE;
  if (readb(shmem)==TESTvalue
      && readb(shmem-mirror_size)!=TESTvalue
      && readb(shmem-2*mirror_size)==TESTvalue)
    mirror_size*=2;

  first_mirror=last_mirror=shmem;
  while (readb(first_mirror)==TESTvalue) first_mirror-=mirror_size;
  first_mirror+=mirror_size;

  while (readb(last_mirror)==TESTvalue) last_mirror+=mirror_size;
  last_mirror-=mirror_size;

  dev->mem_start=first_mirror;
  dev->mem_end=last_mirror+MIRROR_SIZE-1;
  dev->rmem_start=dev->mem_start+BUFFER_SIZE*0;
  dev->rmem_end=dev->mem_start+BUFFER_SIZE*2-1;

  /* Initialize the rest of the device structure. */

  dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
  if (dev->priv == NULL)
    {
      free_irq(airq,dev);
      return -ENOMEM;
    }
  memset(dev->priv,0,sizeof(struct arcnet_local));
  lp=(struct arcnet_local *)(dev->priv);
  lp->card_type = ARC_RIM_I;
  lp->card_type_str = "RIM I";
  lp->arcnet_reset=arcrimi_reset;
  lp->asetmask=arcrimi_setmask;
  lp->astatus=arcrimi_status;
  lp->acommand=arcrimi_command;
  lp->openclose_device=arcrimi_openclose;
  lp->prepare_tx=arcrimi_prepare_tx;
  lp->inthandler=arcrimi_inthandler;

  /* Fill in the fields of the device structure with generic
   * values.
   */
  arcnet_setup(dev);

  /* And now fill particular fields with arcnet values */
  dev->mtu=1500; /* completely arbitrary - agrees with ether, though */
  dev->hard_header_len=sizeof(struct ClientData);
  lp->sequence=1;
  lp->recbuf=0;

  BUGMSG(D_DURING,"ClientData header size is %d.\n",
	 sizeof(struct ClientData));
  BUGMSG(D_DURING,"HardHeader size is %d.\n",
	 sizeof(struct archdr));

  /* get and check the station ID from offset 1 in shmem */
  lp->stationid = readb(first_mirror+1);

  if (lp->stationid==0)
    BUGMSG(D_NORMAL,"WARNING!  Station address 00 is reserved "
	   "for broadcasts!\n");
  else if (lp->stationid==255)
    BUGMSG(D_NORMAL,"WARNING!  Station address FF may confuse "
	   "DOS networking programs!\n");
  dev->dev_addr[0]=lp->stationid;

  BUGMSG(D_NORMAL,"ARCnet RIM I: station %02Xh found at IRQ %d, "
	 "ShMem %lXh (%ld*%d bytes).\n",
	 lp->stationid,
	 dev->irq, dev->mem_start,
	 (dev->mem_end-dev->mem_start+1)/mirror_size,mirror_size);

  return 0;
}