static int __init amiga_zorro_probe(struct platform_device *pdev)
{
	struct zorro_bus *bus;
	struct zorro_dev *z;
	struct resource *r;
	unsigned int i;
	int error;

	
	bus = kzalloc(sizeof(*bus), GFP_KERNEL);
	if (!bus)
		return -ENOMEM;

	INIT_LIST_HEAD(&bus->devices);
	bus->dev.parent = &pdev->dev;
	dev_set_name(&bus->dev, "zorro");
	error = device_register(&bus->dev);
	if (error) {
		pr_err("Zorro: Error registering zorro_bus\n");
		put_device(&bus->dev);
		kfree(bus);
		return error;
	}
	platform_set_drvdata(pdev, bus);

	pr_info("Zorro: Probing AutoConfig expansion devices: %u device%s\n",
		 zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");

	
	for (i = 0; i < zorro_num_autocon; i++) {
		z = &zorro_autocon[i];
		z->id = (z->rom.er_Manufacturer<<16) | (z->rom.er_Product<<8);
		if (z->id == ZORRO_PROD_GVP_EPC_BASE) {
			
			unsigned long magic = zorro_resource_start(z)+0x8000;
			z->id |= *(u16 *)ZTWO_VADDR(magic) & GVP_PRODMASK;
		}
		sprintf(z->name, "Zorro device %08x", z->id);
		zorro_name_device(z);
		z->resource.name = z->name;
		r = zorro_find_parent_resource(pdev, z);
		error = request_resource(r, &z->resource);
		if (error)
			dev_err(&bus->dev,
				"Address space collision on device %s %pR\n",
				z->name, &z->resource);
		dev_set_name(&z->dev, "%02x", i);
		z->dev.parent = &bus->dev;
		z->dev.bus = &zorro_bus_type;
	}

	
	for (i = 0; i < zorro_num_autocon; i++) {
		z = &zorro_autocon[i];
		error = device_register(&z->dev);
		if (error) {
			dev_err(&bus->dev, "Error registering device %s\n",
				z->name);
			put_device(&z->dev);
			continue;
		}
		error = zorro_create_sysfs_dev_files(z);
		if (error)
			dev_err(&z->dev, "Error creating sysfs files\n");
	}

	
	zorro_for_each_dev(z) {
		if (z->rom.er_Type & ERTF_MEMLIST)
			mark_region(zorro_resource_start(z),
				    zorro_resource_end(z)+1, 1);
	}

	
	for (i = 0; i < m68k_num_memory; i++)
		if (m68k_memory[i].addr < 16*1024*1024)
			mark_region(m68k_memory[i].addr,
				    m68k_memory[i].addr+m68k_memory[i].size,
				    0);

	return 0;
}
Example #2
0
File: vlynq.c Project: 020gzh/linux
static int vlynq_probe(struct platform_device *pdev)
{
	struct vlynq_device *dev;
	struct resource *regs_res, *mem_res, *irq_res;
	int len, result;

	regs_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
	if (!regs_res)
		return -ENODEV;

	mem_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem");
	if (!mem_res)
		return -ENODEV;

	irq_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "devirq");
	if (!irq_res)
		return -ENODEV;

	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev) {
		printk(KERN_ERR
		       "vlynq: failed to allocate device structure\n");
		return -ENOMEM;
	}

	dev->id = pdev->id;
	dev->dev.bus = &vlynq_bus_type;
	dev->dev.parent = &pdev->dev;
	dev_set_name(&dev->dev, "vlynq%d", dev->id);
	dev->dev.platform_data = pdev->dev.platform_data;
	dev->dev.release = vlynq_device_release;

	dev->regs_start = regs_res->start;
	dev->regs_end = regs_res->end;
	dev->mem_start = mem_res->start;
	dev->mem_end = mem_res->end;

	len = resource_size(regs_res);
	if (!request_mem_region(regs_res->start, len, dev_name(&dev->dev))) {
		printk(KERN_ERR "%s: Can't request vlynq registers\n",
		       dev_name(&dev->dev));
		result = -ENXIO;
		goto fail_request;
	}

	dev->local = ioremap(regs_res->start, len);
	if (!dev->local) {
		printk(KERN_ERR "%s: Can't remap vlynq registers\n",
		       dev_name(&dev->dev));
		result = -ENXIO;
		goto fail_remap;
	}

	dev->remote = (struct vlynq_regs *)((void *)dev->local +
					    VLYNQ_REMOTE_OFFSET);

	dev->irq = platform_get_irq_byname(pdev, "irq");
	dev->irq_start = irq_res->start;
	dev->irq_end = irq_res->end;
	dev->local_irq = dev->irq_end - dev->irq_start;
	dev->remote_irq = dev->local_irq - 1;

	if (device_register(&dev->dev))
		goto fail_register;
	platform_set_drvdata(pdev, dev);

	printk(KERN_INFO "%s: regs 0x%p, irq %d, mem 0x%p\n",
	       dev_name(&dev->dev), (void *)dev->regs_start, dev->irq,
	       (void *)dev->mem_start);

	dev->dev_id = 0;
	dev->divisor = vlynq_div_auto;
	result = __vlynq_enable_device(dev);
	if (result == 0) {
		dev->dev_id = readl(&dev->remote->chip);
		((struct plat_vlynq_ops *)(dev->dev.platform_data))->off(dev);
	}
	if (dev->dev_id)
		printk(KERN_INFO "Found a VLYNQ device: %08x\n", dev->dev_id);

	return 0;

fail_register:
	iounmap(dev->local);
fail_remap:
fail_request:
	release_mem_region(regs_res->start, len);
	kfree(dev);
	return result;
}
static int ide_gd_probe(ide_drive_t *drive)
{
	const struct ide_disk_ops *disk_ops = NULL;
	struct ide_disk_obj *idkp;
	struct gendisk *g;

	
	if (!strstr("ide-gd", drive->driver_req))
		goto failed;

#ifdef CONFIG_IDE_GD_ATA
	if (drive->media == ide_disk)
		disk_ops = &ide_ata_disk_ops;
#endif
#ifdef CONFIG_IDE_GD_ATAPI
	if (drive->media == ide_floppy)
		disk_ops = &ide_atapi_disk_ops;
#endif
	if (disk_ops == NULL)
		goto failed;

	if (disk_ops->check(drive, DRV_NAME) == 0) {
		printk(KERN_ERR PFX "%s: not supported by this driver\n",
			drive->name);
		goto failed;
	}

	idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
	if (!idkp) {
		printk(KERN_ERR PFX "%s: can't allocate a disk structure\n",
			drive->name);
		goto failed;
	}

	g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif));
	if (!g)
		goto out_free_idkp;

	ide_init_disk(g, drive);

	idkp->dev.parent = &drive->gendev;
	idkp->dev.release = ide_disk_release;
	dev_set_name(&idkp->dev, dev_name(&drive->gendev));

	if (device_register(&idkp->dev))
		goto out_free_disk;

	idkp->drive = drive;
	idkp->driver = &ide_gd_driver;
	idkp->disk = g;

	g->private_data = &idkp->driver;

	drive->driver_data = idkp;
	drive->debug_mask = debug_mask;
	drive->disk_ops = disk_ops;

	disk_ops->setup(drive);

	set_capacity(g, ide_gd_capacity(drive));

	g->minors = IDE_DISK_MINORS;
	g->driverfs_dev = &drive->gendev;
	g->flags |= GENHD_FL_EXT_DEVT;
	if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
		g->flags = GENHD_FL_REMOVABLE;
	g->fops = &ide_gd_ops;
	add_disk(g);
	return 0;

out_free_disk:
	put_disk(g);
out_free_idkp:
	kfree(idkp);
