Esempio n. 1
0
static int do_mem_probe(u_long base, u_long num,
			int (*is_valid)(u_long), int (*do_cksum)(u_long))
{
    u_long i, j, bad, fail, step;

    printk(KERN_INFO "cs: memory probe 0x%06lx-0x%06lx:",
	   base, base+num-1);
    bad = fail = 0;
    step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
    for (i = j = base; i < base+num; i = j + step) {
	if (!fail) {	
	    for (j = i; j < base+num; j += step)
		if ((check_mem_region(j, step) == 0) && is_valid(j))
		    break;
	    fail = ((i == base) && (j == base+num));
	}
	if (fail) {
	    for (j = i; j < base+num; j += 2*step)
		if ((check_mem_region(j, 2*step) == 0) &&
		    do_cksum(j) && do_cksum(j+step))
		    break;
	}
	if (i != j) {
	    if (!bad) printk(" excluding");
	    printk(" %#05lx-%#05lx", i, j-1);
	    sub_interval(&mem_db, i, j-i);
	    bad += j-i;
	}
    }
    printk(bad ? "\n" : " clean.\n");
    return (num - bad);
}
Esempio n. 2
0
static int __devinit chd_pci_reserve_mem(struct crystalhd_adp *pinfo)
{
	int rc;
	unsigned long bar2 = pci_resource_start(pinfo->pdev, 2);
	uint32_t mem_len   = pci_resource_len(pinfo->pdev, 2);
	unsigned long bar0 = pci_resource_start(pinfo->pdev, 0);
	uint32_t i2o_len   = pci_resource_len(pinfo->pdev, 0);

	BCMLOG(BCMLOG_SSTEP, "bar2:0x%lx-0x%08x  bar0:0x%lx-0x%08x\n",
	       bar2, mem_len, bar0, i2o_len);

	rc = check_mem_region(bar2, mem_len);
	if (rc) {
		BCMLOG_ERR("No valid mem region...\n");
		return -ENOMEM;
	}

	pinfo->addr = ioremap_nocache(bar2, mem_len);
	if (!pinfo->addr) {
		BCMLOG_ERR("Failed to remap mem region...\n");
		return -ENOMEM;
	}

	pinfo->pci_mem_start = bar2;
	pinfo->pci_mem_len   = mem_len;

	rc = check_mem_region(bar0, i2o_len);
	if (rc) {
		BCMLOG_ERR("No valid mem region...\n");
		return -ENOMEM;
	}

	pinfo->i2o_addr = ioremap_nocache(bar0, i2o_len);
	if (!pinfo->i2o_addr) {
		BCMLOG_ERR("Failed to remap mem region...\n");
		return -ENOMEM;
	}

	pinfo->pci_i2o_start = bar0;
	pinfo->pci_i2o_len   = i2o_len;

	rc = pci_request_regions(pinfo->pdev, pinfo->name);
	if (rc < 0) {
		BCMLOG_ERR("Region request failed: %d\n", rc);
		return rc;
	}

	BCMLOG(BCMLOG_SSTEP, "Mapped addr:0x%08lx  i2o_addr:0x%08lx\n",
	       (unsigned long)pinfo->addr, (unsigned long)pinfo->i2o_addr);

	return 0;
}
Esempio n. 3
0
// 모듈을 커널 내부로 삽입
// 모듈 프로그램의 핵심적인 목적은 커널 내부로 들어가서 서비스를 제공받는 것이므로
// 커널 내부로 들어가는 init()을 먼저 시작한다.
// 응용 프로그램은 소스 내부에서 정의되지 않은 많은 함수를 사용한다. 그것은 외부
// 라이브러리가 컴파일 과정에서 링크되어 사용되기 때문이다. 모듈 프로그램은 커널
// 내부하고만 링크되기 때문에 커널에서 정의하고 허용하는 함수만을 사용할 수 있다.
int cis_init(void) 
{
	int result;

	result = register_chrdev(CIS_MAJOR,CIS_NAME,&cis_fops);

	if(result < 0) {
		printk(KERN_WARNING"Can't get major %d\n",CIS_MAJOR);
		return result;
	} 

	/* FPGA MEMORY MAPPING */
	flag_ioremap = ioremap(FLAG_ADDRESS, FLAG_ADDRESS_RANGE);
	if(!check_mem_region((unsigned long)flag_ioremap, FLAG_ADDRESS_RANGE))
		request_mem_region((unsigned long)flag_ioremap, FLAG_ADDRESS_RANGE,CIS_NAME);
	else {
		printk("driver : unable to use the FLAG address\n");
		return 0;
	}

	// DATA Mapping
	data_ioremap = ioremap(DATA_ADDRESS, DATA_ADDRESS_RANGE);
	if(!check_mem_region((unsigned long)data_ioremap, DATA_ADDRESS_RANGE))
		request_mem_region((unsigned long)data_ioremap, DATA_ADDRESS_RANGE,CIS_NAME);
	else {
		printk("driver: unable to use the DATA Address\n");
		return 0;
	}

	//SUB Sampling Memory Mapping
	sub_sampling = ioremap(SUBSAMPLING_ADDRESS,FLAG_ADDRESS_RANGE);
	if(!check_mem_region((unsigned long)sub_sampling, FLAG_ADDRESS_RANGE))
		request_mem_region((unsigned long)sub_sampling, FLAG_ADDRESS_RANGE,CIS_NAME);
	else {
		printk("driver : unable to use the SUBSAMPLING_ADDRESS\n");
		return 0;
	}

	//MODE Memory Mapping
	mode_select = ioremap(MODE_ADDRESS,FLAG_ADDRESS_RANGE);
	if(!check_mem_region((unsigned long)mode_select, FLAG_ADDRESS_RANGE))
		request_mem_region((unsigned long)mode_select, FLAG_ADDRESS_RANGE,CIS_NAME);
	else {
		printk("driver : unable to use the MODE address\n");
		return 0;
	}

	printk("driver: Insert CIS module succeed Major Number:%d\n",CIS_MAJOR);

	return 0;
}
/*
 * ioremap and request iomem
 */
