/* This is the function that scans the DIO space and works out what
 * hardware is actually present.
 */
static int __init dio_init(void)
{
        int scode;
        struct dioboard *b, *bprev = NULL;
   
        printk("Scanning for DIO devices...\n");
        
        for (scode = 0; scode < DIO_SCMAX; ++scode)
        {
                u_char prid, secid = 0;        /* primary, secondary ID bytes */
                u_char *va;
                
                if (DIO_SCINHOLE(scode))
                        continue;
                
                va = dio_scodetoviraddr(scode);
                if (!va || !hwreg_present(va + DIO_IDOFF))
                        continue;              /* no board present at that select code */

                /* Found a board, allocate it an entry in the list */
                b = kmalloc(sizeof(struct dioboard), GFP_KERNEL);
                
                /* read the ID byte(s) and encode if necessary. Note workaround 
                 * for broken internal HPIB devices...
                 */
                if (!DIO_ISIHPIB(scode))
                        prid = DIO_ID(va);
                else 
                        prid = DIO_ID_IHPIB;
                
                if (DIO_NEEDSSECID(prid))
                {
                        secid = DIO_SECID(va);
                        b->id = DIO_ENCODE_ID(prid, secid);
                }
                else
                        b->id = prid;
      
                b->configured = 0;
                b->scode = scode;
                b->ipl = DIO_IPL(va);
                b->name = dio_getname(b->id);
                printk("select code %3d: ipl %d: ID %02X", scode, b->ipl, prid);
                if (DIO_NEEDSSECID(b->id))
                        printk(":%02X", secid);
                printk(": %s\n", b->name);
                
                b->next = NULL;

                if (bprev)
                        bprev->next = b;
                else
                        blist = b;
                bprev = b;
        }
	return 0;
}
Exemple #2
0
/* This is the function that scans the DIO space and works out what
 * hardware is actually present.
 */
static int __init dio_init(void)
{
	int scode;
	mm_segment_t fs;
	int i;
	struct dio_dev *dev;
	int error;

	if (!MACH_IS_HP300)
		return 0;

        printk(KERN_INFO "Scanning for DIO devices...\n");

	/* Initialize the DIO bus */ 
	INIT_LIST_HEAD(&dio_bus.devices);
	dev_set_name(&dio_bus.dev, "dio");
	error = device_register(&dio_bus.dev);
	if (error) {
		pr_err("DIO: Error registering dio_bus\n");
		return error;
	}

	/* Request all resources */
	dio_bus.num_resources = (hp300_model == HP_320 ? 1 : 2);
	for (i = 0; i < dio_bus.num_resources; i++)
		request_resource(&iomem_resource, &dio_bus.resources[i]);

	/* Register all devices */
        for (scode = 0; scode < DIO_SCMAX; ++scode)
        {
                u_char prid, secid = 0;        /* primary, secondary ID bytes */
                u_char *va;
		unsigned long pa;
                
                if (DIO_SCINHOLE(scode))
                        continue;

		pa = dio_scodetophysaddr(scode);

		if (!pa)
			continue;

		if (scode < DIOII_SCBASE)
			va = (void *)(pa + DIO_VIRADDRBASE);
		else
			va = ioremap(pa, PAGE_SIZE);

		fs = get_fs();
		set_fs(KERNEL_DS);

                if (get_user(i, (unsigned char *)va + DIO_IDOFF)) {
			set_fs(fs);
			if (scode >= DIOII_SCBASE)
				iounmap(va);
                        continue;              /* no board present at that select code */
		}

		set_fs(fs);

                /* Found a board, allocate it an entry in the list */
		dev = kzalloc(sizeof(struct dio_dev), GFP_KERNEL);
		if (!dev)
			return 0;

		dev->bus = &dio_bus;
		dev->dev.parent = &dio_bus.dev;
		dev->dev.bus = &dio_bus_type;
		dev->scode = scode;
		dev->resource.start = pa;
		dev->resource.end = pa + DIO_SIZE(scode, va);
		dev_set_name(&dev->dev, "%02x", scode);

                /* read the ID byte(s) and encode if necessary. */
		prid = DIO_ID(va);

                if (DIO_NEEDSSECID(prid)) {
                        secid = DIO_SECID(va);
                        dev->id = DIO_ENCODE_ID(prid, secid);
                } else
                        dev->id = prid;

                dev->ipl = DIO_IPL(va);
                strcpy(dev->name,dio_getname(dev->id));
                printk(KERN_INFO "select code %3d: ipl %d: ID %02X", dev->scode, dev->ipl, prid);
                if (DIO_NEEDSSECID(prid))
                        printk(":%02X", secid);
                printk(": %s\n", dev->name);

		if (scode >= DIOII_SCBASE)
			iounmap(va);
		error = device_register(&dev->dev);
		if (error) {
			pr_err("DIO: Error registering device %s\n",
			       dev->name);
			continue;
		}
		error = dio_create_sysfs_dev_files(dev);
		if (error)
			dev_err(&dev->dev, "Error creating sysfs files\n");
        }
	return 0;
}