示例#1
0
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;

	/* strstr("foo", "") is non-NULL */
	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);

	kref_init(&idkp->kref);

	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_idkp:
	kfree(idkp);
failed:
	return -ENODEV;
}
示例#2
0
int usb_parse_configuration(struct device *ddev, int cfgidx,
    struct usb_host_config *config, unsigned char *buffer, int size)
{
	unsigned char *buffer0 = buffer;
	int cfgno;
	int nintf, nintf_orig;
	int i, j, n;
	struct usb_interface_cache *intfc;
	unsigned char *buffer2;
	int size2;
	struct usb_descriptor_header *header;
	int len, retval;
	u8 inums[USB_MAXINTERFACES], nalts[USB_MAXINTERFACES];

	memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE);
	if (config->desc.bDescriptorType != USB_DT_CONFIG ||
	    config->desc.bLength < USB_DT_CONFIG_SIZE) {
		dev_err(ddev, "invalid descriptor for config index %d: "
		    "type = 0x%X, length = %d\n", cfgidx,
		    config->desc.bDescriptorType, config->desc.bLength);
		return -EINVAL;
	}
	cfgno = config->desc.bConfigurationValue;

	buffer += config->desc.bLength;
	size -= config->desc.bLength;

	nintf = nintf_orig = config->desc.bNumInterfaces;
	if (nintf > USB_MAXINTERFACES) {
		dev_warn(ddev, "config %d has too many interfaces: %d, "
		    "using maximum allowed: %d\n",
		    cfgno, nintf, USB_MAXINTERFACES);
		nintf = USB_MAXINTERFACES;
	}

	/* Go through the descriptors, checking their length and counting the
	 * number of altsettings for each interface */
	n = 0;
	for ((buffer2 = buffer, size2 = size);
	      size2 > 0;
	     (buffer2 += header->bLength, size2 -= header->bLength)) {

		if (size2 < sizeof(struct usb_descriptor_header)) {
			dev_warn(ddev, "config %d descriptor has %d excess "
			    "byte%s, ignoring\n",
			    cfgno, size2, plural(size2));
			break;
		}

		header = (struct usb_descriptor_header *) buffer2;
		if ((header->bLength > size2) || (header->bLength < 2)) {
			dev_warn(ddev, "config %d has an invalid descriptor "
			    "of length %d, skipping remainder of the config\n",
			    cfgno, header->bLength);
			break;
		}

		if (header->bDescriptorType == USB_DT_INTERFACE) {
			struct usb_interface_descriptor *d;
			int inum;

			d = (struct usb_interface_descriptor *) header;
			if (d->bLength < USB_DT_INTERFACE_SIZE) {
				dev_warn(ddev, "config %d has an invalid "
				    "interface descriptor of length %d, "
				    "skipping\n", cfgno, d->bLength);
				continue;
			}

			inum = d->bInterfaceNumber;
			if (inum >= nintf_orig)
				dev_warn(ddev, "config %d has an invalid "
				    "interface number: %d but max is %d\n",
				    cfgno, inum, nintf_orig - 1);

			/* Have we already encountered this interface?
			 * Count its altsettings */
			for (i = 0; i < n; ++i) {
				if (inums[i] == inum)
					break;
			}
			if (i < n) {
				if (nalts[i] < 255)
					++nalts[i];
			} else if (n < USB_MAXINTERFACES) {
				inums[n] = inum;
				nalts[n] = 1;
				++n;
			}

		} else if (header->bDescriptorType == USB_DT_DEVICE ||
			    header->bDescriptorType == USB_DT_CONFIG)
			dev_warn(ddev, "config %d contains an unexpected "
			    "descriptor of type 0x%X, skipping\n",
			    cfgno, header->bDescriptorType);

	}	/* for ((buffer2 = buffer, size2 = size); ...) */
	size = buffer2 - buffer;
	config->desc.wTotalLength = buffer2 - buffer0;

	if (n != nintf)
		dev_warn(ddev, "config %d has %d interface%s, different from "
		    "the descriptor's value: %d\n",
		    cfgno, n, plural(n), nintf_orig);
	else if (n == 0)
		dev_warn(ddev, "config %d has no interfaces?\n", cfgno);
	config->desc.bNumInterfaces = nintf = n;

	/* Check for missing interface numbers */
	for (i = 0; i < nintf; ++i) {
		for (j = 0; j < nintf; ++j) {
			if (inums[j] == i)
				break;
		}
		if (j >= nintf)
			dev_warn(ddev, "config %d has no interface number "
			    "%d\n", cfgno, i);
	}

	/* Allocate the usb_interface_caches and altsetting arrays */
	for (i = 0; i < nintf; ++i) {
		j = nalts[i];
		if (j > USB_MAXALTSETTING) {
			dev_warn(ddev, "too many alternate settings for "
			    "config %d interface %d: %d, "
			    "using maximum allowed: %d\n",
			    cfgno, inums[i], j, USB_MAXALTSETTING);
			nalts[i] = j = USB_MAXALTSETTING;
		}

		len = sizeof(*intfc) + sizeof(struct usb_host_interface) * j;
		config->intf_cache[i] = intfc = kmalloc(len, GFP_KERNEL);
		if (!intfc)
			return -ENOMEM;
		memset(intfc, 0, len);
		kref_init(&intfc->ref);
	}

	/* Skip over any Class Specific or Vendor Specific descriptors;
	 * find the first interface descriptor */
	config->extra = buffer;
	i = find_next_descriptor(buffer, size, USB_DT_INTERFACE,
	    USB_DT_INTERFACE, &n);
	config->extralen = i;
	if (n > 0)
		dev_dbg(ddev, "skipped %d descriptor%s after %s\n",
		    n, plural(n), "configuration");
	buffer += i;
	size -= i;

	/* Parse all the interface/altsetting descriptors */
	while (size > 0) {
		retval = usb_parse_interface(ddev, cfgno, config,
		    buffer, size, inums, nalts);
		if (retval < 0)
			return retval;

		buffer += retval;
		size -= retval;
	}

	/* Check for missing altsettings */
	for (i = 0; i < nintf; ++i) {
		intfc = config->intf_cache[i];
		for (j = 0; j < intfc->num_altsetting; ++j) {
			for (n = 0; n < intfc->num_altsetting; ++n) {
				if (intfc->altsetting[n].desc.
				    bAlternateSetting == j)
					break;
			}
			if (n >= intfc->num_altsetting)
				dev_warn(ddev, "config %d interface %d has no "
				    "altsetting %d\n", cfgno, inums[i], j);
		}
	}

	return 0;
}
示例#3
0
/*
 * build new request AND message, calculate layout, and adjust file
 * extent as needed.
 *
 * if the file was recently truncated, we include information about its
 * old and new size so that the object can be updated appropriately.  (we
 * avoid synchronously deleting truncated objects because it's slow.)
 *
 * if @do_sync, include a 'startsync' command so that the osd will flush
 * data quickly.
 */
struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
					       struct ceph_file_layout *layout,
					       struct ceph_vino vino,
					       u64 off, u64 *plen,
					       int opcode, int flags,
					       struct ceph_snap_context *snapc,
					       int do_sync,
					       u32 truncate_seq,
					       u64 truncate_size,
					       struct timespec *mtime,
					       bool use_mempool, int num_reply)
{
	struct ceph_osd_request *req;
	struct ceph_msg *msg;
	struct ceph_osd_request_head *head;
	struct ceph_osd_op *op;
	void *p;
	int num_op = 1 + do_sync;
	size_t msg_size = sizeof(*head) + num_op*sizeof(*op);
	int i;

	if (use_mempool) {
		req = mempool_alloc(osdc->req_mempool, GFP_NOFS);
		memset(req, 0, sizeof(*req));
	} else {
		req = kzalloc(sizeof(*req), GFP_NOFS);
	}
	if (req == NULL)
		return NULL;

	req->r_osdc = osdc;
	req->r_mempool = use_mempool;
	kref_init(&req->r_kref);
	init_completion(&req->r_completion);
	init_completion(&req->r_safe_completion);
	INIT_LIST_HEAD(&req->r_unsafe_item);
	req->r_flags = flags;

	WARN_ON((flags & (CEPH_OSD_FLAG_READ|CEPH_OSD_FLAG_WRITE)) == 0);

	/* create reply message */
	if (use_mempool)
		msg = ceph_msgpool_get(&osdc->msgpool_op_reply, 0);
	else
		msg = ceph_msg_new(CEPH_MSG_OSD_OPREPLY,
				   OSD_OPREPLY_FRONT_LEN, GFP_NOFS);
	if (!msg) {
		ceph_osdc_put_request(req);
		return NULL;
	}
	req->r_reply = msg;

	/* create request message; allow space for oid */
	msg_size += 40;
	if (snapc)
		msg_size += sizeof(u64) * snapc->num_snaps;
	if (use_mempool)
		msg = ceph_msgpool_get(&osdc->msgpool_op, 0);
	else
		msg = ceph_msg_new(CEPH_MSG_OSD_OP, msg_size, GFP_NOFS);
	if (!msg) {
		ceph_osdc_put_request(req);
		return NULL;
	}
	msg->hdr.type = cpu_to_le16(CEPH_MSG_OSD_OP);
	memset(msg->front.iov_base, 0, msg->front.iov_len);
	head = msg->front.iov_base;
	op = (void *)(head + 1);
	p = (void *)(op + num_op);

	req->r_request = msg;
	req->r_snapc = ceph_get_snap_context(snapc);

	head->client_inc = cpu_to_le32(1); /* always, for now. */
	head->flags = cpu_to_le32(flags);
	if (flags & CEPH_OSD_FLAG_WRITE)
		ceph_encode_timespec(&head->mtime, mtime);
	head->num_ops = cpu_to_le16(num_op);
	op->op = cpu_to_le16(opcode);

	/* calculate max write size */
	calc_layout(osdc, vino, layout, off, plen, req);
	req->r_file_layout = *layout;  /* keep a copy */

	if (flags & CEPH_OSD_FLAG_WRITE) {
		req->r_request->hdr.data_off = cpu_to_le16(off);
		req->r_request->hdr.data_len = cpu_to_le32(*plen);
		op->payload_len = cpu_to_le32(*plen);
	}
	op->extent.truncate_size = cpu_to_le64(truncate_size);
	op->extent.truncate_seq = cpu_to_le32(truncate_seq);

	/* fill in oid */
	head->object_len = cpu_to_le32(req->r_oid_len);
	memcpy(p, req->r_oid, req->r_oid_len);
	p += req->r_oid_len;

	if (do_sync) {
		op++;
		op->op = cpu_to_le16(CEPH_OSD_OP_STARTSYNC);
	}
	if (snapc) {
		head->snap_seq = cpu_to_le64(snapc->seq);
		head->num_snaps = cpu_to_le32(snapc->num_snaps);
		for (i = 0; i < snapc->num_snaps; i++) {
			put_unaligned_le64(snapc->snaps[i], p);
			p += sizeof(u64);
		}
	}

	BUG_ON(p > msg->front.iov_base + msg->front.iov_len);
	msg_size = p - msg->front.iov_base;
	msg->front.iov_len = msg_size;
	msg->hdr.front_len = cpu_to_le32(msg_size);
	return req;
}
static int skel_probe(struct usb_interface *interface,
		      const struct usb_device_id *id)
{
	struct usb_skel *dev;
	struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *endpoint;
	size_t buffer_size;
	int i;
	int retval = -ENOMEM;

	
	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev) {
		err("Out of memory");
		goto error;
	}
	kref_init(&dev->kref);
	sema_init(&dev->limit_sem, WRITES_IN_FLIGHT);
	mutex_init(&dev->io_mutex);
	spin_lock_init(&dev->err_lock);
	init_usb_anchor(&dev->submitted);
	init_completion(&dev->bulk_in_completion);

	dev->udev = usb_get_dev(interface_to_usbdev(interface));
	dev->interface = interface;

	
	
	iface_desc = interface->cur_altsetting;
	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
		endpoint = &iface_desc->endpoint[i].desc;

		if (!dev->bulk_in_endpointAddr &&
		    usb_endpoint_is_bulk_in(endpoint)) {
			
			buffer_size = usb_endpoint_maxp(endpoint);
			dev->bulk_in_size = buffer_size;
			dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
			dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
			if (!dev->bulk_in_buffer) {
				err("Could not allocate bulk_in_buffer");
				goto error;
			}
			dev->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL);
			if (!dev->bulk_in_urb) {
				err("Could not allocate bulk_in_urb");
				goto error;
			}
		}

		if (!dev->bulk_out_endpointAddr &&
		    usb_endpoint_is_bulk_out(endpoint)) {
			
			dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
		}
	}
	if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
		err("Could not find both bulk-in and bulk-out endpoints");
		goto error;
	}

	
	usb_set_intfdata(interface, dev);

	
	retval = usb_register_dev(interface, &skel_class);
	if (retval) {
		
		err("Not able to get a minor for this device.");
		usb_set_intfdata(interface, NULL);
		goto error;
	}

	
	dev_info(&interface->dev,
		 "USB Skeleton device now attached to USBSkel-%d",
		 interface->minor);
	return 0;

error:
	if (dev)
		
		kref_put(&dev->kref, skel_delete);
	return retval;
}
示例#5
0
/**
 * drm_dev_init - Initialise new DRM device
 * @dev: DRM device
 * @driver: DRM driver
 * @parent: Parent device object
 *
 * Initialize a new DRM device. No device registration is done.
 * Call drm_dev_register() to advertice the device to user space and register it
 * with other core subsystems. This should be done last in the device
 * initialization sequence to make sure userspace can't access an inconsistent
 * state.
 *
 * The initial ref-count of the object is 1. Use drm_dev_ref() and
 * drm_dev_unref() to take and drop further ref-counts.
 *
 * Note that for purely virtual devices @parent can be NULL.
 *
 * Drivers that do not want to allocate their own device struct
 * embedding struct &drm_device can call drm_dev_alloc() instead.
 *
 * RETURNS:
 * 0 on success, or error code on failure.
 */
int drm_dev_init(struct drm_device *dev,
		 struct drm_driver *driver,
		 struct device *parent)
{
	int ret;

	kref_init(&dev->ref);
	dev->dev = parent;
	dev->driver = driver;