static int register_tsiomem(struct tsc_dev *devp)
{
    char *addr;
    int ret;
    struct resource *res;

    ret = check_mem_region(REGS_BASE, REGS_SIZE);
    TSC_DBG("%s: check_mem_region return: %d\n", __func__, ret);
    res = request_mem_region(REGS_BASE, REGS_SIZE, "ts regs");
    if (res == NULL)    {
        TSC_ERR("%s: cannot reserve region for register\n", __func__);
        goto err;
    }
    devp->regs = res;

    addr = ioremap(REGS_BASE, REGS_SIZE);
    if (!addr) {
        TSC_ERR("%s: cannot map region for register\n", __func__);
        goto err;
    }

    devp->regsaddr = addr;
    TSC_DBG("%s: devp->regsaddr: 0x%08x\n", __func__, (unsigned int)devp->regsaddr);

    return 0;

err:
    if (devp->regs) {
        release_resource(devp->regs);
        devp->regs = NULL;
    }
    return -1;
}
Esempio n. 5
0
int pnp_check_mem(struct pnp_dev * dev, int idx)
{
	int tmp;
	struct pnp_dev *tdev;
	unsigned long *addr, *end, *taddr, *tend;
	addr = &dev->res.mem_resource[idx].start;
	end = &dev->res.mem_resource[idx].end;

	/* if the resource doesn't exist, don't complain about it */
	if (dev->res.mem_resource[idx].flags & IORESOURCE_UNSET)
		return 1;

	/* check if the resource is already in use, skip if the
	 * device is active because it itself may be in use */
	if(!dev->active) {
		if (check_mem_region(*addr, length(addr,end)))
			return 0;
	}

	/* check if the resource is reserved */
	for (tmp = 0; tmp < 8; tmp++) {
		int raddr = pnp_reserve_mem[tmp << 1];
		int rend = pnp_reserve_mem[(tmp << 1) + 1] + raddr - 1;
		if (ranged_conflict(addr,end,&raddr,&rend))
			return 0;
	}

	/* check for internal conflicts */
	for (tmp = 0; tmp < PNP_MAX_MEM && tmp != idx; tmp++) {
		if (dev->res.mem_resource[tmp].flags & IORESOURCE_MEM) {
			taddr = &dev->res.mem_resource[tmp].start;
			tend = &dev->res.mem_resource[tmp].end;
			if (ranged_conflict(addr,end,taddr,tend))
				return 0;
		}
	}

	/* check for conflicts with other pnp devices */
	pnp_for_each_dev(tdev) {
		if (tdev == dev)
			continue;
		for (tmp = 0; tmp < PNP_MAX_MEM; tmp++) {
			if (tdev->res.mem_resource[tmp].flags & IORESOURCE_MEM) {
				if (pnp_mem_flags(dev, tmp) & IORESOURCE_DISABLED)
					continue;
				taddr = &tdev->res.mem_resource[tmp].start;
				tend = &tdev->res.mem_resource[tmp].end;
				if (ranged_conflict(addr,end,taddr,tend))
					return 0;
			}
		}
	}

	return 1;
}
Esempio n. 6
0
int segcounter_open(struct inode *inode, struct file *flip) {
    if (segcounter_usage !=0) return -EBUSY;

    counter_data_input = ioremap(COUNTER_ADDRESS_DATA_INPUT, COUNTER_ADDRESS_DATA_RANGE);
    counter_data_output = ioremap(COUNTER_ADDRESS_DATA_OUTPUT, COUNTER_ADDRESS_DATA_RANGE);
    counter_start = ioremap(COUNTER_ADDRESS_START, COUNTER_ADDRESS_START_RANGE);
    counter_set = ioremap(COUNTER_ADDRESS_SET, COUNTER_ADDRESS_SET_RANGE);

    if (!check_mem_region((unsigned long)counter_data_input, COUNTER_ADDRESS_DATA_RANGE) &&
        !check_mem_region((unsigned long)counter_data_output, COUNTER_ADDRESS_DATA_RANGE) &&
        !check_mem_region((unsigned long)counter_start, COUNTER_ADDRESS_START_RANGE) &&
        !check_mem_region((unsigned long)counter_set, COUNTER_ADDRESS_SET_RANGE)) {
        request_region((unsigned long)counter_data_input, COUNTER_ADDRESS_DATA_RANGE, SEGCOUNTER_NAME);
        request_region((unsigned long)counter_data_output, COUNTER_ADDRESS_DATA_RANGE, SEGCOUNTER_NAME);
        request_region((unsigned long)counter_start, COUNTER_ADDRESS_START_RANGE, SEGCOUNTER_NAME);
        request_region((unsigned long)counter_set, COUNTER_ADDRESS_SET_RANGE, SEGCOUNTER_NAME);
    } else {
        printk("Driver: Unable To Register This\n");
    }

    segcounter_usage = 1;
    return 0;
}
int
eicon_isa_find_card(int Mem, int Irq, char * Id)
{
	int primary = 1;
	unsigned long amem;

	if (!strlen(Id))
		return -1;

	if (Mem == -1)
		return -1;

	/* Check for valid membase address */
	if ((Mem < 0x0c0000) ||
	    (Mem > 0x0fc000) ||
	    (Mem & 0xfff)) { 
		printk(KERN_WARNING "eicon_isa: illegal membase 0x%x for %s\n",
			 Mem, Id);
		return -1;
	}
	if (check_mem_region(Mem, RAMSIZE)) {
		printk(KERN_WARNING "eicon_isa_boot: memory at 0x%x already in use.\n", Mem);
		return -1;
	}

	amem = (unsigned long) ioremap(Mem, RAMSIZE);
        writew(0x55aa, amem + 0x402);
        if (readw(amem + 0x402) != 0x55aa) primary = 0;
	writew(0, amem + 0x402);
	if (readw(amem + 0x402) != 0) primary = 0;

	printk(KERN_INFO "Eicon: Driver-ID: %s\n", Id);
	if (primary) {
		printk(KERN_INFO "Eicon: assuming pri card at 0x%x\n", Mem);
		writeb(0, amem + 0x3ffe);
		iounmap((unsigned char *)amem);
		return EICON_CTYPE_ISAPRI;
	} else {
		printk(KERN_INFO "Eicon: assuming bri card at 0x%x\n", Mem);
		writeb(0, amem + 0x400);
		iounmap((unsigned char *)amem);
		return EICON_CTYPE_ISABRI;
	}
	return -1;
}
Esempio n. 8
0
static int papilio_fifo_init(void)
{
	dev_t dev = 0;
	struct cdev cdev ;
	int result ;
	setupGPMCClock();
	if(setupGPMCNonMuxed() < 0 ){
		printk(KERN_WARNING "%s: can't initialize gpmc \n",gDrvrName);
		return -1;		
	}

	if (check_mem_region(FPGA_BASE_ADDR, 256 * sizeof(short)) ){
	    printk("%s: memory already in use\n", gDrvrName);
	    return -EBUSY;
	}
	

	if (gDrvrMajor) {
		dev = MKDEV(gDrvrMajor, gDrvrMinor);
		result = register_chrdev(gDrvrMajor, gDrvrName, &papilio_fifo_ops);
	} else {
		result = alloc_chrdev_region(&dev, gDrvrMinor, nbDevices, gDrvrName);
		gDrvrMajor = MAJOR(dev);
     		cdev_init(&cdev, &papilio_fifo_ops);
         	result = cdev_add (&cdev, MKDEV(gDrvrMajor, 0), 1);
         /* Fail gracefully if need be */
		 if (result)
		         printk(KERN_NOTICE "Error %d adding papilio_fifo%d", result, 0);
	}
	if (result < 0) {
		printk(KERN_WARNING "%s: can't get major %d\n",gDrvrName,gDrvrMajor);
		return -1;
	}
	printk(KERN_INFO"%s: Init: module registered with major number %d \n", gDrvrName, gDrvrMajor);

	printk("%s driver is loaded\n", gDrvrName);

	return 0;
}
static __init int sja1000_gw2_init_module(void)
{
	int i;
	struct net_device *dev;
	void *base;

	if (clk < 1000 ) /* MHz command line value */
		clk *= 1000000;

	if (clk < 1000000 ) /* kHz command line value */
		clk *= 1000;

	printk(KERN_INFO "%s - %s driver v%s (%s)\n",
	       chip_name, drv_name, drv_version, drv_reldate);
	printk(KERN_INFO "%s - options [clk %d.%06d MHz] [restart_ms %dms] [debug %d]\n",
	       chip_name, clk/1000000, clk%1000000, restart_ms, debug);

	for (i = 0; base_addr[i]; i++) {
		printk(KERN_DEBUG "%s: checking for %s on address 0x%X ...\n",
		       chip_name, chip_name, base_addr[i]);
		if (check_mem_region(base_addr[i], RSIZE)) {
			printk(KERN_ERR "%s: memory already in use\n", chip_name);
			sja1000_gw2_cleanup_module();
			return -EBUSY;
		}
		request_mem_region(base_addr[i], RSIZE, chip_name);
		base = ioremap(base_addr[i], RSIZE);
		dev = sja1000_gw2_probe((uint32_t)base, irq[i], speed[i], btr[i], rx_probe[i], clk, debug, restart_ms);
		if (dev != NULL) {
			can_dev[i] = dev;
			sja1000_proc_init(drv_name, can_dev, MAX_CAN);
		} else {
			can_dev[i] = NULL;
			iounmap(base);
			release_mem_region(base_addr[i], RSIZE);
		}
	}
	return 0;
}
Esempio n. 10
0
/* initialisation of the driver: getting resources etc. */
static int __init dt330_init_one(struct pci_dev *dev, const struct pci_device_id *ent) {
    static int dev_count = 0;

    /* make sure there is only one card */
    dev_count++;
    if (dev_count > 1) {
        printk ("this driver only supports 1 board\n");
        return -ENODEV;
    }

    /* get resources */
    irq_number = dev->irq;
    mem_base0 = pci_resource_start(dev, 0);

    /* register resources with kernel */
    if (pci_enable_device (dev))
        return -EIO;
    if (check_mem_region(mem_base0,IOCARD_SPACE+1)) {
        printk("dt330: memory at %x already in use\n",mem_base0);
        goto out1;
    }
    request_mem_region(mem_base0,IOCARD_SPACE+1, IOCARD_NAME);
    /* get virtual address for the pci mem */
    cardspace = (char *) ioremap_nocache(mem_base0,IOCARD_SPACE+1);
    printk("dt330: got new mem pointer: %p\n",cardspace);
    /* register char devices with kernel */
    if (register_chrdev(IOCARD_MAJOR, IOCARD_NAME, &dt330_fops)<0) {
        printk("Error in registering major device %d\n",IOCARD_MAJOR);
        goto out2;
    }

    return 0; /* everything is fine */
out2:
    iounmap(cardspace);
    release_mem_region(mem_base0,IOCARD_SPACE+1);
out1:
    return -EBUSY;
}
Esempio n. 11
0
/*
 * We cannot probe for a RIM I card; one reason is I don't know how to reset
 * them.  In fact, we can't even get their node ID automatically.  So, we
 * need to be passed a specific shmem address, IRQ, and node ID.
 */
