Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f32f125b authored by Stephen M. Cameron's avatar Stephen M. Cameron Committed by Jens Axboe
Browse files

cciss: factor out cciss_passthru

parent 0894b32c
Loading
Loading
Loading
Loading
+101 −111
Original line number Diff line number Diff line
@@ -1398,41 +1398,7 @@ static int cciss_getluninfo(ctlr_info_t *h,
	return 0;
}

static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	unsigned int cmd, unsigned long arg)
{
	struct gendisk *disk = bdev->bd_disk;
	ctlr_info_t *h = get_host(disk);
	void __user *argp = (void __user *)arg;

	dev_dbg(&h->pdev->dev, "cciss_ioctl: Called with cmd=%x %lx\n",
		cmd, arg);
	switch (cmd) {
	case CCISS_GETPCIINFO:
		return cciss_getpciinfo(h, argp);
	case CCISS_GETINTINFO:
		return cciss_getintinfo(h, argp);
	case CCISS_SETINTINFO:
		return cciss_setintinfo(h, argp);
	case CCISS_GETNODENAME:
		return cciss_getnodename(h, argp);
	case CCISS_SETNODENAME:
		return cciss_setnodename(h, argp);
	case CCISS_GETHEARTBEAT:
		return cciss_getheartbeat(h, argp);
	case CCISS_GETBUSTYPES:
		return cciss_getbustypes(h, argp);
	case CCISS_GETFIRMVER:
		return cciss_getfirmver(h, argp);
	case CCISS_GETDRIVVER:
		return cciss_getdrivver(h, argp);
	case CCISS_DEREGDISK:
	case CCISS_REGNEWD:
	case CCISS_REVALIDVOLS:
		return rebuild_lun_table(h, 0, 1);
	case CCISS_GETLUNINFO:
		return cciss_getluninfo(h, disk, argp);
	case CCISS_PASSTHRU:
static int cciss_passthru(ctlr_info_t *h, void __user *argp)
{
	IOCTL_Command_struct iocommand;
	CommandList_struct *c;
@@ -1440,7 +1406,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	u64bit temp64;
	DECLARE_COMPLETION_ONSTACK(wait);

			if (!arg)
	if (!argp)
		return -EINVAL;

	if (!capable(CAP_SYS_RAWIO))
@@ -1453,11 +1419,6 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	    (iocommand.Request.Type.Direction != XFER_NONE)) {
		return -EINVAL;
	}
#if 0				/* 'buf_size' member is 16-bits, and always smaller than kmalloc limit */
			/* Check kmalloc limits */
			if (iocommand.buf_size > 128000)
				return -EINVAL;
#endif
	if (iocommand.buf_size > 0) {
		buff = kmalloc(iocommand.buf_size, GFP_KERNEL);
		if (buff == NULL)
@@ -1465,8 +1426,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	}
	if (iocommand.Request.Type.Direction == XFER_WRITE) {
		/* Copy the data into the buffer we created */
				if (copy_from_user
				    (buff, iocommand.buf, iocommand.buf_size)) {
		if (copy_from_user(buff, iocommand.buf, iocommand.buf_size)) {
			kfree(buff);
			return -EFAULT;
		}
@@ -1482,12 +1442,10 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	c->cmd_type = CMD_IOCTL_PEND;
	/* Fill in Command Header */
	c->Header.ReplyQueue = 0;   /* unused in simple mode */
			if (iocommand.buf_size > 0) /* buffer to fill */
			{
	if (iocommand.buf_size > 0) { /* buffer to fill */
		c->Header.SGList = 1;
		c->Header.SGTotal = 1;
			} else /* no buffers to fill */
			{
	} else { /* no buffers to fill */
		c->Header.SGList = 0;
		c->Header.SGTotal = 0;
	}
@@ -1501,8 +1459,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	/* Fill in the scatter gather information */
	if (iocommand.buf_size > 0) {
		temp64.val = pci_map_single(h->pdev, buff,
					iocommand.buf_size,
					PCI_DMA_BIDIRECTIONAL);
			iocommand.buf_size, PCI_DMA_BIDIRECTIONAL);
		c->SG[0].Addr.lower = temp64.val32.lower;
		c->SG[0].Addr.upper = temp64.val32.upper;
		c->SG[0].Len = iocommand.buf_size;
@@ -1516,16 +1473,13 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	/* unlock the buffers from DMA */
	temp64.val32.lower = c->SG[0].Addr.lower;
	temp64.val32.upper = c->SG[0].Addr.upper;
			pci_unmap_single(h->pdev, (dma_addr_t) temp64.val,
					 iocommand.buf_size,
	pci_unmap_single(h->pdev, (dma_addr_t) temp64.val, iocommand.buf_size,
			 PCI_DMA_BIDIRECTIONAL);

	check_ioctl_unit_attention(h, c);

	/* Copy the error information out */
	iocommand.error_info = *(c->err_info);
			if (copy_to_user
			    (argp, &iocommand, sizeof(IOCTL_Command_struct))) {
	if (copy_to_user(argp, &iocommand, sizeof(IOCTL_Command_struct))) {
		kfree(buff);
		cmd_special_free(h, c);
		return -EFAULT;
@@ -1533,8 +1487,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,

	if (iocommand.Request.Type.Direction == XFER_READ) {
		/* Copy the data out of the buffer we created */
				if (copy_to_user
				    (iocommand.buf, buff, iocommand.buf_size)) {
		if (copy_to_user(iocommand.buf, buff, iocommand.buf_size)) {
			kfree(buff);
			cmd_special_free(h, c);
			return -EFAULT;
@@ -1544,6 +1497,43 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	cmd_special_free(h, c);
	return 0;
}

static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	unsigned int cmd, unsigned long arg)
{
	struct gendisk *disk = bdev->bd_disk;
	ctlr_info_t *h = get_host(disk);
	void __user *argp = (void __user *)arg;

	dev_dbg(&h->pdev->dev, "cciss_ioctl: Called with cmd=%x %lx\n",
		cmd, arg);
	switch (cmd) {
	case CCISS_GETPCIINFO:
		return cciss_getpciinfo(h, argp);
	case CCISS_GETINTINFO:
		return cciss_getintinfo(h, argp);
	case CCISS_SETINTINFO:
		return cciss_setintinfo(h, argp);
	case CCISS_GETNODENAME:
		return cciss_getnodename(h, argp);
	case CCISS_SETNODENAME:
		return cciss_setnodename(h, argp);
	case CCISS_GETHEARTBEAT:
		return cciss_getheartbeat(h, argp);
	case CCISS_GETBUSTYPES:
		return cciss_getbustypes(h, argp);
	case CCISS_GETFIRMVER:
		return cciss_getfirmver(h, argp);
	case CCISS_GETDRIVVER:
		return cciss_getdrivver(h, argp);
	case CCISS_DEREGDISK:
	case CCISS_REGNEWD:
	case CCISS_REVALIDVOLS:
		return rebuild_lun_table(h, 0, 1);
	case CCISS_GETLUNINFO:
		return cciss_getluninfo(h, disk, argp);
	case CCISS_PASSTHRU:
		return cciss_passthru(h, argp);
	case CCISS_BIG_PASSTHRU:{
			BIG_IOCTL_Command_struct *ioc;
			CommandList_struct *c;