static int ps3_ohci_remove(struct ps3_system_bus_device *dev)
{
	unsigned int tmp;
	struct usb_hcd *hcd = ps3_system_bus_get_drvdata(dev);

	BUG_ON(!hcd);

	dev_dbg(&dev->core, "%s:%d: regs %p\n", __func__, __LINE__, hcd->regs);
	dev_dbg(&dev->core, "%s:%d: irq %u\n", __func__, __LINE__, hcd->irq);

	tmp = hcd->irq;

	ohci_shutdown(hcd);
	usb_remove_hcd(hcd);

	ps3_system_bus_set_drvdata(dev, NULL);

	BUG_ON(!hcd->regs);
	iounmap(hcd->regs);

	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
	usb_put_hcd(hcd);

	ps3_io_irq_destroy(tmp);
	ps3_free_mmio_region(dev->m_region);

	ps3_dma_region_free(dev->d_region);
	ps3_close_hv_device(dev);

	return 0;
}
static int ps3flash_remove(struct ps3_system_bus_device *_dev)
{
	struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);

	ps3_os_area_flash_register(NULL);
	misc_deregister(&ps3flash_misc);
	ps3stor_teardown(dev);
	kfree(ps3_system_bus_get_drvdata(&dev->sbd));
	ps3_system_bus_set_drvdata(&dev->sbd, NULL);
	ps3flash_dev = NULL;
	return 0;
}
Example #3
0
static int ps3encdec_remove(struct ps3_system_bus_device *_dev)
{
	struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);

	misc_deregister(&ps3encdec_misc);
	ps3stor_teardown(dev);
	kfree(ps3_system_bus_get_drvdata(&dev->sbd));
	ps3_system_bus_set_drvdata(&dev->sbd, NULL);
	kfree(dev->bounce_buf);
	ps3encdec_dev = NULL;

	return 0;
}
Example #4
0
static int ps3flash_read_write_sectors(struct ps3_storage_device *dev,
				       u64 start_sector, int write)
{
	struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
	u64 res = ps3stor_read_write_sectors(dev, dev->bounce_lpar,
					     start_sector, priv->chunk_sectors,
					     write);
	if (res) {
		dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__,
			__LINE__, write ? "write" : "read", res);
		return -EIO;
	}
	return 0;
}
Example #5
0
static int ps3flash_writeback(struct ps3_storage_device *dev)
{
	struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
	int res;

	if (!priv->dirty || priv->tag < 0)
		return 0;

	res = ps3flash_read_write_sectors(dev, priv->tag, 1);
	if (res)
		return res;

	priv->dirty = false;
	return 0;
}
Example #6
0
static int ps3flash_fetch(struct ps3_storage_device *dev, u64 start_sector)
{
	struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
	int res;

	if (start_sector == priv->tag)
		return 0;

	res = ps3flash_writeback(dev);
	if (res)
		return res;

	priv->tag = -1;

	res = ps3flash_read_write_sectors(dev, start_sector, 0);
	if (res)
		return res;

	priv->tag = start_sector;
	return 0;
}
Example #7
0
static ssize_t ps3flash_write(const char __user *userbuf,
			      const void *kernelbuf, size_t count, loff_t *pos)
{
	struct ps3_storage_device *dev = ps3flash_dev;
	struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
	u64 size, sector, offset;
	int res = 0;
	size_t remaining, n;
	void *dst;

	dev_dbg(&dev->sbd.core,
		"%s:%u: Writing %zu bytes at position %lld from U0x%p/K0x%p\n",
		__func__, __LINE__, count, *pos, userbuf, kernelbuf);

	size = dev->regions[dev->region_idx].size*dev->blk_size;
	if (*pos >= size || !count)
		return 0;

	if (*pos + count > size) {
		dev_dbg(&dev->sbd.core,
			"%s:%u Truncating count from %zu to %llu\n", __func__,
			__LINE__, count, size - *pos);
		count = size - *pos;
	}

	sector = *pos / dev->bounce_size * priv->chunk_sectors;
	offset = *pos % dev->bounce_size;

	remaining = count;
	do {
		n = min_t(u64, remaining, dev->bounce_size - offset);
		dst = dev->bounce_buf + offset;

		mutex_lock(&priv->mutex);

		if (n != dev->bounce_size)
			res = ps3flash_fetch(dev, sector);
		else if (sector != priv->tag)
			res = ps3flash_writeback(dev);
		if (res)
			goto fail;

		dev_dbg(&dev->sbd.core,
			"%s:%u: copy %lu bytes from U0x%p/K0x%p to 0x%p\n",
			__func__, __LINE__, n, userbuf, kernelbuf, dst);
		if (userbuf) {
			if (copy_from_user(dst, userbuf, n)) {
				res = -EFAULT;
				goto fail;
			}
			userbuf += n;
		}
		if (kernelbuf) {
			memcpy(dst, kernelbuf, n);
			kernelbuf += n;
		}

		priv->tag = sector;
		priv->dirty = true;

		mutex_unlock(&priv->mutex);

		*pos += n;
		remaining -= n;
		sector += priv->chunk_sectors;
		offset = 0;
	} while (remaining > 0);

	return count;

fail:
	mutex_unlock(&priv->mutex);
	return res;
}
Example #8
0
static long ps3encdec_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct ps3_storage_device *dev = ps3encdec_dev;
	struct ps3encdec_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
	void __user *argp = (void __user *) arg;
	int res = -EFAULT;

	mutex_lock(&priv->mutex);

	pr_debug("%s:%d cmd %x\n", __func__, __LINE__, cmd);

	switch (cmd) {
	case PS3ENCDEC_IOCTL_DO_REQUEST:
		{
			struct ps3encdec_ioctl_do_request do_request;
			void *cmdbuf;
			u64 cmdbuf_lpar;

			if (copy_from_user(&do_request, argp, sizeof(do_request))) {
				pr_debug("%s:%d: copy_from_user failed\n", __func__, __LINE__);
				res = -EFAULT;
				break;
			}

			BUG_ON(do_request.respbuf_size > BOUNCE_SIZE);

			pr_debug("%s:%d: cmd (%llx) cmdbuf_size (%lld) respbuf_size (%lld)\n",
				__func__, __LINE__, do_request.cmd, do_request.cmdbuf_size,
				do_request.respbuf_size);

			cmdbuf = kmalloc(do_request.cmdbuf_size, GFP_KERNEL);
			if (!cmdbuf) {
				pr_debug("%s:%d: kmalloc failed\n", __func__, __LINE__);
				res = -ENOMEM;
				break;
			}

			if (copy_from_user(cmdbuf, (const void __user *) do_request.cmdbuf,
				do_request.cmdbuf_size)) {
				pr_debug("%s:%d: copy_from_user failed\n", __func__, __LINE__);
				res = -EFAULT;
				goto kfree_cmdbuf;
			}

			cmdbuf_lpar = ps3_mm_phys_to_lpar(__pa(cmdbuf));

			res = ps3stor_send_command(dev, do_request.cmd,
				cmdbuf_lpar, do_request.cmdbuf_size,
				dev->bounce_lpar, do_request.respbuf_size);
			if (res) {
				pr_debug("%s:%d: ps3stor_send_command failed (%d)\n",
					__func__, __LINE__, res);
				res = -EFAULT;
				goto kfree_cmdbuf;
			}

			if (copy_to_user((void __user *) do_request.respbuf, dev->bounce_buf,
				do_request.respbuf_size)) {
				pr_debug("%s:%d: copy_to_user failed\n", __func__, __LINE__);
				res = -EFAULT;
				goto kfree_cmdbuf;
			}

			res = 0;

		kfree_cmdbuf:

			kfree(cmdbuf);

			break;
		}
	}

	mutex_unlock(&priv->mutex);

	return res;
}