static int __init arcrimi_probe(struct net_device *dev)
{
	BUGLVL(D_NORMAL) printk(VERSION);
	BUGLVL(D_NORMAL) printk("E-mail me if you actually test the RIM I driver, please!\n");

	BUGMSG(D_NORMAL, "Given: node %02Xh, shmem %lXh, irq %d\n",
	       dev->dev_addr[0], dev->mem_start, dev->irq);

	if (dev->mem_start <= 0 || dev->irq <= 0) {
		BUGMSG(D_NORMAL, "No autoprobe for RIM I; you "
		       "must specify the shmem and irq!\n");
		return -ENODEV;
	}
	if (check_mem_region(dev->mem_start, BUFFER_SIZE)) {
		BUGMSG(D_NORMAL, "Card memory already allocated\n");
		return -ENODEV;
	}
	if (dev->dev_addr[0] == 0) {
		BUGMSG(D_NORMAL, "You need to specify your card's station "
		       "ID!\n");
		return -ENODEV;
	}
	return arcrimi_found(dev);
}
Esempio n. 12
0
int setupGPMCClock(void){
	volatile unsigned int * prcm_reg_pointer ;
	printk("Configuring Clock for GPMC \n");  
	if (check_mem_region(SOC_PRCM_REGS + CM_PER_GPMC_CLKCTRL/4, 4)) {
	    printk("%s: memory already in use\n", gDrvrName);
	    return -EBUSY;
	}
	request_mem_region(SOC_PRCM_REGS + CM_PER_GPMC_CLKCTRL, 4, gDrvrName);
	

	prcm_reg_pointer = ioremap_nocache(SOC_PRCM_REGS + CM_PER_GPMC_CLKCTRL, sizeof(int));
	//enable clock to GPMC module
	
	orShortRegister(CM_PER_GPMC_CLKCTRL_MODULEMODE_ENABLE, prcm_reg_pointer);
	//check to see if enabled
	printk("CM_PER_GPMC_CLKCTRL value :%x \n",ioread32(prcm_reg_pointer)); 
	while((ioread32(prcm_reg_pointer) & 
	CM_PER_GPMC_CLKCTRL_IDLEST) != (CM_PER_GPMC_CLKCTRL_IDLEST_FUNC << CM_PER_GPMC_CLKCTRL_IDLEST_SHIFT));
	printk("GPMC clock is running \n");
	iounmap(prcm_reg_pointer);
	release_mem_region(SOC_PRCM_REGS + CM_PER_GPMC_CLKCTRL/4, 4);

	return 1;
}
Esempio n. 13
0
/* initialisation of the driver: getting resources etc. */
static int dt330_init_one(struct pci_dev *dev, const struct pci_device_id *ent) {
    struct cardinfo *cp; /* pointer to this card */
    int isref; /* int stuff reference pointer */


    /* make sure there is enough card space */
    if (dev_count >= NUMBER_OF_CARDS) {
        printk ("dt330: this driver only supports %d boards\n",
                NUMBER_OF_CARDS);
        return -ENODEV;
    }
    cp = (struct cardinfo *)kmalloc(sizeof(struct cardinfo),GFP_KERNEL);
    if (!cp) {
        printk("dt330: Cannot kmalloc device memory\n");
        return -ENOMEM;
    }

    cp->iocard_opened = 0; /* no open */
    cp->my_async_queue = NULL; /* prevent crash later */

    /* enable device before accessing resources 5.9.07chk */
    if (pci_enable_device (dev))
        return -EIO;

    /* get resources */
    cp->irq_number = dev->irq;
    cp->mem_base0 = pci_resource_start(dev, 0);

    /* register resources with kernel */
    if (check_mem_region(cp->mem_base0,IOCARD_SPACE+1)) {
        printk("dt330: memory at %x already in use\n",cp->mem_base0);
        goto out1;
    }
    request_mem_region(cp->mem_base0,IOCARD_SPACE+1, IOCARD_NAME);

    /* get virtual address for the pci mem */
    cp->cardspace = (char *) ioremap_nocache(cp->mem_base0,IOCARD_SPACE+1);
    printk("dt330: got new mem pointer: %p\n",cp->cardspace);

    /* register char devices with kernel */
    cp->major = register_chrdev(IOCARD_MAJOR, IOCARD_NAME, &dt330_fops);
    if (cp->major<0) {
        printk("Error in registering major device %d\n",IOCARD_MAJOR);
        goto out2;
    }
    if (IOCARD_MAJOR) cp->major=IOCARD_MAJOR;

    /* for acessing irq flags */
    isref = dev_count;
    itable[isref].countflag=0;
    itable[isref].notify_flag=0;
    itable[isref].last_IRQ_note=0;
    itable[isref].pending=0;
    cp->intstuffref=isref;

    cif[dev_count]=cp; /* for shorter reference */
    dev_count++; /* got one more card */

    return 0; /* everything is fine */
out2:
    iounmap(cp->cardspace);
    release_mem_region(cp->mem_base0,IOCARD_SPACE+1);
out1:
    return -EBUSY;
}
Esempio n. 14
0
int short_init(void)
{
    int result;

    /*
     * first, sort out the base/short_base ambiguity: we'd better
     * use short_base in the code, for clarity, but allow setting
     * just "base" at load time. Same for "irq".
     */
    short_base = base;
    short_irq = irq;


    if (!use_mem) {
	result = check_region(short_base, SHORT_NR_PORTS);
	if (result) {
	    printk(KERN_INFO "short: can't get I/O port address 0x%lx\n",
		   short_base);
	    return result;
	}
	request_region(short_base, SHORT_NR_PORTS, "short");
    } else {
	result = check_mem_region(short_base, SHORT_NR_PORTS);
	if (result) {
	    printk(KERN_INFO "short: can't get I/O mem address 0x%lx\n",
		   short_base);
	    return result;
	}
	request_mem_region(short_base, SHORT_NR_PORTS, "short");

	/* also, ioremap it */
	short_phys = short_base;
	short_base = (unsigned long)short_remap(short_base);
	/* Hmm... we should check the return value */
    }
    result = register_chrdev(major, "short", &short_fops);
    if (result < 0) {
        printk(KERN_INFO "short: can't get major number\n");
        release_region(short_base,SHORT_NR_PORTS);
        return result;
    }
    if (major == 0) major = result; /* dynamic */

    short_buffer = __get_free_pages(GFP_KERNEL,0); /* never fails */
    short_head = short_tail = short_buffer;

    /*
     * Fill the short_task structure, used for the bottom half handler.
     * The cast is there to prevent warnings about the type of the
     * (unused) argument. -- FIXME: how does this cast work?
     */
    short_task.routine = short_do_tasklet;
    short_task.data = NULL; /* unused */

    /*
     * Now we deal with the interrupt: either kernel-based
     * autodetection, DIY detection or default number
     */

    if (short_irq < 0 && probe == 1)
        short_kernelprobe();

    if (short_irq < 0 && probe == 2)
        short_selfprobe();

    if (short_irq < 0) /* not yet specified: force the default on */
        switch(short_base) {
          case 0x378: short_irq = 7; break;
          case 0x278: short_irq = 2; break;
          case 0x3bc: short_irq = 5; break;
        }

    /*
     * If shared has been specified, installed the shared handler
     * instead of the normal one. Do it first, before a -EBUSY will
     * force short_irq to -1.
     */
    if (short_irq >= 0 && share > 0) {
        result = request_irq(short_irq, short_sh_interrupt,
                             SA_SHIRQ | SA_INTERRUPT,"short",
                             short_sh_interrupt);
        if (result) {
            printk(KERN_INFO "short: can't get assigned irq %i\n", short_irq);
            short_irq = -1;
        }
        else { /* actually enable it -- assume this *is* a parallel port */
            outb(0x10,short_base+2);
        }
        return 0; /* the rest of the function only installs handlers */
    }

    if (short_irq >= 0) {
        result = request_irq(short_irq, short_interrupt,
                             SA_INTERRUPT, "short", NULL);
        if (result) {
            printk(KERN_INFO "short: can't get assigned irq %i\n",
                   short_irq);
            short_irq = -1;
        }
        else { /* actually enable it -- assume this *is* a parallel port */
            outb(0x10,short_base+2);
        }
    }

    /*
     * Ok, now change the interrupt handler if using top/bottom halves
     * has been requested
     */
    if (short_irq >= 0 && (bh + tasklet) > 0) {
        free_irq(short_irq,NULL);
        result = request_irq(short_irq,
#ifdef HAVE_TASKLETS
                        tasklet ? short_tl_interrupt :
#endif
                        short_bh_interrupt,
                        SA_INTERRUPT,"short-bh", NULL);
        if (result) {
            printk(KERN_INFO "short-bh: can't get assigned irq %i\n",
                   short_irq);
            short_irq = -1;
        }
    }

    return 0;
}
Esempio n. 15
0
int setupGPMCNonMuxed(void){
	unsigned int temp = 0;
	unsigned short int csNum = 1 ;	
	volatile unsigned int * gpmc_reg_pointer ;

	printk("Configuring GPMC for non muxed access \n");	


	if (check_mem_region(SOC_GPMC_0_REGS, 720)) {
	    printk("%s: memory already in use\n", gDrvrName);
	    return -EBUSY;
	}
	request_mem_region(SOC_GPMC_0_REGS, 720, gDrvrName);
	gpmc_reg_pointer = ioremap_nocache(SOC_GPMC_0_REGS,  720);



	printk("GPMC_REVISION value :%x \n", ioread32(gpmc_reg_pointer + GPMC_REVISION/4)); 
	
	orShortRegister(GPMC_SYSCONFIG_SOFTRESET, gpmc_reg_pointer + GPMC_SYSCONFIG/4 ) ;
	printk("Trying to reset GPMC \n"); 
	printk("GPMC_SYSSTATUS value :%x \n", ioread32(gpmc_reg_pointer + GPMC_SYSSTATUS/4)); 
	while((ioread32(gpmc_reg_pointer + GPMC_SYSSTATUS/4) & 
		GPMC_SYSSTATUS_RESETDONE) == GPMC_SYSSTATUS_RESETDONE_RSTONGOING){
		printk("GPMC_SYSSTATUS value :%x \n", ioread32(gpmc_reg_pointer + 
		GPMC_SYSSTATUS/4));
	}
	printk("GPMC reset \n");
	temp = ioread32(gpmc_reg_pointer + GPMC_SYSCONFIG/4);
	temp &= ~GPMC_SYSCONFIG_IDLEMODE;
	temp |= GPMC_SYSCONFIG_IDLEMODE_NOIDLE << GPMC_SYSCONFIG_IDLEMODE_SHIFT;
	iowrite32(temp, gpmc_reg_pointer + GPMC_SYSCONFIG/4);
	iowrite32(0x00, gpmc_reg_pointer + GPMC_IRQENABLE/4) ;
	iowrite32(0x00, gpmc_reg_pointer + GPMC_TIMEOUT_CONTROL/4);

	iowrite32((0x0 |
	(GPMC_CONFIG1_0_DEVICESIZE_SIXTEENBITS <<
		GPMC_CONFIG1_0_DEVICESIZE_SHIFT ) |
	(GPMC_CONFIG1_0_ATTACHEDDEVICEPAGELENGTH_FOUR <<
		GPMC_CONFIG1_0_ATTACHEDDEVICEPAGELENGTH_SHIFT ) |
	(GPMC_CONFIG1_0_MUXADDDATA_NONMUX << GPMC_CONFIG1_0_MUXADDDATA_SHIFT )), 
	gpmc_reg_pointer + GPMC_CONFIG1(csNum)/4) ;	//Address/Data not multiplexed


	iowrite32( (0x0 |
	(0) |	// CS_ON_TIME
	(6 << GPMC_CONFIG2_0_CSRDOFFTIME_SHIFT) |	// CS_DEASSERT_RD
	(6 << GPMC_CONFIG2_0_CSWROFFTIME_SHIFT)),	//CS_DEASSERT_WR
	gpmc_reg_pointer + GPMC_CONFIG2(csNum)/4)  ;	

	iowrite32((0x0 |
	(0 << GPMC_CONFIG3_0_ADVONTIME_SHIFT) | //ADV_ASSERT
	(0 << GPMC_CONFIG3_0_ADVRDOFFTIME_SHIFT) | //ADV_DEASSERT_RD
	(0 << GPMC_CONFIG3_0_ADVWROFFTIME_SHIFT)), //ADV_DEASSERT_WR
	gpmc_reg_pointer + GPMC_CONFIG3(csNum)/4) ; 

	iowrite32((0x0 |
	(1 << GPMC_CONFIG4_0_OEONTIME_SHIFT) |	//OE_ASSERT
	(6 << GPMC_CONFIG4_0_OEOFFTIME_SHIFT) |	//OE_DEASSERT
	(1 << GPMC_CONFIG4_0_WEONTIME_SHIFT)| //WE_ASSERT
	(6 << GPMC_CONFIG4_0_WEOFFTIME_SHIFT)), //WE_DEASSERT
	gpmc_reg_pointer + GPMC_CONFIG4(csNum)/4)  ; 

	iowrite32((0x0 |
	(7 << GPMC_CONFIG5_0_RDCYCLETIME_SHIFT)|	//CFG_5_RD_CYCLE_TIM
	(7 << GPMC_CONFIG5_0_WRCYCLETIME_SHIFT)|	//CFG_5_WR_CYCLE_TIM
	(6 << GPMC_CONFIG5_0_RDACCESSTIME_SHIFT)),	// CFG_5_RD_ACCESS_TIM
	gpmc_reg_pointer + GPMC_CONFIG5(csNum)/4)  ;  

	iowrite32( (0x0 |
	(0 << //GPMC_CONFIG6_0_CYCLE2CYCLESAMECSEN_C2CDELAY
			GPMC_CONFIG6_0_CYCLE2CYCLESAMECSEN_SHIFT) |
	(0 << GPMC_CONFIG6_0_CYCLE2CYCLEDELAY_SHIFT) | //CYC2CYC_DELAY
	(0 << GPMC_CONFIG6_0_WRDATAONADMUXBUS_SHIFT)| //WR_DATA_ON_ADMUX
	(0 << GPMC_CONFIG6_0_WRACCESSTIME_SHIFT)), //CFG_6_WR_ACCESS_TIM
	gpmc_reg_pointer + GPMC_CONFIG6(csNum)/4) ;  

	iowrite32((0x09 << GPMC_CONFIG7_0_BASEADDRESS_SHIFT) | //CFG_7_BASE_ADDR
	(0x1 << GPMC_CONFIG7_0_CSVALID_SHIFT) |
	(0x0f << GPMC_CONFIG7_0_MASKADDRESS_SHIFT), //CFG_7_MASK
	gpmc_reg_pointer + GPMC_CONFIG7(csNum)/4);  
	iounmap(gpmc_reg_pointer);
	release_mem_region(SOC_GPMC_0_REGS, 720);
	return 1;
}
Esempio n. 16
0
static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name)
{
	unsigned long bar5	= pci_resource_start(dev, 5);
	unsigned long len5	= pci_resource_len(dev, 5);
	u8 tmpbyte	= 0;
	unsigned long addr;
	void *ioaddr;

	/*
	 *	Drop back to PIO if we can't map the mmio. Some
	 *	systems seem to get terminally confused in the PCI
	 *	spaces.
	 */
	 
	if(check_mem_region(bar5, len5)!=0)
	{
		printk(KERN_WARNING "siimage: IDE controller MMIO ports not available.\n");
		return 0;
	}
		
	ioaddr = ioremap_nocache(bar5, len5);

	if (ioaddr == NULL)
		return 0;

	pci_set_master(dev);
	pci_set_drvdata(dev, ioaddr);
	addr = (unsigned long) ioaddr;

	if (dev->device == PCI_DEVICE_ID_SII_3112) {
		writel(0, DEVADDR(0x148));
		writel(0, DEVADDR(0x1C8));
	}

	writeb(0, DEVADDR(0xB4));
	writeb(0, DEVADDR(0xF4));
	tmpbyte = readb(DEVADDR(0x4A));

	switch(tmpbyte & 0x30) {
		case 0x00:
			/* In 100 MHz clocking, try and switch to 133 */
			writeb(tmpbyte|0x10, DEVADDR(0x4A));
			break;
		case 0x10:
			/* On 133Mhz clocking */
			break;
		case 0x20:
			/* On PCIx2 clocking */
			break;
		case 0x30:
			/* Clocking is disabled */
			/* 133 clock attempt to force it on */
			writeb(tmpbyte & ~0x20, DEVADDR(0x4A));
			break;
	}
	
	writeb(0x72, DEVADDR(0xA1));
	writew(0x328A, DEVADDR(0xA2));
	writel(0x62DD62DD, DEVADDR(0xA4));
	writel(0x43924392, DEVADDR(0xA8));
	writel(0x40094009, DEVADDR(0xAC));
	writeb(0x72, DEVADDR(0xE1));
	writew(0x328A, DEVADDR(0xE2));
	writel(0x62DD62DD, DEVADDR(0xE4));
	writel(0x43924392, DEVADDR(0xE8));
	writel(0x40094009, DEVADDR(0xEC));

	if (dev->device == PCI_DEVICE_ID_SII_3112) {
		writel(0xFFFF0000, DEVADDR(0x108));
		writel(0xFFFF0000, DEVADDR(0x188));
		writel(0x00680000, DEVADDR(0x148));
		writel(0x00680000, DEVADDR(0x1C8));
	}

	tmpbyte = readb(DEVADDR(0x4A));

	proc_reports_siimage(dev, (tmpbyte>>=4), name);
	return 1;
}
Esempio n. 17
0
int 
reg_open(struct inode *inode, struct file *filp)
{



	MOD_INC_USE_COUNT; 
	printk("<1>Opening leds...\n");
	
	//comprueba memoria
	if(check_mem_region(DIO_DDA, 1)) {
               printk("DUMB: espacio de memoria en uso: DIO_DDA\n");
               return -EBUSY;
       }
	

       if(check_mem_region(DIO_DA, 1)) {
               printk("DUMB: espacio de memoria en uso: DIO_DA\n");
               return -EBUSY;
       }
	if(check_mem_region(DIO_B, 1)) {
               printk("DUMB: espacio de memoria en uso: DIO_B\n");
               return -EBUSY;
       }
	

 



      
	//Tomar memoria

	 request_mem_region(DIO_DDA, 1, "dio_dda");
	 dio_dda = __ioremap(DIO_DDA, 1, 0);

	 request_mem_region(DIO_DA, 1, "dio_da");
	 dio_da = __ioremap(DIO_DA, 1, 0);

 	request_mem_region(DIO_B, 1, "dio_b");
	 dio_b = __ioremap(DIO_B, 1, 0);




	

	 printk("dumb: dio_dda remap = %p\n", dio_dda);
	 printk("dumb: dio_da remap = %p\n", dio_da);
	 printk("dumb: dio_b remap = %p\n", dio_b);
	
	
	*dio_dda = 0xFF; // hacer con mascaras?
	*dio_b = 0xF0;
	printk("<1> dio_dda= 0x%x \n", *dio_dda);
	printk("<1> dio_b= 0x%x \n", *dio_b);
/**
  _peddr = inb(0x80840024);
  _peddr |= 0x03;
  outb(_peddr, 0x80840024);

  _pedr = inl (0x80840020);
  _pedr &= (~0xFFFFFFFC);
  outl (_pedr, 0x80840020);
**/

  printk("<1>leds init done\n");
  
  return 0;
}
Esempio n. 18
0
int __init
setup_teles0(struct IsdnCard *card)
{
	u_char val;
	struct IsdnCardState *cs = card->cs;
	char tmp[64];

	strcpy(tmp, teles0_revision);
	printk(KERN_INFO "HiSax: Teles 8.0/16.0 driver Rev. %s\n", HiSax_getrev(tmp));
	if ((cs->typ != ISDN_CTYPE_16_0) && (cs->typ != ISDN_CTYPE_8_0))
		return (0);

	if (cs->typ == ISDN_CTYPE_16_0)
		cs->hw.teles0.cfg_reg = card->para[2];
	else			/* 8.0 */
		cs->hw.teles0.cfg_reg = 0;

	if (card->para[1] < 0x10000) {
		card->para[1] <<= 4;
		printk(KERN_INFO
		   "Teles0: membase configured DOSish, assuming 0x%lx\n",
		       (unsigned long) card->para[1]);
	}
	cs->irq = card->para[0];
	if (cs->hw.teles0.cfg_reg) {
		if (check_region(cs->hw.teles0.cfg_reg, 8)) {
			printk(KERN_WARNING
			  "HiSax: %s config port %x-%x already in use\n",
			       CardType[card->typ],
			       cs->hw.teles0.cfg_reg,
			       cs->hw.teles0.cfg_reg + 8);
			return (0);
		} else {
			request_region(cs->hw.teles0.cfg_reg, 8, "teles cfg");
		}
	}
	if (cs->hw.teles0.cfg_reg) {
		if ((val = bytein(cs->hw.teles0.cfg_reg + 0)) != 0x51) {
			printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",
			       cs->hw.teles0.cfg_reg + 0, val);
			release_region(cs->hw.teles0.cfg_reg, 8);
			return (0);
		}
		if ((val = bytein(cs->hw.teles0.cfg_reg + 1)) != 0x93) {
			printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",
			       cs->hw.teles0.cfg_reg + 1, val);
			release_region(cs->hw.teles0.cfg_reg, 8);
			return (0);
		}
		val = bytein(cs->hw.teles0.cfg_reg + 2);	/* 0x1e=without AB
								   * 0x1f=with AB
								   * 0x1c 16.3 ???
								 */
		if (val != 0x1e && val != 0x1f) {
			printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",
			       cs->hw.teles0.cfg_reg + 2, val);
			release_region(cs->hw.teles0.cfg_reg, 8);
			return (0);
		}
	}
	/* 16.0 and 8.0 designed for IOM1 */
	test_and_set_bit(HW_IOM1, &cs->HW_Flags);
	cs->hw.teles0.phymem = card->para[1];
	if (check_mem_region(cs->hw.teles0.phymem, TELES_IOMEM_SIZE)) {
		printk(KERN_WARNING
			"HiSax: %s memory region %lx-%lx already in use\n",
			CardType[card->typ],
			cs->hw.teles0.phymem,
			cs->hw.teles0.phymem + TELES_IOMEM_SIZE);
		if (cs->hw.teles0.cfg_reg)
			release_region(cs->hw.teles0.cfg_reg, 8);
		return (0);
	} else {
		request_mem_region(cs->hw.teles0.phymem, TELES_IOMEM_SIZE,
			"teles iomem");
	}
	cs->hw.teles0.membase =
		(unsigned long) ioremap(cs->hw.teles0.phymem, TELES_IOMEM_SIZE);
	printk(KERN_INFO
	       "HiSax: %s config irq:%d mem:0x%lX cfg:0x%X\n",
	       CardType[cs->typ], cs->irq,
	       cs->hw.teles0.membase, cs->hw.teles0.cfg_reg);
	if (reset_teles0(cs)) {
		printk(KERN_WARNING "Teles0: wrong IRQ\n");
		release_io_teles0(cs);
		return (0);
	}
	cs->readisac = &ReadISAC;
	cs->writeisac = &WriteISAC;
	cs->readisacfifo = &ReadISACfifo;
	cs->writeisacfifo = &WriteISACfifo;
	cs->BC_Read_Reg = &ReadHSCX;
	cs->BC_Write_Reg = &WriteHSCX;
	cs->BC_Send_Data = &hscx_fill_fifo;
	cs->cardmsg = &Teles_card_msg;
	cs->irq_func = &teles0_interrupt;
	ISACVersion(cs, "Teles0:");
	if (HscxVersion(cs, "Teles0:")) {
		printk(KERN_WARNING
		 "Teles0: wrong HSCX versions check IO/MEM addresses\n");
		release_io_teles0(cs);
		return (0);
	}
	return (1);
}
int
eicon_isa_bootload(eicon_isa_card *card, eicon_isa_codebuf *cb) {
	int	tmp;
	int               timeout;
	eicon_isa_codebuf cbuf;
	unsigned char     *code;
	eicon_isa_boot    *boot;

	if (copy_from_user(&cbuf, cb, sizeof(eicon_isa_codebuf)))
		return -EFAULT;

	/* Allocate code-buffer and copy code from userspace */
	if (cbuf.bootstrap_len > 1024) {
		printk(KERN_WARNING "eicon_isa_boot: Invalid startup-code size %ld\n",
		       cbuf.bootstrap_len);
		return -EINVAL;
	}
	if (!(code = kmalloc(cbuf.bootstrap_len, GFP_KERNEL))) {
		printk(KERN_WARNING "eicon_isa_boot: Couldn't allocate code buffer\n");
		return -ENOMEM;
	}
	if (copy_from_user(code, &cb->code, cbuf.bootstrap_len)) {
		kfree(code);
		return -EFAULT;
	}

	if (card->type == EICON_CTYPE_ISAPRI)
		card->ramsize  = RAMSIZE_P;
	else
		card->ramsize  = RAMSIZE;

	if (check_mem_region(card->physmem, card->ramsize)) {
		printk(KERN_WARNING "eicon_isa_boot: memory at 0x%lx already in use.\n",
			card->physmem);
		kfree(code);
		return -EBUSY;
	}
	request_mem_region(card->physmem, card->ramsize, "Eicon ISA ISDN");
	card->shmem = (eicon_isa_shmem *) ioremap(card->physmem, card->ramsize);
#ifdef EICON_MCA_DEBUG
	printk(KERN_INFO "eicon_isa_boot: card->ramsize = %d.\n", card->ramsize);
#endif
	card->mvalid = 1;

	switch(card->type) {
		case EICON_CTYPE_S:
		case EICON_CTYPE_SX:
		case EICON_CTYPE_SCOM:
		case EICON_CTYPE_QUADRO:
		case EICON_CTYPE_ISABRI:
			card->intack   = (__u8 *)card->shmem + INTACK;
			card->startcpu = (__u8 *)card->shmem + STARTCPU;
			card->stopcpu  = (__u8 *)card->shmem + STOPCPU;
			break;
		case EICON_CTYPE_S2M:
		case EICON_CTYPE_ISAPRI:
			card->intack   = (__u8 *)card->shmem + INTACK_P;
			card->startcpu = (__u8 *)card->shmem + STARTCPU_P;
			card->stopcpu  = (__u8 *)card->shmem + STOPCPU_P;
			break;
		default:
			printk(KERN_WARNING "eicon_isa_boot: Invalid card type %d\n", card->type);
			eicon_isa_release_shmem(card);
			kfree(code);
			return -EINVAL;
	}

	/* clear any pending irq's */
	readb(card->intack);
#ifdef CONFIG_MCA
	if (MCA_bus) {
		if (card->type == EICON_CTYPE_SCOM) {
			outb_p(0,card->io+1);
		}
		else {
			printk(KERN_WARNING "eicon_isa_boot: Card type not supported yet.\n");
			eicon_isa_release_shmem(card);
			return -EINVAL;
		};

#ifdef EICON_MCA_DEBUG
	printk(KERN_INFO "eicon_isa_boot: card->io      = %x.\n", card->io);
	printk(KERN_INFO "eicon_isa_boot: card->irq     = %d.\n", (int)card->irq);
#endif
	}
#else
	/* set reset-line active */
	writeb(0, card->stopcpu); 
#endif  /* CONFIG_MCA */
	/* clear irq-requests */
	writeb(0, card->intack);
	readb(card->intack);

	/* Copy code into card */
	memcpy_toio(&card->shmem->c, code, cbuf.bootstrap_len);

	/* Check for properly loaded code */
	if (!check_signature((unsigned long)&card->shmem->c, code, 1020)) {
		printk(KERN_WARNING "eicon_isa_boot: Could not load startup-code\n");
		eicon_isa_release_shmem(card);
		kfree(code);
		return -EIO;
	}
	/* if 16k-ramsize, duplicate the reset-jump-code */
	if (card->ramsize == RAMSIZE_P)
		memcpy_toio((__u8 *)card->shmem + 0x3ff0, &code[0x3f0], 12);

	kfree(code);
	boot = &card->shmem->boot;

	/* Delay 0.2 sec. */
	SLEEP(HZ / 5);

	/* Start CPU */
	writeb(cbuf.boot_opt, &boot->ctrl);
#ifdef CONFIG_MCA
	if (MCA_bus) {
		outb_p(0, card->io);
	}
#else 
	writeb(0, card->startcpu); 
#endif /* CONFIG_MCA */

	/* Delay 0.2 sec. */
	SLEEP(HZ / 5);

	timeout = jiffies + (HZ * 22);
	while (time_before(jiffies, timeout)) {
		if (readb(&boot->ctrl) == 0)
			break;
		SLEEP(10);
	}
	if (readb(&boot->ctrl) != 0) {
		printk(KERN_WARNING "eicon_isa_boot: CPU test failed.\n");
#ifdef EICON_MCA_DEBUG
		printk(KERN_INFO "eicon_isa_boot: &boot->ctrl = %d.\n",
			readb(&boot->ctrl));
#endif
		eicon_isa_release_shmem(card);
		return -EIO;
	}

	/* Check for memory-test errors */
	if (readw(&boot->ebit)) {
		printk(KERN_WARNING "eicon_isa_boot: memory test failed (bit 0x%04x at 0x%08x)\n",
		       readw(&boot->ebit), readl(&boot->eloc));
		eicon_isa_release_shmem(card);
		return -EIO;
	}

        /* Check card type and memory size */
        tmp = readb(&boot->card);
	if ((tmp < 0) || (tmp > 4)) {
		printk(KERN_WARNING "eicon_isa_boot: Type detect failed\n");
		eicon_isa_release_shmem(card);
		return -EIO;
	}
	card->type = tmp;
	((eicon_card *)card->card)->type = tmp;

        tmp = readb(&boot->msize);
        if (tmp != 8 && tmp != 16 && tmp != 24 &&
            tmp != 32 && tmp != 48 && tmp != 60) {
                printk(KERN_WARNING "eicon_isa_boot: invalid memsize\n");
		eicon_isa_release_shmem(card);
                return -EIO;
        }
	printk(KERN_INFO "%s: startup-code loaded\n", eicon_ctype_name[card->type]); 
	if ((card->type == EICON_CTYPE_QUADRO) && (card->master)) {
		tmp = eicon_addcard(card->type, card->physmem, card->irq, 
				((eicon_card *)card->card)->regname, 0);
		printk(KERN_INFO "Eicon: %d adapters added\n", tmp);
	}
	return 0;
}
Esempio n. 20
0
static int XPCIe_init(void)
{
    gDev = pci_find_device (PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_XILINX_PCIE, gDev);
    if (NULL == gDev) {
        printk(/*KERN_WARNING*/"%s: Init: Hardware not found.\n", gDrvrName);
        //return (CRIT_ERR);
        return (-1);
    }

    if (0 > pci_enable_device(gDev)) {
        printk(/*KERN_WARNING*/"%s: Init: Device not enabled.\n", gDrvrName);
        //return (CRIT_ERR);
        return (-1);
    }

    // Get Base Address of registers from pci structure. Should come from pci_dev
    // structure, but that element seems to be missing on the development system.
    gBaseHdwr = pci_resource_start (gDev, 0);
    if (0 > gBaseHdwr) {
        printk(/*KERN_WARNING*/"%s: Init: Base Address not set.\n", gDrvrName);
        //return (CRIT_ERR);
        return (-1);
    } 
    printk(/*KERN_WARNING*/"Base hw val %X\n", (unsigned int)gBaseHdwr);

    gBaseLen = pci_resource_len (gDev, 0);
    printk(/*KERN_WARNING*/"Base hw len %d\n", (unsigned int)gBaseLen);

    // Remap the I/O register block so that it can be safely accessed.
    // I/O register block starts at gBaseHdwr and is 32 bytes long.
    // It is cast to char because that is the way Linus does it.
    // Reference "/usr/src/Linux-2.4/Documentation/IO-mapping.txt".

    gBaseVirt = ioremap(gBaseHdwr, gBaseLen);
    if (!gBaseVirt) {
        printk(/*KERN_WARNING*/"%s: Init: Could not remap memory.\n", gDrvrName);
        //return (CRIT_ERR);
        return (-1);
    } 

    printk(/*KERN_WARNING*/"Virt hw val %X\n", (unsigned int)gBaseVirt);

    // Get IRQ from pci_dev structure. It may have been remapped by the kernel,
    // and this value will be the correct one.

    gIrq = gDev->irq;
    printk("irq: %d\n",gIrq);

    //--- START: Initialize Hardware

    // Try to gain exclusive control of memory for demo hardware.
    if (0 > check_mem_region(gBaseHdwr, KINBURN_REGISTER_SIZE)) {
        printk(/*KERN_WARNING*/"%s: Init: Memory in use.\n", gDrvrName);
        //return (CRIT_ERR);
        return (-1);
    }

    request_mem_region(gBaseHdwr, KINBURN_REGISTER_SIZE, "3GIO_Demo_Drv");
    gStatFlags = gStatFlags | HAVE_REGION;

    printk(/*KERN_WARNING*/"%s: Init:  Initialize Hardware Done..\n",gDrvrName);

    // Request IRQ from OS.
#if 0
    if (0 > request_irq(gIrq, &XPCIe_IRQHandler,/* SA_INTERRUPT |*/ SA_SHIRQ, gDrvrName, gDev)) {
        printk(/*KERN_WARNING*/"%s: Init: Unable to allocate IRQ",gDrvrName);
        return (-1);
    }
    gStatFlags = gStatFlags | HAVE_IRQ;
#endif

    initcode();

    //--- END: Initialize Hardware

    //--- START: Allocate Buffers

    gBufferUnaligned = kmalloc(BUF_SIZE, GFP_KERNEL);
                                                                                
    gReadBuffer = gBufferUnaligned;
    if (NULL == gBufferUnaligned) {
        printk(KERN_CRIT"%s: Init: Unable to allocate gBuffer.\n",gDrvrName);
        return (-1);
    }
                                                                                
    gWriteBuffer = kmalloc(BUF_SIZE, GFP_KERNEL);
    if (NULL == gWriteBuffer) {
        printk(KERN_CRIT"%s: Init: Unable to allocate gBuffer.\n",gDrvrName);
        return (-1);
    }

    //--- END: Allocate Buffers

    //--- START: Register Driver
    // Register with the kernel as a character device.
    // Abort if it fails.
    if (0 > register_chrdev(gDrvrMajor, gDrvrName, &XPCIe_Intf)) {
        printk(KERN_WARNING"%s: Init: will not register\n", gDrvrName);
        return (CRIT_ERR);
    }
    printk(KERN_INFO"%s: Init: module registered\n", gDrvrName);
    gStatFlags = gStatFlags | HAVE_KREG;

    printk("%s driver is loaded\n", gDrvrName);

  return 0;
}
Esempio n. 21
0
int __init
setup_isurf(struct IsdnCard *card)
{
	int ver;
	struct IsdnCardState *cs = card->cs;
	char tmp[64];

	strcpy(tmp, ISurf_revision);
	printk(KERN_INFO "HiSax: ISurf driver Rev. %s\n", HiSax_getrev(tmp));
	
 	if (cs->typ != ISDN_CTYPE_ISURF)
 		return(0);
	if (card->para[1] && card->para[2]) {
		cs->hw.isurf.reset = card->para[1];
		cs->hw.isurf.phymem = card->para[2];
		cs->irq = card->para[0];
	} else {
		printk(KERN_WARNING "HiSax: %s port/mem not set\n",
			CardType[card->typ]);
		return (0);
	}
	if (check_region(cs->hw.isurf.reset, 1)) {
		printk(KERN_WARNING
			"HiSax: %s config port %x already in use\n",
			CardType[card->typ],
			cs->hw.isurf.reset);
			return (0);
	} else {
		request_region(cs->hw.isurf.reset, 1, "isurf isdn");
	}
	if (check_mem_region(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE)) {
		printk(KERN_WARNING
			"HiSax: %s memory region %lx-%lx already in use\n",
			CardType[card->typ],
			cs->hw.isurf.phymem,
			cs->hw.isurf.phymem + ISURF_IOMEM_SIZE);
		release_region(cs->hw.isurf.reset, 1);
		return (0);
	} else {
		request_mem_region(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE,
			"isurf iomem");
	}
	cs->hw.isurf.isar =
		(unsigned long) ioremap(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE);
	cs->hw.isurf.isac = cs->hw.isurf.isar + ISURF_ISAC_OFFSET;
	printk(KERN_INFO
	       "ISurf: defined at 0x%x 0x%lx IRQ %d\n",
	       cs->hw.isurf.reset,
	       cs->hw.isurf.phymem,
	       cs->irq);

	cs->cardmsg = &ISurf_card_msg;
	cs->irq_func = &isurf_interrupt;
	cs->auxcmd = &isurf_auxcmd;
	cs->readisac = &ReadISAC;
	cs->writeisac = &WriteISAC;
	cs->readisacfifo = &ReadISACfifo;
	cs->writeisacfifo = &WriteISACfifo;
	cs->bcs[0].hw.isar.reg = &cs->hw.isurf.isar_r;
	cs->bcs[1].hw.isar.reg = &cs->hw.isurf.isar_r;
	reset_isurf(cs, ISURF_RESET);
	test_and_set_bit(HW_ISAR, &cs->HW_Flags);
	ISACVersion(cs, "ISurf:");
	cs->BC_Read_Reg = &ReadISAR;
	cs->BC_Write_Reg = &WriteISAR;
	cs->BC_Send_Data = &isar_fill_fifo;
	ver = ISARVersion(cs, "ISurf:");
	if (ver < 0) {
		printk(KERN_WARNING
			"ISurf: wrong ISAR version (ret = %d)\n", ver);
		release_io_isurf(cs);
		return (0);
	}
	return (1);
}
Esempio n. 22
0
/* ======================================================================== */
static int Godshand_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
	int err = 0;
	int ret = 0;
	void * Godshand_location = NULL;
	DWORD tmp;
	GODSHAND_Dev *dev = (GODSHAND_Dev *)filp->private_data;
	DWORD GODSHAND_LOCATION;
	DWORD GODSHAND_AREA_SIZE;
	Godshand_info = (GODSHAND_Info *)arg;

	GODSHAND_LOCATION = Godshand_info->dwAddress;
	GODSHAND_AREA_SIZE = GODSHAND_SIZE; 
	PDEBUG("the address is %x\n",Godshand_info->dwAddress);
	if (Godshand_info->dwFlag & GODSHAND_FLAG_AREA)
	{
		GODSHAND_AREA_SIZE = Godshand_info->dwSize;
	}

	if (check_mem_region(GODSHAND_START, GODSHAND_SIZE) < 0) {
		PDEBUG("ERROR: allocated fail!\n\r");
		ret = -EBUSY;
		goto fail;
	}
	request_mem_region(GODSHAND_START, GODSHAND_SIZE, "GODSHAND module .");

	Godshand_base = (unsigned long *)ioremap((int)GODSHAND_START, (int)GODSHAND_SIZE);
	Godshand_location = (unsigned long *)ioremap((int)GODSHAND_LOCATION, (int)GODSHAND_AREA_SIZE);
	PDEBUG("%x: Allocated\n\r", (int)Godshand_base);

	if (!dev) {
		return -ENODEV;
	}
	/*
	 * extract the type and number bitfields, and don't decode
	 * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok()
	 */
	if (_IOC_TYPE(cmd) != GODSHAND_IOC_MAGIC) {
		return -ENOTTY;
	}

	if (_IOC_NR(cmd) > GODSHAND_IOC_MAXNUM) {
		return -ENOTTY;
	}
	/*
	 * the direction is a bitmask, and VERIFY_WRITE catches R/W
	 * transfers. `Type' is user-oriented, while
	 * access_ok is kernel-oriented, so the concept of "read" and
	  * "write" is reversed
	*/
	if (_IOC_DIR(cmd) & _IOC_READ) {
		err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
	} else if (_IOC_DIR(cmd) & _IOC_WRITE){
		err = !access_ok(VERIFY_READ,  (void *)arg, _IOC_SIZE(cmd));
	}
	
	if (err) {
		return -EFAULT;
	}

	switch (cmd)
	{
		case GODSHAND_IOC_RESET :
			break;
		case GODSHAND_IOC_CLEAR :
			break;
		case GODSHAND_IOC_READ :
			if (down_interruptible(&dev->sem)) {
				return -ERESTARTSYS;
			}
			ret = __put_user(readl((u32*)(Godshand_location)), (u32*)(&Godshand_info->dwData));
			up(&dev->sem);
			break;
		case GODSHAND_IOC_READ_AREA :
			if (down_interruptible(&dev->sem)) {
				return -ERESTARTSYS;
			}
			ret = copy_to_user(Godshand_info->pDataBuffer, ((u32*)Godshand_location), GODSHAND_AREA_SIZE);
			up(&dev->sem);
			break;
		case GODSHAND_IOC_WRITE :
			ret = __get_user(tmp, (u32*)(&Godshand_info->dwData));
			if (down_interruptible(&dev->sem)) {
				return -ERESTARTSYS;
			}
			writel(tmp,(u32*)(Godshand_location));
			up(&dev->sem);
			break;
		case GODSHAND_IOC_WRITE_AREA :
			ret = __get_user(tmp, (u32*)(&Godshand_info->dwData));
			if (down_interruptible(&dev->sem)) {
				return -ERESTARTSYS;
			}
			writel(tmp,(u32*)(Godshand_location));
			up(&dev->sem);
			break;
		default:  /* redundant, as cmd was checked against MAXNR */
			return -ENOTTY;
	}
