예제 #1
0
파일: btt_devs.c 프로젝트: suntodai/prd
static ssize_t uuid_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t len)
{
	struct nd_btt *nd_btt = to_nd_btt(dev);
	ssize_t rc;

	device_lock(dev);
	rc = nd_uuid_store(dev, &nd_btt->uuid, buf, len);
	dev_dbg(dev, "%s: result: %zd wrote: %s%s", __func__,
			rc, buf, buf[len - 1] == '\n' ? "" : "\n");
	device_unlock(dev);

	return rc ? rc : len;
}
예제 #2
0
파일: aerdrv_core.c 프로젝트: 7799/linux
static int report_error_detected(struct pci_dev *dev, void *data)
{
	pci_ers_result_t vote;
	const struct pci_error_handlers *err_handler;
	struct aer_broadcast_data *result_data;
	result_data = (struct aer_broadcast_data *) data;

	device_lock(&dev->dev);
	dev->error_state = result_data->state;

	if (!dev->driver ||
		!dev->driver->err_handler ||
		!dev->driver->err_handler->error_detected) {
		if (result_data->state == pci_channel_io_frozen &&
			!(dev->hdr_type & PCI_HEADER_TYPE_BRIDGE)) {
			/*
			 * In case of fatal recovery, if one of down-
			 * stream device has no driver. We might be
			 * unable to recover because a later insmod
			 * of a driver for this device is unaware of
			 * its hw state.
			 */
			dev_printk(KERN_DEBUG, &dev->dev, "device has %s\n",
				   dev->driver ?
				   "no AER-aware driver" : "no driver");
		}

		/*
		 * If there's any device in the subtree that does not
		 * have an error_detected callback, returning
		 * PCI_ERS_RESULT_NO_AER_DRIVER prevents calling of
		 * the subsequent mmio_enabled/slot_reset/resume
		 * callbacks of "any" device in the subtree. All the
		 * devices in the subtree are left in the error state
		 * without recovery.
		 */

		if (!(dev->hdr_type & PCI_HEADER_TYPE_BRIDGE))
			vote = PCI_ERS_RESULT_NO_AER_DRIVER;
		else
			vote = PCI_ERS_RESULT_NONE;
	} else {
		err_handler = dev->driver->err_handler;
		vote = err_handler->error_detected(dev, result_data->state);
	}

	result_data->result = merge_result(result_data->result, vote);
	device_unlock(&dev->dev);
	return 0;
}
예제 #3
0
/* Helper for bus_rescan_devices's iter */
static int __must_check bus_rescan_devices_helper(struct device *dev,
						  void *data)
{
	int ret = 0;

	if (!dev->driver) {
		if (dev->parent)	/* Needed for USB */
			device_lock(dev->parent);
		ret = device_attach(dev);
		if (dev->parent)
			device_unlock(dev->parent);
	}
	return ret < 0 ? ret : 0;
}
예제 #4
0
static ssize_t store_ehci_power(struct device *dev,
                                struct device_attribute *attr,
                                const char *buf, size_t count)
{
    struct platform_device *pdev = to_platform_device(dev);
    struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
    struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev);
    struct usb_hcd *hcd = s5p_ehci->hcd;
    int power_on;
    int irq;
    int retval;

    if (sscanf(buf, "%d", &power_on) != 1)
        return -EINVAL;

    device_lock(dev);

    pm_runtime_get_sync(dev);
    if (!power_on && s5p_ehci->power_on) {
        printk(KERN_DEBUG "%s: EHCI turns off\n", __func__);
        s5p_ehci->power_on = 0;
        usb_remove_hcd(hcd);

        if (pdata && pdata->phy_exit)
            pdata->phy_exit(pdev, S5P_USB_PHY_HSIC);
    } else if (power_on) {
        printk(KERN_DEBUG "%s: EHCI turns on\n", __func__);
        if (s5p_ehci->power_on) {
            usb_remove_hcd(hcd);
        }

        if (pdata && pdata->phy_init)
            pdata->phy_init(pdev, S5P_USB_PHY_HSIC);
        s5p_ehci_configurate(hcd);

        irq = platform_get_irq(pdev, 0);
        retval = usb_add_hcd(hcd, irq,
                             IRQF_DISABLED | IRQF_SHARED);
        if (retval < 0) {
            dev_err(dev, "Power On Fail\n");
            goto exit;
        }

        s5p_ehci->power_on = 1;
    }