	INIT_LIST_HEAD(&dev->filelist);
	INIT_LIST_HEAD(&dev->ctxlist);
	INIT_LIST_HEAD(&dev->vmalist);
	INIT_LIST_HEAD(&dev->maplist);
	INIT_LIST_HEAD(&dev->vblank_event_list);

	spin_lock_init(&dev->buf_lock);
	spin_lock_init(&dev->event_lock);
	mutex_init(&dev->struct_mutex);
	mutex_init(&dev->filelist_mutex);
	mutex_init(&dev->ctxlist_mutex);
	mutex_init(&dev->master_mutex);

	dev->anon_inode = drm_fs_inode_new();
	if (IS_ERR(dev->anon_inode)) {
		ret = PTR_ERR(dev->anon_inode);
		DRM_ERROR("Cannot allocate anonymous inode: %d\n", ret);
		goto err_free;
	}

	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
		ret = drm_minor_alloc(dev, DRM_MINOR_CONTROL);
		if (ret)
			goto err_minors;
	}

	if (drm_core_check_feature(dev, DRIVER_RENDER)) {
		ret = drm_minor_alloc(dev, DRM_MINOR_RENDER);
		if (ret)
			goto err_minors;
	}

	ret = drm_minor_alloc(dev, DRM_MINOR_PRIMARY);
	if (ret)
		goto err_minors;

	ret = drm_ht_create(&dev->map_hash, 12);
	if (ret)
		goto err_minors;

	drm_legacy_ctxbitmap_init(dev);

	if (drm_core_check_feature(dev, DRIVER_GEM)) {
		ret = drm_gem_init(dev);
		if (ret) {
			DRM_ERROR("Cannot initialize graphics execution manager (GEM)\n");
			goto err_ctxbitmap;
		}
	}

	/* Use the parent device name as DRM device unique identifier, but fall
	 * back to the driver name for virtual devices like vgem. */
	ret = drm_dev_set_unique(dev, parent ? dev_name(parent) : driver->name);
	if (ret)
		goto err_setunique;

	return 0;

err_setunique:
	if (drm_core_check_feature(dev, DRIVER_GEM))
		drm_gem_destroy(dev);
err_ctxbitmap:
	drm_legacy_ctxbitmap_cleanup(dev);
	drm_ht_remove(&dev->map_hash);
err_minors:
	drm_minor_free(dev, DRM_MINOR_PRIMARY);
	drm_minor_free(dev, DRM_MINOR_RENDER);
	drm_minor_free(dev, DRM_MINOR_CONTROL);
	drm_fs_inode_free(dev->anon_inode);
err_free:
	mutex_destroy(&dev->master_mutex);
	return ret;
}
示例#6
0
文件: match.c 项目: 020gzh/linux
/**
 * aa_dfa_unpack - unpack the binary tables of a serialized dfa
 * @blob: aligned serialized stream of data to unpack  (NOT NULL)
 * @size: size of data to unpack
 * @flags: flags controlling what type of accept tables are acceptable
 *
 * Unpack a dfa that has been serialized.  To find information on the dfa
 * format look in Documentation/security/apparmor.txt
 * Assumes the dfa @blob stream has been aligned on a 8 byte boundary
 *
 * Returns: an unpacked dfa ready for matching or ERR_PTR on failure
 */
struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
{
	int hsize;
	int error = -ENOMEM;
	char *data = blob;
	struct table_header *table = NULL;
	struct aa_dfa *dfa = kzalloc(sizeof(struct aa_dfa), GFP_KERNEL);
	if (!dfa)
		goto fail;

	kref_init(&dfa->count);

	error = -EPROTO;

	/* get dfa table set header */
	if (size < sizeof(struct table_set_header))
		goto fail;

	if (ntohl(*(u32 *) data) != YYTH_MAGIC)
		goto fail;

	hsize = ntohl(*(u32 *) (data + 4));
	if (size < hsize)
		goto fail;

	dfa->flags = ntohs(*(u16 *) (data + 12));
	data += hsize;
	size -= hsize;

	while (size > 0) {
		table = unpack_table(data, size);
		if (!table)
			goto fail;

		switch (table->td_id) {
		case YYTD_ID_ACCEPT:
			if (!(table->td_flags & ACCEPT1_FLAGS(flags)))
				goto fail;
			break;
		case YYTD_ID_ACCEPT2:
			if (!(table->td_flags & ACCEPT2_FLAGS(flags)))
				goto fail;
			break;
		case YYTD_ID_BASE:
			if (table->td_flags != YYTD_DATA32)
				goto fail;
			break;
		case YYTD_ID_DEF:
		case YYTD_ID_NXT:
		case YYTD_ID_CHK:
			if (table->td_flags != YYTD_DATA16)
				goto fail;
			break;
		case YYTD_ID_EC:
			if (table->td_flags != YYTD_DATA8)
				goto fail;
			break;
		default:
			goto fail;
		}
		/* check for duplicate table entry */
		if (dfa->tables[table->td_id])
			goto fail;
		dfa->tables[table->td_id] = table;
		data += table_size(table->td_lolen, table->td_flags);
		size -= table_size(table->td_lolen, table->td_flags);
		table = NULL;
	}

	error = verify_dfa(dfa, flags);
	if (error)
		goto fail;

	return dfa;

fail:
	kvfree(table);
	dfa_free(dfa);
	return ERR_PTR(error);
}
示例#7
0
文件: ttm_bo.c 项目: dezelin/vmwgfx
int ttm_bo_init(struct ttm_bo_device *bdev,
		struct ttm_buffer_object *bo,
		unsigned long size,
		enum ttm_bo_type type,
		struct ttm_placement *placement,
		uint32_t page_alignment,
		unsigned long buffer_start,
		bool interruptible,
		struct file *persistant_swap_storage,
		size_t acc_size,
		void (*destroy) (struct ttm_buffer_object *))
{
	int ret = 0;
	unsigned long num_pages;

	size += buffer_start & ~PAGE_MASK;
	num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
	if (num_pages == 0) {
		printk(KERN_ERR TTM_PFX "Illegal buffer object size.\n");
		if (destroy)
			(*destroy)(bo);
		else
			kfree(bo);
		return -EINVAL;
	}
	bo->destroy = destroy;

	kref_init(&bo->kref);
	kref_init(&bo->list_kref);
	atomic_set(&bo->cpu_writers, 0);
	atomic_set(&bo->reserved, 1);
	init_waitqueue_head(&bo->event_queue);
	INIT_LIST_HEAD(&bo->lru);
	INIT_LIST_HEAD(&bo->ddestroy);
	INIT_LIST_HEAD(&bo->swap);
	INIT_LIST_HEAD(&bo->io_reserve_lru);
	bo->bdev = bdev;
	bo->glob = bdev->glob;
	bo->type = type;
	bo->num_pages = num_pages;
	bo->mem.size = num_pages << PAGE_SHIFT;
	bo->mem.mem_type = TTM_PL_SYSTEM;
	bo->mem.num_pages = bo->num_pages;
	bo->mem.mm_node = NULL;
	bo->mem.page_alignment = page_alignment;
	bo->mem.bus.io_reserved_vm = false;
	bo->mem.bus.io_reserved_count = 0;
	bo->buffer_start = buffer_start & PAGE_MASK;
	bo->priv_flags = 0;
	bo->mem.placement = (TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED);
	bo->seq_valid = false;
	bo->persistant_swap_storage = persistant_swap_storage;
	bo->acc_size = acc_size;
	atomic_inc(&bo->glob->bo_count);

	ret = ttm_bo_check_placement(bo, placement);
	if (unlikely(ret != 0))
		goto out_err;

	/*
	 * For ttm_bo_type_device buffers, allocate
	 * address space from the device.
	 */
	if (bo->type == ttm_bo_type_device) {
		ret = ttm_bo_setup_vm(bo);
		if (ret)
			goto out_err;
	}

	ret = ttm_bo_validate(bo, placement, interruptible, false, false);
	if (ret)
		goto out_err;

	ttm_bo_unreserve(bo);
	return 0;

out_err:
	ttm_bo_unreserve(bo);
	ttm_bo_unref(&bo);

	return ret;
}
示例#8
0
/**
 * unflatten_dt_node - Alloc and populate a device_node from the flat tree
 * @blob: The parent device tree blob
 * @mem: Memory chunk to use for allocating device nodes and properties
 * @p: pointer to node in flat tree
 * @dad: Parent struct device_node
 * @allnextpp: pointer to ->allnext from last allocated device_node
 * @fpsize: Size of the node path up at the current depth.
 */
static void * unflatten_dt_node(struct boot_param_header *blob,
				void *mem,
				void **p,
				struct device_node *dad,
				struct device_node ***allnextpp,
				unsigned long fpsize)
{
	struct device_node *np;
	struct property *pp, **prev_pp = NULL;
	char *pathp;
	u32 tag;
	unsigned int l, allocl;
	int has_name = 0;
	int new_format = 0;

	tag = be32_to_cpup(*p);
	if (tag != OF_DT_BEGIN_NODE) {
		pr_err("Weird tag at start of node: %x\n", tag);
		return mem;
	}
	*p += 4;
	pathp = *p;
	l = allocl = strlen(pathp) + 1;
	*p = PTR_ALIGN(*p + l, 4);

	/* version 0x10 has a more compact unit name here instead of the full
	 * path. we accumulate the full path size using "fpsize", we'll rebuild
	 * it later. We detect this because the first character of the name is
	 * not '/'.
	 */
	if ((*pathp) != '/') {
		new_format = 1;
		if (fpsize == 0) {
			/* root node: special case. fpsize accounts for path
			 * plus terminating zero. root node only has '/', so
			 * fpsize should be 2, but we want to avoid the first
			 * level nodes to have two '/' so we use fpsize 1 here
			 */
			fpsize = 1;
			allocl = 2;
			l = 1;
			*pathp = '\0';
		} else {
			/* account for '/' and path size minus terminal 0
			 * already in 'l'
			 */
			fpsize += l;
			allocl = fpsize;
		}
	}

	np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
				__alignof__(struct device_node));
	if (allnextpp) {
		char *fn;
		np->full_name = fn = ((char *)np) + sizeof(*np);
		if (new_format) {
			/* rebuild full path for new format */
			if (dad && dad->parent) {
				strcpy(fn, dad->full_name);
#ifdef DEBUG
				if ((strlen(fn) + l + 1) != allocl) {
					pr_debug("%s: p: %d, l: %d, a: %d\n",
						pathp, (int)strlen(fn),
						l, allocl);
				}
#endif
				fn += strlen(fn);
			}
			*(fn++) = '/';
		}
		memcpy(fn, pathp, l);

		prev_pp = &np->properties;
		**allnextpp = np;
		*allnextpp = &np->allnext;
		if (dad != NULL) {
			np->parent = dad;
			/* we temporarily use the next field as `last_child'*/
			if (dad->next == NULL)
				dad->child = np;
			else
				dad->next->sibling = np;
			dad->next = np;
		}
		kref_init(&np->kref);
	}
	/* process properties */
	while (1) {
		u32 sz, noff;
		char *pname;

		tag = be32_to_cpup(*p);
		if (tag == OF_DT_NOP) {
			*p += 4;
			continue;
		}
		if (tag != OF_DT_PROP)
			break;
		*p += 4;
		sz = be32_to_cpup(*p);
		noff = be32_to_cpup(*p + 4);
		*p += 8;
		if (be32_to_cpu(blob->version) < 0x10)
			*p = PTR_ALIGN(*p, sz >= 8 ? 8 : 4);

		pname = of_fdt_get_string(blob, noff);
		if (pname == NULL) {
			pr_info("Can't find property name in list !\n");
			break;
		}
		if (strcmp(pname, "name") == 0)
			has_name = 1;
		l = strlen(pname) + 1;
		pp = unflatten_dt_alloc(&mem, sizeof(struct property),
					__alignof__(struct property));
		if (allnextpp) {
			/* We accept flattened tree phandles either in
			 * ePAPR-style "phandle" properties, or the
			 * legacy "linux,phandle" properties.  If both
			 * appear and have different values, things
			 * will get weird.  Don't do that. */
			if ((strcmp(pname, "phandle") == 0) ||
			    (strcmp(pname, "linux,phandle") == 0)) {
				if (np->phandle == 0)
					np->phandle = be32_to_cpup((__be32*)*p);
			}
			/* And we process the "ibm,phandle" property
			 * used in pSeries dynamic device tree
			 * stuff */
			if (strcmp(pname, "ibm,phandle") == 0)
				np->phandle = be32_to_cpup((__be32 *)*p);
			pp->name = pname;
			pp->length = sz;
			pp->value = *p;
			*prev_pp = pp;
			prev_pp = &pp->next;
		}
		*p = PTR_ALIGN((*p) + sz, 4);
	}
	/* with version 0x10 we may not have the name property, recreate
	 * it here from the unit name if absent
	 */
	if (!has_name) {
		char *p1 = pathp, *ps = pathp, *pa = NULL;
		int sz;

		while (*p1) {
			if ((*p1) == '@')
				pa = p1;
			if ((*p1) == '/')
				ps = p1 + 1;
			p1++;
		}
		if (pa < ps)
			pa = p1;
		sz = (pa - ps) + 1;
		pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
					__alignof__(struct property));
		if (allnextpp) {
			pp->name = "name";
			pp->length = sz;
			pp->value = pp + 1;
			*prev_pp = pp;
			prev_pp = &pp->next;
			memcpy(pp->value, ps, sz - 1);
			((char *)pp->value)[sz - 1] = 0;
			pr_debug("fixed up name for %s -> %s\n", pathp,
				(char *)pp->value);
		}
	}
