cciss: factor out cciss_getbustypes
[linux-2.6-block.git] / drivers / block / cciss.c
index 31064df1370a96320f548d1ce5f191eaf2e97051..e7b650b7f548c585c7ae8865adae533ae3554701 100644 (file)
@@ -1230,9 +1230,133 @@ static void check_ioctl_unit_attention(ctlr_info_t *h, CommandList_struct *c)
                        c->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION)
                (void)check_for_unit_attention(h, c);
 }
-/*
- * ioctl
- */
+
+static int cciss_getpciinfo(ctlr_info_t *h, void __user *argp)
+{
+       cciss_pci_info_struct pciinfo;
+
+       if (!argp)
+               return -EINVAL;
+       pciinfo.domain = pci_domain_nr(h->pdev->bus);
+       pciinfo.bus = h->pdev->bus->number;
+       pciinfo.dev_fn = h->pdev->devfn;
+       pciinfo.board_id = h->board_id;
+       if (copy_to_user(argp, &pciinfo, sizeof(cciss_pci_info_struct)))
+               return -EFAULT;
+       return 0;
+}
+
+static int cciss_getintinfo(ctlr_info_t *h, void __user *argp)
+{
+       cciss_coalint_struct intinfo;
+
+       if (!argp)
+               return -EINVAL;
+       intinfo.delay = readl(&h->cfgtable->HostWrite.CoalIntDelay);
+       intinfo.count = readl(&h->cfgtable->HostWrite.CoalIntCount);
+       if (copy_to_user
+           (argp, &intinfo, sizeof(cciss_coalint_struct)))
+               return -EFAULT;
+       return 0;
+}
+
+static int cciss_setintinfo(ctlr_info_t *h, void __user *argp)
+{
+       cciss_coalint_struct intinfo;
+       unsigned long flags;
+       int i;
+
+       if (!argp)
+               return -EINVAL;
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+       if (copy_from_user(&intinfo, argp, sizeof(intinfo)))
+               return -EFAULT;
+       if ((intinfo.delay == 0) && (intinfo.count == 0))
+               return -EINVAL;
+       spin_lock_irqsave(&h->lock, flags);
+       /* Update the field, and then ring the doorbell */
+       writel(intinfo.delay, &(h->cfgtable->HostWrite.CoalIntDelay));
+       writel(intinfo.count, &(h->cfgtable->HostWrite.CoalIntCount));
+       writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
+
+       for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
+               if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
+                       break;
+               udelay(1000); /* delay and try again */
+       }
+       spin_unlock_irqrestore(&h->lock, flags);
+       if (i >= MAX_IOCTL_CONFIG_WAIT)
+               return -EAGAIN;
+       return 0;
+}
+
+static int cciss_getnodename(ctlr_info_t *h, void __user *argp)
+{
+       NodeName_type NodeName;
+       int i;
+
+       if (!argp)
+               return -EINVAL;
+       for (i = 0; i < 16; i++)
+               NodeName[i] = readb(&h->cfgtable->ServerName[i]);
+       if (copy_to_user(argp, NodeName, sizeof(NodeName_type)))
+               return -EFAULT;
+       return 0;
+}
+
+static int cciss_setnodename(ctlr_info_t *h, void __user *argp)
+{
+       NodeName_type NodeName;
+       unsigned long flags;
+       int i;
+
+       if (!argp)
+               return -EINVAL;
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+       if (copy_from_user(NodeName, argp, sizeof(NodeName_type)))
+               return -EFAULT;
+       spin_lock_irqsave(&h->lock, flags);
+       /* Update the field, and then ring the doorbell */
+       for (i = 0; i < 16; i++)
+               writeb(NodeName[i], &h->cfgtable->ServerName[i]);
+       writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
+       for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
+               if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
+                       break;
+               udelay(1000); /* delay and try again */
+       }
+       spin_unlock_irqrestore(&h->lock, flags);
+       if (i >= MAX_IOCTL_CONFIG_WAIT)
+               return -EAGAIN;
+       return 0;
+}
+
+static int cciss_getheartbeat(ctlr_info_t *h, void __user *argp)
+{
+       Heartbeat_type heartbeat;
+
+       if (!argp)
+               return -EINVAL;
+       heartbeat = readl(&h->cfgtable->HeartBeat);
+       if (copy_to_user(argp, &heartbeat, sizeof(Heartbeat_type)))
+               return -EFAULT;
+       return 0;
+}
+
+static int cciss_getbustypes(ctlr_info_t *h, void __user *argp)
+{
+       BusTypes_type BusTypes;
+
+       if (!argp)
+               return -EINVAL;
+       BusTypes = readl(&h->cfgtable->BusTypes);
+       if (copy_to_user(argp, &BusTypes, sizeof(BusTypes_type)))
+               return -EFAULT;
+       return 0;
+}
+
 static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
                       unsigned int cmd, unsigned long arg)
 {
@@ -1245,144 +1369,19 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
                cmd, arg);
        switch (cmd) {
        case CCISS_GETPCIINFO:
-               {
-                       cciss_pci_info_struct pciinfo;
-
-                       if (!arg)
-                               return -EINVAL;
-                       pciinfo.domain = pci_domain_nr(h->pdev->bus);
-                       pciinfo.bus = h->pdev->bus->number;
-                       pciinfo.dev_fn = h->pdev->devfn;
-                       pciinfo.board_id = h->board_id;
-                       if (copy_to_user
-                           (argp, &pciinfo, sizeof(cciss_pci_info_struct)))
-                               return -EFAULT;
-                       return 0;
-               }
+               return cciss_getpciinfo(h, argp);
        case CCISS_GETINTINFO:
-               {
-                       cciss_coalint_struct intinfo;
-                       if (!arg)
-                               return -EINVAL;
-                       intinfo.delay =
-                           readl(&h->cfgtable->HostWrite.CoalIntDelay);
-                       intinfo.count =
-                           readl(&h->cfgtable->HostWrite.CoalIntCount);
-                       if (copy_to_user
-                           (argp, &intinfo, sizeof(cciss_coalint_struct)))
-                               return -EFAULT;
-                       return 0;
-               }
+               return cciss_getintinfo(h, argp);
        case CCISS_SETINTINFO:
-               {
-                       cciss_coalint_struct intinfo;
-                       unsigned long flags;
-                       int i;
-
-                       if (!arg)
-                               return -EINVAL;
-                       if (!capable(CAP_SYS_ADMIN))
-                               return -EPERM;
-                       if (copy_from_user
-                           (&intinfo, argp, sizeof(cciss_coalint_struct)))
-                               return -EFAULT;
-                       if ((intinfo.delay == 0) && (intinfo.count == 0))
-                               return -EINVAL;
-                       spin_lock_irqsave(&h->lock, flags);
-                       /* Update the field, and then ring the doorbell */
-                       writel(intinfo.delay,
-                              &(h->cfgtable->HostWrite.CoalIntDelay));
-                       writel(intinfo.count,
-                              &(h->cfgtable->HostWrite.CoalIntCount));
-                       writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
-
-                       for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
-                               if (!(readl(h->vaddr + SA5_DOORBELL)
-                                     & CFGTBL_ChangeReq))
-                                       break;
-                               /* delay and try again */
-                               udelay(1000);
-                       }
-                       spin_unlock_irqrestore(&h->lock, flags);
-                       if (i >= MAX_IOCTL_CONFIG_WAIT)
-                               return -EAGAIN;
-                       return 0;
-               }
+               return cciss_setintinfo(h, argp);
        case CCISS_GETNODENAME:
-               {
-                       NodeName_type NodeName;
-                       int i;
-
-                       if (!arg)
-                               return -EINVAL;
-                       for (i = 0; i < 16; i++)
-                               NodeName[i] =
-                                   readb(&h->cfgtable->ServerName[i]);
-                       if (copy_to_user(argp, NodeName, sizeof(NodeName_type)))
-                               return -EFAULT;
-                       return 0;
-               }
+               return cciss_getnodename(h, argp);
        case CCISS_SETNODENAME:
-               {
-                       NodeName_type NodeName;
-                       unsigned long flags;
-                       int i;
-
-                       if (!arg)
-                               return -EINVAL;
-                       if (!capable(CAP_SYS_ADMIN))
-                               return -EPERM;
-
-                       if (copy_from_user
-                           (NodeName, argp, sizeof(NodeName_type)))
-                               return -EFAULT;
-
-                       spin_lock_irqsave(&h->lock, flags);
-
-                       /* Update the field, and then ring the doorbell */
-                       for (i = 0; i < 16; i++)
-                               writeb(NodeName[i],
-                                      &h->cfgtable->ServerName[i]);
-
-                       writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
-
-                       for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
-                               if (!(readl(h->vaddr + SA5_DOORBELL)
-                                     & CFGTBL_ChangeReq))
-                                       break;
-                               /* delay and try again */
-                               udelay(1000);
-                       }
-                       spin_unlock_irqrestore(&h->lock, flags);
-                       if (i >= MAX_IOCTL_CONFIG_WAIT)
-                               return -EAGAIN;
-                       return 0;
-               }
-
+               return cciss_setnodename(h, argp);
        case CCISS_GETHEARTBEAT:
-               {
-                       Heartbeat_type heartbeat;
-
-                       if (!arg)
-                               return -EINVAL;
-                       heartbeat = readl(&h->cfgtable->HeartBeat);
-                       if (copy_to_user
-                           (argp, &heartbeat, sizeof(Heartbeat_type)))
-                               return -EFAULT;
-                       return 0;
-               }
+               return cciss_getheartbeat(h, argp);
        case CCISS_GETBUSTYPES:
-               {
-                       BusTypes_type BusTypes;
-
-                       if (!arg)
-                               return -EINVAL;
-                       BusTypes = readl(&h->cfgtable->BusTypes);
-                       if (copy_to_user
-                           (argp, &BusTypes, sizeof(BusTypes_type)))
-                               return -EFAULT;
-                       return 0;
-               }
+               return cciss_getbustypes(h, argp);
        case CCISS_GETFIRMVER:
                {
                        FirmwareVer_type firmware;