提交 f32f125b 编写于 作者: S Stephen M. Cameron 提交者: Jens Axboe

cciss: factor out cciss_passthru

Signed-off-by: NStephen M. Cameron <scameron@beardog.cce.hp.com>
Signed-off-by: NJens Axboe <jaxboe@fusionio.com>
上级 0894b32c
...@@ -1398,49 +1398,15 @@ static int cciss_getluninfo(ctlr_info_t *h, ...@@ -1398,49 +1398,15 @@ static int cciss_getluninfo(ctlr_info_t *h,
return 0; return 0;
} }
static int cciss_ioctl(struct block_device *bdev, fmode_t mode, static int cciss_passthru(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:
{
IOCTL_Command_struct iocommand; IOCTL_Command_struct iocommand;
CommandList_struct *c; CommandList_struct *c;
char *buff = NULL; char *buff = NULL;
u64bit temp64; u64bit temp64;
DECLARE_COMPLETION_ONSTACK(wait); DECLARE_COMPLETION_ONSTACK(wait);
if (!arg) if (!argp)
return -EINVAL; return -EINVAL;
if (!capable(CAP_SYS_RAWIO)) if (!capable(CAP_SYS_RAWIO))
...@@ -1453,11 +1419,6 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, ...@@ -1453,11 +1419,6 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
(iocommand.Request.Type.Direction != XFER_NONE)) { (iocommand.Request.Type.Direction != XFER_NONE)) {
return -EINVAL; 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) { if (iocommand.buf_size > 0) {
buff = kmalloc(iocommand.buf_size, GFP_KERNEL); buff = kmalloc(iocommand.buf_size, GFP_KERNEL);
if (buff == NULL) if (buff == NULL)
...@@ -1465,8 +1426,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, ...@@ -1465,8 +1426,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
} }
if (iocommand.Request.Type.Direction == XFER_WRITE) { if (iocommand.Request.Type.Direction == XFER_WRITE) {
/* Copy the data into the buffer we created */ /* Copy the data into the buffer we created */
if (copy_from_user if (copy_from_user(buff, iocommand.buf, iocommand.buf_size)) {
(buff, iocommand.buf, iocommand.buf_size)) {
kfree(buff); kfree(buff);
return -EFAULT; return -EFAULT;
} }
...@@ -1482,12 +1442,10 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, ...@@ -1482,12 +1442,10 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
c->cmd_type = CMD_IOCTL_PEND; c->cmd_type = CMD_IOCTL_PEND;
/* Fill in Command Header */ /* Fill in Command Header */
c->Header.ReplyQueue = 0; /* unused in simple mode */ 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.SGList = 1;
c->Header.SGTotal = 1; c->Header.SGTotal = 1;
} else /* no buffers to fill */ } else { /* no buffers to fill */
{
c->Header.SGList = 0; c->Header.SGList = 0;
c->Header.SGTotal = 0; c->Header.SGTotal = 0;
} }
...@@ -1501,8 +1459,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, ...@@ -1501,8 +1459,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
/* Fill in the scatter gather information */ /* Fill in the scatter gather information */
if (iocommand.buf_size > 0) { if (iocommand.buf_size > 0) {
temp64.val = pci_map_single(h->pdev, buff, temp64.val = pci_map_single(h->pdev, buff,
iocommand.buf_size, iocommand.buf_size, PCI_DMA_BIDIRECTIONAL);
PCI_DMA_BIDIRECTIONAL);
c->SG[0].Addr.lower = temp64.val32.lower; c->SG[0].Addr.lower = temp64.val32.lower;
c->SG[0].Addr.upper = temp64.val32.upper; c->SG[0].Addr.upper = temp64.val32.upper;
c->SG[0].Len = iocommand.buf_size; c->SG[0].Len = iocommand.buf_size;
...@@ -1516,16 +1473,13 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, ...@@ -1516,16 +1473,13 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
/* unlock the buffers from DMA */ /* unlock the buffers from DMA */
temp64.val32.lower = c->SG[0].Addr.lower; temp64.val32.lower = c->SG[0].Addr.lower;
temp64.val32.upper = c->SG[0].Addr.upper; temp64.val32.upper = c->SG[0].Addr.upper;
pci_unmap_single(h->pdev, (dma_addr_t) temp64.val, pci_unmap_single(h->pdev, (dma_addr_t) temp64.val, iocommand.buf_size,
iocommand.buf_size,
PCI_DMA_BIDIRECTIONAL); PCI_DMA_BIDIRECTIONAL);
check_ioctl_unit_attention(h, c); check_ioctl_unit_attention(h, c);
/* Copy the error information out */ /* Copy the error information out */
iocommand.error_info = *(c->err_info); iocommand.error_info = *(c->err_info);
if (copy_to_user if (copy_to_user(argp, &iocommand, sizeof(IOCTL_Command_struct))) {
(argp, &iocommand, sizeof(IOCTL_Command_struct))) {
kfree(buff); kfree(buff);
cmd_special_free(h, c); cmd_special_free(h, c);
return -EFAULT; return -EFAULT;
...@@ -1533,8 +1487,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, ...@@ -1533,8 +1487,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
if (iocommand.Request.Type.Direction == XFER_READ) { if (iocommand.Request.Type.Direction == XFER_READ) {
/* Copy the data out of the buffer we created */ /* Copy the data out of the buffer we created */
if (copy_to_user if (copy_to_user(iocommand.buf, buff, iocommand.buf_size)) {
(iocommand.buf, buff, iocommand.buf_size)) {
kfree(buff); kfree(buff);
cmd_special_free(h, c); cmd_special_free(h, c);
return -EFAULT; return -EFAULT;
...@@ -1543,7 +1496,44 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, ...@@ -1543,7 +1496,44 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
kfree(buff); kfree(buff);
cmd_special_free(h, c); cmd_special_free(h, c);
return 0; 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:{ case CCISS_BIG_PASSTHRU:{
BIG_IOCTL_Command_struct *ioc; BIG_IOCTL_Command_struct *ioc;
CommandList_struct *c; CommandList_struct *c;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册