static int proto_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
    struct usb_skel *dev = NULL;
    struct usb_host_interface *iface_desc;
    struct usb_endpoint_descriptor *endpoint;
    size_t buffer_size;
    int i;
    int retval = -ENOMEM;

    /* allocate memory for our device state and initialize it */
    dev = kmalloc(sizeof(struct usb_skel), GFP_KERNEL);
    if (dev == NULL) {
        pr_err("Out of memory");
        goto error;
    }
    memset(dev, 0x00, sizeof (*dev));
    kref_init(&dev->kref);

    dev->udev = usb_get_dev(interface_to_usbdev(interface));
    udev2 = dev->udev;
    dev->interface = interface;

    /* set up the endpoint information */
    /* use only the first bulk-in and bulk-out endpoints */
    iface_desc = interface->cur_altsetting;
    for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
        endpoint = &iface_desc->endpoint[i].desc;

        if (!dev->bulk_in_endpointAddr &&
            (endpoint->bEndpointAddress & USB_DIR_IN) &&
            ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) {
                /* we found a bulk in endpoint */
                buffer_size = endpoint->wMaxPacketSize;
                dev->bulk_in_size = buffer_size;
                dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
                dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
                if (!dev->bulk_in_buffer) {
                    pr_err("Could not allocate bulk_in_buffer");
                    goto error;
                }
        }

        if (!dev->bulk_out_endpointAddr &&
            !(endpoint->bEndpointAddress & USB_DIR_IN) &&
            ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) {
                /* we found a bulk out endpoint */
                dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
        }
    }
    if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
        pr_err("Could not find both bulk-in and bulk-out endpoints");
        goto error;
    }

    /* save our data pointer in this interface device */
    usb_set_intfdata(interface, dev);

    /* we can register the device now, as it is ready */
    retval = usb_register_dev(interface, &proto_class);
    if (retval) {
        /* something prevented us from registering this driver */
        pr_err("Not able to get a minor for this device.");
        usb_set_intfdata(interface, NULL);
        goto error;
    }

    // create struct
    struct usb_skel * data;
    // alocs struct
    data = kmalloc(sizeof(*data), GFP_KERNEL);

    if (!data)
    {
        printk("Can't allocate memory for data structure\n");
        return -99;
    }

    // clear all
    memset(data, 0, sizeof(*data));
    // pass udev
    data->udev = udev2;

    /* let the user know what node this device is now attached to */
    dev_info(&interface->dev, "USB Skeleton device now attached to USBSkel-%d", interface->minor);
    data->interface = interface;
    data->bulk_out_endpointAddr = dev->bulk_out_endpointAddr;

    init_timer(&timer_write_periodic);
    timer_write_periodic.function = proto_write_periodic;
    timer_write_periodic.data = (unsigned long) data;
    timer_write_periodic.expires = jiffies + HZ; /* 1 second */
    printk(KERN_ALERT"Timer Module loaded\n");
    add_timer(&timer_write_periodic); /* Starting the timer */



    // seta baudrate ara 9600
    //https://github.com/damg/arnie-robot-controller/blob/f036c7066c2ca894911f8286df5219d6c42a5b2a/src/libftdi-0.14/ftdi.c
    //https://github.com/cyphunk/sectk/blob/50f7b5f552647fe073d25684dfddc9b8d59d17b4/often/bitbang_in_python/ftdibb-0.5/ftdibb.c
    //http://www.ftdichip.com/Support/Knowledgebase/index.html?whatbaudratesareachieveabl.htm
    //http://lxr.free-electrons.com/source/drivers/usb/serial/ftdi_sio.c
    //http://lxr.free-electrons.com/source/drivers/usb/serial/ftdi_sio.h
    //http://sourceforge.net/p/ftdi-usb-sio/mailman/message/4079784/
    //http://www.virtsync.com/c-error-codes-include-errno
    //https://www.kumari.net/index.php/random/37-determing-unknown-baud-rate
    //http://arduino.stackexchange.com/questions/296/how-high-of-a-baud-rate-can-i-go-without-errors
    //ftp://ftp.u-aizu.ac.jp/pub/os/Linux/kernel/v2.3/patch-html/patch-2.3.48/linux_drivers_usb_usb-serial.c.html
    //http://lxr.free-electrons.com/source/drivers/usb/serial/ftdi_sio.h?v=2.2.26
    //dev->udev, dev->bulk_out_endpointAddr
    int re = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), 3, 0x40, 0x4138, 0, NULL, 0, HZ*5);
    //int re=0;
    if (re != 0)
    	printk(KERN_ALERT" >> Setting new baudrate failed %d",re);
    	else
    	printk(KERN_ALERT" >> Setting new baudrate sucess");

    return 0;

error:
    if (dev)
        kref_put(&dev->kref, proto_delete);
    return retval;
}
示例#10
0
/**
 * zfcp_adapter_enqueue - enqueue a new adapter to the list
 * @ccw_device: pointer to the struct cc_device
 *
 * Returns:	struct zfcp_adapter*
 * Enqueues an adapter at the end of the adapter list in the driver data.
 * All adapter internal structures are set up.
 * Proc-fs entries are also created.
 */
struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device)
{
	struct zfcp_adapter *adapter;

	if (!get_device(&ccw_device->dev))
		return ERR_PTR(-ENODEV);

	adapter = kzalloc(sizeof(struct zfcp_adapter), GFP_KERNEL);
	if (!adapter) {
		put_device(&ccw_device->dev);
		return ERR_PTR(-ENOMEM);
	}

	kref_init(&adapter->ref);

	ccw_device->handler = NULL;
	adapter->ccw_device = ccw_device;

	INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler);
	INIT_WORK(&adapter->scan_work, zfcp_fc_scan_ports);

	if (zfcp_qdio_setup(adapter))
		goto failed;

	if (zfcp_allocate_low_mem_buffers(adapter))
		goto failed;

	adapter->req_list = zfcp_reqlist_alloc();
	if (!adapter->req_list)
		goto failed;

	if (zfcp_dbf_adapter_register(adapter))
		goto failed;

	if (zfcp_setup_adapter_work_queue(adapter))
		goto failed;

	if (zfcp_fc_gs_setup(adapter))
		goto failed;

	rwlock_init(&adapter->port_list_lock);
	INIT_LIST_HEAD(&adapter->port_list);

	init_waitqueue_head(&adapter->erp_ready_wq);
	init_waitqueue_head(&adapter->erp_done_wqh);

	INIT_LIST_HEAD(&adapter->erp_ready_head);
	INIT_LIST_HEAD(&adapter->erp_running_head);

	rwlock_init(&adapter->erp_lock);
	rwlock_init(&adapter->abort_lock);

	if (zfcp_erp_thread_setup(adapter))
		goto failed;

	adapter->service_level.seq_print = zfcp_print_sl;

	dev_set_drvdata(&ccw_device->dev, adapter);

	if (sysfs_create_group(&ccw_device->dev.kobj,
			       &zfcp_sysfs_adapter_attrs))
		goto failed;

	if (!zfcp_adapter_scsi_register(adapter))
		return adapter;

failed:
	zfcp_adapter_unregister(adapter);
	return ERR_PTR(-ENOMEM);
}
示例#11
0
static int as102_usb_probe(struct usb_interface *intf,
			   const struct usb_device_id *id)
{
	int ret;
	struct as102_dev_t *as102_dev;
	int i;

	/* This should never actually happen */
	if (ARRAY_SIZE(as102_usb_id_table) !=
	    (sizeof(as102_device_names) / sizeof(const char *))) {
		pr_err("Device names table invalid size");
		return -EINVAL;
	}

	as102_dev = kzalloc(sizeof(struct as102_dev_t), GFP_KERNEL);
	if (as102_dev == NULL)
		return -ENOMEM;

	/* Assign the user-friendly device name */
	for (i = 0; i < ARRAY_SIZE(as102_usb_id_table); i++) {
		if (id == &as102_usb_id_table[i]) {
			as102_dev->name = as102_device_names[i];
			as102_dev->elna_cfg = as102_elna_cfg[i];
		}
	}

	if (as102_dev->name == NULL)
		as102_dev->name = "Unknown AS102 device";

	/* set private callback functions */
	as102_dev->bus_adap.ops = &as102_priv_ops;

	/* init cmd token for usb bus */
	as102_dev->bus_adap.cmd = &as102_dev->bus_adap.token.usb.c;
	as102_dev->bus_adap.rsp = &as102_dev->bus_adap.token.usb.r;

	/* init kernel device reference */
	kref_init(&as102_dev->kref);

	/* store as102 device to usb_device private data */
	usb_set_intfdata(intf, (void *) as102_dev);

	/* store in as102 device the usb_device pointer */
	as102_dev->bus_adap.usb_dev = usb_get_dev(interface_to_usbdev(intf));

	/* we can register the device now, as it is ready */
	ret = usb_register_dev(intf, &as102_usb_class_driver);
	if (ret < 0) {
		/* something prevented us from registering this driver */
		dev_err(&intf->dev,
			"%s: usb_register_dev() failed (errno = %d)\n",
			__func__, ret);
		goto failed;
	}

	pr_info("%s: device has been detected\n", DRIVER_NAME);

	/* request buffer allocation for streaming */
	ret = as102_alloc_usb_stream_buffer(as102_dev);
	if (ret != 0)
		goto failed_stream;

	/* register dvb layer */
	ret = as102_dvb_register(as102_dev);
	if (ret != 0)
		goto failed_dvb;

	return ret;

failed_dvb:
	as102_free_usb_stream_buffer(as102_dev);
failed_stream:
	usb_deregister_dev(intf, &as102_usb_class_driver);
failed:
	usb_put_dev(as102_dev->bus_adap.usb_dev);
	usb_set_intfdata(intf, NULL);
	kfree(as102_dev);
	return ret;
}
示例#12
0
/*
    Create system device file for the enabled slot.
*/
ndas_error_t slot_enable(int s)
{
    ndas_error_t ret = NDAS_ERROR_INTERNAL;
    int got;
    struct ndas_slot* slot = NDAS_GET_SLOT_DEV(s); 
    dbgl_blk(3, "ing s#=%d slot=%p",s, slot);
    got = try_module_get(THIS_MODULE);
    MOD_INC_USE_COUNT;
    
    if ( slot == NULL)
        goto out1;
    
    if ( slot->enabled ) {
        dbgl_blk(1, "already enabled");
        ret = NDAS_OK;
        goto out2;
    }
    ret = ndas_query_slot(s, &slot->info);
    if ( !NDAS_SUCCESS(ret) ) {
        dbgl_blk(1, "fail ndas_query_slot");
        goto out2;
    }
    dbgl_blk(1, "mode=%d", slot->info.mode);
    
    slot->enabled = 1;
    
#if LINUX_VERSION_25_ABOVE

    slot->disk = NULL;
    spin_lock_init(&slot->lock);
    slot->queue = blk_init_queue(
        nblk_request_proc, 
        &slot->lock
    );
	#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,33))    
	    blk_queue_max_phys_segments(slot->queue, ND_BLK_MAX_REQ_SEGMENT);
	    blk_queue_max_hw_segments(slot->queue, ND_BLK_MAX_REQ_SEGMENT);
	#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,33))
	    blk_queue_max_segments(slot->queue, ND_BLK_MAX_REQ_SEGMENT);	//renamed in 2.6.34	
	    //blk_queue_max_hw_segments(slot->queue, ND_BLK_MAX_REQ_SEGMENT); //removed in 2.6.34
	#endif

	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31))
	    blk_queue_logical_block_size(slot->queue, slot->info.sector_size);
	#else
	    blk_queue_hardsect_size(slot->queue, slot->info.sector_size);
	#endif

	#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,33))
	    blk_queue_max_sectors(slot->queue, DEFAULT_ND_MAX_SECTORS);
	#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,33))
	    blk_queue_max_hw_sectors(slot->queue, DEFAULT_ND_MAX_SECTORS); //renamed in 2.6.34
	#endif

	#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16))
	    // Set ordered queue property.
		#if 0
		    blk_queue_ordered(slot->queue, QUEUE_ORDERED_TAG_FLUSH, nblk_prepare_flush);
		#endif
	#endif

    slot->disk = alloc_disk(NR_PARTITION);
    if ( slot->disk == NULL ) {
        slot->enabled = 0;
        dbgl_blk(1, "fail alloc disk");
        goto out2;
    }

    slot->disk->major = NDAS_BLK_MAJOR;
    slot->disk->first_minor = (s - NDAS_FIRST_SLOT_NR) << PARTN_BITS;
    slot->disk->fops = &ndas_fops;
    slot->disk->queue = slot->queue;
    slot->disk->private_data = (void*) (long)s;
    slot->queue_flags = 0;

    dbgl_blk(1, "mode=%d", slot->info.mode);
    if ( slot->info.mode == NDAS_DISK_MODE_SINGLE || 
        slot->info.mode == NDAS_DISK_MODE_ATAPI ||
        slot->info.mode == NDAS_DISK_MODE_MEDIAJUKE) 
    {
        char short_serial[NDAS_SERIAL_SHORT_LENGTH + 1];
        if (strlen(slot->info.ndas_serial) > 8) {
            /* Extended serial number is too long as sysfs object name. Use last 8 digit only */
            strncpy(
                short_serial,
                slot->info.ndas_serial + ( NDAS_SERIAL_EXTEND_LENGTH - NDAS_SERIAL_SHORT_LENGTH),
                8);
        } else {
            strncpy(short_serial, slot->info.ndas_serial, 8);
        }
        short_serial[8] =0;
        snprintf(slot->devname,
            sizeof(slot->devname)-1, 
            "ndas-%s-%d", short_serial, slot->info.unit
        );

        strcpy(slot->disk->disk_name, slot->devname);

	    dbgl_blk(1, "just set slot->disk->%s, slot->%s", slot->disk->disk_name, slot->devname );

	#if !LINUX_VERSION_DEVFS_REMOVED_COMPLETELY
	        strcpy(slot->disk->devfs_name, slot->devname);
	#endif
        set_capacity(slot->disk, slot->info.sectors);
	    dbgl_blk(1, "just set capacity slot->disk, slot->info.sectors:%llu", slot->info.sectors);

    } else {
        /* Other mode is not implemented */

    }
    
    if (slot->info.mode == NDAS_DISK_MODE_ATAPI) {
        slot->disk->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
	    dbgl_blk(1, "just set slot->disk->flags");
	#if 0
	        kref_init(&slot->ndascd.kref);
	#endif
    }

    dbgl_blk(4, "adding disk: slot=%d, first_minor=%d, capacity=%llu", s, slot->disk->first_minor, slot->info.sectors);
    add_disk(slot->disk);
    dbgl_blk(1, "added disk: slot=%d", s);
   
		#ifndef NDAS_DONT_CARE_SCHEDULER
			#if LINUX_VERSION_AVOID_CFQ_SCHEDULER
				#if CONFIG_SYSFS
				    sal_assert(slot->queue->kobj.ktype);	
				    sal_assert(slot->queue->kobj.ktype->default_attrs);
				    {
				        struct queue_sysfs_entry {
				        	struct attribute attr;
				        	ssize_t (*show)(struct request_queue *, char *);
				        	ssize_t (*store)(struct request_queue *, const char *, size_t);
				        };
				        struct attribute *attr = slot->queue->kobj.ktype->default_attrs[4];
				        struct queue_sysfs_entry *entry = container_of(attr , struct queue_sysfs_entry, attr);
				        //dbgl_blk(1, "now to set the scheduler: slot-queue=%d, scheduler==%s, scheduler_len=%d", slot->queue, NDAS_QUEUE_SCHEDULER, strlen(NDAS_QUEUE_SCHEDULER));
				        entry->store(slot->queue,NDAS_QUEUE_SCHEDULER,strlen(NDAS_QUEUE_SCHEDULER)); 
				        
				    }
				#else
					#error "NDAS driver doesn't work well with CFQ scheduler of 2.6.13 or above kernel." \
				   "if you forcely want to use it, please specify compiler flags by " \
				   "export NDAS_EXTRA_CFLAGS=\"-DNDAS_DONT_CARE_SCHEDULER\" "\
				   "then compile the source again."
				#endif
			#endif
		#endif        
    printk("ndas: /dev/%s enabled\n" , 
            slot->devname);
