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

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

cciss: factor out cciss_big_passthru

parent f32f125b
Loading
Loading
Loading
Loading
+151 −156
Original line number Original line Diff line number Diff line
@@ -1498,43 +1498,8 @@ static int cciss_passthru(ctlr_info_t *h, void __user *argp)
	return 0;
	return 0;
}
}


static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
static int cciss_bigpassthru(ctlr_info_t *h, void __user *argp)
	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;
	BIG_IOCTL_Command_struct *ioc;
	CommandList_struct *c;
	CommandList_struct *c;
	unsigned char **buff = NULL;
	unsigned char **buff = NULL;
@@ -1548,7 +1513,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	__u32 sz;
	__u32 sz;
	BYTE __user *data_ptr;
	BYTE __user *data_ptr;


			if (!arg)
	if (!argp)
		return -EINVAL;
		return -EINVAL;
	if (!capable(CAP_SYS_RAWIO))
	if (!capable(CAP_SYS_RAWIO))
		return -EPERM;
		return -EPERM;
@@ -1576,14 +1541,12 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
		status = -EINVAL;
		status = -EINVAL;
		goto cleanup1;
		goto cleanup1;
	}
	}
			buff =
	buff = kzalloc(MAXSGENTRIES * sizeof(char *), GFP_KERNEL);
			    kzalloc(MAXSGENTRIES * sizeof(char *), GFP_KERNEL);
	if (!buff) {
	if (!buff) {
		status = -ENOMEM;
		status = -ENOMEM;
		goto cleanup1;
		goto cleanup1;
	}
	}
			buff_size = kmalloc(MAXSGENTRIES * sizeof(int),
	buff_size = kmalloc(MAXSGENTRIES * sizeof(int), GFP_KERNEL);
						   GFP_KERNEL);
	if (!buff_size) {
	if (!buff_size) {
		status = -ENOMEM;
		status = -ENOMEM;
		goto cleanup1;
		goto cleanup1;
@@ -1591,9 +1554,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	left = ioc->buf_size;
	left = ioc->buf_size;
	data_ptr = ioc->buf;
	data_ptr = ioc->buf;
	while (left) {
	while (left) {
				sz = (left >
		sz = (left > ioc->malloc_size) ? ioc->malloc_size : left;
				      ioc->malloc_size) ? ioc->
				    malloc_size : left;
		buff_size[sg_used] = sz;
		buff_size[sg_used] = sz;
		buff[sg_used] = kmalloc(sz, GFP_KERNEL);
		buff[sg_used] = kmalloc(sz, GFP_KERNEL);
		if (buff[sg_used] == NULL) {
		if (buff[sg_used] == NULL) {
@@ -1601,8 +1562,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
			goto cleanup1;
			goto cleanup1;
		}
		}
		if (ioc->Request.Type.Direction == XFER_WRITE) {
		if (ioc->Request.Type.Direction == XFER_WRITE) {
					if (copy_from_user
			if (copy_from_user(buff[sg_used], data_ptr, sz)) {
					    (buff[sg_used], data_ptr, sz)) {
				status = -EFAULT;
				status = -EFAULT;
				goto cleanup1;
				goto cleanup1;
			}
			}
@@ -1635,13 +1595,10 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	if (ioc->buf_size > 0) {
	if (ioc->buf_size > 0) {
		for (i = 0; i < sg_used; i++) {
		for (i = 0; i < sg_used; i++) {
			temp64.val =
			temp64.val =
					    pci_map_single(h->pdev, buff[i],
			    pci_map_single(h->pdev, buff[i], buff_size[i],
						    buff_size[i],
				    PCI_DMA_BIDIRECTIONAL);
				    PCI_DMA_BIDIRECTIONAL);
					c->SG[i].Addr.lower =
			c->SG[i].Addr.lower = temp64.val32.lower;
					    temp64.val32.lower;
			c->SG[i].Addr.upper = temp64.val32.upper;
					c->SG[i].Addr.upper =
					    temp64.val32.upper;
			c->SG[i].Len = buff_size[i];
			c->SG[i].Len = buff_size[i];
			c->SG[i].Ext = 0;	/* we are not chaining */
			c->SG[i].Ext = 0;	/* we are not chaining */
		}
		}
@@ -1669,8 +1626,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
		/* Copy the data out of the buffer we created */
		/* Copy the data out of the buffer we created */
		BYTE __user *ptr = ioc->buf;
		BYTE __user *ptr = ioc->buf;
		for (i = 0; i < sg_used; i++) {
		for (i = 0; i < sg_used; i++) {
					if (copy_to_user
			if (copy_to_user(ptr, buff[i], buff_size[i])) {
					    (ptr, buff[i], buff_size[i])) {
				cmd_special_free(h, c);
				cmd_special_free(h, c);
				status = -EFAULT;
				status = -EFAULT;
				goto cleanup1;
				goto cleanup1;
@@ -1691,6 +1647,45 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	return status;
	return status;
}
}


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:
		return cciss_bigpassthru(h, argp);

	/* scsi_cmd_ioctl handles these, below, though some are not */
	/* scsi_cmd_ioctl handles these, below, though some are not */
	/* very meaningful for cciss.  SG_IO is the main one people want. */
	/* very meaningful for cciss.  SG_IO is the main one people want. */