failed:
	return -ENODEV;
}
Example #4
0
static int xenbus_probe_node(struct xen_bus_type *bus,
			     const char *type,
			     const char *nodename)
{
	int err;
	struct xenbus_device *xendev;
	size_t stringlen;
	char *tmpstring;

	enum xenbus_state state = xenbus_read_driver_state(nodename);

	if (bus->error)
		return bus->error;

	if (state != XenbusStateInitialising) {
		/* Device is not new, so ignore it.  This can happen if a
		   device is going away after switching to Closed.  */
		return 0;
	}

	stringlen = strlen(nodename) + 1 + strlen(type) + 1;
	xendev = kzalloc(sizeof(*xendev) + stringlen, GFP_KERNEL);
	if (!xendev)
		return -ENOMEM;

	xendev->state = XenbusStateInitialising;

	/* Copy the strings into the extra space. */

	tmpstring = (char *)(xendev + 1);
	strcpy(tmpstring, nodename);
	xendev->nodename = tmpstring;

	tmpstring += strlen(tmpstring) + 1;
	strcpy(tmpstring, type);
	xendev->devicetype = tmpstring;
	init_completion(&xendev->down);

	xendev->dev.parent = &bus->dev;
	xendev->dev.bus = &bus->bus;
	xendev->dev.release = xenbus_dev_release;

	err = bus->get_bus_id(xendev->dev.bus_id, xendev->nodename);
	if (err)
		goto fail;

	/* Register with generic device framework. */
	err = device_register(&xendev->dev);
	if (err)
		goto fail;

	err = device_create_file(&xendev->dev, &dev_attr_nodename);
	if (err)
		goto unregister;
	err = device_create_file(&xendev->dev, &dev_attr_devtype);
	if (err)
		goto unregister;

	return 0;
unregister:
	device_remove_file(&xendev->dev, &dev_attr_nodename);
	device_remove_file(&xendev->dev, &dev_attr_devtype);
	device_unregister(&xendev->dev);
fail:
	kfree(xendev);
	return err;
}
Example #5
0
static void mtp_tunnel_bind(struct usb_endpoint **ept, void *_ctxt)
{
	struct mtp_tunnel_context *ctxt = _ctxt;
	struct usb_request *req;
	int ret;
#ifndef ALLOCATE_16K_BUFF
	int n;
#endif
	ctxt->registered = 0;
	ctxt->out = ept[0];
	ctxt->in = ept[1];

	printk(KERN_DEBUG "mtp_tunnel_bind() %p, %p\n", ctxt->out, ctxt->in);

#ifndef ALLOCATE_16K_BUFF
	for (n = 0; n < RX_REQ_MAX; n++)
#endif
	{
		req = usb_ept_alloc_req(ctxt->out, TXN_MAX);
		if (req == 0) goto fail;
		req->context = ctxt;
		req->complete = mtp_tunnel_complete_out;
		req_put(ctxt, &ctxt->rx_idle, req);
	}


#ifndef ALLOCATE_16K_BUFF
	for (n = 0; n < TX_REQ_MAX; n++)
#endif
	{
		req = usb_ept_alloc_req(ctxt->in, TXN_MAX);
		if (req == 0) goto fail;
		req->context = ctxt;
		req->complete = mtp_tunnel_complete_in;
		req_put(ctxt, &ctxt->tx_idle, req);
	}

#ifndef ALLOCATE_16K_BUFF
	printk(KERN_DEBUG
	       "mtp_tunnel_bind() allocated %d rx and %d tx requests\n",
	       RX_REQ_MAX, TX_REQ_MAX);
#else
	printk(KERN_DEBUG
		"%s(): allocated buffer: %d\n", __func__, TXN_MAX);
#endif

	misc_register(&mtp_tunnel_device);
	misc_register(&mtp_tunnel_enable_device);

	mtp_tunnel_dev.release = mtp_tunnel_dev_release;
	mtp_tunnel_dev.parent = &ctxt->pdev->dev;
	strcpy(mtp_tunnel_dev.bus_id, "interface");

	ret = device_register(&mtp_tunnel_dev);
	if (ret != 0) {
		printk(KERN_WARNING "mtp_tunnel_dev failed to register device: %d\n", ret);
		goto fail_dev_register_fail;
	}
	ret = device_create_file(&mtp_tunnel_dev, &dev_attr_mtp_tunnel_status);
	if (ret != 0) {
		printk(KERN_WARNING "mtp_tunnel_dev device_create_file failed: %d\n", ret);
		device_unregister(&mtp_tunnel_dev);
		goto fail_dev_register_fail;
	}
	ctxt->registered = 1;
	return;

fail_dev_register_fail:
	printk(KERN_ERR "%s() could not allocate requests\n", __func__);

fail:
	printk(KERN_WARNING "mtp_tunnel_bind() could not allocate requests\n");
	mtp_tunnel_unbind(ctxt);
}
Example #6
0
/*
 * try to add a new ccwgroup device for one driver
 * argc and argv[] are a list of bus_id's of devices
 * belonging to the driver.
 */