#else 
    /* < LINUX_VERSION_25_ABOVE */
    dbgl_blk(4, "blksize=%d", DEFAULT_ND_BLKSIZE);
    dbgl_blk(4, "size=%lld", slot->info.sectors);
    dbgl_blk(1, "hardsectsize=%d", slot->info.sector_size);
    ndas_ops_set_blk_size(
        s, 
        DEFAULT_ND_BLKSIZE, 
        slot->info.sectors,
        slot->info.sector_size, 
        DEFAULT_ND_MAX_SECTORS
    );
#ifdef NDAS_DEVFS    
    printk("ndas: /dev/nd/disc%d enabled\n" , 
            s - NDAS_FIRST_SLOT_NR);
#else
    printk("ndas: /dev/nd%c enabled\n" , 
            s + 'a' - NDAS_FIRST_SLOT_NR);
#endif

#endif
    
    //up(&slot->mutex);
 #ifdef NDAS_MSHARE 
    if(NDAS_GET_SLOT_DEV(s)->info.mode == NDAS_DISK_MODE_MEDIAJUKE)
    {
  	    ndas_CheckFormat(s);
    }
 #endif
#if !LINUX_VERSION_25_ABOVE
    ndas_ops_read_partition(s);
#endif
    dbgl_blk(3, "ed");
    return NDAS_OK;
out2:    
    //up(&slot->mutex);
out1:    
    if ( got ) module_put(THIS_MODULE);
    MOD_DEC_USE_COUNT;
    return ret;
}
示例#13
0
struct ion_client *ion_client_create(struct ion_device *dev,
				     unsigned int heap_mask,
				     const char *name)
{
	struct ion_client *client;
	struct task_struct *task;
	struct rb_node **p;
	struct rb_node *parent = NULL;
	struct ion_client *entry;
	pid_t pid;
	unsigned int name_len = strnlen(name, 64);

	get_task_struct(current->group_leader);
	task_lock(current->group_leader);
	pid = task_pid_nr(current->group_leader);
	/* don't bother to store task struct for kernel threads,
	   they can't be killed anyway */
	if (current->group_leader->flags & PF_KTHREAD) {
		put_task_struct(current->group_leader);
		task = NULL;
	} else {
		task = current->group_leader;
	}
	task_unlock(current->group_leader);

	/* if this isn't a kernel thread, see if a client already
	   exists */
	if (task) {
		client = ion_client_lookup(dev, task);
		if (!IS_ERR_OR_NULL(client)) {
			put_task_struct(current->group_leader);
			return client;
		}
	}

	client = kzalloc(sizeof(struct ion_client), GFP_KERNEL);
	if (!client) {
		put_task_struct(current->group_leader);
		return ERR_PTR(-ENOMEM);
	}

	client->dev = dev;
	client->handles = RB_ROOT;
	mutex_init(&client->lock);

	client->name = kzalloc(name_len+1, GFP_KERNEL);
	if (!client->name) {
		put_task_struct(current->group_leader);
		kfree(client);
		return ERR_PTR(-ENOMEM);
	} else {
		strlcpy(client->name, name, name_len+1);
	}

	client->heap_mask = heap_mask;
	client->task = task;
	client->pid = pid;
	kref_init(&client->ref);

	mutex_lock(&dev->lock);
	if (task) {
		p = &dev->user_clients.rb_node;
		while (*p) {
			parent = *p;
			entry = rb_entry(parent, struct ion_client, node);

			if (task < entry->task)
				p = &(*p)->rb_left;
			else if (task > entry->task)
				p = &(*p)->rb_right;
		}
		rb_link_node(&client->node, parent, p);
		rb_insert_color(&client->node, &dev->user_clients);
	} else {
示例#14
0
static int wf_sat_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct device_node *dev = client->dev.of_node;
	struct wf_sat *sat;
	struct wf_sat_sensor *sens;
	const u32 *reg;
	const char *loc, *type;
	u8 chip, core;
	struct device_node *child;
	int shift, cpu, index;
	char *name;
	int vsens[2], isens[2];

	sat = kzalloc(sizeof(struct wf_sat), GFP_KERNEL);
	if (sat == NULL)
		return -ENOMEM;
	sat->nr = -1;
	sat->node = of_node_get(dev);
	kref_init(&sat->ref);
	mutex_init(&sat->mutex);
	sat->i2c = client;
	INIT_LIST_HEAD(&sat->sensors);
	i2c_set_clientdata(client, sat);

	vsens[0] = vsens[1] = -1;
	isens[0] = isens[1] = -1;
	child = NULL;
	while ((child = of_get_next_child(dev, child)) != NULL) {
		reg = of_get_property(child, "reg", NULL);
		type = of_get_property(child, "device_type", NULL);
		loc = of_get_property(child, "location", NULL);
		if (reg == NULL || loc == NULL)
			continue;

		/* the cooked sensors are between 0x30 and 0x37 */
		if (*reg < 0x30 || *reg > 0x37)
			continue;
		index = *reg - 0x30;

		/* expect location to be CPU [AB][01] ... */
		if (strncmp(loc, "CPU ", 4) != 0)
			continue;
		chip = loc[4] - 'A';
		core = loc[5] - '0';
		if (chip > 1 || core > 1) {
			printk(KERN_ERR "wf_sat_create: don't understand "
			       "location %s for %s\n", loc, child->full_name);
			continue;
		}
		cpu = 2 * chip + core;
		if (sat->nr < 0)
			sat->nr = chip;
		else if (sat->nr != chip) {
			printk(KERN_ERR "wf_sat_create: can't cope with "
			       "multiple CPU chips on one SAT (%s)\n", loc);
			continue;
		}

		if (strcmp(type, "voltage-sensor") == 0) {
			name = "cpu-voltage";
			shift = 4;
			vsens[core] = index;
		} else if (strcmp(type, "current-sensor") == 0) {
			name = "cpu-current";
			shift = 8;
			isens[core] = index;
		} else if (strcmp(type, "temp-sensor") == 0) {
			name = "cpu-temp";
			shift = 10;
		} else
			continue;	/* hmmm shouldn't happen */

		/* the +16 is enough for "cpu-voltage-n" */
		sens = kzalloc(sizeof(struct wf_sat_sensor) + 16, GFP_KERNEL);
		if (sens == NULL) {
			printk(KERN_ERR "wf_sat_create: couldn't create "
			       "%s sensor %d (no memory)\n", name, cpu);
			continue;
		}
		sens->index = index;
		sens->index2 = -1;
		sens->shift = shift;
		sens->sat = sat;
		sens->sens.ops = &wf_sat_ops;
		sens->sens.name = (char *) (sens + 1);
		snprintf((char *)sens->sens.name, 16, "%s-%d", name, cpu);

		if (wf_register_sensor(&sens->sens))
			kfree(sens);
		else {
			list_add(&sens->link, &sat->sensors);
			kref_get(&sat->ref);
		}
	}

	/* make the power sensors */
	for (core = 0; core < 2; ++core) {
		if (vsens[core] < 0 || isens[core] < 0)
			continue;
		cpu = 2 * sat->nr + core;
		sens = kzalloc(sizeof(struct wf_sat_sensor) + 16, GFP_KERNEL);
		if (sens == NULL) {
			printk(KERN_ERR "wf_sat_create: couldn't create power "
			       "sensor %d (no memory)\n", cpu);
			continue;
		}
		sens->index = vsens[core];
		sens->index2 = isens[core];
		sens->shift = 0;
		sens->sat = sat;
		sens->sens.ops = &wf_sat_ops;
		sens->sens.name = (char *) (sens + 1);
		snprintf((char *)sens->sens.name, 16, "cpu-power-%d", cpu);

		if (wf_register_sensor(&sens->sens))
			kfree(sens);
		else {
			list_add(&sens->link, &sat->sensors);
			kref_get(&sat->ref);
		}
	}

	if (sat->nr >= 0)
		sats[sat->nr] = sat;

	return 0;
}
示例#15
0
/*
 * Attach a new iface.
 *
 * Must be called with ifaces lock hold and with a reference onto the ifp.
 */
static int
omx_iface_attach(struct net_device * ifp)
{
	struct omx_iface * iface;
	struct device *dev;
	char *hostname;
	unsigned mtu = ifp->mtu;
	unsigned rx_coalesce;
	int ret;
	int i;

	if (omx_iface_nr == omx_iface_max) {
		printk(KERN_ERR "Open-MX: Too many interfaces already attached\n");
		ret = -EBUSY;
		goto out;
	}

	if (omx_iface_find_by_ifp(ifp)) {
		printk(KERN_ERR "Open-MX: Interface '%s' already attached\n", ifp->name);
		ret = -EBUSY;
		goto out;
	}

	for(i=0; i<omx_iface_max; i++)
		if (rcu_access_pointer(omx_ifaces[i]) == NULL)
			break;

	iface = kzalloc(sizeof(struct omx_iface), GFP_KERNEL);
	if (!iface) {
		printk(KERN_ERR "Open-MX: Failed to allocate interface as board %d\n", i);
		ret = -ENOMEM;
		goto out;
	}

	iface->reverse_peer_indexes = kmalloc(omx_peer_max * sizeof(*iface->reverse_peer_indexes), GFP_KERNEL);
	if (!iface->reverse_peer_indexes) {
		printk(KERN_ERR "Open-MX: Failed to allocate interface reverse peer index array\n");
		ret = -ENOMEM;
		goto out_with_iface;
	}

	printk(KERN_INFO "Open-MX: Attaching %sEthernet interface '%s' as #%i, MTU=%d\n",
	       (ifp->type == ARPHRD_ETHER ? "" : "non-"), ifp->name, i, mtu);

	dev = omx_ifp_to_dev(ifp);
#ifdef CONFIG_PCI
	if (dev && dev->bus == &pci_bus_type) {
		struct pci_dev *pdev = to_pci_dev(dev);

		BUG_ON(!pdev->driver);
		printk(KERN_INFO "Open-MX:   Interface '%s' is PCI device '%s' managed by driver '%s'\n",
		       ifp->name, omx_dev_name(dev), pdev->driver->name);
	}
#endif

	if (!(dev_get_flags(ifp) & IFF_UP))
		printk(KERN_WARNING "Open-MX:   WARNING: Interface '%s' is not up\n",
		       ifp->name);
	if (mtu < OMX_MTU)
		printk(KERN_WARNING "Open-MX:   WARNING: Interface '%s' MTU should be at least %d, current value %d might cause problems\n",
		       ifp->name, OMX_MTU, mtu);
	if (!omx_iface_get_rx_coalesce(ifp, &rx_coalesce)
	    && rx_coalesce >= OMX_IFACE_RX_USECS_WARN_MIN)
		printk(KERN_WARNING "Open-MX:   WARNING: Interface '%s' interrupt coalescing very high (%ldus)\n",
		       ifp->name, (unsigned long) rx_coalesce);

	hostname = kmalloc(OMX_HOSTNAMELEN_MAX, GFP_KERNEL);
	if (!hostname) {
		printk(KERN_ERR "Open-MX:   Failed to allocate interface hostname\n");
		ret = -ENOMEM;
		goto out_with_iface_reverse_indexes;
	}

	if (ifp->type == ARPHRD_LOOPBACK)
		snprintf(hostname, OMX_HOSTNAMELEN_MAX, "localhost");
	else
		snprintf(hostname, OMX_HOSTNAMELEN_MAX, "%s:%d", omx_current_utsname.nodename, i);
	hostname[OMX_HOSTNAMELEN_MAX-1] = '\0';
	iface->peer.hostname = hostname;
	iface->peer.index = OMX_UNKNOWN_REVERSE_PEER_INDEX;
	iface->peer.board_addr = omx_board_addr_from_netdevice(ifp);
	/* reverse_peer_indexes will be initialized in omx_peers_notify_iface_attach */

	iface->eth_ifp = ifp;
	iface->endpoint_nr = 0;
	iface->endpoints = kzalloc(omx_endpoint_max * sizeof(struct omx_endpoint *), GFP_KERNEL);
	if (!iface->endpoints) {
		printk(KERN_ERR "Open-MX:   Failed to allocate interface endpoint pointers\n");
		ret = -ENOMEM;
		goto out_with_iface_hostname;
	}

	omx_iface_raw_init(&iface->raw);

	kref_init(&iface->refcount);
	mutex_init(&iface->endpoints_mutex);

	/* insert in the peer table */
	ret = omx_peers_notify_iface_attach(iface);
	if (ret < 0)
		goto out_with_raw;

	iface->index = i;
	rcu_assign_pointer(omx_ifaces[i], iface);
	omx_iface_nr++;

	return 0;

 out_with_raw:
	omx_iface_raw_exit(&iface->raw);
	kfree(iface->endpoints);
 out_with_iface_hostname:
	kfree(hostname);
 out_with_iface_reverse_indexes:
	kfree(iface->reverse_peer_indexes);
 out_with_iface:
	kfree(iface);
 out:
	return ret;
}
示例#16
0
static int
diag_bridge_probe(struct usb_interface *ifc, const struct usb_device_id *id)
{
	struct diag_bridge		*dev;
	struct usb_host_interface	*ifc_desc;
	struct usb_endpoint_descriptor	*ep_desc;
	int				i;
	int				ret = -ENOMEM;
	__u8				ifc_num;

	pr_debug("id:%lu", id->driver_info);

	ifc_num = ifc->cur_altsetting->desc.bInterfaceNumber;

	/* is this interface supported ? */
	if (ifc_num != id->driver_info)
		return -ENODEV;

	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev) {
		pr_err("unable to allocate dev");
		return -ENOMEM;
	}
	dev->pdev = platform_device_alloc("diag_bridge", -1);
	if (!dev->pdev) {
		pr_err("unable to allocate platform device");
		kfree(dev);
		return -ENOMEM;
	}
	__dev = dev;

	dev->udev = usb_get_dev(interface_to_usbdev(ifc));
	dev->ifc = ifc;
	kref_init(&dev->kref);
	mutex_init(&dev->ifc_mutex);
	init_usb_anchor(&dev->submitted);

	ifc_desc = ifc->cur_altsetting;
	for (i = 0; i < ifc_desc->desc.bNumEndpoints; i++) {
		ep_desc = &ifc_desc->endpoint[i].desc;
#ifdef LG_FW_HSIC_EMS_DEBUG /* secheol.pyo - endpoint logging */
		printk("[%s]for ++, i= %d, ifc_desc->desc.bNumEndpoints = %d\n", __func__,i, ifc_desc->desc.bNumEndpoints);
#endif /* secheol.pyo - endpoint logging */

		if (!dev->in_epAddr && usb_endpoint_is_bulk_in(ep_desc))
			dev->in_epAddr = ep_desc->bEndpointAddress;

		if (!dev->out_epAddr && usb_endpoint_is_bulk_out(ep_desc))
			dev->out_epAddr = ep_desc->bEndpointAddress;
#ifdef LG_FW_HSIC_EMS_DEBUG /* secheol.pyo - endpoint logging */
		printk("[%s]for --, i= %d, dev->in_epAddr = %d, dev->out_epAddr = %d \n", __func__,i, dev->in_epAddr, dev->out_epAddr);
#endif/* secheol.pyo - endpoint logging */
	}

	if (!(dev->in_epAddr && dev->out_epAddr)) {
		pr_err("could not find bulk in and bulk out endpoints");
		ret = -ENODEV;
		goto error;
	}

	usb_set_intfdata(ifc, dev);
	diag_bridge_debugfs_init();
	platform_device_add(dev->pdev);

	dev_dbg(&dev->ifc->dev, "%s: complete\n", __func__);

	return 0;

error:
	if (dev)
		kref_put(&dev->kref, diag_bridge_delete);

	return ret;
}
static int
diag_bridge_probe(struct usb_interface *ifc, const struct usb_device_id *id)
{
	struct diag_bridge		*dev;
	struct usb_host_interface	*ifc_desc;
	struct usb_endpoint_descriptor	*ep_desc;
	int				i, devid, ret = -ENOMEM;

	pr_debug("id:%lu", id->driver_info);

	devid = id->driver_info & 0xFF;
	if (devid < 0 || devid >= MAX_DIAG_BRIDGE_DEVS)
		return -ENODEV;

	/* already probed? */
	if (__dev[devid]) {
		pr_err("Diag device already probed");
		return -ENODEV;
	}

	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev) {
		pr_err("unable to allocate dev");
		return -ENOMEM;
	}

	__dev[devid] = dev;
	dev->id = devid;

	dev->udev = usb_get_dev(interface_to_usbdev(ifc));
	dev->ifc = ifc;
	kref_init(&dev->kref);
	mutex_init(&dev->ifc_mutex);
	init_usb_anchor(&dev->submitted);

	ifc_desc = ifc->cur_altsetting;
	for (i = 0; i < ifc_desc->desc.bNumEndpoints; i++) {
		ep_desc = &ifc_desc->endpoint[i].desc;

		if (!dev->in_epAddr && usb_endpoint_is_bulk_in(ep_desc))
			dev->in_epAddr = ep_desc->bEndpointAddress;

		if (!dev->out_epAddr && usb_endpoint_is_bulk_out(ep_desc))
			dev->out_epAddr = ep_desc->bEndpointAddress;
	}

	if (!(dev->in_epAddr && dev->out_epAddr)) {
		pr_err("could not find bulk in and bulk out endpoints");
		ret = -ENODEV;
		goto error;
	}

	usb_set_intfdata(ifc, dev);
	diag_bridge_debugfs_init();
	dev->pdev = platform_device_register_simple("diag_bridge", devid,
						    NULL, 0);
	if (IS_ERR(dev->pdev)) {
		pr_err("unable to allocate platform device");
		ret = PTR_ERR(dev->pdev);
		goto error;
	}

	dev_dbg(&dev->ifc->dev, "%s: complete\n", __func__);

	return 0;