exit:
    pm_runtime_put_sync(dev);
    device_unlock(dev);
    return count;
}
예제 #5
0
파일: btt_devs.c 프로젝트: suntodai/prd
static ssize_t namespace_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t len)
{
	ssize_t rc;

	nvdimm_bus_lock(dev);
	device_lock(dev);
	rc = __namespace_store(dev, attr, buf, len);
	dev_dbg(dev, "%s: result: %zd wrote: %s%s", __func__,
			rc, buf, buf[len - 1] == '\n' ? "" : "\n");
	device_unlock(dev);
	nvdimm_bus_unlock(dev);

	return rc;
}
예제 #6
0
static void ar9170_usb_firmware_failed(struct ar9170_usb *aru)
{
	struct device *parent = aru->udev->dev.parent;

	complete(&aru->firmware_loading_complete);

	/* unbind anything failed */
	if (parent)
		device_lock(parent);
	device_release_driver(&aru->udev->dev);
	if (parent)
		device_unlock(parent);

	usb_put_dev(aru->udev);
}
예제 #7
0
static ssize_t autosuspend_delay_ms_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t n)
{
	long delay;

	if (!dev->power.use_autosuspend)
		return -EIO;

	if (kstrtol(buf, 10, &delay) != 0 || delay != (int) delay)
		return -EINVAL;

	device_lock(dev);
	pm_runtime_set_autosuspend_delay(dev, delay);
	device_unlock(dev);
	return n;
}
예제 #8
0
static int floppy_request(vnode *node, int cmd, ULONG sector, ULONG count, char *buffer)
{
	if (sector>=FLOPPY_SECTOR_COUNT) return -EINVAL;
	device_lock(node);
	if (sector+count>=FLOPPY_SECTOR_COUNT)
		count=FLOPPY_SECTOR_COUNT-sector;
	switch (cmd) {
		case REQUEST_READ:
			fdc_read_block(sector,buffer,count);
			break;
		case REQUEST_WRITE:
			fdc_rw(sector,buffer,0,count);
			break;
	}
	device_unlock(node);
	return count;
}
예제 #9
0
static ssize_t align_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t len)
{
	struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev);
	ssize_t rc;

	device_lock(dev);
	nvdimm_bus_lock(dev);
	rc = nd_size_select_store(dev, buf, &nd_pfn->align,
			nd_pfn_supported_alignments());
	dev_dbg(dev, "%s: result: %zd wrote: %s%s", __func__,
			rc, buf, buf[len - 1] == '\n' ? "" : "\n");
	nvdimm_bus_unlock(dev);
	device_unlock(dev);

	return rc ? rc : len;
}
예제 #10
0
파일: media-dev.c 프로젝트: 020gzh/linux
static int fimc_md_register_platform_entity(struct fimc_md *fmd,
					    struct platform_device *pdev,
					    int plat_entity)
{
	struct device *dev = &pdev->dev;
	int ret = -EPROBE_DEFER;
	void *drvdata;

	/* Lock to ensure dev->driver won't change. */
	device_lock(dev);

	if (!dev->driver || !try_module_get(dev->driver->owner))
		goto dev_unlock;

	drvdata = dev_get_drvdata(dev);
	/* Some subdev didn't probe successfully id drvdata is NULL */
	if (drvdata) {
		switch (plat_entity) {
		case IDX_FIMC:
			ret = register_fimc_entity(fmd, drvdata);
			break;
		case IDX_FLITE:
			ret = register_fimc_lite_entity(fmd, drvdata);
			break;
		case IDX_CSIS:
			ret = register_csis_entity(fmd, pdev, drvdata);
			break;
		case IDX_IS_ISP:
			ret = register_fimc_is_entity(fmd, drvdata);
			break;
		default:
			ret = -ENODEV;
		}
	}

	module_put(dev->driver->owner);
dev_unlock:
	device_unlock(dev);
	if (ret == -EPROBE_DEFER)
		dev_info(&fmd->pdev->dev, "deferring %s device registration\n",
			dev_name(dev));
	else if (ret < 0)
		dev_err(&fmd->pdev->dev, "%s device registration failed (%d)\n",
			dev_name(dev), ret);
	return ret;
}
예제 #11
0
파일: btt_devs.c 프로젝트: suntodai/prd
static ssize_t sector_size_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t len)
{
	struct nd_btt *nd_btt = to_nd_btt(dev);
	ssize_t rc;

	device_lock(dev);
	nvdimm_bus_lock(dev);
	rc = nd_sector_size_store(dev, buf, &nd_btt->lbasize,
			btt_lbasize_supported);
	dev_dbg(dev, "%s: result: %zd wrote: %s%s", __func__,
			rc, buf, buf[len - 1] == '\n' ? "" : "\n");
	nvdimm_bus_unlock(dev);
	device_unlock(dev);

	return rc ? rc : len;
}
예제 #12
0
static int report_resume(struct pci_dev *dev, void *data)
{
	const struct pci_error_handlers *err_handler;

	device_lock(&dev->dev);
	dev->error_state = pci_channel_io_normal;

	if (!dev->driver ||
		!dev->driver->err_handler ||
		!dev->driver->err_handler->resume)
		goto out;

	err_handler = dev->driver->err_handler;
	err_handler->resume(dev);
out:
	device_unlock(&dev->dev);
	return 0;
}
예제 #13
0
static ssize_t alt_name_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t len)
{
	struct nd_region *nd_region = to_nd_region(dev->parent);
	ssize_t rc;

	device_lock(dev);
	nvdimm_bus_lock(dev);
	wait_nvdimm_bus_probe_idle(dev);
	rc = __alt_name_store(dev, buf, len);
	if (rc >= 0)
		rc = nd_namespace_label_update(nd_region, dev);
	dev_dbg(dev, "%s: %s(%zd)\n", __func__, rc < 0 ? "fail " : "", rc);
	nvdimm_bus_unlock(dev);
	device_unlock(dev);

	return rc < 0 ? rc : len;
}
예제 #14
0
static ssize_t control_store(struct device * dev, struct device_attribute *attr,
			     const char * buf, size_t n)
{
	char *cp;
	int len = n;

	cp = memchr(buf, '\n', n);
	if (cp)
		len = cp - buf;
	device_lock(dev);
	if (len == sizeof ctrl_auto - 1 && strncmp(buf, ctrl_auto, len) == 0)
		pm_runtime_allow(dev);
	else if (len == sizeof ctrl_on - 1 && strncmp(buf, ctrl_on, len) == 0)
		pm_runtime_forbid(dev);
	else
		n = -EINVAL;
	device_unlock(dev);
	return n;
}
예제 #15
0
static ssize_t gpp_wppart_set(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t n)
{
	long part;
	struct mmc_card *card = mmc_dev_to_card(dev);

	if (card == NULL)
		return -ENODEV;
	if (kstrtol(buf, 10, &part) != 0 || part != (u32)part)
		return -EINVAL;
	if (part > EXT_CSD_GPP_NUM || part <= 0)
		return -EINVAL;
	if (!card->ext_csd.gpp_sz[part - 1])
		return -EINVAL;
	device_lock(dev);
	/* make GPP number recognized by eMMC device */
	gpp_wppart = part + EXT_CSD_PART_CONFIG_ACC_GP0 - 1;
	device_unlock(dev);
	return n;
}
예제 #16
0
static int report_slot_reset(struct pci_dev *dev, void *data)
{
	pci_ers_result_t vote;
	const struct pci_error_handlers *err_handler;
	struct aer_broadcast_data *result_data;
	result_data = (struct aer_broadcast_data *) data;

	device_lock(&dev->dev);
	if (!dev->driver ||
		!dev->driver->err_handler ||
		!dev->driver->err_handler->slot_reset)
		goto out;

	err_handler = dev->driver->err_handler;
	vote = err_handler->slot_reset(dev);
	result_data->result = merge_result(result_data->result, vote);
out:
	device_unlock(&dev->dev);
	return 0;
}
예제 #17
0
/* Manually detach a device from its associated driver. */
static ssize_t driver_unbind(struct device_driver *drv,
			     const char *buf, size_t count)
{
	struct bus_type *bus = bus_get(drv->bus);
	struct device *dev;
	int err = -ENODEV;

	dev = bus_find_device_by_name(bus, NULL, buf);
	if (dev && dev->driver == drv) {
		if (dev->parent)	/* Needed for USB */
			device_lock(dev->parent);
		device_release_driver(dev);
		if (dev->parent)
			device_unlock(dev->parent);
		err = count;
	}
	put_device(dev);
	bus_put(bus);
	return err;
}
예제 #18
0
static void rtl_usb_unbind(struct ieee80211_hw *hw)
{
	struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
	struct device *parent = rtlusb->udev->dev.parent;
	struct usb_device *udev;

	/* Store a copy of the usb_device pointer locally.
	 * This is because device_release_driver initiates
	 * rtl_usb_disconnect, which in turn frees our
	 * driver context (rtl_priv).
	 */
	udev = rtlusb->udev;

	/* unbind anything failed */
	if (parent)
		device_lock(parent);

	device_release_driver(&udev->dev);
	if (parent)
		device_unlock(parent);
}
예제 #19
0
/**
 * device_attach - try to attach device to a driver.
 * @dev: device.
 *
 * Walk the list of drivers that the bus has and call
 * driver_probe_device() for each pair. If a compatible
 * pair is found, break out and return.
 *
 * Returns 1 if the device was bound to a driver;
 * 0 if no matching driver was found;
 * -ENODEV if the device is not registered.
 *
 * When called for a USB interface, @dev->parent lock must be held.
 */