int
ccwgroup_create(struct device *root,
		unsigned int creator_id,
		struct ccw_driver *cdrv,
		int argc, char *argv[])
{
	struct ccwgroup_device *gdev;
	int i;
	int rc;

	if (argc > 256) /* disallow dumb users */
		return -EINVAL;

	gdev = kzalloc(sizeof(*gdev) + argc*sizeof(gdev->cdev[0]), GFP_KERNEL);
	if (!gdev)
		return -ENOMEM;

	atomic_set(&gdev->onoff, 0);
	mutex_init(&gdev->reg_mutex);
	mutex_lock(&gdev->reg_mutex);
	for (i = 0; i < argc; i++) {
		gdev->cdev[i] = get_ccwdev_by_busid(cdrv, argv[i]);

		/* all devices have to be of the same type in
		 * order to be grouped */
		if (!gdev->cdev[i]
		    || gdev->cdev[i]->id.driver_info !=
		    gdev->cdev[0]->id.driver_info) {
			rc = -EINVAL;
			goto error;
		}
		/* Don't allow a device to belong to more than one group. */
		if (gdev->cdev[i]->dev.driver_data) {
			rc = -EINVAL;
			goto error;
		}
		gdev->cdev[i]->dev.driver_data = gdev;
	}

	gdev->creator_id = creator_id;
	gdev->count = argc;
	gdev->dev.bus = &ccwgroup_bus_type;
	gdev->dev.parent = root;
	gdev->dev.release = ccwgroup_release;

	snprintf (gdev->dev.bus_id, BUS_ID_SIZE, "%s",
			gdev->cdev[0]->dev.bus_id);

	rc = device_register(&gdev->dev);
	if (rc)
		goto error;
	get_device(&gdev->dev);
	rc = device_create_file(&gdev->dev, &dev_attr_ungroup);

	if (rc) {
		device_unregister(&gdev->dev);
		goto error;
	}

	rc = __ccwgroup_create_symlinks(gdev);
	if (!rc) {
		mutex_unlock(&gdev->reg_mutex);
		put_device(&gdev->dev);
		return 0;
	}
	device_remove_file(&gdev->dev, &dev_attr_ungroup);
	device_unregister(&gdev->dev);
error:
	for (i = 0; i < argc; i++)
		if (gdev->cdev[i]) {
			if (gdev->cdev[i]->dev.driver_data == gdev)
				gdev->cdev[i]->dev.driver_data = NULL;
			put_device(&gdev->cdev[i]->dev);
		}
	mutex_unlock(&gdev->reg_mutex);
	put_device(&gdev->dev);
	return rc;
}
int felica_snfc_register(struct device *dev, struct felica_data *felica_data)
{
	int ret;
	struct felica_dev *d;

	dev_dbg(dev, "%s\n", __func__);

	if (reg_device) {
		dev_err(dev, "%s: felica_snfc was registered.\n",  __func__);
		ret =  -EBUSY;
		goto err_inval;
	}

	if (!dev) {
		dev_err(dev, "%s: device is null.\n",  __func__);
		ret =  -EINVAL;
		goto err_inval;
	}
	if (!felica_data) {
		dev_err(dev, "%s: felica_data is null.\n",  __func__);
		ret =  -EINVAL;
		goto err_inval;
	}
	if (!felica_data->flcen || !felica_data->flpon ||
		!felica_data->flrfs || !felica_data->flint) {
		dev_err(dev, "%s: felica ops is null.\n",  __func__);
		ret =  -EINVAL;
		goto err_inval;
	}
	if (FELICA_SNFC == felica_data->type &&
		(!felica_data->flintu || !felica_data->flhsel ||
		!felica_data->flldo)) {
		dev_err(dev, "%s: nfc ops is null.\n",  __func__);
		ret =  -EINVAL;
		goto err_inval;
	}

	d = kzalloc(sizeof(struct felica_dev), GFP_KERNEL);
	if (!d) {
		dev_err(dev, "%s: no memory\n", __func__);
		ret = -ENOMEM;
		goto err_alloc;
	}
	d->felica_data = felica_data;
	d->irq_shutdown = true;

	d->device_cen.minor = MISC_DYNAMIC_MINOR;
	d->device_cen.name = "felica_cen";
	d->device_cen.fops = &felica_cen_fops;

	d->device_pon.minor = MISC_DYNAMIC_MINOR;
	d->device_pon.name = "felica_pon";
	d->device_pon.fops = &felica_pon_fops;

	d->device_rfs.minor = MISC_DYNAMIC_MINOR;
	d->device_rfs.name = "felica_rfs";
	d->device_rfs.fops = &felica_rfs_fops;

	d->device_rws.minor = MISC_DYNAMIC_MINOR;
	d->device_rws.name = "felica_rws";
	d->device_rws.fops = &felica_rws_fops;

	if (FELICA_SNFC == felica_data->type) {
		d->device_hsel.minor = MISC_DYNAMIC_MINOR;
		d->device_hsel.name = "snfc_hsel";
		d->device_hsel.fops = &nfc_hsel_fops;

		d->device_intu_poll.minor = MISC_DYNAMIC_MINOR;
		d->device_intu_poll.name = "snfc_intu_poll";
		d->device_intu_poll.fops = &nfc_intu_poll_fops;

		d->device_available_poll.minor = MISC_DYNAMIC_MINOR;
		d->device_available_poll.name = "snfc_available_poll";
		d->device_available_poll.fops = &nfc_available_poll_fops;
	}

	d->dev = dev;
	dev_set_drvdata(dev, d);

	ret = felica_cen_probe_func(d);
	if (ret) {
		dev_err(dev, "%s: CEN probe failure\n", __func__);
		goto err_cen_probe;
	}

	ret = felica_pon_probe_func(d);
	if (ret) {
		dev_err(dev, "%s: PON probe failure\n", __func__);
		goto err_pon_probe;
	}

	ret = felica_rfs_probe_func(d);
	if (ret) {
		dev_err(dev, "%s: RFS probe failure\n", __func__);
		goto err_rfs_probe;
	}

	ret = felica_int_probe_func(d);
	if (ret) {
		dev_err(dev, "%s: INT probe failure\n", __func__);
		goto err_int_probe;
	}

	ret = felica_rws_probe_func(d);
	if (ret) {
		dev_err(dev, "%s: RWS probe failure\n", __func__);
		goto err_rws_probe;
	}

	if (FELICA_SNFC == felica_data->type) {
		ret = nfc_hsel_probe_func(d);
		if (ret) {
			dev_err(dev, "%s: NFC HSEL probe failure\n", __func__);
			goto err_nfc_hsel_probe;
		}

		ret = nfc_intu_poll_probe_func(d);
		if (ret) {
			dev_err(dev, "%s: NFC INTU POLL probe failure\n",
				__func__);
			goto err_nfc_intu_poll_probe;
		}
		init_waitqueue_head(&d->intu_wait_queue);

		ret = nfc_available_poll_probe_func(d);
		if (ret) {
			dev_err(dev, "%s: NFC AVAILABLE POLL probe failure\n",
				__func__);
			goto err_nfc_available_poll_probe;
		}
		init_waitqueue_head(&d->available_poll_wait);
		d->available_poll_nfc = 0;
	}
	d->sysfs_dev.init_name = "felica_snfc";
	dev_set_drvdata(&d->sysfs_dev, d);
	ret = device_register(&d->sysfs_dev);
	if (ret) {
		dev_err(dev, "%s: failed to register device.\n", __func__);
		goto err_register_device;
	}

	ret = create_sysfs_interfaces(&d->sysfs_dev);
	if (ret) {
		dev_err(dev, "%s: failed to create dev.\n", __func__);
		goto err_create_sysfs;
	}

	reg_device = dev;

	return 0;

err_create_sysfs:
	device_unregister(&d->sysfs_dev);
err_register_device:
	nfc_available_poll_remove_func(d);
err_nfc_available_poll_probe:
	nfc_intu_poll_remove_func(d);
err_nfc_intu_poll_probe:
	nfc_hsel_remove_func(d);
err_nfc_hsel_probe:
	felica_rws_remove_func(d);
err_rws_probe:
	felica_int_remove_func(d);
err_int_probe:
	felica_rfs_remove_func(d);
err_rfs_probe:
	felica_pon_remove_func(d);
err_pon_probe:
	felica_cen_remove_func(d);
err_cen_probe:
	kfree(d);
err_alloc:
err_inval:
	return ret;
}
struct qcom_glink *qcom_glink_smem_register(struct device *parent,
					    struct device_node *node)
{
	struct glink_smem_pipe *rx_pipe;
	struct glink_smem_pipe *tx_pipe;
	struct qcom_glink *glink;
	struct device *dev;
	u32 remote_pid;
	__le32 *descs;
	size_t size;
	int ret;

	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev)
		return ERR_PTR(-ENOMEM);

	dev->parent = parent;
	dev->of_node = node;
	dev->release = qcom_glink_smem_release;
	dev_set_name(dev, "%s:%s", node->parent->name, node->name);
	ret = device_register(dev);
	if (ret) {
		pr_err("failed to register glink edge\n");
		put_device(dev);
		return ERR_PTR(ret);
	}

	ret = of_property_read_u32(dev->of_node, "qcom,remote-pid",
				   &remote_pid);
	if (ret) {
		dev_err(dev, "failed to parse qcom,remote-pid\n");
		goto err_put_dev;
	}

	rx_pipe = devm_kzalloc(dev, sizeof(*rx_pipe), GFP_KERNEL);
	tx_pipe = devm_kzalloc(dev, sizeof(*tx_pipe), GFP_KERNEL);
	if (!rx_pipe || !tx_pipe) {
		ret = -ENOMEM;
		goto err_put_dev;
	}

	ret = qcom_smem_alloc(remote_pid,
			      SMEM_GLINK_NATIVE_XPRT_DESCRIPTOR, 32);
	if (ret && ret != -EEXIST) {
		dev_err(dev, "failed to allocate glink descriptors\n");
		goto err_put_dev;
	}

	descs = qcom_smem_get(remote_pid,
			      SMEM_GLINK_NATIVE_XPRT_DESCRIPTOR, &size);
	if (IS_ERR(descs)) {
		dev_err(dev, "failed to acquire xprt descriptor\n");
		ret = PTR_ERR(descs);
		goto err_put_dev;
	}

	if (size != 32) {
		dev_err(dev, "glink descriptor of invalid size\n");
		ret = -EINVAL;
		goto err_put_dev;
	}

	tx_pipe->tail = &descs[0];
	tx_pipe->head = &descs[1];
	rx_pipe->tail = &descs[2];
	rx_pipe->head = &descs[3];

	ret = qcom_smem_alloc(remote_pid, SMEM_GLINK_NATIVE_XPRT_FIFO_0,
			      SZ_16K);
	if (ret && ret != -EEXIST) {
		dev_err(dev, "failed to allocate TX fifo\n");
		goto err_put_dev;
	}

	tx_pipe->fifo = qcom_smem_get(remote_pid, SMEM_GLINK_NATIVE_XPRT_FIFO_0,
				      &tx_pipe->native.length);
	if (IS_ERR(tx_pipe->fifo)) {
		dev_err(dev, "failed to acquire TX fifo\n");
		ret = PTR_ERR(tx_pipe->fifo);
		goto err_put_dev;
	}

	rx_pipe->native.avail = glink_smem_rx_avail;
	rx_pipe->native.peak = glink_smem_rx_peak;
	rx_pipe->native.advance = glink_smem_rx_advance;
	rx_pipe->remote_pid = remote_pid;

	tx_pipe->native.avail = glink_smem_tx_avail;
	tx_pipe->native.write = glink_smem_tx_write;
	tx_pipe->remote_pid = remote_pid;

	*rx_pipe->tail = 0;
	*tx_pipe->head = 0;

	glink = qcom_glink_native_probe(dev,
					GLINK_FEATURE_INTENT_REUSE,
					&rx_pipe->native, &tx_pipe->native,
					false);
	if (IS_ERR(glink)) {
		ret = PTR_ERR(glink);
		goto err_put_dev;
	}

	return glink;

err_put_dev:
	device_unregister(dev);

	return ERR_PTR(ret);
}
Example #9
0
int gio_device_register(struct gio_device *giodev)
{
	giodev->dev.bus = &gio_bus_type;
	giodev->dev.parent = &gio_bus;
	return device_register(&giodev->dev);
}
Example #10
0
/*
 * Probing for TURBOchannel modules.
 */
static void __init tc_bus_add_devices(struct tc_bus *tbus)
{
	resource_size_t slotsize = tbus->info.slot_size << 20;
	resource_size_t extslotsize = tbus->ext_slot_size;
	resource_size_t slotaddr;
	resource_size_t extslotaddr;
	resource_size_t devsize;
	void __iomem *module;
	struct tc_dev *tdev;
	int i, slot, err;
	u8 pattern[4];
	long offset;

	for (slot = 0; slot < tbus->num_tcslots; slot++) {
		slotaddr = tbus->slot_base + slot * slotsize;
		extslotaddr = tbus->ext_slot_base + slot * extslotsize;
		module = ioremap_nocache(slotaddr, slotsize);
		BUG_ON(!module);

		offset = TC_OLDCARD;

		err = 0;
		err |= tc_preadb(pattern + 0, module + offset + TC_PATTERN0);
		err |= tc_preadb(pattern + 1, module + offset + TC_PATTERN1);
		err |= tc_preadb(pattern + 2, module + offset + TC_PATTERN2);
		err |= tc_preadb(pattern + 3, module + offset + TC_PATTERN3);
		if (err)
			goto out_err;

		if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
		    pattern[2] != 0xaa || pattern[3] != 0xff) {
			offset = TC_NEWCARD;

			err = 0;
			err |= tc_preadb(pattern + 0,
					 module + offset + TC_PATTERN0);
			err |= tc_preadb(pattern + 1,
					 module + offset + TC_PATTERN1);
			err |= tc_preadb(pattern + 2,
					 module + offset + TC_PATTERN2);
			err |= tc_preadb(pattern + 3,
					 module + offset + TC_PATTERN3);
			if (err)
				goto out_err;
		}

		if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
		    pattern[2] != 0xaa || pattern[3] != 0xff)
			goto out_err;

		/* Found a board, allocate it an entry in the list */
		tdev = kzalloc(sizeof(*tdev), GFP_KERNEL);
		if (!tdev) {
			printk(KERN_ERR "tc%x: unable to allocate tc_dev\n",
			       slot);
			goto out_err;
		}
		dev_set_name(&tdev->dev, "tc%x", slot);
		tdev->bus = tbus;
		tdev->dev.parent = &tbus->dev;
		tdev->dev.bus = &tc_bus_type;
		tdev->slot = slot;

		for (i = 0; i < 8; i++) {
			tdev->firmware[i] =
				readb(module + offset + TC_FIRM_VER + 4 * i);
			tdev->vendor[i] =
				readb(module + offset + TC_VENDOR + 4 * i);
			tdev->name[i] =
				readb(module + offset + TC_MODULE + 4 * i);
		}
		tdev->firmware[8] = 0;
		tdev->vendor[8] = 0;
		tdev->name[8] = 0;

		pr_info("%s: %s %s %s\n", dev_name(&tdev->dev), tdev->vendor,
			tdev->name, tdev->firmware);

		devsize = readb(module + offset + TC_SLOT_SIZE);
		devsize <<= 22;
		if (devsize <= slotsize) {
			tdev->resource.start = slotaddr;
			tdev->resource.end = slotaddr + devsize - 1;
		} else if (devsize <= extslotsize) {
			tdev->resource.start = extslotaddr;
			tdev->resource.end = extslotaddr + devsize - 1;
		} else {
			printk(KERN_ERR "%s: Cannot provide slot space "
			       "(%dMiB required, up to %dMiB supported)\n",
			       dev_name(&tdev->dev), devsize >> 20,
			       max(slotsize, extslotsize) >> 20);
			kfree(tdev);
			goto out_err;
		}
		tdev->resource.name = tdev->name;
		tdev->resource.flags = IORESOURCE_MEM;

		tc_device_get_irq(tdev);

		device_register(&tdev->dev);
		list_add_tail(&tdev->node, &tbus->devices);