error:
	if (dev)
		kref_put(&dev->kref, diag_bridge_delete);

	return ret;
}
示例#18
0
static int usb_dio_probe(struct usb_interface *intf, const struct usb_device_id *id) {
  struct usb_cdc_union_desc *union_header = NULL;
	unsigned char *buffer = intf->altsetting->extra;
	int buflen = intf->altsetting->extralen;
	struct usb_interface *control_interface;
	struct usb_interface *data_interface;
	struct usb_device *usb_dev = interface_to_usbdev(intf);
  int retval = 0;
  
  usb_dio_dev *dev;
  
  /* prevent usb_dio_probe() from racing usb_dio_disconnect() */
  lock_kernel();
  
  FUNC_HI();
  dev = kmalloc(sizeof(usb_dio_dev), GFP_KERNEL);
  if (dev == NULL) {
    err("Out of Memory");
    unlock_kernel();
    FUNC_ERR();
    return -ENOMEM;
  }
	memset(dev, 0x00, sizeof (usb_dio_dev));
  dev->dev = usb_get_dev(interface_to_usbdev(intf));
	kref_init(&(dev->kref));
  usb_set_intfdata(intf, dev);
  
  printk(KERN_ALERT "%s: === Starting device probe ===\n", usb_dio_driver.name);
  
  if (!buflen) {
    printk(KERN_ALERT "%s: === Invalid / unwanted device ===\n", usb_dio_driver.name);
    unlock_kernel();
    FUNC_ERR();
    return -EINVAL;
  }

  DPRINTK(KERN_ALERT "%s: == Chunk size    = %2d ==\n", usb_dio_driver.name, buffer[0]);
  DPRINTK(KERN_ALERT "%s: == Buffer length = %2d ==\n", usb_dio_driver.name, buflen);
	while (buflen > 0) {
		switch (buffer[2]) {
      case USB_CDC_UNION_TYPE: /* we've found it */
        DPRINTK(KERN_ALERT "%s: ==== USB_CDC_UNION_TYPE ==============\n", usb_dio_driver.name);
        if (union_header) {
          DPRINTK(KERN_ALERT "%s: ===== More than one union header! =====\n", usb_dio_driver.name);
          break;
        }
        union_header = (struct usb_cdc_union_desc *)buffer;
        break;
      default:
        DPRINTK(KERN_ALERT "%s: ==== Unwanted default... =============\n", usb_dio_driver.name);
        break;
		}
    DPRINTK(KERN_ALERT "%s: === continuation with %2d remaining... ===\n", usb_dio_driver.name, buflen - buffer[0]);
		buflen -= buffer[0];
		buffer += buffer[0];
	}
  DPRINTK(KERN_ALERT "%s: == complete with %2d remaining ==\n", usb_dio_driver.name, buflen);

  control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0);
  data_interface = usb_ifnum_to_if(usb_dev, union_header->bSlaveInterface0);
  if (!control_interface || !data_interface) {
    printk(KERN_ALERT "%s: === missing interface(s)! ===\n", usb_dio_driver.name);
    unlock_kernel();
    FUNC_ERR();
    return -ENODEV;
  }

  sema_init(&dev->buffer_sem,1);
  sema_init(&dev->buffer_empty_sem,1);

  dev->bulk_in = &(data_interface->cur_altsetting->endpoint[0].desc);
  dev->bulk_in_urb = NULL;
  dev->bulk_in_size = dev->bulk_in->wMaxPacketSize;
  dev->bulk_in_endpointAddr = dev->bulk_in->bEndpointAddress & 0xF;
  dev->bulk_in_endpointPipe = usb_rcvbulkpipe(dev->dev,dev->bulk_in_endpointAddr);
  dev->bulk_in_buffer = kmalloc(dev->bulk_in->wMaxPacketSize, GFP_KERNEL);
  dev->bulk_in_workqueue = create_singlethread_workqueue("Rx");
  INIT_WORK(&(dev->bulk_in_work.work),(void(*)(struct work_struct *))diodev_rx_work);
  dev->bulk_in_work.arg = NULL;
  dev->bulk_in_work.dev = dev;
  
  dev->bulk_out = &(data_interface->cur_altsetting->endpoint[1].desc);
  dev->bulk_out_endpointAddr = dev->bulk_out->bEndpointAddress & 0xF;
  dev->bulk_out_endpointPipe = usb_sndbulkpipe(dev->dev,dev->bulk_out_endpointAddr);
  dev->bulk_out_cb_urb_chain = NULL;
  sema_init(&dev->bulk_out_cb_urb_chain_sem,1);
  dev->bulk_out_urb_chain = NULL;
  sema_init(&dev->bulk_out_urb_chain_sem,1);
  dev->bulk_out_workqueue = create_singlethread_workqueue("Tx");
  INIT_WORK(&(dev->bulk_out_work.work),(void(*)(struct work_struct *))diodev_write_work);
  dev->bulk_out_work.arg = NULL;
  dev->bulk_out_work.dev = dev;
  
  dev->bulk_ctrl = &(control_interface->cur_altsetting->endpoint[0].desc);
  dev->bulk_ctrl_endpointAddr = dev->bulk_ctrl->bEndpointAddress & 0xF;
  
  retval = usb_register_dev(intf, &usb_dio_class);
  if (retval) {
    printk(KERN_ALERT "%s: Not able to get a minor for this device...\n", usb_dio_driver.name);
    usb_set_intfdata(intf, NULL);
  } else {
    printk(KERN_ALERT "%s: Minor device %d\n", usb_dio_driver.name, intf->minor);
  }
  
  dev->running = 1;
  diodev_rx_setup(dev);
  
  unlock_kernel();
  
  FUNC_BYE();
  return retval;
}
示例#19
0
static unsigned long unflatten_dt_node(struct boot_param_header *blob,
				unsigned long mem,
				unsigned long *p,
				struct device_node *dad,
				struct device_node ***allnextpp,
				unsigned long fpsize)
{
	struct device_node *np;
	struct property *pp, **prev_pp = NULL;
	char *pathp;
	u32 tag;
	unsigned int l, allocl;
	int has_name = 0;
	int new_format = 0;

	tag = be32_to_cpup((__be32 *)(*p));
	if (tag != OF_DT_BEGIN_NODE) {
		pr_err("Weird tag at start of node: %x\n", tag);
		return mem;
	}
	*p += 4;
	pathp = (char *)*p;
	l = allocl = strlen(pathp) + 1;
	*p = ALIGN(*p + l, 4);

	if ((*pathp) != '/') {
		new_format = 1;
		if (fpsize == 0) {
			fpsize = 1;
			allocl = 2;
		} else {
			fpsize += l;
			allocl = fpsize;
		}
	}

	np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
				__alignof__(struct device_node));
	if (allnextpp) {
		memset(np, 0, sizeof(*np));
		np->full_name = ((char *)np) + sizeof(struct device_node);
		if (new_format) {
			char *fn = np->full_name;
			
			if (dad && dad->parent) {
				strcpy(fn, dad->full_name);
#ifdef DEBUG
				if ((strlen(fn) + l + 1) != allocl) {
					pr_debug("%s: p: %d, l: %d, a: %d\n",
						pathp, (int)strlen(fn),
						l, allocl);
				}
#endif
				fn += strlen(fn);
			}
			*(fn++) = '/';
			memcpy(fn, pathp, l);
		} else
			memcpy(np->full_name, pathp, l);
		prev_pp = &np->properties;
		**allnextpp = np;
		*allnextpp = &np->allnext;
		if (dad != NULL) {
			np->parent = dad;
			
			if (dad->next == NULL)
				dad->child = np;
			else
				dad->next->sibling = np;
			dad->next = np;
		}
		kref_init(&np->kref);
	}
	
	while (1) {
		u32 sz, noff;
		char *pname;

		tag = be32_to_cpup((__be32 *)(*p));
		if (tag == OF_DT_NOP) {
			*p += 4;
			continue;
		}
		if (tag != OF_DT_PROP)
			break;
		*p += 4;
		sz = be32_to_cpup((__be32 *)(*p));
		noff = be32_to_cpup((__be32 *)((*p) + 4));
		*p += 8;
		if (be32_to_cpu(blob->version) < 0x10)
			*p = ALIGN(*p, sz >= 8 ? 8 : 4);

		pname = of_fdt_get_string(blob, noff);
		if (pname == NULL) {
			pr_info("Can't find property name in list !\n");
			break;
		}
		if (strcmp(pname, "name") == 0)
			has_name = 1;
		l = strlen(pname) + 1;
		pp = unflatten_dt_alloc(&mem, sizeof(struct property),
					__alignof__(struct property));
		if (allnextpp) {
			if ((strcmp(pname, "phandle") == 0) ||
			    (strcmp(pname, "linux,phandle") == 0)) {
				if (np->phandle == 0)
					np->phandle = be32_to_cpup((__be32*)*p);
			}
			if (strcmp(pname, "ibm,phandle") == 0)
				np->phandle = be32_to_cpup((__be32 *)*p);
			pp->name = pname;
			pp->length = sz;
			pp->value = (void *)*p;
			*prev_pp = pp;
			prev_pp = &pp->next;
		}
		*p = ALIGN((*p) + sz, 4);
	}
	if (!has_name) {
		char *p1 = pathp, *ps = pathp, *pa = NULL;
		int sz;

		while (*p1) {
			if ((*p1) == '@')
				pa = p1;
			if ((*p1) == '/')
				ps = p1 + 1;
			p1++;
		}
		if (pa < ps)
			pa = p1;
		sz = (pa - ps) + 1;
		pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
					__alignof__(struct property));
		if (allnextpp) {
			pp->name = "name";
			pp->length = sz;
			pp->value = pp + 1;
			*prev_pp = pp;
			prev_pp = &pp->next;
			memcpy(pp->value, ps, sz - 1);
			((char *)pp->value)[sz - 1] = 0;
			pr_debug("fixed up name for %s -> %s\n", pathp,
				(char *)pp->value);
		}
	}