int device_attach(struct device *dev)
{
	int ret = 0;

	device_lock(dev);
	if (dev->driver) {
		ret = device_bind_driver(dev);
		if (ret == 0)
			ret = 1;
		else {
			dev->driver = NULL;
			ret = 0;
		}
	} else {
		pm_runtime_get_noresume(dev);
		ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
		pm_runtime_put_sync(dev);
	}
	device_unlock(dev);
	return ret;
}
예제 #20
0
파일: netlink.c 프로젝트: AllenDou/linux
static int nfc_genl_stop_poll(struct sk_buff *skb, struct genl_info *info)
{
	struct nfc_dev *dev;
	int rc;
	u32 idx;

	if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
		return -EINVAL;

	idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);

	dev = nfc_get_device(idx);
	if (!dev)
		return -ENODEV;

	device_lock(&dev->dev);

	if (!dev->polling) {
		device_unlock(&dev->dev);
		return -EINVAL;
	}

	device_unlock(&dev->dev);

	mutex_lock(&dev->genl_data.genl_data_mutex);

	if (dev->genl_data.poll_req_portid != info->snd_portid) {
		rc = -EBUSY;
		goto out;
	}

	rc = nfc_stop_poll(dev);
	dev->genl_data.poll_req_portid = 0;

out:
	mutex_unlock(&dev->genl_data.genl_data_mutex);
	nfc_put_device(dev);
	return rc;
}
예제 #21
0
파일: image.cpp 프로젝트: mgschwan/blensor
void ImageManager::device_free_image(Device *, ImageDataType type, int slot)
{
	Image *img = images[type][slot];

	if(img) {
		if(osl_texture_system && !img->builtin_data) {
#ifdef WITH_OSL
			ustring filename(images[type][slot]->filename);
			((OSL::TextureSystem*)osl_texture_system)->invalidate(filename);
#endif
		}

		if(img->mem) {
			thread_scoped_lock device_lock(device_mutex);
			delete img->mem;
		}

		delete img;
		images[type][slot] = NULL;
		--tex_num_images[type];
	}
}
예제 #22
0
static ssize_t store_mipi_lli_control(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	struct mipi_lli *lli = dev_get_drvdata(dev);
	int command;

	if (sscanf(buf, "%10d", &command) != 1)
		return -EINVAL;

	device_lock(dev);

	if (command == 0)
		lli->driver->debug_info(lli);
	else if (command == 1)
		lli->driver->init(lli);
	else if (command == 2)
		lli->driver->set_master(lli, true);
	else if (command == 3)
		lli->driver->link_startup_mount(lli);
	else if (command == 4)
		lli->driver->exit(lli);
	else if (command == 5)
		mipi_lli_send_signal_test(lli);
	else if (command == 6)
		lli->driver->loopback_test(lli);
	else if (command == 98)
		print_hex_dump(KERN_INFO, "llimem: ", DUMP_PREFIX_OFFSET, 16, 1,
				g_lli->shdmem_addr + SZ_1K, 512, true);
	else if (command == 99)
		print_hex_dump(KERN_INFO, "llimem: ", DUMP_PREFIX_OFFSET, 16, 1,
				g_lli->shdmem_addr + SZ_1K + 512, 512, true);
	else
		dev_err(dev, "Un-support control command\n");

	device_unlock(dev);

	return count;
}
static int smbus_do_alert(struct device *dev, void *addrp)
{
	struct i2c_client *client = i2c_verify_client(dev);
	struct alert_data *data = addrp;

	if (!client || client->addr != data->addr)
		return 0;
	if (client->flags & I2C_CLIENT_TEN)
		return 0;

	device_lock(dev);
	if (client->driver) {
		if (client->driver->alert)
			client->driver->alert(client, data->flag);
		else
			dev_warn(&client->dev, "no driver alert()!\n");
	} else
		dev_dbg(&client->dev, "alert with no driver\n");
	device_unlock(dev);

	
	return -EBUSY;
}
예제 #24
0
  Pointer<Device> LinuxDeviceManager::applyDevicePolicy(uint32_t seqn, Rule::Target target)
  {
    log->debug("Applying device policy {} to device {}", target, seqn);
    Pointer<LinuxDevice> device = std::static_pointer_cast<LinuxDevice>(getDevice(seqn));
    std::unique_lock<std::mutex> device_lock(device->refDeviceMutex());

    const char *target_file = nullptr;
    int target_value = 0;

    switch (target)
      {
      case Rule::Target::Allow:
	target_file = "authorized";
	target_value = 1;
	break;
      case Rule::Target::Block:
	target_file = "authorized";
	target_value = 0;
	break;
      case Rule::Target::Reject:
	target_file = "remove";
	target_value = 1;
	break;
      default:
	log->critical("BUG: unknown rule target");
	throw std::runtime_error("Uknown rule target in applyDevicePolicy");
      }

    char sysio_path[SYSIO_PATH_MAX];
    snprintf(sysio_path, SYSIO_PATH_MAX, "%s/%s",
	     device->getSysPath().c_str(), target_file);
    /* FIXME: check that snprintf wrote the whole path */
    log->debug("SysIO: writing '{}' to {}", target_value, sysio_path);
    sysioWrite(sysio_path, target_value);

    return std::move(device);
  }