fail :
	PDEBUG("%s iounmap\n",__func__);
	iounmap(Godshand_location);
	iounmap(Godshand_base);
	Godshand_base = NULL;
	PDEBUG("%s release_mem_region\n",__func__);
	release_mem_region(GODSHAND_START,GODSHAND_SIZE);
	return ret;

}
Esempio n. 23
0
int sg_ssp_init(void)
{
  int result;
  
  /* Set up owner pointers.*/
  SET_MODULE_OWNER(&sg_ssp_fops);
  
  /* Get our needed resources. */
  result = check_mem_region(SG_SSP_PHYSBASE, SG_SSP_SIZE);
  if (result) {
    printk(KERN_INFO "sg_ssp: can't get I/O mem address 0x%lx\n",
	   SG_SSP_PHYSBASE);
    return result;
  }
  request_mem_region(SG_SSP_PHYSBASE, SG_SSP_SIZE, "SSP");
  
  result = check_mem_region(SG_GPIOCNTL_PHYSBASE, SG_GPIOCNTL_SIZE);
  if (result) {
    printk(KERN_INFO "sg_ssp: can't get GPIO I/O mem address 0x%lx\n",
	   SG_GPIOCNTL_PHYSBASE);
    return result;
  }
  request_mem_region(SG_GPIOCNTL_PHYSBASE, SG_GPIOCNTL_SIZE, "SSPGPIO");

  /* also, ioremap it */
  sg_ssp_vbase = (unsigned long)sg_ssp_remap(SG_SSP_PHYSBASE,SG_SSP_SIZE);
  /* Hmm... we should check the return value */
  
  result = register_chrdev(major, "ssp", &sg_ssp_fops);
  if (result < 0) {
    printk(KERN_INFO "sg_ssp: can't get major number\n");
    sg_ssp_unmap((void *)sg_ssp_vbase);
    release_mem_region(SG_SSP_PHYSBASE,SG_SSP_SIZE);
    return result;
  }
  if (major == 0) major = result; /* dynamic */
  
  result = request_irq(IRQ_SSP, sg_ssp_interrupt,
		       SA_INTERRUPT, "ssp", NULL);
  if (result) {
    printk(KERN_INFO "sg_ssp: can't get assigned irq %i\n",
	   IRQ_SSP);
    sg_ssp_unmap((void *)sg_ssp_vbase);
    release_mem_region(SG_SSP_PHYSBASE,SG_SSP_SIZE);
    return result;
  }

  SSSR = SSPS_ROR;
  SSCR1 = 0;

  // Enable the SSP alternate functions
  set_GPIO_mode(GPIO23_SCLK_md);
  set_GPIO_mode(GPIO25_STXD_MD); // Enable the SSP TX/RX lines
  set_GPIO_mode(GPIO26_SRXD_MD);

  set_GPIO_mode((GPIO27_SEXTCLK | GPIO_IN));    // Avoid driving the RED LED
  set_GPIO_mode((22 | GPIO_OUT));		// MUX Selector
  set_GPIO_mode((77 | GPIO_OUT));		// RSTN 

  /* Set the state of the reset pin */
  GPSR(77) = GPIO_bit(77);  // RSTN -> 1
 
  return 0;
}
Esempio n. 24
0
//------------------------------------------------------
// int reg_open(struct inode *inode, struct file *filp)
//
// Descripción:
// 	Función para abrir e inicializar	
//	 
//------------------------------------------------------
int 
reg_open(struct inode *inode, struct file *filp)
{
	unsigned long val;	
	MOD_INC_USE_COUNT;  //para "decir" que lo estoy usando
	printk("<1>Opening adc...\n");
	
//comprobar disponibilidad de memoria
/**
 	if(check_mem_region(SYS_SW_LOCK, 4)) {
               printk("DUMB: espacio de memoria en uso: SYS_SW_LOCK\n");
               return -EBUSY;
       }
	printk ("hola hola hola hola");
	

       if(check_mem_region(ADC_CLK_DIV, 4)) {
               printk("DUMB: espacio de memoria en uso: ADC_CLK_DIV\n");
               return -EBUSY;
       }

	printk ("hola2 hola2 hola2 hola2");
	

 	if(check_mem_region(DEVICE_CFG, 4)) {
               printk("DUMB: espacio de memoria en uso: DEVICE_CFG\n");
               return -EBUSY;
       }


       if(check_mem_region(ADC_RESULT, 4)) {
               printk("DUMB: espacio de memoria en uso: ADC_RESULT\n");
               return -EBUSY;
       }
 	if(check_mem_region(ADC_SWITCH, 4)) {
               printk("DUMB: espacio de memoria en uso: ADC_SWITCH\n");
               return -EBUSY;
       }


       if(check_mem_region(ADC_SW_LOCK, 4)) {
               printk("DUMB: espacio de memoria en uso: ADC_SW_LOCK\n");
               return -EBUSY;
       }
**/

	if(check_mem_region(SYS_PAGE, 1024)) {
               printk("DUMB: espacio de memoria en uso: SYS_PAGE\n");
               return -EBUSY;
       }
	

       if(check_mem_region(ADC_PAGE, 1024)) {
               printk("DUMB: espacio de memoria en uso: ADC_PAGE\n");
               return -EBUSY;
       }	
	//Tomar memoria

	 /*request_mem_region(SYS_SW_LOCK, 4, "sys_sw_lock");
	 sys_sw_lock = __ioremap(SYS_SW_LOCK, 4, 0);

	 request_mem_region(ADC_CLK_DIV, 4, "adc_clk_div");
	 adc_clk_div = __ioremap(ADC_CLK_DIV, 4, 0);

	 request_mem_region(DEVICE_CFG, 4, "device_cfg");
	 device_cfg = __ioremap(DEVICE_CFG, 4, 0);

	 request_mem_region(ADC_RESULT, 4, "adc_result");
	 adc_result = __ioremap(ADC_RESULT, 4, 0);

	 request_mem_region(ADC_SWITCH, 4, "adc_switch");
	 adc_switch = __ioremap(ADC_SWITCH, 4, 0);

	 request_mem_region(ADC_SW_LOCK, 4, "adc_sw_lock");
	 adc_sw_lock = __ioremap(ADC_SW_LOCK, 4, 0);*/
	
	request_mem_region(SYS_PAGE, 1024, "sys_page");
	 sys_page = __ioremap(SYS_PAGE, 1024, 0);

	request_mem_region(ADC_PAGE, 1024, "adc_page");
	 adc_page = __ioremap(ADC_PAGE, 1024, 0);
	

	 /*printk("dumb: sys_sw_lock remap = %p\n", sys_sw_lock);
	 printk("dumb: adc_clk_div remap = %p\n", adc_clk_div);
	 printk("dumb: device_cfg remap = %p\n", device_cfg);
	 printk("dumb: adc_result remap = %p\n", adc_result);
	 printk("dumb: adc_switch remap = %p\n", adc_switch);
	 printk("dumb: adc_sw_lock remap = %p\n", adc_sw_lock);
	*/
	printk("dumb: sys_page remap = %p\n", sys_page);
	printk("dumb: adc_page remap = %p\n", adc_page);

	//Configura registros
	//val = *adc_clk_div;
	//*adc_sw_lock = 0xAA;
	val = *(sys_page + ADC_CLK_DIV);	
	*(sys_page + SYS_SW_LOCK) = 0xAA;	
	*(sys_page + ADC_CLK_DIV)= val | 0x80000000;
	//*sys_sw_lock = 0x000000AA;
	//*device_cfg = 0x08000D00;// <---da error (Pag.91 manual EP...)
	val = *(sys_page + DEVICE_CFG);
	*(sys_page + SYS_SW_LOCK) = 0xAA;
	*(sys_page + DEVICE_CFG)= val | 0x20000;//mascara para activar ADCEN	
	//*sys_sw_lock = 0xAA;
	//*device_cfg = val | 0x20000;
	val = *(sys_page +DEVICE_CFG);
	*(sys_page + SYS_SW_LOCK) = 0xAA;
	*(sys_page +DEVICE_CFG)= val & ~0x04;//Mascara para poner a "0" ADCPD
	
	//*sys_sw_lock = 0x000000AA;
	//*device_cfg &= 0xFFFFFFFB;
	val = *(adc_page + ADC_SWITCH);
	*(adc_page + ADC_SW_LOCK) = 0xAA;
	*(adc_page + ADC_SWITCH)= 0x0608;
	//*adc_sw_lock = 0x000000AA;
	//*adc_switch = 0x00000608;

/**
	//*((volatile unsigned int *)(SYS_SW_LOCK)) = 0xAA;   //desbloqueo software
	*((volatile unsigned int *)(ADC_SW_LOCK)) = 0xAA;
	//*((volatile unsigned int *)(ADC_CLK_DIV)) = 0x80000000; //reloj dividido por 16
	*((volatile unsigned int *)(ADC_CLK_DIV)) |= 0x80000000 ;
	*((volatile unsigned int *)(SYS_SW_LOCK)) = 0xAA;
	//*((volatile unsigned int *)(DEVICE_CFG)) = 0x00020000; //activar ADC	
	*((volatile unsigned int *)(DEVICE_CFG)) | 0x00020000; //ADCEN a "1"
	*((volatile unsigned int *)(SYS_SW_LOCK)) = 0xAA;
	*((volatile unsigned int *)(DEVICE_CFG)) & 0xFFFFFFFB; //ADCPD a "0"
	*((volatile unsigned int *)(ADC_SW_LOCK)) = 0xAA;  
	*((volatile unsigned int *)(ADC_SWITCH)) = 0x00000608; //ADC0 pin 27
	//*((volatile unsigned int *)(ADC_INT_EN)) = 0x00000000;     //desactivar interrupciones
**/
	printk("<1>adc init done\n");
  
	return 0;
}
Esempio n. 25
0
File: com90xx.c Progetto: nhanh0/hah
int __init com90xx_probe(struct net_device *dev)
{
    int count, status, ioaddr, numprint, airq, retval = -ENODEV,
                                               openparen = 0;
    unsigned long airqmask;
    int ports[(0x3f0 - 0x200) / 16 + 1] =
    {0};
    u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1] =
    {0};
    int numports, numshmems, *port;
    u_long *shmem;

    if (!dev && com90xx_skip_probe)
        return -ENODEV;