示例#20
0
static unsigned long __init unflatten_dt_node(unsigned long mem,
					      unsigned long *p,
					      struct device_node *dad,
					      struct device_node ***allnextpp,
					      unsigned long fpsize)
{
	struct device_node *np;
	struct property *pp, **prev_pp = NULL;
	char *pathp;
	u32 tag;
	unsigned int l, allocl;
	int has_name = 0;
	int new_format = 0;

	tag = *((u32 *)(*p));
	if (tag != OF_DT_BEGIN_NODE) {
		printk("Weird tag at start of node: %x\n", tag);
		return mem;
	}
	*p += 4;
	pathp = (char *)*p;
	l = allocl = strlen(pathp) + 1;
	*p = _ALIGN(*p + l, 4);

	/* version 0x10 has a more compact unit name here instead of the full
	 * path. we accumulate the full path size using "fpsize", we'll rebuild
	 * it later. We detect this because the first character of the name is
	 * not '/'.
	 */
	if ((*pathp) != '/') {
		new_format = 1;
		if (fpsize == 0) {
			/* root node: special case. fpsize accounts for path
			 * plus terminating zero. root node only has '/', so
			 * fpsize should be 2, but we want to avoid the first
			 * level nodes to have two '/' so we use fpsize 1 here
			 */
			fpsize = 1;
			allocl = 2;
		} else {
			/* account for '/' and path size minus terminal 0
			 * already in 'l'
			 */
			fpsize += l;
			allocl = fpsize;
		}
	}


	np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
				__alignof__(struct device_node));
	if (allnextpp) {
		memset(np, 0, sizeof(*np));
		np->full_name = ((char*)np) + sizeof(struct device_node);
		if (new_format) {
			char *p = np->full_name;
			/* rebuild full path for new format */
			if (dad && dad->parent) {
				strcpy(p, dad->full_name);
#ifdef DEBUG
				if ((strlen(p) + l + 1) != allocl) {
					DBG("%s: p: %d, l: %d, a: %d\n",
					    pathp, (int)strlen(p), l, allocl);
				}
#endif
				p += strlen(p);
			}
			*(p++) = '/';
			memcpy(p, pathp, l);
		} else
			memcpy(np->full_name, pathp, l);
		prev_pp = &np->properties;
		**allnextpp = np;
		*allnextpp = &np->allnext;
		if (dad != NULL) {
			np->parent = dad;
			/* we temporarily use the next field as `last_child'*/
			if (dad->next == 0)
				dad->child = np;
			else
				dad->next->sibling = np;
			dad->next = np;
		}
		kref_init(&np->kref);
	}
	while(1) {
		u32 sz, noff;
		char *pname;

		tag = *((u32 *)(*p));
		if (tag == OF_DT_NOP) {
			*p += 4;
			continue;
		}
		if (tag != OF_DT_PROP)
			break;
		*p += 4;
		sz = *((u32 *)(*p));
		noff = *((u32 *)((*p) + 4));
		*p += 8;
		if (initial_boot_params->version < 0x10)
			*p = _ALIGN(*p, sz >= 8 ? 8 : 4);

		pname = find_flat_dt_string(noff);
		if (pname == NULL) {
			printk("Can't find property name in list !\n");
			break;
		}
		if (strcmp(pname, "name") == 0)
			has_name = 1;
		l = strlen(pname) + 1;
		pp = unflatten_dt_alloc(&mem, sizeof(struct property),
					__alignof__(struct property));
		if (allnextpp) {
			if (strcmp(pname, "linux,phandle") == 0) {
				np->node = *((u32 *)*p);
				if (np->linux_phandle == 0)
					np->linux_phandle = np->node;
			}
			if (strcmp(pname, "ibm,phandle") == 0)
				np->linux_phandle = *((u32 *)*p);
			pp->name = pname;
			pp->length = sz;
			pp->value = (void *)*p;
			*prev_pp = pp;
			prev_pp = &pp->next;
		}
		*p = _ALIGN((*p) + sz, 4);
	}
	/* with version 0x10 we may not have the name property, recreate
	 * it here from the unit name if absent
	 */
	if (!has_name) {
		char *p = pathp, *ps = pathp, *pa = NULL;
		int sz;

		while (*p) {
			if ((*p) == '@')
				pa = p;
			if ((*p) == '/')
				ps = p + 1;
			p++;
		}
		if (pa < ps)
			pa = p;
		sz = (pa - ps) + 1;
		pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
					__alignof__(struct property));
		if (allnextpp) {
			pp->name = "name";
			pp->length = sz;
			pp->value = (unsigned char *)(pp + 1);
			*prev_pp = pp;
			prev_pp = &pp->next;
			memcpy(pp->value, ps, sz - 1);
			((char *)pp->value)[sz - 1] = 0;
			DBG("fixed up name for %s -> %s\n", pathp, pp->value);
		}
	}
示例#21
0
static int synccom_probe(struct usb_interface *interface,
		      const struct usb_device_id *id)
{
	struct synccom_port *port;
	
	struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *endpoint;
	size_t buffer_size;
	int i;
	int retval = -ENOMEM;

	/* allocate memory for our device state and initialize it */
	port = kzalloc(sizeof(*port), GFP_KERNEL);
	if (!port) {
		dev_err(&interface->dev, "Out of memory\n");
		goto error;
	}
	kref_init(&port->kref);
	sema_init(&port->limit_sem, WRITES_IN_FLIGHT);
	mutex_init(&port->io_mutex);
	spin_lock_init(&port->err_lock);
	init_usb_anchor(&port->submitted);
	init_waitqueue_head(&port->bulk_in_wait);

	port->udev = usb_get_dev(interface_to_usbdev(interface));
	port->interface = interface;

	/* set up the endpoint information */
	/* use only the first bulk-in and bulk-out endpoints */
	iface_desc = interface->cur_altsetting;
	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
		endpoint = &iface_desc->endpoint[i].desc;

		if (!port->bulk_in_endpointAddr &&
		    usb_endpoint_is_bulk_in(endpoint)) {
			/* we found a bulk in endpoint */
			buffer_size = endpoint->wMaxPacketSize;
						port->bulk_in_size = buffer_size;
			port->bulk_in_endpointAddr = endpoint->bEndpointAddress;
			port->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
			if (!port->bulk_in_buffer) {
				dev_err(&interface->dev,
					"Could not allocate bulk_in_buffer\n");
				goto error;
			}
			port->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL);
			if (!port->bulk_in_urb) {
				dev_err(&interface->dev,
					"Could not allocate bulk_in_urb\n");
				goto error;
			}
		}

		if (!port->bulk_out_endpointAddr &&
		    usb_endpoint_is_bulk_out(endpoint)) {
			/* we found a bulk out endpoint */
			port->bulk_out_endpointAddr = endpoint->bEndpointAddress;
			
		}

                if (port->bulk_out_endpointAddr &&
		    usb_endpoint_is_bulk_out(endpoint)) {
			/* we found a bulk out endpoint */
			port->bulk_out_endpointAddr2 = endpoint->bEndpointAddress;
		}

	}
	if (!(port->bulk_in_endpointAddr && port->bulk_out_endpointAddr)) {
		dev_err(&interface->dev,
			"Could not find both bulk-in and bulk-out endpoints\n");
		goto error;
	}

	/* save our data pointer in this interface device */
	usb_set_intfdata(interface, port);

	/* we can register the device now, as it is ready */
	retval = usb_register_dev(interface, &synccom_class);
	if (retval) {
		/* something prevented us from registering this driver */
		dev_err(&interface->dev,
			"Not able to get a minor for this device.\n");
		usb_set_intfdata(interface, NULL);
		goto error;
	}

	/* let the user know what node this device is now attached to */
	dev_info(&interface->dev,
		 "USB synccom device now attached to synccom%d\n",
		 interface->minor);
    
	initialize(port);
	
	return 0;

error:
	if (port)
		/* this frees allocated memory */
		kref_put(&port->kref, synccom_delete);
	return retval;
}
示例#22
0
static int vs_add_dev(struct pdp_info *dev)
{
	struct tty_driver *tty_driver;

	switch (dev->id) {
		case 1:
			tty_driver = &dev->vs_dev.tty_driver[0];
			tty_driver->minor_start = CSD_MINOR_NUM;
			break;

		case 8:
			tty_driver = &dev->vs_dev.tty_driver[1];
			tty_driver->minor_start = 1;
			break;

		case 5:
			tty_driver = &dev->vs_dev.tty_driver[2];
			tty_driver->minor_start = 2;
			break;

		case 6:
			tty_driver = &dev->vs_dev.tty_driver[3];
			tty_driver->minor_start = 3;
			break;
			
		case 25:
			tty_driver = &dev->vs_dev.tty_driver[4];
			tty_driver->minor_start = 4;
			break;
			
		case 30:
			tty_driver = &dev->vs_dev.tty_driver[5];
			tty_driver->minor_start = 5;
			break;
			
#ifdef LOOP_BACK_TEST
		case 31:
			tty_driver = &dev->vs_dev.tty_driver[6];
			tty_driver->minor_start = 6;
			break;
#endif
		default:
			tty_driver = NULL;
	}

	if (!tty_driver) {
		printk("tty driver is NULL!\n");
		return -1;
	}

	kref_init(&tty_driver->kref);

	tty_driver->magic	= TTY_DRIVER_MAGIC;
	tty_driver->driver_name	= "multipdp";
	tty_driver->name	= dev->vs_dev.tty_name;
	tty_driver->major	= CSD_MAJOR_NUM;
//	tty_driver->minor_start = CSD_MINOR_NUM;
	tty_driver->num		= 1;
	tty_driver->type	= TTY_DRIVER_TYPE_SERIAL;
	tty_driver->subtype	= SERIAL_TYPE_NORMAL;
	tty_driver->flags	= TTY_DRIVER_REAL_RAW;
	tty_driver->ttys	= dev->vs_dev.tty_table; // 2.6 kernel porting
	tty_driver->termios	= dev->vs_dev.termios;
	tty_driver->termios_locked	= dev->vs_dev.termios_locked;

//	tty_driver->init_termios = tty_std_termios;

	tty_set_operations(tty_driver, &multipdp_tty_ops);
	return tty_register_driver(tty_driver);
}
示例#23
0
/**
 * unflatten_dt_node - Alloc and populate a device_node from the flat tree
 * @blob: The parent device tree blob
 * @mem: Memory chunk to use for allocating device nodes and properties
 * @p: pointer to node in flat tree
 * @dad: Parent struct device_node
 * @allnextpp: pointer to ->allnext from last allocated device_node
 * @fpsize: Size of the node path up at the current depth.
 */