out_err:
		iounmap(module);
	}
}
Example #11
0
static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_data)
{
	const usbh_driver_t *lld = dev->lld;
	usbh_generic_data_t *lld_data = lld->driver_data;
	uint8_t *usbh_buffer = lld_data->usbh_buffer;
	uint8_t state_start = dev->state; // Detection of hang
//	LOG_PRINTF("\nSTATE: %d\n", state);
	switch (dev->state) {
	case 1:
		{
			switch (cb_data.status) {
			case USBH_PACKET_CALLBACK_STATUS_OK:
				dev->state++;
				device_xfer_control_read(0, 0, device_enumerate, dev);
				break;

			case USBH_PACKET_CALLBACK_STATUS_EFATAL:
			case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
			case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
				device_enumeration_terminate(dev);
				break;
			}
		}
		break;

	case 2:
		switch (cb_data.status) {
		case USBH_PACKET_CALLBACK_STATUS_OK:
			if (dev->address == 0) {
				dev->address = usbh_data.address_temporary;
			}

			struct usb_setup_data setup_data;

			setup_data.bmRequestType = 0b10000000;
			setup_data.bRequest = USB_REQ_GET_DESCRIPTOR;
			setup_data.wValue = USB_DT_DEVICE << 8;
			setup_data.wIndex = 0;
			setup_data.wLength = USB_DT_DEVICE_SIZE;

			dev->state++;
			device_xfer_control_write(&setup_data, sizeof(setup_data),
				device_enumerate, dev);
			break;

		case USBH_PACKET_CALLBACK_STATUS_EFATAL:
		case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
		case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
			device_enumeration_terminate(dev);
			break;
		}
		break;

	case 3:
		{
			switch (cb_data.status) {
			case USBH_PACKET_CALLBACK_STATUS_OK:
				dev->state++;
				device_xfer_control_read(&usbh_buffer[0], USB_DT_DEVICE_SIZE,
					device_enumerate, dev);
				break;

			case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
				dev->state = 2;

				// WARNING: Recursion
				// .. but should work
				cb_data.status = USBH_PACKET_CALLBACK_STATUS_OK;
				device_enumerate(dev, cb_data);
				break;

			case USBH_PACKET_CALLBACK_STATUS_EFATAL:
			case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
				device_enumeration_terminate(dev);
				break;
			}
		}
		break;

	case 4:
		{
			switch (cb_data.status) {
			case USBH_PACKET_CALLBACK_STATUS_OK:
				{
					struct usb_device_descriptor *ddt =
							(struct usb_device_descriptor *)&usbh_buffer[0];
					dev->packet_size_max0 = ddt->bMaxPacketSize0;
					struct usb_setup_data setup_data;

					setup_data.bmRequestType = 0b10000000;
					setup_data.bRequest = USB_REQ_GET_DESCRIPTOR;
					setup_data.wValue = USB_DT_CONFIGURATION << 8;
					setup_data.wIndex = 0;
					setup_data.wLength = ddt->bMaxPacketSize0;//USB_DT_CONFIGURATION_SIZE;

					dev->state++;
					device_xfer_control_write(&setup_data, sizeof(setup_data),
						device_enumerate, dev);
				}
				break;

			case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
				if (cb_data.transferred_length >= 8) {
					struct usb_device_descriptor *ddt =
						(struct usb_device_descriptor *)&usbh_buffer[0];
					dev->packet_size_max0 = ddt->bMaxPacketSize0;
					dev->state = 2;

					// WARNING: Recursion
					// .. but should work
					cb_data.status = USBH_PACKET_CALLBACK_STATUS_OK;
					device_enumerate(dev, cb_data);
				}
				break;

			case USBH_PACKET_CALLBACK_STATUS_EFATAL:
			case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
				device_enumeration_terminate(dev);
				break;
			}
		}
		break;

	case 5:
		{
			switch (cb_data.status) {
			case USBH_PACKET_CALLBACK_STATUS_OK:
				dev->state++;
				device_xfer_control_read(&usbh_buffer[USB_DT_DEVICE_SIZE],
					dev->packet_size_max0, device_enumerate, dev);
				break;

			case USBH_PACKET_CALLBACK_STATUS_EFATAL:
			case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
			case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
				device_enumeration_terminate(dev);
				break;
			}
		}
		break;

	case 6:
		{
			switch (cb_data.status) {
			case USBH_PACKET_CALLBACK_STATUS_OK:
				{
					struct usb_config_descriptor *cdt =
						(struct usb_config_descriptor *)&usbh_buffer[USB_DT_DEVICE_SIZE];
					struct usb_setup_data setup_data;
					setup_data.bmRequestType = 0b10000000;
					setup_data.bRequest = USB_REQ_GET_DESCRIPTOR;
					setup_data.wValue = USB_DT_CONFIGURATION << 8;
					setup_data.wIndex = 0;
					setup_data.wLength = cdt->wTotalLength;

					dev->state++;
					device_xfer_control_write(&setup_data, sizeof(setup_data),
						device_enumerate, dev);
				}
				break;

			case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
				if (cb_data.transferred_length >= USB_DT_CONFIGURATION_SIZE) {
					struct usb_config_descriptor *cdt =
						(struct usb_config_descriptor *)&usbh_buffer[USB_DT_DEVICE_SIZE];
					if (cb_data.transferred_length <= cdt->wTotalLength) {
						dev->state = 8;

						// WARNING: Recursion
						// .. but should work
						cb_data.status = USBH_PACKET_CALLBACK_STATUS_OK;
						device_enumerate(dev, cb_data);
					}
				}
				break;

			case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
			case USBH_PACKET_CALLBACK_STATUS_EFATAL:
				device_enumeration_terminate(dev);
				break;
			}
		}
		break;

	case 7:
		{
			switch (cb_data.status) {
			case USBH_PACKET_CALLBACK_STATUS_OK:
				{
					struct usb_config_descriptor *cdt =
						(struct usb_config_descriptor *)&usbh_buffer[USB_DT_DEVICE_SIZE];
					dev->state++;
					device_xfer_control_read(&usbh_buffer[USB_DT_DEVICE_SIZE],
						cdt->wTotalLength, device_enumerate, dev);
				}
				break;

			case USBH_PACKET_CALLBACK_STATUS_EFATAL:
			case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
			case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
				device_enumeration_terminate(dev);
				break;
			}
		}
		break;

	case 8:
		{
			switch (cb_data.status) {
			case USBH_PACKET_CALLBACK_STATUS_OK:
				{
					struct usb_config_descriptor *cdt =
						(struct usb_config_descriptor *)&usbh_buffer[USB_DT_DEVICE_SIZE];
					device_register(usbh_buffer, cdt->wTotalLength + USB_DT_DEVICE_SIZE, dev);
					dev->state++;

					reset_enumeration();
				}
				break;

			case USBH_PACKET_CALLBACK_STATUS_EFATAL:
			case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
			case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
				device_enumeration_terminate(dev);
				break;
			}

		}
		break;

	default:
		break;
	}

	if (state_start == dev->state) {
	}
}
Example #12
0
int mcp_host_register(struct mcp *mcp)
{
	dev_set_name(&mcp->attached_device, "mcp0");
	return device_register(&mcp->attached_device);
}
Example #13
0
int xenbus_probe_node(struct xen_bus_type *bus,
		      const char *type,
		      const char *nodename)
{
	int err;
	struct xenbus_device *xendev;
	size_t stringlen;
	char *tmpstring;

	enum xenbus_state state = xenbus_read_driver_state(nodename);

	if (bus->error)
		return bus->error;

	if (state != XenbusStateInitialising) {
		/* Device is not new, so ignore it.  This can happen if a
		   device is going away after switching to Closed.  */
		return 0;
	}

	stringlen = strlen(nodename) + 1 + strlen(type) + 1;
	xendev = kzalloc(sizeof(*xendev) + stringlen, GFP_KERNEL);
	if (!xendev)
		return -ENOMEM;

	xendev->state = XenbusStateInitialising;

	/* Copy the strings into the extra space. */

	tmpstring = (char *)(xendev + 1);
	strcpy(tmpstring, nodename);
	xendev->nodename = tmpstring;

	tmpstring += strlen(tmpstring) + 1;
	strcpy(tmpstring, type);
	xendev->devicetype = tmpstring;
	init_completion(&xendev->down);

#if defined(CONFIG_XEN) || defined(MODULE)
	xendev->dev.parent = &bus->dev;
#endif
	xendev->dev.bus = &bus->bus;
	xendev->dev.release = xenbus_dev_release;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
	{
		char devname[XEN_BUS_ID_SIZE];

		err = bus->get_bus_id(devname, xendev->nodename);
		if (!err)
			dev_set_name(&xendev->dev, devname);
	}
#else
	err = bus->get_bus_id(xendev->dev.bus_id, xendev->nodename);
#endif
	if (err)
		goto fail;

	/* Register with generic device framework. */
	err = device_register(&xendev->dev);
	if (err)
		goto fail;

	err = device_create_file(&xendev->dev, &dev_attr_nodename);
	if (err)
		goto fail_unregister;

	err = device_create_file(&xendev->dev, &dev_attr_devtype);
	if (err)
		goto fail_remove_nodename;

	err = device_create_file(&xendev->dev, &dev_attr_modalias);
	if (err)
		goto fail_remove_devtype;

	return 0;
fail_remove_devtype:
	device_remove_file(&xendev->dev, &dev_attr_devtype);
fail_remove_nodename:
	device_remove_file(&xendev->dev, &dev_attr_nodename);
fail_unregister:
	device_unregister(&xendev->dev);
fail:
	kfree(xendev);
	return err;
}
Example #14
0
static int __init omap_device_init(void)
{
	return device_register(&omap_device_parent);
}
Example #15
0
/**
 * zfcp_port_enqueue - enqueue port to port list of adapter
 * @adapter: adapter where remote port is added
 * @wwpn: WWPN of the remote port to be enqueued
 * @status: initial status for the port
 * @d_id: destination id of the remote port to be enqueued
 * Returns: pointer to enqueued port on success, ERR_PTR on error
 * Locks: config_mutex must be held to serialize changes to the port list
 *
 * All port internal structures are set up and the sysfs entry is generated.
 * d_id is used to enqueue ports with a well known address like the Directory
 * Service for nameserver lookup.
 */
struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
				     u32 status, u32 d_id)
{
	struct zfcp_port *port;

	read_lock_irq(&zfcp_data.config_lock);
	if (zfcp_get_port_by_wwpn(adapter, wwpn)) {
		read_unlock_irq(&zfcp_data.config_lock);
		return ERR_PTR(-EINVAL);
	}
	read_unlock_irq(&zfcp_data.config_lock);

	port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL);
	if (!port)
		return ERR_PTR(-ENOMEM);

	init_waitqueue_head(&port->remove_wq);
	INIT_LIST_HEAD(&port->unit_list_head);
	INIT_WORK(&port->gid_pn_work, zfcp_fc_port_did_lookup);
	INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work);
	INIT_WORK(&port->rport_work, zfcp_scsi_rport_work);

	port->adapter = adapter;
	port->d_id = d_id;
	port->wwpn = wwpn;
	port->rport_task = RPORT_NONE;

	/* mark port unusable as long as sysfs registration is not complete */
	atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status);
	atomic_set(&port->refcount, 0);

	if (dev_set_name(&port->sysfs_device, "0x%016llx",
			 (unsigned long long)wwpn)) {
		kfree(port);
		return ERR_PTR(-ENOMEM);
	}
	port->sysfs_device.parent = &adapter->ccw_device->dev;
	port->sysfs_device.release = zfcp_sysfs_port_release;
	dev_set_drvdata(&port->sysfs_device, port);

	if (device_register(&port->sysfs_device)) {
		put_device(&port->sysfs_device);
		return ERR_PTR(-EINVAL);
	}

	if (sysfs_create_group(&port->sysfs_device.kobj,
			       &zfcp_sysfs_port_attrs)) {
		device_unregister(&port->sysfs_device);
		return ERR_PTR(-EINVAL);
	}

	zfcp_port_get(port);

	write_lock_irq(&zfcp_data.config_lock);
	list_add_tail(&port->list, &adapter->port_list_head);
	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
	atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status);

	write_unlock_irq(&zfcp_data.config_lock);

	zfcp_adapter_get(adapter);
	return port;
}
Example #16
0
static int __init exynos_init(void)
{
	printk(KERN_INFO "EXYNOS: Initializing architecture\n");

	return device_register(&exynos4_dev);
}
Example #17
0
File: dma.c Project: Afek/linux
static int s3c64xx_dma_init1(int chno, enum dma_ch chbase,
			     int irq, unsigned int base)
{
	struct s3c2410_dma_chan *chptr = &s3c2410_chans[chno];
	struct s3c64xx_dmac *dmac;
	char clkname[16];
	void __iomem *regs;
	void __iomem *regptr;
	int err, ch;

	dmac = kzalloc(sizeof(struct s3c64xx_dmac), GFP_KERNEL);
	if (!dmac) {
		printk(KERN_ERR "%s: failed to alloc mem\n", __func__);
		return -ENOMEM;
	}

	dmac->dev.id = chno / 8;
	dmac->dev.bus = &dma_subsys;

	err = device_register(&dmac->dev);
	if (err) {
		printk(KERN_ERR "%s: failed to register device\n", __func__);
		goto err_alloc;
	}

	regs = ioremap(base, 0x200);
	if (!regs) {
		printk(KERN_ERR "%s: failed to ioremap()\n", __func__);
		err = -ENXIO;
		goto err_dev;
	}

	snprintf(clkname, sizeof(clkname), "dma%d", dmac->dev.id);

	dmac->clk = clk_get(NULL, clkname);
	if (IS_ERR(dmac->clk)) {
		printk(KERN_ERR "%s: failed to get clock %s\n", __func__, clkname);
		err = PTR_ERR(dmac->clk);
		goto err_map;
	}

	clk_enable(dmac->clk);

	dmac->regs = regs;
	dmac->chanbase = chbase;
	dmac->channels = chptr;

	err = request_irq(irq, s3c64xx_dma_irq, 0, "DMA", dmac);
	if (err < 0) {
		printk(KERN_ERR "%s: failed to get irq\n", __func__);
		goto err_clk;
	}

	regptr = regs + PL080_Cx_BASE(0);

	for (ch = 0; ch < 8; ch++, chptr++) {
		pr_debug("%s: registering DMA %d (%p)\n",
			 __func__, chno + ch, regptr);

		chptr->bit = 1 << ch;
		chptr->number = chno + ch;
		chptr->dmac = dmac;
		chptr->regs = regptr;
		regptr += PL080_Cx_STRIDE;
	}

	/* for the moment, permanently enable the controller */
	writel(PL080_CONFIG_ENABLE, regs + PL080_CONFIG);

	printk(KERN_INFO "PL080: IRQ %d, at %p, channels %d..%d\n",
	       irq, regs, chno, chno+8);

	return 0;

err_clk:
	clk_disable(dmac->clk);
	clk_put(dmac->clk);
err_map:
	iounmap(regs);
err_dev:
	device_unregister(&dmac->dev);
err_alloc:
	kfree(dmac);
	return err;
}
Example #18
0
/*-----------------------------------------------------------------------------
 *  This func is used to create all the necessary stuff, bind
 * the fixed phy driver and register all it on the mdio_bus_type.
 * speed is either 10 or 100, duplex is boolean.
 * number is used to create multiple fixed PHYs, so that several devices can
 * utilize them simultaneously.
 *-----------------------------------------------------------------------------*/