예제 #25
0
static ssize_t resource_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev);
	ssize_t rc;

	device_lock(dev);
	if (dev->driver) {
		struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb;
		u64 offset = __le64_to_cpu(pfn_sb->dataoff);
		struct nd_namespace_common *ndns = nd_pfn->ndns;
		u32 start_pad = __le32_to_cpu(pfn_sb->start_pad);
		struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev);

		rc = sprintf(buf, "%#llx\n", (unsigned long long) nsio->res.start
				+ start_pad + offset);
	} else {
		/* no address to convey if the pfn instance is disabled */
		rc = -ENXIO;
	}
	device_unlock(dev);

	return rc;
}
예제 #26
0
파일: image.cpp 프로젝트: diekev/blender
void ImageManager::device_free_image(Device *device, DeviceScene *dscene, ImageDataType type, int slot)
{
	Image *img = images[type][slot];

	if(img) {
		if(osl_texture_system && !img->builtin_data) {
#ifdef WITH_OSL
			ustring filename(images[type][slot]->filename);
			((OSL::TextureSystem*)osl_texture_system)->invalidate(filename);
#endif
		}
		else if(type == IMAGE_DATA_TYPE_FLOAT4) {
			device_vector<float4>& tex_img = dscene->tex_float4_image[slot];

			if(tex_img.device_pointer) {
				thread_scoped_lock device_lock(device_mutex);
				device->tex_free(tex_img);
			}

			tex_img.clear();
		}
		else if(type == IMAGE_DATA_TYPE_FLOAT) {
			device_vector<float>& tex_img = dscene->tex_float_image[slot];

			if(tex_img.device_pointer) {
				thread_scoped_lock device_lock(device_mutex);
				device->tex_free(tex_img);
			}

			tex_img.clear();
		}
		else if(type == IMAGE_DATA_TYPE_BYTE4) {
			device_vector<uchar4>& tex_img = dscene->tex_byte4_image[slot];

			if(tex_img.device_pointer) {
				thread_scoped_lock device_lock(device_mutex);
				device->tex_free(tex_img);
			}

			tex_img.clear();
		}
		else if(type == IMAGE_DATA_TYPE_BYTE){
			device_vector<uchar>& tex_img = dscene->tex_byte_image[slot];

			if(tex_img.device_pointer) {
				thread_scoped_lock device_lock(device_mutex);
				device->tex_free(tex_img);
			}

			tex_img.clear();
		}
		else if(type == IMAGE_DATA_TYPE_HALF4){
			device_vector<half4>& tex_img = dscene->tex_half4_image[slot];

			if(tex_img.device_pointer) {
				thread_scoped_lock device_lock(device_mutex);
				device->tex_free(tex_img);
			}

			tex_img.clear();
		}
		else if(type == IMAGE_DATA_TYPE_HALF){
			device_vector<half>& tex_img = dscene->tex_half_image[slot];

			if(tex_img.device_pointer) {
				thread_scoped_lock device_lock(device_mutex);
				device->tex_free(tex_img);
			}

			tex_img.clear();
		}

		delete images[type][slot];
		images[type][slot] = NULL;
	}
}
예제 #27
0
파일: image.cpp 프로젝트: mgschwan/blensor
void ImageManager::device_load_image(Device *device,
                                     Scene *scene,
                                     ImageDataType type,
                                     int slot,
                                     Progress *progress)
{
	if(progress->get_cancel())
		return;

	Image *img = images[type][slot];

	if(osl_texture_system && !img->builtin_data)
		return;

	string filename = path_filename(images[type][slot]->filename);
	progress->set_status("Updating Images", "Loading " + filename);

	const int texture_limit = scene->params.texture_limit;

	/* Slot assignment */
	int flat_slot = type_index_to_flattened_slot(slot, type);
	img->mem_name = string_printf("__tex_image_%s_%03d", name_from_type(type).c_str(), flat_slot);

	/* Free previous texture in slot. */
	if(img->mem) {
		thread_scoped_lock device_lock(device_mutex);
		delete img->mem;
		img->mem = NULL;
	}

	/* Create new texture. */
	if(type == IMAGE_DATA_TYPE_FLOAT4) {
		device_vector<float4> *tex_img
			= new device_vector<float4>(device, img->mem_name.c_str(), MEM_TEXTURE);

		if(!file_load_image<TypeDesc::FLOAT, float>(img,
		                                            type,
		                                            texture_limit,
		                                            *tex_img))
		{
			/* on failure to load, we set a 1x1 pixels pink image */
			thread_scoped_lock device_lock(device_mutex);
			float *pixels = (float*)tex_img->alloc(1, 1);

			pixels[0] = TEX_IMAGE_MISSING_R;
			pixels[1] = TEX_IMAGE_MISSING_G;
			pixels[2] = TEX_IMAGE_MISSING_B;
			pixels[3] = TEX_IMAGE_MISSING_A;
		}

		img->mem = tex_img;
		img->mem->interpolation = img->interpolation;
		img->mem->extension = img->extension;

		thread_scoped_lock device_lock(device_mutex);
		tex_img->copy_to_device();
	}
	else if(type == IMAGE_DATA_TYPE_FLOAT) {
		device_vector<float> *tex_img
			= new device_vector<float>(device, img->mem_name.c_str(), MEM_TEXTURE);

		if(!file_load_image<TypeDesc::FLOAT, float>(img,
		                                            type,
		                                            texture_limit,
		                                            *tex_img))
		{
			/* on failure to load, we set a 1x1 pixels pink image */
			thread_scoped_lock device_lock(device_mutex);
			float *pixels = (float*)tex_img->alloc(1, 1);

			pixels[0] = TEX_IMAGE_MISSING_R;
		}

		img->mem = tex_img;
		img->mem->interpolation = img->interpolation;
		img->mem->extension = img->extension;

		thread_scoped_lock device_lock(device_mutex);
		tex_img->copy_to_device();
	}
	else if(type == IMAGE_DATA_TYPE_BYTE4) {
		device_vector<uchar4> *tex_img
			= new device_vector<uchar4>(device, img->mem_name.c_str(), MEM_TEXTURE);

		if(!file_load_image<TypeDesc::UINT8, uchar>(img,
		                                            type,
		                                            texture_limit,
		                                            *tex_img))
		{
			/* on failure to load, we set a 1x1 pixels pink image */
			thread_scoped_lock device_lock(device_mutex);
			uchar *pixels = (uchar*)tex_img->alloc(1, 1);

			pixels[0] = (TEX_IMAGE_MISSING_R * 255);
			pixels[1] = (TEX_IMAGE_MISSING_G * 255);
			pixels[2] = (TEX_IMAGE_MISSING_B * 255);
			pixels[3] = (TEX_IMAGE_MISSING_A * 255);
		}

		img->mem = tex_img;
		img->mem->interpolation = img->interpolation;
		img->mem->extension = img->extension;

		thread_scoped_lock device_lock(device_mutex);
		tex_img->copy_to_device();
	}
	else if(type == IMAGE_DATA_TYPE_BYTE) {
		device_vector<uchar> *tex_img
			= new device_vector<uchar>(device, img->mem_name.c_str(), MEM_TEXTURE);

		if(!file_load_image<TypeDesc::UINT8, uchar>(img,
		                                            type,
		                                            texture_limit,
		                                            *tex_img)) {
			/* on failure to load, we set a 1x1 pixels pink image */
			thread_scoped_lock device_lock(device_mutex);
			uchar *pixels = (uchar*)tex_img->alloc(1, 1);

			pixels[0] = (TEX_IMAGE_MISSING_R * 255);
		}

		img->mem = tex_img;
		img->mem->interpolation = img->interpolation;
		img->mem->extension = img->extension;

		thread_scoped_lock device_lock(device_mutex);
		tex_img->copy_to_device();
	}
	else if(type == IMAGE_DATA_TYPE_HALF4) {
		device_vector<half4> *tex_img
			= new device_vector<half4>(device, img->mem_name.c_str(), MEM_TEXTURE);

		if(!file_load_image<TypeDesc::HALF, half>(img,
		                                          type,
		                                          texture_limit,
		                                          *tex_img)) {
			/* on failure to load, we set a 1x1 pixels pink image */
			thread_scoped_lock device_lock(device_mutex);
			half *pixels = (half*)tex_img->alloc(1, 1);

			pixels[0] = TEX_IMAGE_MISSING_R;
			pixels[1] = TEX_IMAGE_MISSING_G;
			pixels[2] = TEX_IMAGE_MISSING_B;
			pixels[3] = TEX_IMAGE_MISSING_A;
		}

		img->mem = tex_img;
		img->mem->interpolation = img->interpolation;
		img->mem->extension = img->extension;

		thread_scoped_lock device_lock(device_mutex);
		tex_img->copy_to_device();
	}
	else if(type == IMAGE_DATA_TYPE_HALF) {
		device_vector<half> *tex_img
			= new device_vector<half>(device, img->mem_name.c_str(), MEM_TEXTURE);

		if(!file_load_image<TypeDesc::HALF, half>(img,
		                                          type,
		                                          texture_limit,
		                                          *tex_img)) {
			/* on failure to load, we set a 1x1 pixels pink image */
			thread_scoped_lock device_lock(device_mutex);
			half *pixels = (half*)tex_img->alloc(1, 1);

			pixels[0] = TEX_IMAGE_MISSING_R;
		}

		img->mem = tex_img;
		img->mem->interpolation = img->interpolation;
		img->mem->extension = img->extension;

		thread_scoped_lock device_lock(device_mutex);
		tex_img->copy_to_device();
	}

	img->need_load = false;
}
예제 #28
0
파일: image.cpp 프로젝트: mgschwan/blensor
bool ImageManager::file_load_image(Image *img,
                                   ImageDataType type,
                                   int texture_limit,
                                   device_vector<DeviceType>& tex_img)
{
	const StorageType alpha_one = (FileFormat == TypeDesc::UINT8)? 255 : 1;
	ImageInput *in = NULL;
	int width, height, depth, components;
	if(!file_load_image_generic(img, &in, width, height, depth, components)) {
		return false;
	}
	/* Read RGBA pixels. */
	vector<StorageType> pixels_storage;
	StorageType *pixels;
	const size_t max_size = max(max(width, height), depth);
	if(max_size == 0) {
		/* Don't bother with invalid images. */
		return false;
	}
	if(texture_limit > 0 && max_size > texture_limit) {
		pixels_storage.resize(((size_t)width)*height*depth*4);
		pixels = &pixels_storage[0];
	}
	else {
		thread_scoped_lock device_lock(device_mutex);
		pixels = (StorageType*)tex_img.alloc(width, height, depth);
	}
	if(pixels == NULL) {
		/* Could be that we've run out of memory. */
		return false;
	}
	bool cmyk = false;
	const size_t num_pixels = ((size_t)width) * height * depth;
	if(in) {
		StorageType *readpixels = pixels;
		vector<StorageType> tmppixels;
		if(components > 4) {
			tmppixels.resize(((size_t)width)*height*components);
			readpixels = &tmppixels[0];
		}
		if(depth <= 1) {
			size_t scanlinesize = ((size_t)width)*components*sizeof(StorageType);
			in->read_image(FileFormat,
			               (uchar*)readpixels + (height-1)*scanlinesize,
			               AutoStride,
			               -scanlinesize,
			               AutoStride);
		}
		else {
			in->read_image(FileFormat, (uchar*)readpixels);
		}
		if(components > 4) {
			size_t dimensions = ((size_t)width)*height;
			for(size_t i = dimensions-1, pixel = 0; pixel < dimensions; pixel++, i--) {
				pixels[i*4+3] = tmppixels[i*components+3];
				pixels[i*4+2] = tmppixels[i*components+2];
				pixels[i*4+1] = tmppixels[i*components+1];
				pixels[i*4+0] = tmppixels[i*components+0];
			}
			tmppixels.clear();
		}
		cmyk = strcmp(in->format_name(), "jpeg") == 0 && components == 4;
		in->close();
		delete in;
	}
	else {
		if(FileFormat == TypeDesc::FLOAT) {
			builtin_image_float_pixels_cb(img->filename,
			                              img->builtin_data,
			                              (float*)&pixels[0],
			                              num_pixels * components,
			                              img->builtin_free_cache);
		}
		else if(FileFormat == TypeDesc::UINT8) {
			builtin_image_pixels_cb(img->filename,
			                        img->builtin_data,
			                        (uchar*)&pixels[0],
			                        num_pixels * components,
			                        img->builtin_free_cache);
		}
		else {
			/* TODO(dingto): Support half for ImBuf. */
		}
	}
	/* Check if we actually have a float4 slot, in case components == 1,
	 * but device doesn't support single channel textures.
	 */
	bool is_rgba = (type == IMAGE_DATA_TYPE_FLOAT4 ||
	                type == IMAGE_DATA_TYPE_HALF4 ||
	                type == IMAGE_DATA_TYPE_BYTE4);
	if(is_rgba) {
		if(cmyk) {
			/* CMYK */
			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
				pixels[i*4+2] = (pixels[i*4+2]*pixels[i*4+3])/255;
				pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255;
				pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255;
				pixels[i*4+3] = alpha_one;
			}
		}
		else if(components == 2) {
			/* grayscale + alpha */
			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
				pixels[i*4+3] = pixels[i*2+1];
				pixels[i*4+2] = pixels[i*2+0];
				pixels[i*4+1] = pixels[i*2+0];
				pixels[i*4+0] = pixels[i*2+0];
			}
		}
		else if(components == 3) {
			/* RGB */
			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
				pixels[i*4+3] = alpha_one;
				pixels[i*4+2] = pixels[i*3+2];
				pixels[i*4+1] = pixels[i*3+1];
				pixels[i*4+0] = pixels[i*3+0];
			}
		}
		else if(components == 1) {
			/* grayscale */
			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
				pixels[i*4+3] = alpha_one;
				pixels[i*4+2] = pixels[i];
				pixels[i*4+1] = pixels[i];
				pixels[i*4+0] = pixels[i];
			}
		}
		if(img->use_alpha == false) {
			for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
				pixels[i*4+3] = alpha_one;
			}
		}
	}
	/* Make sure we don't have buggy values. */
	if(FileFormat == TypeDesc::FLOAT) {
		/* For RGBA buffers we put all channels to 0 if either of them is not
		 * finite. This way we avoid possible artifacts caused by fully changed
		 * hue.
		 */
		if(is_rgba) {
			for(size_t i = 0; i < num_pixels; i += 4) {
				StorageType *pixel = &pixels[i*4];
				if(!isfinite(pixel[0]) ||
				   !isfinite(pixel[1]) ||
				   !isfinite(pixel[2]) ||
				   !isfinite(pixel[3]))
				{
					pixel[0] = 0;
					pixel[1] = 0;
					pixel[2] = 0;
					pixel[3] = 0;
				}
			}
		}
		else {
			for(size_t i = 0; i < num_pixels; ++i) {
				StorageType *pixel = &pixels[i];
				if(!isfinite(pixel[0])) {
					pixel[0] = 0;
				}
			}
		}
	}
	/* Scale image down if needed. */
	if(pixels_storage.size() > 0) {
		float scale_factor = 1.0f;
		while(max_size * scale_factor > texture_limit) {
			scale_factor *= 0.5f;
		}
		VLOG(1) << "Scaling image " << img->filename
		        << " by a factor of " << scale_factor << ".";
		vector<StorageType> scaled_pixels;
		size_t scaled_width, scaled_height, scaled_depth;
		util_image_resize_pixels(pixels_storage,
		                         width, height, depth,
		                         is_rgba ? 4 : 1,
		                         scale_factor,
		                         &scaled_pixels,
		                         &scaled_width, &scaled_height, &scaled_depth);

		StorageType *texture_pixels;

		{
			thread_scoped_lock device_lock(device_mutex);
			texture_pixels = (StorageType*)tex_img.alloc(scaled_width,
			                                             scaled_height,
			                                             scaled_depth);
		}

		memcpy(texture_pixels,
		       &scaled_pixels[0],
		       scaled_pixels.size() * sizeof(StorageType));
	}
	return true;
}
예제 #29
0
파일: image.cpp 프로젝트: mgschwan/blensor
int ImageManager::add_image(const string& filename,
                            void *builtin_data,
                            bool animated,
                            float frame,
                            InterpolationType interpolation,
                            ExtensionType extension,
                            bool use_alpha,
                            ImageMetaData& metadata)
{
	Image *img;
	size_t slot;

	get_image_metadata(filename, builtin_data, metadata);
	ImageDataType type = metadata.type;

	thread_scoped_lock device_lock(device_mutex);

	/* No half textures on OpenCL, use full float instead. */
	if(!has_half_images) {
		if(type == IMAGE_DATA_TYPE_HALF4) {
			type = IMAGE_DATA_TYPE_FLOAT4;
		}
		else if(type == IMAGE_DATA_TYPE_HALF) {
			type = IMAGE_DATA_TYPE_FLOAT;
		}
	}

	/* Fnd existing image. */
	for(slot = 0; slot < images[type].size(); slot++) {
		img = images[type][slot];
		if(img && image_equals(img,
		                       filename,
		                       builtin_data,
		                       interpolation,
		                       extension,
		                       use_alpha))
		{
			if(img->frame != frame) {
				img->frame = frame;
				img->need_load = true;
			}
			if(img->use_alpha != use_alpha) {
				img->use_alpha = use_alpha;
				img->need_load = true;
			}
			img->users++;
			return type_index_to_flattened_slot(slot, type);
		}
	}

	/* Find free slot. */
	for(slot = 0; slot < images[type].size(); slot++) {
		if(!images[type][slot])
			break;
	}

	/* Count if we're over the limit.
	 * Very unlikely, since max_num_images is insanely big. But better safe than sorry. */
	int tex_count = 0;
	for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
		tex_count += tex_num_images[type];
	}
	if(tex_count > max_num_images) {
		printf("ImageManager::add_image: Reached image limit (%d), skipping '%s'\n",
			max_num_images, filename.c_str());
		return -1;
	}

	if(slot == images[type].size()) {
		images[type].resize(images[type].size() + 1);
	}

	/* Add new image. */
	img = new Image();
	img->filename = filename;
	img->builtin_data = builtin_data;
	img->builtin_free_cache = metadata.builtin_free_cache;
	img->need_load = true;
	img->animated = animated;
	img->frame = frame;
	img->interpolation = interpolation;
	img->extension = extension;
	img->users = 1;
	img->use_alpha = use_alpha;
	img->mem = NULL;

	images[type][slot] = img;

	++tex_num_images[type];

	need_update = true;

	return type_index_to_flattened_slot(slot, type);
}
static ssize_t store_ehci_power(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
	struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev);
	struct usb_hcd *hcd = s5p_ehci->hcd;
	int power_on;
	int irq;
	int retval;

	if (sscanf(buf, "%d", &power_on) != 1)
		return -EINVAL;

	device_lock(dev);

	if (!power_on && s5p_ehci->power_on) {
		printk(KERN_DEBUG "%s: EHCI turns off\n", __func__);
#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB)
		if (hcd->self.root_hub)
			pm_runtime_forbid(&hcd->self.root_hub->dev);
#endif
		pm_runtime_forbid(dev);
		s5p_ehci->power_on = 0;
		usb_remove_hcd(hcd);

		if (pdata && pdata->phy_exit)
			pdata->phy_exit(pdev, S5P_USB_PHY_HOST);

#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB)
		/*HSIC IPC control the ACTIVE_STATE*/
		if (pdata && pdata->noti_host_states)
			pdata->noti_host_states(pdev, S5P_HOST_OFF);
#endif
	} else if (power_on) {
		printk(KERN_DEBUG "%s: EHCI turns on\n", __func__);
		if (s5p_ehci->power_on) {
			pm_runtime_forbid(dev);
			usb_remove_hcd(hcd);
#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB)
			/*HSIC IPC control the ACTIVE_STATE*/
			if (pdata && pdata->noti_host_states)
				pdata->noti_host_states(pdev, S5P_HOST_OFF);
#endif
		} else
			s5p_ehci_phy_init(pdev);

		irq = platform_get_irq(pdev, 0);
		retval = usb_add_hcd(hcd, irq,
				IRQF_DISABLED | IRQF_SHARED);
		if (retval < 0) {
			dev_err(dev, "Power On Fail\n");
			goto exit;
		}

		s5p_ehci->power_on = 1;
#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB)
		/* Sometimes XMM6262 send remote wakeup when hub enter suspend
		 * So, set the hub waiting 500ms autosuspend delay*/
		if (hcd->self.root_hub)
			pm_runtime_set_autosuspend_delay(
				&hcd->self.root_hub->dev,
				msecs_to_jiffies(500));

		/*HSIC IPC control the ACTIVE_STATE*/
		if (pdata && pdata->noti_host_states)
			pdata->noti_host_states(pdev, S5P_HOST_ON);
#endif
		pm_runtime_allow(dev);
	}
exit:
	device_unlock(dev);
	return count;
}