static void * unflatten_dt_node(void *blob,
				void *mem,
				int *poffset,
				struct device_node *dad,
				struct device_node ***allnextpp,
				unsigned long fpsize)
{
	const __be32 *p;
	struct device_node *np;
	struct property *pp, **prev_pp = NULL;
	const char *pathp;
	unsigned int l, allocl;
	static int depth = 0;
	int old_depth;
	int offset;
	int has_name = 0;
	int new_format = 0;

	pathp = fdt_get_name(blob, *poffset, &l);
	if (!pathp)
		return mem;

	allocl = l++;

	/* version 0x10 has a more compact unit name here instead of the full
	 * path. we accumulate the full path size using "fpsize", we'll rebuild
	 * it later. We detect this because the first character of the name is
	 * not '/'.
	 */
	if ((*pathp) != '/') {
		new_format = 1;
		if (fpsize == 0) {
			/* root node: special case. fpsize accounts for path
			 * plus terminating zero. root node only has '/', so
			 * fpsize should be 2, but we want to avoid the first
			 * level nodes to have two '/' so we use fpsize 1 here
			 */
			fpsize = 1;
			allocl = 2;
			l = 1;
			pathp = "";
		} else {
			/* account for '/' and path size minus terminal 0
			 * already in 'l'
			 */
			fpsize += l;
			allocl = fpsize;
		}
	}

	np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
				__alignof__(struct device_node));
	if (allnextpp) {
		char *fn;
		memset(np, 0, sizeof(*np));
		np->full_name = fn = ((char *)np) + sizeof(*np);
		if (new_format) {
			/* rebuild full path for new format */
			if (dad && dad->parent) {
				strcpy(fn, dad->full_name);
#ifdef DEBUG
				if ((strlen(fn) + l + 1) != allocl) {
					pr_debug("%s: p: %d, l: %d, a: %d\n",
						pathp, (int)strlen(fn),
						l, allocl);
				}
#endif
				fn += strlen(fn);
			}
			*(fn++) = '/';
		}
		memcpy(fn, pathp, l);

		prev_pp = &np->properties;
		**allnextpp = np;
		*allnextpp = &np->allnext;
		if (dad != NULL) {
			np->parent = dad;
			/* we temporarily use the next field as `last_child'*/
			if (dad->next == NULL)
				dad->child = np;
			else
				dad->next->sibling = np;
			dad->next = np;
		}
		kref_init(&np->kref);
	}
	/* process properties */
	for (offset = fdt_first_property_offset(blob, *poffset);
	     (offset >= 0);
	     (offset = fdt_next_property_offset(blob, offset))) {
		const char *pname;
		u32 sz;

		if (!(p = fdt_getprop_by_offset(blob, offset, &pname, &sz))) {
			offset = -FDT_ERR_INTERNAL;
			break;
		}

		if (pname == NULL) {
			pr_info("Can't find property name in list !\n");
			break;
		}
		if (strcmp(pname, "name") == 0)
			has_name = 1;
		pp = unflatten_dt_alloc(&mem, sizeof(struct property),
					__alignof__(struct property));
		if (allnextpp) {
			/* We accept flattened tree phandles either in
			 * ePAPR-style "phandle" properties, or the
			 * legacy "linux,phandle" properties.  If both
			 * appear and have different values, things
			 * will get weird.  Don't do that. */
			if ((strcmp(pname, "phandle") == 0) ||
			    (strcmp(pname, "linux,phandle") == 0)) {
				if (np->phandle == 0)
					np->phandle = be32_to_cpup(p);
			}
			/* And we process the "ibm,phandle" property
			 * used in pSeries dynamic device tree
			 * stuff */
			if (strcmp(pname, "ibm,phandle") == 0)
				np->phandle = be32_to_cpup(p);
			pp->name = (char *)pname;
			pp->length = sz;
			pp->value = (__be32 *)p;
			*prev_pp = pp;
			prev_pp = &pp->next;
		}
	}
	/* with version 0x10 we may not have the name property, recreate
	 * it here from the unit name if absent
	 */
	if (!has_name) {
		const char *p1 = pathp, *ps = pathp, *pa = NULL;
		int sz;

		while (*p1) {
			if ((*p1) == '@')
				pa = p1;
			if ((*p1) == '/')
				ps = p1 + 1;
			p1++;
		}
		if (pa < ps)
			pa = p1;
		sz = (pa - ps) + 1;
		pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
					__alignof__(struct property));
		if (allnextpp) {
			pp->name = "name";
			pp->length = sz;
			pp->value = pp + 1;
			*prev_pp = pp;
			prev_pp = &pp->next;
			memcpy(pp->value, ps, sz - 1);
			((char *)pp->value)[sz - 1] = 0;
			pr_debug("fixed up name for %s -> %s\n", pathp,
				(char *)pp->value);
		}
	}
	if (allnextpp) {
		*prev_pp = NULL;
		np->name = of_get_property(np, "name", NULL);
		np->type = of_get_property(np, "device_type", NULL);

		if (!np->name)
			np->name = "<NULL>";
		if (!np->type)
			np->type = "<NULL>";
	}

	old_depth = depth;
	*poffset = fdt_next_node(blob, *poffset, &depth);
	if (depth < 0)
		depth = 0;
	while (*poffset > 0 && depth > old_depth)
		mem = unflatten_dt_node(blob, mem, poffset, np, allnextpp,
					fpsize);

	if (*poffset < 0 && *poffset != -FDT_ERR_NOTFOUND)
		pr_err("unflatten: error %d processing FDT\n", *poffset);

	return mem;
}
示例#24
0
static int usbtmc_probe(struct usb_interface *intf,
                        const struct usb_device_id *id)
{
    struct usbtmc_device_data *data;
    struct usb_host_interface *iface_desc;
    struct usb_endpoint_descriptor *endpoint;
    int n;
    int retcode;

    dev_dbg(&intf->dev, "%s called\n", __func__);

    data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL);
    if (!data)
        return -ENOMEM;

    data->intf = intf;
    data->id = id;
    data->usb_dev = usb_get_dev(interface_to_usbdev(intf));
    usb_set_intfdata(intf, data);
    kref_init(&data->kref);
    mutex_init(&data->io_mutex);
    data->zombie = 0;

    /* Determine if it is a Rigol or not */
    data->rigol_quirk = 0;
    dev_dbg(&intf->dev, "Trying to find if device Vendor 0x%04X Product 0x%04X has the RIGOL quirk\n",
            le16_to_cpu(data->usb_dev->descriptor.idVendor),
            le16_to_cpu(data->usb_dev->descriptor.idProduct));
    for(n = 0; usbtmc_id_quirk[n].idVendor > 0; n++) {
        if ((usbtmc_id_quirk[n].idVendor == le16_to_cpu(data->usb_dev->descriptor.idVendor)) &&
                (usbtmc_id_quirk[n].idProduct == le16_to_cpu(data->usb_dev->descriptor.idProduct))) {
            dev_dbg(&intf->dev, "Setting this device as having the RIGOL quirk\n");
            data->rigol_quirk = 1;
            break;
        }
    }

    /* Initialize USBTMC bTag and other fields */
    data->bTag	= 1;
    data->TermCharEnabled = 0;
    data->TermChar = '\n';

    /* USBTMC devices have only one setting, so use that */
    iface_desc = data->intf->cur_altsetting;

    /* Find bulk in endpoint */
    for (n = 0; n < iface_desc->desc.bNumEndpoints; n++) {
        endpoint = &iface_desc->endpoint[n].desc;

        if (usb_endpoint_is_bulk_in(endpoint)) {
            data->bulk_in = endpoint->bEndpointAddress;
            dev_dbg(&intf->dev, "Found bulk in endpoint at %u\n",
                    data->bulk_in);
            break;
        }
    }

    /* Find bulk out endpoint */
    for (n = 0; n < iface_desc->desc.bNumEndpoints; n++) {
        endpoint = &iface_desc->endpoint[n].desc;

        if (usb_endpoint_is_bulk_out(endpoint)) {
            data->bulk_out = endpoint->bEndpointAddress;
            dev_dbg(&intf->dev, "Found Bulk out endpoint at %u\n",
                    data->bulk_out);
            break;
        }
    }

    retcode = get_capabilities(data);
    if (retcode)
        dev_err(&intf->dev, "can't read capabilities\n");
    else
        retcode = sysfs_create_group(&intf->dev.kobj,
                                     &capability_attr_grp);

    retcode = sysfs_create_group(&intf->dev.kobj, &data_attr_grp);

    retcode = usb_register_dev(intf, &usbtmc_class);
    if (retcode) {
        dev_err(&intf->dev, "Not able to get a minor"
                " (base %u, slice default): %d\n", USBTMC_MINOR_BASE,
                retcode);
        goto error_register;
    }
    dev_dbg(&intf->dev, "Using minor number %d\n", intf->minor);

    return 0;

error_register:
    sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp);
    sysfs_remove_group(&intf->dev.kobj, &data_attr_grp);
    kref_put(&data->kref, usbtmc_delete);
    return retcode;
}
示例#25
0
static int pixcir_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct usb_host_interface *interface = intf->cur_altsetting;
	struct usb_device *dev = interface_to_usbdev(intf);
	struct input_dev *input_dev1;

	int n = 0, insize = TOUCH_PACKAGE_LEN;
	int err;
 	const char *path;
 	int  len;
 	char input_buf[10];
	
 	struct pixcir_mt_usb *psmt = kzalloc(sizeof(struct pixcir_mt_usb), GFP_KERNEL);

	kref_init(&psmt->kref);
	mutex_init(&psmt->io_mutex);
	
  	printk("%s\n", __FUNCTION__);
	psmt->type = &type;
	psmt->udev = dev;

	if (dev->manufacturer)
    strlcpy(psmt->name, dev->manufacturer, sizeof(psmt->name));

	if (dev->product) {
    if (dev->manufacturer)
      strlcat(psmt->name, " ", sizeof(psmt->name));
    strlcat(psmt->name, dev->product, sizeof(psmt->name));
	}

	if (!strlen(psmt->name))
    snprintf(psmt->name, sizeof(psmt->name), "USB Touchscreen %04x:%04x", le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct));

	if (!psmt->type->process_pkt) {
    printk("process_pkt is null\n");
    psmt->type->process_pkt = usbtouch_process_pkt;
 	}

	usb_set_intfdata(intf, psmt);
	
	err = usb_register_dev(intf,&pixcir_class_driver);
	if(err){
		printk("Not able to get minor for this device.");
	}

	dev_info(&intf->dev,"now attach to USB-%d",intf->minor);	

	input_dev1 = input_allocate_device();
	input_dev1->name = "pixcir_usb_ts";
	usb_to_input_id(dev, &input_dev1->id);
	psmt->input_dev = input_dev1;

	if(!psmt|| !input_dev1) {
    printk("Memory is not enough\n");
    goto fail1;
	}

	input_dev1->dev.parent = &intf->dev;
	input_set_drvdata(input_dev1, psmt);

	set_bit(EV_SYN, input_dev1->evbit);
	set_bit(EV_KEY, input_dev1->evbit);
	set_bit(EV_ABS, input_dev1->evbit);
	set_bit(BTN_TOUCH, input_dev1->keybit);
	input_set_abs_params(input_dev1, ABS_X, psmt->type->min_xc, psmt->type->max_xc, 0, 0);
	input_set_abs_params(input_dev1, ABS_Y, psmt->type->min_yc, psmt->type->max_yc, 0, 0);
	input_set_abs_params(input_dev1, ABS_MT_POSITION_X, psmt->type->min_xc, psmt->type->max_xc, 0, 0);
	input_set_abs_params(input_dev1, ABS_MT_POSITION_Y, psmt->type->min_yc, psmt->type->max_yc, 0, 0);
  input_set_abs_params(input_dev1, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
  input_set_abs_params(input_dev1, ABS_MT_WIDTH_MAJOR, 0, 25, 0, 0);

  psmt->data = usb_alloc_coherent(dev, insize, GFP_KERNEL, &psmt->data_dma);

  if(!psmt->data) {
    printk("psmt->data allocating fail");
    goto fail;
  }

  for (n = 0; n < interface->desc.bNumEndpoints; n++) {
    struct usb_endpoint_descriptor *endpoint;
    int pipe;
    int interval;

    endpoint = &interface->endpoint[n].desc;


		/*find a int endpoint*/
    if (!usb_endpoint_xfer_int(endpoint))
                   continue;

    interval = endpoint->bInterval;
    if (usb_endpoint_dir_in(endpoint)) {
      if (psmt->urb)
        continue;
      if (!(psmt->urb = usb_alloc_urb(0, GFP_KERNEL)))
        goto fail;

      pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
      usb_fill_int_urb(psmt->urb, dev, pipe, psmt->data, insize, pixcir_mt_irq, psmt, interval);
      psmt->urb->transfer_dma = psmt->data_dma;
      psmt->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
    }
  }


  if (usb_submit_urb(psmt->urb, GFP_ATOMIC)) {
    printk("usb submit urb error\n");
    return -EIO;
  }

  err = input_register_device(psmt->input_dev);
  if(err) {
    printk("pixcir_probe: Could not register input device(touchscreen)!\n");
      return -EIO;
  }

  path = kobject_get_path(&psmt->input_dev->dev.kobj, GFP_KERNEL);
  len=strlen(path);
  if(len>10){
		if(path[len-2]=='t'){
			memset(input_buf,'\0',9);
			strncpy(input_buf,&path[len-6],6);
		}else if(path[len-3]=='t'){
			memset(input_buf,'\0',9);
			strncpy(input_buf,&path[len-7],7);
		}else{
			 goto fail;
		}
  }else{
     	    goto fail;
  }

  usb_make_path(dev, psmt->phys0, sizeof(psmt->phys0));
  strlcat(psmt->phys0,input_buf, sizeof(psmt->phys0));

  return 0;

fail:
  usb_free_urb(psmt->urb);
  psmt->urb = NULL;
  usb_free_coherent(dev, insize, psmt->data, psmt->data_dma);
fail1:
  input_free_device(input_dev1);
  kfree(psmt);
  return 1;
}
示例#26
0
static int skel_probe(struct usb_interface *interface,
		      const struct usb_device_id *id)
{
	struct usb_skel *dev;
	struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *endpoint;
	size_t buffer_size;
	int i;
	int retval = -ENOMEM;
	printk(KERN_INFO "eric_prob,vid= %04x, pid=%04x\n", USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID );

	/* allocate memory for our device state and initialize it */
	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev) {
		err("Out of memory");
		goto error;
	}
	kref_init(&dev->kref);
	sema_init(&dev->limit_sem, WRITES_IN_FLIGHT);
	mutex_init(&dev->io_mutex);
	spin_lock_init(&dev->err_lock);
	init_usb_anchor(&dev->submitted);
	init_completion(&dev->bulk_in_completion);

	dev->udev = usb_get_dev(interface_to_usbdev(interface));
	dev->interface = interface;

	/* set up the endpoint information */
	/* use only the first bulk-in and bulk-out endpoints */
	iface_desc = interface->cur_altsetting;
	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
		endpoint = &iface_desc->endpoint[i].desc;

		if (!dev->bulk_in_endpointAddr &&
		    usb_endpoint_is_bulk_in(endpoint)) {
			/* we found a bulk in endpoint */
			buffer_size = usb_endpoint_maxp(endpoint);
			dev->bulk_in_size = buffer_size;
			dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
			dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
			if (!dev->bulk_in_buffer) {
				err("Could not allocate bulk_in_buffer");
				goto error;
			}
			dev->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL);
			if (!dev->bulk_in_urb) {
				err("Could not allocate bulk_in_urb");
				goto error;
			}
		}

		if (!dev->bulk_out_endpointAddr &&
		    usb_endpoint_is_bulk_out(endpoint)) {
			/* we found a bulk out endpoint */
			dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
		}
	}
	if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
		err("Could not find both bulk-in and bulk-out endpoints");
		goto error;
	}

	/* save our data pointer in this interface device */
	usb_set_intfdata(interface, dev);

	/* we can register the device now, as it is ready */
	retval = usb_register_dev(interface, &skel_class);
	if (retval) {
		/* something prevented us from registering this driver */
		err("Not able to get a minor for this device.");
		usb_set_intfdata(interface, NULL);
		goto error;
	}

	/* let the user know what node this device is now attached to */
	dev_info(&interface->dev,
		 "USB Skeleton device now attached to USBSkel-%d",
		 interface->minor);
	return 0;