#ifndef MODULE
    arcnet_init();
#endif

    BUGLVL(D_NORMAL) printk(VERSION);

    /* set up the arrays where we'll store the possible probe addresses */
    numports = numshmems = 0;
    if (dev && dev->base_addr)
        ports[numports++] = dev->base_addr;
    else
        for (count = 0x200; count <= 0x3f0; count += 16)
            ports[numports++] = count;
    if (dev && dev->mem_start)
        shmems[numshmems++] = dev->mem_start;
    else
        for (count = 0xA0000; count <= 0xFF800; count += 2048)
            shmems[numshmems++] = count;

    /* Stage 1: abandon any reserved ports, or ones with status==0xFF
     * (empty), and reset any others by reading the reset port.
     */
    numprint = -1;
    for (port = &ports[0]; port - ports < numports; port++) {
        numprint++;
        numprint %= 8;
        if (!numprint) {
            BUGMSG2(D_INIT, "\n");
            BUGMSG2(D_INIT, "S1: ");
        }
        BUGMSG2(D_INIT, "%Xh ", *port);

        ioaddr = *port;

        if (check_region(*port, ARCNET_TOTAL_SIZE)) {
            BUGMSG2(D_INIT_REASONS, "(check_region)\n");
            BUGMSG2(D_INIT_REASONS, "S1: ");
            BUGLVL(D_INIT_REASONS) numprint = 0;
            *port = ports[numports - 1];
            numports--;
            port--;
            continue;
        }
        if (ASTATUS() == 0xFF) {
            BUGMSG2(D_INIT_REASONS, "(empty)\n");
            BUGMSG2(D_INIT_REASONS, "S1: ");
            BUGLVL(D_INIT_REASONS) numprint = 0;
            *port = ports[numports - 1];
            numports--;
            port--;
            continue;
        }
        inb(_RESET);	/* begin resetting card */

        BUGMSG2(D_INIT_REASONS, "\n");
        BUGMSG2(D_INIT_REASONS, "S1: ");
        BUGLVL(D_INIT_REASONS) numprint = 0;
    }
    BUGMSG2(D_INIT, "\n");

    if (!numports) {
        BUGMSG2(D_NORMAL, "S1: No ARCnet cards found.\n");
        return -ENODEV;
    }
    /* Stage 2: we have now reset any possible ARCnet cards, so we can't
     * do anything until they finish.  If D_INIT, print the list of
     * cards that are left.
     */
    numprint = -1;
    for (port = &ports[0]; port - ports < numports; port++) {
        numprint++;
        numprint %= 8;
        if (!numprint) {
            BUGMSG2(D_INIT, "\n");
            BUGMSG2(D_INIT, "S2: ");
        }
        BUGMSG2(D_INIT, "%Xh ", *port);
    }
    BUGMSG2(D_INIT, "\n");
    mdelay(RESETtime);

    /* Stage 3: abandon any shmem addresses that don't have the signature
     * 0xD1 byte in the right place, or are read-only.
     */
    numprint = -1;
    for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {
        u_long ptr = *shmem;

        numprint++;
        numprint %= 8;
        if (!numprint) {
            BUGMSG2(D_INIT, "\n");
            BUGMSG2(D_INIT, "S3: ");
        }
        BUGMSG2(D_INIT, "%lXh ", *shmem);

        if (check_mem_region(*shmem, BUFFER_SIZE)) {
            BUGMSG2(D_INIT_REASONS, "(check_mem_region)\n");
            BUGMSG2(D_INIT_REASONS, "Stage 3: ");
            BUGLVL(D_INIT_REASONS) numprint = 0;
            *shmem = shmems[numshmems - 1];
            numshmems--;
            shmem--;
            continue;
        }
        if (isa_readb(ptr) != TESTvalue) {
            BUGMSG2(D_INIT_REASONS, "(%02Xh != %02Xh)\n",
                    isa_readb(ptr), TESTvalue);
            BUGMSG2(D_INIT_REASONS, "S3: ");
            BUGLVL(D_INIT_REASONS) numprint = 0;
            *shmem = shmems[numshmems - 1];
            numshmems--;
            shmem--;
            continue;
        }
        /* By writing 0x42 to the TESTvalue location, we also make
         * sure no "mirror" shmem areas show up - if they occur
         * in another pass through this loop, they will be discarded
         * because *cptr != TESTvalue.
         */
        isa_writeb(0x42, ptr);
        if (isa_readb(ptr) != 0x42) {
            BUGMSG2(D_INIT_REASONS, "(read only)\n");
            BUGMSG2(D_INIT_REASONS, "S3: ");
            *shmem = shmems[numshmems - 1];
            numshmems--;
            shmem--;
            continue;
        }
        BUGMSG2(D_INIT_REASONS, "\n");
        BUGMSG2(D_INIT_REASONS, "S3: ");
        BUGLVL(D_INIT_REASONS) numprint = 0;
    }
    BUGMSG2(D_INIT, "\n");

    if (!numshmems) {
        BUGMSG2(D_NORMAL, "S3: No ARCnet cards found.\n");
        return -ENODEV;
    }
    /* Stage 4: something of a dummy, to report the shmems that are
     * still possible after stage 3.
     */
    numprint = -1;
    for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {
        numprint++;
        numprint %= 8;
        if (!numprint) {
            BUGMSG2(D_INIT, "\n");
            BUGMSG2(D_INIT, "S4: ");
        }
        BUGMSG2(D_INIT, "%lXh ", *shmem);
    }
    BUGMSG2(D_INIT, "\n");

    /* Stage 5: for any ports that have the correct status, can disable
     * the RESET flag, and (if no irq is given) generate an autoirq,
     * register an ARCnet device.
     *
     * Currently, we can only register one device per probe, so quit
     * after the first one is found.
     */
    numprint = -1;
    for (port = &ports[0]; port - ports < numports; port++) {
        numprint++;
        numprint %= 8;
        if (!numprint) {
            BUGMSG2(D_INIT, "\n");
            BUGMSG2(D_INIT, "S5: ");
        }
        BUGMSG2(D_INIT, "%Xh ", *port);

        ioaddr = *port;
        status = ASTATUS();

        if ((status & 0x9D)
                != (NORXflag | RECONflag | TXFREEflag | RESETflag)) {
            BUGMSG2(D_INIT_REASONS, "(status=%Xh)\n", status);
            BUGMSG2(D_INIT_REASONS, "S5: ");
            BUGLVL(D_INIT_REASONS) numprint = 0;
            *port = ports[numports - 1];
            numports--;
            port--;
            continue;
        }
        ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
        status = ASTATUS();
        if (status & RESETflag) {
            BUGMSG2(D_INIT_REASONS, " (eternal reset, status=%Xh)\n",
                    status);
            BUGMSG2(D_INIT_REASONS, "S5: ");
            BUGLVL(D_INIT_REASONS) numprint = 0;
            *port = ports[numports - 1];
            numports--;
            port--;
            continue;
        }
        /* skip this completely if an IRQ was given, because maybe
         * we're on a machine that locks during autoirq!
         */
        if (!dev || !dev->irq) {
            /* if we do this, we're sure to get an IRQ since the
             * card has just reset and the NORXflag is on until
             * we tell it to start receiving.
             */
            airqmask = probe_irq_on();
            AINTMASK(NORXflag);
            udelay(1);
            AINTMASK(0);
            airq = probe_irq_off(airqmask);

            if (airq <= 0) {
                BUGMSG2(D_INIT_REASONS, "(airq=%d)\n", airq);
                BUGMSG2(D_INIT_REASONS, "S5: ");
                BUGLVL(D_INIT_REASONS) numprint = 0;
                *port = ports[numports - 1];
                numports--;
                port--;
                continue;
            }
        } else {
            airq = dev->irq;
        }

        BUGMSG2(D_INIT, "(%d,", airq);
        openparen = 1;

        /* Everything seems okay.  But which shmem, if any, puts
         * back its signature byte when the card is reset?
         *
         * If there are multiple cards installed, there might be
         * multiple shmems still in the list.
         */
#ifdef FAST_PROBE
        if (numports > 1 || numshmems > 1) {
            inb(_RESET);
            mdelay(RESETtime);
        } else {
            /* just one shmem and port, assume they match */
            isa_writeb(TESTvalue, shmems[0]);
        }
#else
        inb(_RESET);
        mdelay(RESETtime);
#endif

        for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {
            u_long ptr = *shmem;

            if (isa_readb(ptr) == TESTvalue) {	/* found one */
                BUGMSG2(D_INIT, "%lXh)\n", *shmem);
                openparen = 0;

                /* register the card */
                retval = com90xx_found(dev, *port, airq, *shmem);
                numprint = -1;

                /* remove shmem from the list */
                *shmem = shmems[numshmems - 1];
                numshmems--;

                break;	/* go to the next I/O port */
            } else {
                BUGMSG2(D_INIT_REASONS, "%Xh-", isa_readb(ptr));
            }
        }

        if (openparen) {
            BUGLVL(D_INIT) printk("no matching shmem)\n");
            BUGLVL(D_INIT_REASONS) printk("S5: ");
            BUGLVL(D_INIT_REASONS) numprint = 0;
        }
        *port = ports[numports - 1];
        numports--;
        port--;
    }

    BUGLVL(D_INIT_REASONS) printk("\n");

    /* Now put back TESTvalue on all leftover shmems. */
    for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++)
        isa_writeb(TESTvalue, *shmem);

    if (retval && dev && !numcards)
        BUGMSG2(D_NORMAL, "S5: No ARCnet cards found.\n");
    return retval;
}