scsi: mpt3sas: Replace unnecessary dynamic allocation with a static one
[linux-2.6-microblaze.git] / drivers / scsi / mpt3sas / mpt3sas_ctl.c
index c8a0ce1..e7582fb 100644 (file)
@@ -454,7 +454,7 @@ out:
 }
 
 /**
- * mpt3sas_ctl_reset_handler - reset callback handler (for ctl)
+ * mpt3sas_ctl_pre_reset_handler - reset callback handler (for ctl)
  * @ioc: per adapter object
  *
  * The handler for doing any required cleanup or initialization.
@@ -479,12 +479,14 @@ void mpt3sas_ctl_pre_reset_handler(struct MPT3SAS_ADAPTER *ioc)
                ioc_info(ioc,
                    "%s: Releasing the trace buffer due to adapter reset.",
                    __func__);
+               ioc->htb_rel.buffer_rel_condition =
+                   MPT3_DIAG_BUFFER_REL_TRIGGER;
                mpt3sas_send_diag_release(ioc, i, &issue_reset);
        }
 }
 
 /**
- * mpt3sas_ctl_reset_handler - clears outstanding ioctl cmd.
+ * mpt3sas_ctl_clear_outstanding_ioctls - clears outstanding ioctl cmd.
  * @ioc: per adapter object
  *
  * The handler for doing any required cleanup or initialization.
@@ -501,7 +503,7 @@ void mpt3sas_ctl_clear_outstanding_ioctls(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
- * mpt3sas_ctl_reset_handler - reset callback handler (for ctl)
+ * mpt3sas_ctl_reset_done_handler - reset callback handler (for ctl)
  * @ioc: per adapter object
  *
  * The handler for doing any required cleanup or initialization.
@@ -1334,6 +1336,7 @@ _ctl_do_reset(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
        dctlprintk(ioc, ioc_info(ioc, "%s: enter\n",
                                 __func__));
 
+       ioc->reset_from_user = 1;
        retval = mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
        ioc_info(ioc,
            "Ioctl: host reset: %s\n", ((!retval) ? "SUCCESS" : "FAILED"));
@@ -1687,6 +1690,9 @@ _ctl_diag_register_2(struct MPT3SAS_ADAPTER *ioc,
        request_data = ioc->diag_buffer[buffer_type];
        request_data_sz = diag_register->requested_buffer_size;
        ioc->unique_id[buffer_type] = diag_register->unique_id;
+       /* Reset ioc variables used for additional query commands */
+       ioc->reset_from_user = 0;
+       memset(&ioc->htb_rel, 0, sizeof(struct htb_rel_query));
        ioc->diag_buffer_status[buffer_type] &=
            MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED;
        memcpy(ioc->product_specific[buffer_type],
@@ -2469,7 +2475,61 @@ _ctl_diag_read_buffer(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
        return rc;
 }
 
+/**
+ * _ctl_addnl_diag_query - query relevant info associated with diag buffers
+ * @ioc: per adapter object
+ * @arg: user space buffer containing ioctl content
+ *
+ * The application will send only unique_id.  Driver will
+ * inspect unique_id first, if valid, fill the details related to cause
+ * for diag buffer release.
+ */
+static long
+_ctl_addnl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
+{
+       struct mpt3_addnl_diag_query karg;
+       u32 buffer_type = 0;
 
+       if (copy_from_user(&karg, arg, sizeof(karg))) {
+               pr_err("%s: failure at %s:%d/%s()!\n",
+                   ioc->name, __FILE__, __LINE__, __func__);
+               return -EFAULT;
+       }
+       dctlprintk(ioc, ioc_info(ioc, "%s\n",  __func__));
+       if (karg.unique_id == 0) {
+               ioc_err(ioc, "%s: unique_id is(0x%08x)\n",
+                   __func__, karg.unique_id);
+               return -EPERM;
+       }
+       buffer_type = _ctl_diag_get_bufftype(ioc, karg.unique_id);
+       if (buffer_type == MPT3_DIAG_UID_NOT_FOUND) {
+               ioc_err(ioc, "%s: buffer with unique_id(0x%08x) not found\n",
+                   __func__, karg.unique_id);
+               return -EPERM;
+       }
+       memset(&karg.buffer_rel_condition, 0, sizeof(struct htb_rel_query));
+       if ((ioc->diag_buffer_status[buffer_type] &
+           MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) {
+               ioc_info(ioc, "%s: buffer_type(0x%02x) is not registered\n",
+                   __func__, buffer_type);
+               goto out;
+       }
+       if ((ioc->diag_buffer_status[buffer_type] &
+           MPT3_DIAG_BUFFER_IS_RELEASED) == 0) {
+               ioc_err(ioc, "%s: buffer_type(0x%02x) is not released\n",
+                   __func__, buffer_type);
+               return -EPERM;
+       }
+       memcpy(&karg.buffer_rel_condition, &ioc->htb_rel,
+           sizeof(struct  htb_rel_query));
+out:
+       if (copy_to_user(arg, &karg, sizeof(struct mpt3_addnl_diag_query))) {
+               ioc_err(ioc, "%s: unable to write mpt3_addnl_diag_query data @ %p\n",
+                   __func__, arg);
+               return -EFAULT;
+       }
+       return 0;
+}
 
 #ifdef CONFIG_COMPAT
 /**
@@ -2533,7 +2593,7 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
        struct MPT3SAS_ADAPTER *ioc;
        struct mpt3_ioctl_header ioctl_header;
        enum block_state state;
-       long ret = -EINVAL;
+       long ret = -ENOIOCTLCMD;
 
        /* get IOCTL header */
        if (copy_from_user(&ioctl_header, (char __user *)arg,
@@ -2643,6 +2703,10 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
                if (_IOC_SIZE(cmd) == sizeof(struct mpt3_diag_read_buffer))
                        ret = _ctl_diag_read_buffer(ioc, arg);
                break;
+       case MPT3ADDNLDIAGQUERY:
+               if (_IOC_SIZE(cmd) == sizeof(struct mpt3_addnl_diag_query))
+                       ret = _ctl_addnl_diag_query(ioc, arg);
+               break;
        default:
                dctlprintk(ioc,
                           ioc_info(ioc, "unsupported ioctl opcode(0x%08x)\n",
@@ -2695,7 +2759,7 @@ _ctl_mpt2_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 }
 #ifdef CONFIG_COMPAT
 /**
- *ctl_ioctl_compat - main ioctl entry point (compat)
+ * _ctl_ioctl_compat - main ioctl entry point (compat)
  * @file: ?
  * @cmd: ?
  * @arg: ?
@@ -2713,7 +2777,7 @@ _ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg)
 }
 
 /**
- *ctl_mpt2_ioctl_compat - main ioctl entry point (compat)
+ * _ctl_mpt2_ioctl_compat - main ioctl entry point (compat)
  * @file: ?
  * @cmd: ?
  * @arg: ?
@@ -2981,7 +3045,7 @@ fw_queue_depth_show(struct device *cdev, struct device_attribute *attr,
 static DEVICE_ATTR_RO(fw_queue_depth);
 
 /**
- * sas_address_show - sas address
+ * host_sas_address_show - sas address
  * @cdev: pointer to embedded class device
  * @attr: ?
  * @buf: the buffer returned
@@ -3139,7 +3203,7 @@ BRM_status_show(struct device *cdev, struct device_attribute *attr,
 {
        struct Scsi_Host *shost = class_to_shost(cdev);
        struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
-       Mpi2IOUnitPage3_t *io_unit_pg3 = NULL;
+       Mpi2IOUnitPage3_t io_unit_pg3;
        Mpi2ConfigReply_t mpi_reply;
        u16 backup_rail_monitor_status = 0;
        u16 ioc_status;
@@ -3156,17 +3220,10 @@ BRM_status_show(struct device *cdev, struct device_attribute *attr,
        if (ioc->pci_error_recovery || ioc->remove_host)
                goto out;
 
-       /* allocate upto GPIOVal 36 entries */
-       sz = offsetof(Mpi2IOUnitPage3_t, GPIOVal) + (sizeof(u16) * 36);
-       io_unit_pg3 = kzalloc(sz, GFP_KERNEL);
-       if (!io_unit_pg3) {
-               rc = -ENOMEM;
-               ioc_err(ioc, "%s: failed allocating memory for iounit_pg3: (%d) bytes\n",
-                       __func__, sz);
-               goto out;
-       }
+       sz = sizeof(io_unit_pg3);
+       memset(&io_unit_pg3, 0, sz);
 
-       if (mpt3sas_config_get_iounit_pg3(ioc, &mpi_reply, io_unit_pg3, sz) !=
+       if (mpt3sas_config_get_iounit_pg3(ioc, &mpi_reply, &io_unit_pg3, sz) !=
            0) {
                ioc_err(ioc, "%s: failed reading iounit_pg3\n",
                        __func__);
@@ -3182,19 +3239,18 @@ BRM_status_show(struct device *cdev, struct device_attribute *attr,
                goto out;
        }
 
-       if (io_unit_pg3->GPIOCount < 25) {
-               ioc_err(ioc, "%s: iounit_pg3->GPIOCount less than 25 entries, detected (%d) entries\n",
-                       __func__, io_unit_pg3->GPIOCount);
+       if (io_unit_pg3.GPIOCount < 25) {
+               ioc_err(ioc, "%s: iounit_pg3.GPIOCount less than 25 entries, detected (%d) entries\n",
+                       __func__, io_unit_pg3.GPIOCount);
                rc = -EINVAL;
                goto out;
        }
 
        /* BRM status is in bit zero of GPIOVal[24] */
-       backup_rail_monitor_status = le16_to_cpu(io_unit_pg3->GPIOVal[24]);
+       backup_rail_monitor_status = le16_to_cpu(io_unit_pg3.GPIOVal[24]);
        rc = snprintf(buf, PAGE_SIZE, "%d\n", (backup_rail_monitor_status & 1));
 
  out:
-       kfree(io_unit_pg3);
        mutex_unlock(&ioc->pci_access_mutex);
        return rc;
 }
@@ -3425,6 +3481,7 @@ host_trace_buffer_enable_store(struct device *cdev,
                    MPT3_DIAG_BUFFER_IS_RELEASED))
                        goto out;
                ioc_info(ioc, "releasing host trace buffer\n");
+               ioc->htb_rel.buffer_rel_condition = MPT3_DIAG_BUFFER_REL_SYSFS;
                mpt3sas_send_diag_release(ioc, MPI2_DIAG_BUF_TYPE_TRACE,
                    &issue_reset);
        }
@@ -3604,7 +3661,7 @@ static DEVICE_ATTR_RW(diag_trigger_scsi);
 
 
 /**
- * diag_trigger_scsi_show - show the diag_trigger_mpi attribute
+ * diag_trigger_mpi_show - show the diag_trigger_mpi attribute
  * @cdev: pointer to embedded class device
  * @attr: ?
  * @buf: the buffer returned
@@ -3863,7 +3920,7 @@ sas_device_handle_show(struct device *dev, struct device_attribute *attr,
 static DEVICE_ATTR_RO(sas_device_handle);
 
 /**
- * sas_ncq_io_prio_show - send prioritized io commands to device
+ * sas_ncq_prio_enable_show - send prioritized io commands to device
  * @dev: pointer to embedded device
  * @attr: ?
  * @buf: the buffer returned