error:
	if (dev)
		/* this frees allocated memory */
		kref_put(&dev->kref, skel_delete);
	return retval;
}
示例#27
0
文件: usbtmc.c 项目: koll1009/linux
static int usbtmc_probe(struct usb_interface *intf,
			const struct usb_device_id *id)
{
	struct usbtmc_device_data *data;
	struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *endpoint;
	int n;
	int retcode;

	dev_dbg(&intf->dev, "%s called\n", __func__);

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

	data->intf = intf;
	data->id = id;
	data->usb_dev = usb_get_dev(interface_to_usbdev(intf));
	usb_set_intfdata(intf, data);
	kref_init(&data->kref);
	mutex_init(&data->io_mutex);
	init_waitqueue_head(&data->waitq);
	atomic_set(&data->iin_data_valid, 0);
	atomic_set(&data->srq_asserted, 0);
	data->zombie = 0;

	/* Determine if it is a Rigol or not */
	data->rigol_quirk = 0;
	dev_dbg(&intf->dev, "Trying to find if device Vendor 0x%04X Product 0x%04X has the RIGOL quirk\n",
		le16_to_cpu(data->usb_dev->descriptor.idVendor),
		le16_to_cpu(data->usb_dev->descriptor.idProduct));
	for(n = 0; usbtmc_id_quirk[n].idVendor > 0; n++) {
		if ((usbtmc_id_quirk[n].idVendor == le16_to_cpu(data->usb_dev->descriptor.idVendor)) &&
		    (usbtmc_id_quirk[n].idProduct == le16_to_cpu(data->usb_dev->descriptor.idProduct))) {
			dev_dbg(&intf->dev, "Setting this device as having the RIGOL quirk\n");
			data->rigol_quirk = 1;
			break;
		}
	}

	/* Initialize USBTMC bTag and other fields */
	data->bTag	= 1;
	data->TermCharEnabled = 0;
	data->TermChar = '\n';
	/*  2 <= bTag <= 127   USBTMC-USB488 subclass specification 4.3.1 */
	data->iin_bTag = 2;

	/* USBTMC devices have only one setting, so use that */
	iface_desc = data->intf->cur_altsetting;
	data->ifnum = iface_desc->desc.bInterfaceNumber;

	/* Find bulk in endpoint */
	for (n = 0; n < iface_desc->desc.bNumEndpoints; n++) {
		endpoint = &iface_desc->endpoint[n].desc;

		if (usb_endpoint_is_bulk_in(endpoint)) {
			data->bulk_in = endpoint->bEndpointAddress;
			dev_dbg(&intf->dev, "Found bulk in endpoint at %u\n",
				data->bulk_in);
			break;
		}
	}

	/* Find bulk out endpoint */
	for (n = 0; n < iface_desc->desc.bNumEndpoints; n++) {
		endpoint = &iface_desc->endpoint[n].desc;

		if (usb_endpoint_is_bulk_out(endpoint)) {
			data->bulk_out = endpoint->bEndpointAddress;
			dev_dbg(&intf->dev, "Found Bulk out endpoint at %u\n",
				data->bulk_out);
			break;
		}
	}

	if (!data->bulk_out || !data->bulk_in) {
		dev_err(&intf->dev, "bulk endpoints not found\n");
		retcode = -ENODEV;
		goto err_put;
	}

	/* Find int endpoint */
	for (n = 0; n < iface_desc->desc.bNumEndpoints; n++) {
		endpoint = &iface_desc->endpoint[n].desc;

		if (usb_endpoint_is_int_in(endpoint)) {
			data->iin_ep_present = 1;
			data->iin_ep = endpoint->bEndpointAddress;
			data->iin_wMaxPacketSize = usb_endpoint_maxp(endpoint);
			data->iin_interval = endpoint->bInterval;
			dev_dbg(&intf->dev, "Found Int in endpoint at %u\n",
				data->iin_ep);
			break;
		}
	}

	retcode = get_capabilities(data);
	if (retcode)
		dev_err(&intf->dev, "can't read capabilities\n");
	else
		retcode = sysfs_create_group(&intf->dev.kobj,
					     &capability_attr_grp);

	if (data->iin_ep_present) {
		/* allocate int urb */
		data->iin_urb = usb_alloc_urb(0, GFP_KERNEL);
		if (!data->iin_urb) {
			retcode = -ENOMEM;
			goto error_register;
		}

		/* Protect interrupt in endpoint data until iin_urb is freed */
		kref_get(&data->kref);

		/* allocate buffer for interrupt in */
		data->iin_buffer = kmalloc(data->iin_wMaxPacketSize,
					GFP_KERNEL);
		if (!data->iin_buffer) {
			retcode = -ENOMEM;
			goto error_register;
		}

		/* fill interrupt urb */
		usb_fill_int_urb(data->iin_urb, data->usb_dev,
				usb_rcvintpipe(data->usb_dev, data->iin_ep),
				data->iin_buffer, data->iin_wMaxPacketSize,
				usbtmc_interrupt,
				data, data->iin_interval);

		retcode = usb_submit_urb(data->iin_urb, GFP_KERNEL);
		if (retcode) {
			dev_err(&intf->dev, "Failed to submit iin_urb\n");
			goto error_register;
		}
	}

	retcode = sysfs_create_group(&intf->dev.kobj, &data_attr_grp);

	retcode = usb_register_dev(intf, &usbtmc_class);
	if (retcode) {
		dev_err(&intf->dev, "Not able to get a minor"
			" (base %u, slice default): %d\n", USBTMC_MINOR_BASE,
			retcode);
		goto error_register;
	}
	dev_dbg(&intf->dev, "Using minor number %d\n", intf->minor);

	return 0;

error_register:
	sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp);
	sysfs_remove_group(&intf->dev.kobj, &data_attr_grp);
	usbtmc_free_int(data);
err_put:
	kref_put(&data->kref, usbtmc_delete);
	return retcode;
}
示例#28
0
/*
 * The parsing of the command line works exactly like the
 * serial.c code, except that the specifier is "ttyUSB" instead
 * of "ttyS".
 */
static int usb_console_setup(struct console *co, char *options)
{
    struct usbcons_info *info = &usbcons_info;
    int baud = 9600;
    int bits = 8;
    int parity = 'n';
    int doflow = 0;
    int cflag = CREAD | HUPCL | CLOCAL;
    char *s;
    struct usb_serial *serial;
    struct usb_serial_port *port;
    int retval;
    struct tty_struct *tty = NULL;
    struct ktermios dummy;

    dbg("%s", __func__);

    if (options) {
        baud = simple_strtoul(options, NULL, 10);
        s = options;
        while (*s >= '0' && *s <= '9')
            s++;
        if (*s)
            parity = *s++;
        if (*s)
            bits   = *s++ - '0';
        if (*s)
            doflow = (*s++ == 'r');
    }

    /* Sane default */
    if (baud == 0)
        baud = 9600;

    switch (bits) {
    case 7:
        cflag |= CS7;
        break;
    default:
    case 8:
        cflag |= CS8;
        break;
    }
    switch (parity) {
    case 'o':
    case 'O':
        cflag |= PARODD;
        break;
    case 'e':
    case 'E':
        cflag |= PARENB;
        break;
    }
    co->cflag = cflag;

    /*
     * no need to check the index here: if the index is wrong, console
     * code won't call us
     */
    serial = usb_serial_get_by_index(co->index);
    if (serial == NULL) {
        /* no device is connected yet, sorry :( */
        err("No USB device connected to ttyUSB%i", co->index);
        return -ENODEV;
    }

    retval = usb_autopm_get_interface(serial->interface);
    if (retval)
        goto error_get_interface;

    port = serial->port[co->index - serial->minor];
    tty_port_tty_set(&port->port, NULL);

    info->port = port;

    ++port->port.count;
    if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) {
        if (serial->type->set_termios) {
            /*
             * allocate a fake tty so the driver can initialize
             * the termios structure, then later call set_termios to
             * configure according to command line arguments
             */
            tty = kzalloc(sizeof(*tty), GFP_KERNEL);
            if (!tty) {
                retval = -ENOMEM;
                err("no more memory");
                goto reset_open_count;
            }
            kref_init(&tty->kref);
            tty_port_tty_set(&port->port, tty);
            tty->driver = usb_serial_tty_driver;
            tty->index = co->index;
            if (tty_init_termios(tty)) {
                retval = -ENOMEM;
                err("no more memory");
                goto free_tty;
            }
        }

        /* only call the device specific open if this
         * is the first time the port is opened */
        if (serial->type->open)
            retval = serial->type->open(NULL, port);
        else
            retval = usb_serial_generic_open(NULL, port);

        if (retval) {
            err("could not open USB console port");
            goto fail;
        }

        if (serial->type->set_termios) {
            tty->termios->c_cflag = cflag;
            tty_termios_encode_baud_rate(tty->termios, baud, baud);
            memset(&dummy, 0, sizeof(struct ktermios));
            serial->type->set_termios(tty, port, &dummy);

            tty_port_tty_set(&port->port, NULL);
            kfree(tty);
        }
        set_bit(ASYNCB_INITIALIZED, &port->port.flags);
    }
    /* Now that any required fake tty operations are completed restore
     * the tty port count */
    --port->port.count;
    /* The console is special in terms of closing the device so
     * indicate this port is now acting as a system console. */
    port->port.console = 1;

    mutex_unlock(&serial->disc_mutex);
    return retval;

fail:
    tty_port_tty_set(&port->port, NULL);
free_tty:
    kfree(tty);
reset_open_count:
    port->port.count = 0;
    usb_autopm_put_interface(serial->interface);
error_get_interface:
    usb_serial_put(serial);
    mutex_unlock(&serial->disc_mutex);
    return retval;
}
示例#29
0
static int sinosims_probe(struct usb_interface *interface,
                const struct usb_device_id *id)
{
    struct usb_sinosims *dev;
    struct usb_host_interface *iface_desc;
    struct usb_endpoint_descriptor *endpoint;
    size_t buffer_size;
    int i;
    int retval = -ENOMEM;

    /* allocate memory for our device stat and initialize it */    
    dev = kzalloc(sizeof(*dev), GFP_KERNEL);
    if (!dev) {
        dev_err(&interface->dev, "Out of memory\n");
        goto error;
    }
    kref_init(&dev->kref);
    sema_init(&dev->limit_sem, WRITES_IN_FLIGHT);
    mutex_init(&dev->io_mutex);
    spin_lock_init(&dev->err_lock);
    init_usb_anchor(&dev->submitted);
    init_waitqueue_head(&dev->bulk_in_wait);

    dev->udev = usb_get_dev(interface_to_usbdev(interface));
    dev->interface = interface;

    /* set up the endpint information */
    /* our device have only one configuration, in this configuration we have three interface.
       for each interface, there are tow endpints(one is bulk-in, and the other one is bulk-out) */ 
    iface_desc = interface->cur_altsetting;
    for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
        endpoint = &iface_desc->endpoint[i].desc;
        
        if (!dev->bulk_in_endpointAddr && 
            usb_endpoint_is_bulk_in(endpoint)) {
            /* we found a bulk in endpoint */
            buffer_size = usb_endpoint_maxp(endpoint);
            dev->bulk_in_size = buffer_size;
            dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
            dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
            if (!dev->bulk_in_buffer) {
                dev_err(&interface->dev, "Could not allocate bulk_in_buffer\n");
                goto error;
            }
            dev->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL);
            if (!dev->bulk_in_urb) {
                dev_err(&interface->dev, "Could not allocate bulk_in_urb\n");
                goto error;
            }
        }
        
        if (!dev->bulk_out_endpointAddr && 
            usb_endpoint_is_bulk_out(endpoint)) {
            /* we found a bulk out endpoint */
            dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
        }
    }
    if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
        dev_err(&interface->dev, "Could not find both bulk-in and bulk-out endpoints\n");
        goto error;
    }
    
    /* save our data pointer in this interface device */
    usb_set_intfdata(interface, dev);
    
    /* we can register the device now, as it is ready */
    retval = usb_register_dev(interface, &sinosims_class);
    if (retval) {
        /* something prevented us from registering this driver */
        dev_err(&interface->dev, "Not albe to get a minor for this device\n");
        usb_set_intfdata(interface, NULL);
        goto error;
    }

    /* let the user know what node this device is now attached to */
    dev_info(&interface->dev, "USB Sinosims device now attached to USBSino-%d", interface->minor);
    return 0;

error:
    if (dev) {
        /* this frees allocated memory */
        kref_put(&dev->kref, sinosims_delete);
    }
    return retval;
}
示例#30
0
static int skel_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
	struct usb_skel *dev = NULL;
	struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *endpoint;
	size_t buffer_size;
	int i;
	int retval = -ENOMEM;

	/* allocate memory for our device state and initialize it */
	dev = kmalloc(sizeof(struct usb_skel), GFP_KERNEL);
	if (dev == NULL) {
		err("Out of memory");
		goto error;
	}
	memset(dev, 0x00, sizeof (*dev));
	kref_init(&dev->kref);

	dev->udev = usb_get_dev(interface_to_usbdev(interface));
	dev->interface = interface;

	/* set up the endpoint information */
	/* use only the first bulk-in and bulk-out endpoints */
	iface_desc = interface->cur_altsetting;
	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
		endpoint = &iface_desc->endpoint[i].desc;

		if (!dev->bulk_in_endpointAddr &&
		    (endpoint->bEndpointAddress & USB_DIR_IN) &&
		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
					== USB_ENDPOINT_XFER_BULK)) {
			/* we found a bulk in endpoint */
			buffer_size = endpoint->wMaxPacketSize;
			dev->bulk_in_size = buffer_size;
			dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
			dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
			if (!dev->bulk_in_buffer) {
				err("Could not allocate bulk_in_buffer");
				goto error;
			}
		}

		if (!dev->bulk_out_endpointAddr &&
		    !(endpoint->bEndpointAddress & USB_DIR_IN) &&
		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
					== USB_ENDPOINT_XFER_BULK)) {
			/* we found a bulk out endpoint */
			dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
		}
	}
	if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
		err("Could not find both bulk-in and bulk-out endpoints");
		goto error;
	}

	/* save our data pointer in this interface device */
	usb_set_intfdata(interface, dev);

	/* we can register the device now, as it is ready */
	retval = usb_register_dev(interface, &skel_class);
	if (retval) {
		/* something prevented us from registering this driver */
		err("Not able to get a minor for this device.");
		usb_set_intfdata(interface, NULL);
		goto error;
	}

	/* let the user know what node this device is now attached to */
	printk("USB Skeleton device now attached to USBSkel-%d", interface->minor);
	return 0;

error:
	if (dev)
		kref_put(&dev->kref, skel_delete);
	return retval;
}