/* 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] ); }
/* 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; }