static int fixed_mdio_register_device(int number, int speed, int duplex)
{
	struct mii_bus *new_bus;
	struct fixed_info *fixed;
	struct phy_device *phydev;
	int err = 0;

	struct device* dev = kzalloc(sizeof(struct device), GFP_KERNEL);

	if (NULL == dev)
		return -ENOMEM;

	new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);

	if (NULL == new_bus) {
		kfree(dev);
		return -ENOMEM;
	}
	fixed = kzalloc(sizeof(struct fixed_info), GFP_KERNEL);

	if (NULL == fixed) {
		kfree(dev);
		kfree(new_bus);
		return -ENOMEM;
	}

	fixed->regs = kzalloc(MII_REGS_NUM*sizeof(int), GFP_KERNEL);
	fixed->regs_num = MII_REGS_NUM;
	fixed->phy_status.speed = speed;
	fixed->phy_status.duplex = duplex;
	fixed->phy_status.link = 1;

	new_bus->name = "Fixed MII Bus",
	new_bus->read = &fixed_mii_read,
	new_bus->write = &fixed_mii_write,
	new_bus->reset = &fixed_mii_reset,

	/*set up workspace*/
	fixed_mdio_update_regs(fixed);
	new_bus->priv = fixed;

	new_bus->dev = dev;
	dev_set_drvdata(dev, new_bus);

	/* create phy_device and register it on the mdio bus */
	phydev = phy_device_create(new_bus, 0, 0);

	/*
	 Put the phydev pointer into the fixed pack so that bus read/write code could
	 be able to access for instance attached netdev. Well it doesn't have to do
	 so, only in case of utilizing user-specified link-update...
	 */
	fixed->phydev = phydev;

	if(NULL == phydev) {
		err = -ENOMEM;
		goto device_create_fail;
	}

	phydev->irq = -1;
	phydev->dev.bus = &mdio_bus_type;

	if(number)
		snprintf(phydev->dev.bus_id, BUS_ID_SIZE,
				"fixed_%d@%d:%d", number, speed, duplex);
	else
		snprintf(phydev->dev.bus_id, BUS_ID_SIZE,
				"fixed@%d:%d", speed, duplex);
	phydev->bus = new_bus;

	err = device_register(&phydev->dev);
	if(err) {
		printk(KERN_ERR "Phy %s failed to register\n",
				phydev->dev.bus_id);
		goto bus_register_fail;
	}

	/*
	   the mdio bus has phy_id match... In order not to do it
	   artificially, we are binding the driver here by hand;
	   it will be the same for all the fixed phys anyway.
	 */
	down_write(&phydev->dev.bus->subsys.rwsem);

	phydev->dev.driver = &fixed_mdio_driver.driver;

	err = phydev->dev.driver->probe(&phydev->dev);
	if(err < 0) {
		printk(KERN_ERR "Phy %s: problems with fixed driver\n",phydev->dev.bus_id);
		up_write(&phydev->dev.bus->subsys.rwsem);
		goto probe_fail;
	}

	device_bind_driver(&phydev->dev);
	up_write(&phydev->dev.bus->subsys.rwsem);

	return 0;

probe_fail:
	device_unregister(&phydev->dev);
bus_register_fail:
	kfree(phydev);
device_create_fail:
	kfree(dev);
	kfree(new_bus);
	kfree(fixed);

	return err;
}
Example #19
0
int __init s5pc100_init(void)
{
	printk(KERN_INFO "S5PC100: Initializing architecture\n");
	return device_register(&s5pc100_dev);
}
Example #20
0
/**
 * zfcp_unit_enqueue - enqueue unit to unit list of a port.
 * @port: pointer to port where unit is added
 * @fcp_lun: FCP LUN of unit to be enqueued
 * Returns: pointer to enqueued unit on success, ERR_PTR on error
 *
 * Sets up some unit internal structures and creates sysfs entry.
 */
struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
{
	struct zfcp_unit *unit;
	int retval = -ENOMEM;

	get_device(&port->sysfs_device);

	unit = zfcp_get_unit_by_lun(port, fcp_lun);
	if (unit) {
		put_device(&unit->sysfs_device);
		retval = -EEXIST;
		goto err_out;
	}

	unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL);
	if (!unit)
		goto err_out;

	unit->port = port;
	unit->fcp_lun = fcp_lun;
	unit->sysfs_device.parent = &port->sysfs_device;
	unit->sysfs_device.release = zfcp_unit_release;

	if (dev_set_name(&unit->sysfs_device, "0x%016llx",
			 (unsigned long long) fcp_lun)) {
		kfree(unit);
		goto err_out;
	}
	retval = -EINVAL;

	INIT_WORK(&unit->scsi_work, zfcp_scsi_scan);

	spin_lock_init(&unit->latencies.lock);
	unit->latencies.write.channel.min = 0xFFFFFFFF;
	unit->latencies.write.fabric.min = 0xFFFFFFFF;
	unit->latencies.read.channel.min = 0xFFFFFFFF;
	unit->latencies.read.fabric.min = 0xFFFFFFFF;
	unit->latencies.cmd.channel.min = 0xFFFFFFFF;
	unit->latencies.cmd.fabric.min = 0xFFFFFFFF;

	if (device_register(&unit->sysfs_device)) {
		put_device(&unit->sysfs_device);
		goto err_out;
	}

	if (sysfs_create_group(&unit->sysfs_device.kobj,
			       &zfcp_sysfs_unit_attrs))
		goto err_out_put;

	write_lock_irq(&port->unit_list_lock);
	list_add_tail(&unit->list, &port->unit_list);
	write_unlock_irq(&port->unit_list_lock);

	atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status);

	return unit;

err_out_put:
	device_unregister(&unit->sysfs_device);
err_out:
	put_device(&port->sysfs_device);
	return ERR_PTR(retval);
}
/**
 *  rio_bus_init - Register the RapidIO bus with the device model
 *
 *  Registers the RIO bus device and RIO bus type with the Linux
 *  device model.
 */
static int __init rio_bus_init(void)
{
	if (device_register(&rio_bus) < 0)
		printk("RIO: failed to register RIO bus device\n");
	return bus_register(&rio_bus_type);
}
Example #22
0
/**
 * zfcp_port_enqueue - enqueue port to port list of adapter
 * @adapter: adapter where remote port is added
 * @wwpn: WWPN of the remote port to be enqueued
 * @status: initial status for the port
 * @d_id: destination id of the remote port to be enqueued
 * Returns: pointer to enqueued port on success, ERR_PTR on error
 *
 * All port internal structures are set up and the sysfs entry is generated.
 * d_id is used to enqueue ports with a well known address like the Directory
 * Service for nameserver lookup.
 */
struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
				     u32 status, u32 d_id)
{
	struct zfcp_port *port;
	int retval = -ENOMEM;

	kref_get(&adapter->ref);

	port = zfcp_get_port_by_wwpn(adapter, wwpn);
	if (port) {
		put_device(&port->sysfs_device);
		retval = -EEXIST;
		goto err_out;
	}

	port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL);
	if (!port)
		goto err_out;

	rwlock_init(&port->unit_list_lock);
	INIT_LIST_HEAD(&port->unit_list);

	INIT_WORK(&port->gid_pn_work, zfcp_fc_port_did_lookup);
	INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work);
	INIT_WORK(&port->rport_work, zfcp_scsi_rport_work);

	port->adapter = adapter;
	port->d_id = d_id;
	port->wwpn = wwpn;
	port->rport_task = RPORT_NONE;
	port->sysfs_device.parent = &adapter->ccw_device->dev;
	port->sysfs_device.release = zfcp_port_release;

	if (dev_set_name(&port->sysfs_device, "0x%016llx",
			 (unsigned long long)wwpn)) {
		kfree(port);
		goto err_out;
	}
	retval = -EINVAL;

	if (device_register(&port->sysfs_device)) {
		put_device(&port->sysfs_device);
		goto err_out;
	}

	if (sysfs_create_group(&port->sysfs_device.kobj,
			       &zfcp_sysfs_port_attrs))
		goto err_out_put;

	write_lock_irq(&adapter->port_list_lock);
	list_add_tail(&port->list, &adapter->port_list);
	write_unlock_irq(&adapter->port_list_lock);

	atomic_set_mask(status | ZFCP_STATUS_COMMON_RUNNING, &port->status);

	return port;

err_out_put:
	device_unregister(&port->sysfs_device);
err_out:
	zfcp_ccw_adapter_put(adapter);
	return ERR_PTR(retval);
}
static int __init mwave_init(void)
{
	int i;
	int retval = 0;
	pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;

	PRINTK_1(TRACE_MWAVE, "mwavedd::mwave_init entry\n");

	memset(&mwave_s_mdd, 0, sizeof(MWAVE_DEVICE_DATA));

	pDrvData->bBDInitialized = FALSE;
	pDrvData->bResourcesClaimed = FALSE;
	pDrvData->bDSPEnabled = FALSE;
	pDrvData->bDSPReset = FALSE;
	pDrvData->bMwaveDevRegistered = FALSE;
	pDrvData->sLine = -1;

	for (i = 0; i < ARRAY_SIZE(pDrvData->IPCs); i++) {
		pDrvData->IPCs[i].bIsEnabled = FALSE;
		pDrvData->IPCs[i].bIsHere = FALSE;
		pDrvData->IPCs[i].usIntCount = 0;	
		init_waitqueue_head(&pDrvData->IPCs[i].ipc_wait_queue);
	}

	retval = tp3780I_InitializeBoardData(&pDrvData->rBDData);
	PRINTK_2(TRACE_MWAVE,
		"mwavedd::mwave_init, return from tp3780I_InitializeBoardData"
		" retval %x\n",
		retval);
	if (retval) {
		PRINTK_ERROR(KERN_ERR_MWAVE
				"mwavedd::mwave_init: Error:"
				" Failed to initialize board data\n");
		goto cleanup_error;
	}
	pDrvData->bBDInitialized = TRUE;

	retval = tp3780I_CalcResources(&pDrvData->rBDData);
	PRINTK_2(TRACE_MWAVE,
		"mwavedd::mwave_init, return from tp3780I_CalcResources"
		" retval %x\n",
		retval);
	if (retval) {
		PRINTK_ERROR(KERN_ERR_MWAVE
				"mwavedd:mwave_init: Error:"
				" Failed to calculate resources\n");
		goto cleanup_error;
	}

	retval = tp3780I_ClaimResources(&pDrvData->rBDData);
	PRINTK_2(TRACE_MWAVE,
		"mwavedd::mwave_init, return from tp3780I_ClaimResources"
		" retval %x\n",
		retval);
	if (retval) {
		PRINTK_ERROR(KERN_ERR_MWAVE
				"mwavedd:mwave_init: Error:"
				" Failed to claim resources\n");
		goto cleanup_error;
	}
	pDrvData->bResourcesClaimed = TRUE;

	retval = tp3780I_EnableDSP(&pDrvData->rBDData);
	PRINTK_2(TRACE_MWAVE,
		"mwavedd::mwave_init, return from tp3780I_EnableDSP"
		" retval %x\n",
		retval);
	if (retval) {
		PRINTK_ERROR(KERN_ERR_MWAVE
				"mwavedd:mwave_init: Error:"
				" Failed to enable DSP\n");
		goto cleanup_error;
	}
	pDrvData->bDSPEnabled = TRUE;

	if (misc_register(&mwave_misc_dev) < 0) {
		PRINTK_ERROR(KERN_ERR_MWAVE
				"mwavedd:mwave_init: Error:"
				" Failed to register misc device\n");
		goto cleanup_error;
	}
	pDrvData->bMwaveDevRegistered = TRUE;

	pDrvData->sLine = register_serial_portandirq(
		pDrvData->rBDData.rDspSettings.usUartBaseIO,
		pDrvData->rBDData.rDspSettings.usUartIrq
	);
	if (pDrvData->sLine < 0) {
		PRINTK_ERROR(KERN_ERR_MWAVE
				"mwavedd:mwave_init: Error:"
				" Failed to register serial driver\n");
		goto cleanup_error;
	}
	

#if 0
	
	memset(&mwave_device, 0, sizeof (struct device));
	dev_set_name(&mwave_device, "mwave");

	if (device_register(&mwave_device))
		goto cleanup_error;
	pDrvData->device_registered = TRUE;
	for (i = 0; i < ARRAY_SIZE(mwave_dev_attrs); i++) {
		if(device_create_file(&mwave_device, mwave_dev_attrs[i])) {
			PRINTK_ERROR(KERN_ERR_MWAVE
					"mwavedd:mwave_init: Error:"
					" Failed to create sysfs file %s\n",
					mwave_dev_attrs[i]->attr.name);
			goto cleanup_error;
		}
		pDrvData->nr_registered_attrs++;
	}
#endif

	
	return 0;

cleanup_error:
	PRINTK_ERROR(KERN_ERR_MWAVE
			"mwavedd::mwave_init: Error:"
			" Failed to initialize\n");
	mwave_exit(); 

	return -EIO;
}
Example #24
0
int
main(int argc, char *argv[])
{
	int opt, i;
	const struct cmdtab *match, *cc, *tab;

#ifdef WITH_BSNMP
	snmp_client_init(&snmp_client);
	snmp_client.trans = SNMP_TRANS_LOC_STREAM;
	snmp_client_set_host(&snmp_client, PATH_ILMI_SOCK);
#endif

#ifdef WITH_BSNMP
#define	OPTSTR	"htvs:"
#else
#define OPTSTR	"htv"
#endif

	while ((opt = getopt(argc, argv, OPTSTR)) != -1)
		switch (opt) {

		  case 'h':
			help_func(0, argv);

#ifdef WITH_BSNMP
		  case 's':
			parse_server(optarg);
			break;
#endif

		  case 'v':
			verbose++;
			break;

		  case 't':
			notitle = 1;
			break;
		}

	if (argv[optind] == NULL)
		help_func(0, argv);

	argc -= optind;
	argv += optind;

	if ((main_tab = malloc(sizeof(static_main_tab))) == NULL)
		err(1, NULL);
	memcpy(main_tab, static_main_tab, sizeof(static_main_tab));

#ifdef WITH_BSNMP
	/* XXX while this is compiled in */
	device_register();
#endif

	cc = main_tab;
	i = 0;
	for (;;) {
		/*
		 * Scan the table for a match
		 */
		tab = cc;
		match = NULL;
		while (cc->string != NULL) {
			if (substr(argv[i], cc->string)) {
				if (match != NULL) {
					printf("Ambiguous option '%s'",
					    argv[i]);
					cc = tab;
					goto subopts;
				}
				match = cc;
			}
			cc++;
		}
		if ((cc = match) == NULL) {
			printf("Unknown option '%s'", argv[i]);
			cc = tab;
			goto subopts;
		}

		/*
		 * Have a match. If there is no subtable, there must
		 * be either a handler or the command is only a help entry.
		 */
		if (cc->sub == NULL) {
			if (cc->func != NULL)
				break;
			printf("Unknown option '%s'", argv[i]);
			cc = tab;
			goto subopts;
		}

		/*
		 * Look at the next argument. If it doesn't exist or it
		 * looks like a switch, terminate the scan here.
		 */
		if (argv[i + 1] == NULL || argv[i + 1][0] == '-') {
			if (cc->func != NULL)
				break;
			printf("Need sub-option for '%s'", argv[i]);
			cc = cc->sub;
			goto subopts;
		}

		cc = cc->sub;
		i++;
	}

	argc -= i + 1;
	argv += i + 1;

	(*cc->func)(argc, argv);

	return (0);

  subopts:
	printf(". Select one of:\n");
	while (cc->string != NULL) {
		if (cc->func != NULL || cc->sub != NULL)
			printf("%s ", cc->string);
		cc++;
	}
	printf("\n");

	return (1);
}
Example #25
0
int dim2_sysfs_probe(struct device *dev)
{
	dev->groups = dev_attr_groups;
	return device_register(dev);
}
Example #26
0
int __init s3c6410_init(void)
{
	printk("S3C6410: Initialising architecture\n");

	return device_register(&s3c6410_dev);
}
Example #27
0
static int __init camera_detector_init(void) {
	int err = 0;
    __u32 camera_list_size;
    char *camera_list_para      = "camera_list_para";
    char *camera_list_para_used = "camera_list_para_used";
    
	detect_print("camera detect driver init\n");
    
    if (!camera_sub_name_exist(camera_list_para, camera_list_para_used)) {
            __s32 value, ret;

        ret = camera_get_sysconfig(camera_list_para, camera_list_para_used, &value, 1);
        if (ret < 0) {
			detect_print("[camera_list_para] not exist in sys_config1.fex !! \n");
        }
        else if (value == 0) {
            detect_print("[camera_list_para]->camera_list_para_used = 0," 
                    "maybe somebody does not want to use camera detector ...... \n");
        }

        detect_print("camera detector exit, it will do nothing ...... \n");

        goto exit;
    }
        
	camera_detector_device.groups = dev_attr_groups;
	err = device_register(&camera_detector_device);
	if (err) {
		camera_err("%s register camera detect driver as misc device error\n", __FUNCTION__);
		goto exit;
	}
    
    memset(camera_detector, 0, sizeof(__camera_detector_t));
    err = camera_get_board_info(camera_detector);
    if (err)
    {
        camera_err("camera_get_board_info fail !!\n");
        goto exit;
    }
	
    camera_list_size = sizeof(camera_list) / sizeof(__camera_list_t);
    camera_init_module_list(camera_list_size);

    camera_mclk_open(camera_detector);

    if ((camera_detector->camera[0].i2c_id == camera_detector->camera[1].i2c_id)
    && (camera_detector->num == 2)) {
		camera_same_i2c_id_detect(camera_detector, camera_list, camera_list_size);
    }
    else if ((camera_detector->camera[0].i2c_id != camera_detector->camera[1].i2c_id)
    || (camera_detector->num == 1)) {
		camera_diff_i2c_id_detect(camera_detector, camera_list, camera_list_size);
    }

    camera_mclk_close(camera_detector);

    return 0;
    
exit:
	return err;
}
Example #28
0
int __init sys_bus_init(void)
{
	bus_register(&system_bus_type);
	return device_register(&system_bus);
}
/**
 * zfcp_unit_enqueue - enqueue unit to unit list of a port.
 * @port: pointer to port where unit is added
 * @fcp_lun: FCP LUN of unit to be enqueued
 * Returns: pointer to enqueued unit on success, ERR_PTR on error
 * Locks: config_sema must be held to serialize changes to the unit list
 *
 * Sets up some unit internal structures and creates sysfs entry.
 */
struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
{
	struct zfcp_unit *unit;

	unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL);
	if (!unit)
		return ERR_PTR(-ENOMEM);

	atomic_set(&unit->refcount, 0);
	init_waitqueue_head(&unit->remove_wq);

	unit->port = port;
	unit->fcp_lun = fcp_lun;

	dev_set_name(&unit->sysfs_device, "0x%016llx",
		     (unsigned long long) fcp_lun);
	unit->sysfs_device.parent = &port->sysfs_device;
	unit->sysfs_device.release = zfcp_sysfs_unit_release;
	dev_set_drvdata(&unit->sysfs_device, unit);

	/* mark unit unusable as long as sysfs registration is not complete */
	atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);

	spin_lock_init(&unit->latencies.lock);
	unit->latencies.write.channel.min = 0xFFFFFFFF;
	unit->latencies.write.fabric.min = 0xFFFFFFFF;
	unit->latencies.read.channel.min = 0xFFFFFFFF;
	unit->latencies.read.fabric.min = 0xFFFFFFFF;
	unit->latencies.cmd.channel.min = 0xFFFFFFFF;
	unit->latencies.cmd.fabric.min = 0xFFFFFFFF;

	read_lock_irq(&zfcp_data.config_lock);
	if (zfcp_get_unit_by_lun(port, fcp_lun)) {
		read_unlock_irq(&zfcp_data.config_lock);
		goto err_out_free;
	}
	read_unlock_irq(&zfcp_data.config_lock);

	if (device_register(&unit->sysfs_device))
		goto err_out_free;

	if (sysfs_create_group(&unit->sysfs_device.kobj,
			       &zfcp_sysfs_unit_attrs)) {
		device_unregister(&unit->sysfs_device);
		return ERR_PTR(-EIO);
	}

	zfcp_unit_get(unit);

	write_lock_irq(&zfcp_data.config_lock);
	list_add_tail(&unit->list, &port->unit_list_head);
	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
	atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &unit->status);

	write_unlock_irq(&zfcp_data.config_lock);

	zfcp_port_get(port);

	return unit;

err_out_free:
	kfree(unit);
	return ERR_PTR(-EINVAL);
}
Example #30
0
File: usb.c Project: avagin/linux
/**
 * hdm_probe - probe function of USB device driver
 * @interface: Interface of the attached USB device
 * @id: Pointer to the USB ID table.
 *
 * This allocates and initializes the device instance, adds the new
 * entry to the internal list, scans the USB descriptors and registers
 * the interface with the core.
 * Additionally, the DCI objects are created and the hardware is sync'd.
 *
 * Return 0 on success. In case of an error a negative number is returned.
 */
static int
hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
	struct usb_host_interface *usb_iface_desc = interface->cur_altsetting;
	struct usb_device *usb_dev = interface_to_usbdev(interface);
	struct device *dev = &usb_dev->dev;
	struct most_dev *mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
	unsigned int i;
	unsigned int num_endpoints;
	struct most_channel_capability *tmp_cap;
	struct usb_endpoint_descriptor *ep_desc;
	int ret = 0;

	if (!mdev)
		goto err_out_of_memory;

	usb_set_intfdata(interface, mdev);
	num_endpoints = usb_iface_desc->desc.bNumEndpoints;
	mutex_init(&mdev->io_mutex);
	INIT_WORK(&mdev->poll_work_obj, wq_netinfo);
	timer_setup(&mdev->link_stat_timer, link_stat_timer_handler, 0);

	mdev->usb_device = usb_dev;
	mdev->link_stat_timer.expires = jiffies + (2 * HZ);

	mdev->iface.mod = hdm_usb_fops.owner;
	mdev->iface.driver_dev = &interface->dev;
	mdev->iface.interface = ITYPE_USB;
	mdev->iface.configure = hdm_configure_channel;
	mdev->iface.request_netinfo = hdm_request_netinfo;
	mdev->iface.enqueue = hdm_enqueue;
	mdev->iface.poison_channel = hdm_poison_channel;
	mdev->iface.dma_alloc = hdm_dma_alloc;
	mdev->iface.dma_free = hdm_dma_free;
	mdev->iface.description = mdev->description;
	mdev->iface.num_channels = num_endpoints;

	snprintf(mdev->description, sizeof(mdev->description),
		 "%d-%s:%d.%d",
		 usb_dev->bus->busnum,
		 usb_dev->devpath,
		 usb_dev->config->desc.bConfigurationValue,
		 usb_iface_desc->desc.bInterfaceNumber);

	mdev->conf = kcalloc(num_endpoints, sizeof(*mdev->conf), GFP_KERNEL);
	if (!mdev->conf)
		goto err_free_mdev;

	mdev->cap = kcalloc(num_endpoints, sizeof(*mdev->cap), GFP_KERNEL);
	if (!mdev->cap)
		goto err_free_conf;

	mdev->iface.channel_vector = mdev->cap;
	mdev->ep_address =
		kcalloc(num_endpoints, sizeof(*mdev->ep_address), GFP_KERNEL);
	if (!mdev->ep_address)
		goto err_free_cap;

	mdev->busy_urbs =
		kcalloc(num_endpoints, sizeof(*mdev->busy_urbs), GFP_KERNEL);
	if (!mdev->busy_urbs)
		goto err_free_ep_address;

	tmp_cap = mdev->cap;
	for (i = 0; i < num_endpoints; i++) {
		ep_desc = &usb_iface_desc->endpoint[i].desc;
		mdev->ep_address[i] = ep_desc->bEndpointAddress;
		mdev->padding_active[i] = false;
		mdev->is_channel_healthy[i] = true;

		snprintf(&mdev->suffix[i][0], MAX_SUFFIX_LEN, "ep%02x",
			 mdev->ep_address[i]);

		tmp_cap->name_suffix = &mdev->suffix[i][0];
		tmp_cap->buffer_size_packet = MAX_BUF_SIZE;
		tmp_cap->buffer_size_streaming = MAX_BUF_SIZE;
		tmp_cap->num_buffers_packet = BUF_CHAIN_SIZE;
		tmp_cap->num_buffers_streaming = BUF_CHAIN_SIZE;
		tmp_cap->data_type = MOST_CH_CONTROL | MOST_CH_ASYNC |
				     MOST_CH_ISOC | MOST_CH_SYNC;
		if (usb_endpoint_dir_in(ep_desc))
			tmp_cap->direction = MOST_CH_RX;
		else
			tmp_cap->direction = MOST_CH_TX;
		tmp_cap++;
		init_usb_anchor(&mdev->busy_urbs[i]);
		spin_lock_init(&mdev->channel_lock[i]);
	}
	dev_notice(dev, "claimed gadget: Vendor=%4.4x ProdID=%4.4x Bus=%02x Device=%02x\n",
		   le16_to_cpu(usb_dev->descriptor.idVendor),
		   le16_to_cpu(usb_dev->descriptor.idProduct),
		   usb_dev->bus->busnum,
		   usb_dev->devnum);

	dev_notice(dev, "device path: /sys/bus/usb/devices/%d-%s:%d.%d\n",
		   usb_dev->bus->busnum,
		   usb_dev->devpath,
		   usb_dev->config->desc.bConfigurationValue,
		   usb_iface_desc->desc.bInterfaceNumber);

	ret = most_register_interface(&mdev->iface);
	if (ret)
		goto err_free_busy_urbs;

	mutex_lock(&mdev->io_mutex);
	if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81118 ||
	    le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81119 ||
	    le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81210) {
		mdev->dci = kzalloc(sizeof(*mdev->dci), GFP_KERNEL);
		if (!mdev->dci) {
			mutex_unlock(&mdev->io_mutex);
			most_deregister_interface(&mdev->iface);
			ret = -ENOMEM;
			goto err_free_busy_urbs;
		}

		mdev->dci->dev.init_name = "dci";
		mdev->dci->dev.parent = &mdev->iface.dev;
		mdev->dci->dev.groups = dci_attr_groups;
		mdev->dci->dev.release = release_dci;
		if (device_register(&mdev->dci->dev)) {
			mutex_unlock(&mdev->io_mutex);
			most_deregister_interface(&mdev->iface);
			ret = -ENOMEM;
			goto err_free_dci;
		}
		mdev->dci->usb_device = mdev->usb_device;
	}
	mutex_unlock(&mdev->io_mutex);
	return 0;
err_free_dci:
	kfree(mdev->dci);
err_free_busy_urbs:
	kfree(mdev->busy_urbs);
err_free_ep_address:
	kfree(mdev->ep_address);
err_free_cap:
	kfree(mdev->cap);
err_free_conf:
	kfree(mdev->conf);
err_free_mdev:
	kfree(mdev);
err_out_of_memory:
	if (ret == 0 || ret == -ENOMEM) {
		ret = -ENOMEM;
		dev_err(dev, "out of memory\n");
	}
	return ret;
}