]> Pileus Git - ~andy/linux/blobdiff - drivers/scsi/mpt2sas/mpt2sas_ctl.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[~andy/linux] / drivers / scsi / mpt2sas / mpt2sas_ctl.c
index 14e473d1fa7b18193e0673d86dec3bfc8737aa84..57d7246339067992792a5b24b81d3cdb0a2e0692 100644 (file)
@@ -3,7 +3,7 @@
  * controllers
  *
  * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.c
- * Copyright (C) 2007-2008  LSI Corporation
+ * Copyright (C) 2007-2009  LSI Corporation
  *  (mailto:DL-MPTFusionLinux@lsi.com)
  *
  * This program is free software; you can redistribute it and/or
@@ -219,23 +219,25 @@ _ctl_display_some_debug(struct MPT2SAS_ADAPTER *ioc, u16 smid,
  * mpt2sas_ctl_done - ctl module completion routine
  * @ioc: per adapter object
  * @smid: system request message index
- * @VF_ID: virtual function id
+ * @msix_index: MSIX table index supplied by the OS
  * @reply: reply message frame(lower 32bit addr)
  * Context: none.
  *
  * The callback handler when using ioc->ctl_cb_idx.
  *
- * Return nothing.
+ * Return 1 meaning mf should be freed from _base_interrupt
+ *        0 means the mf is freed from this function.
  */
-void
-mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
+u8
+mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
+       u32 reply)
 {
        MPI2DefaultReply_t *mpi_reply;
 
        if (ioc->ctl_cmds.status == MPT2_CMD_NOT_USED)
-               return;
+               return 1;
        if (ioc->ctl_cmds.smid != smid)
-               return;
+               return 1;
        ioc->ctl_cmds.status |= MPT2_CMD_COMPLETE;
        mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
        if (mpi_reply) {
@@ -247,6 +249,7 @@ mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
 #endif
        ioc->ctl_cmds.status &= ~MPT2_CMD_PENDING;
        complete(&ioc->ctl_cmds.done);
+       return 1;
 }
 
 /**
@@ -328,22 +331,25 @@ mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc,
 /**
  * mpt2sas_ctl_event_callback - firmware event handler (called at ISR time)
  * @ioc: per adapter object
- * @VF_ID: virtual function id
+ * @msix_index: MSIX table index supplied by the OS
  * @reply: reply message frame(lower 32bit addr)
  * Context: interrupt.
  *
  * This function merely adds a new work task into ioc->firmware_event_thread.
  * The tasks are worked from _firmware_event_work in user context.
  *
- * Return nothing.
+ * Return 1 meaning mf should be freed from _base_interrupt
+ *        0 means the mf is freed from this function.
  */
-void
-mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply)
+u8
+mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
+       u32 reply)
 {
        Mpi2EventNotificationReply_t *mpi_reply;
 
        mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
        mpt2sas_ctl_add_to_event_log(ioc, mpi_reply);
+       return 1;
 }
 
 /**
@@ -507,7 +513,7 @@ _ctl_set_task_mid(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command *karg,
 
        handle = le16_to_cpu(tm_request->DevHandle);
        spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
-       for (i = ioc->request_depth; i && !found; i--) {
+       for (i = ioc->scsiio_depth; i && !found; i--) {
                scmd = ioc->scsi_lookup[i - 1].scmd;
                if (scmd == NULL || scmd->device == NULL ||
                    scmd->device->hostdata == NULL)
@@ -614,7 +620,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
                printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
                    ioc->name, __func__);
 
-       smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx);
+       smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->ctl_cb_idx, NULL);
        if (!smid) {
                printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
                    ioc->name, __func__);
@@ -737,7 +743,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
                    (u32)mpt2sas_base_get_sense_buffer_dma(ioc, smid);
                priv_sense = mpt2sas_base_get_sense_buffer(ioc, smid);
                memset(priv_sense, 0, SCSI_SENSE_BUFFERSIZE);
-               mpt2sas_base_put_smid_scsi_io(ioc, smid, 0,
+               mpt2sas_base_put_smid_scsi_io(ioc, smid,
                    le16_to_cpu(mpi_request->FunctionDependent1));
                break;
        }
@@ -759,8 +765,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
                mutex_lock(&ioc->tm_cmds.mutex);
                mpt2sas_scsih_set_tm_flag(ioc, le16_to_cpu(
                    tm_request->DevHandle));
-               mpt2sas_base_put_smid_hi_priority(ioc, smid,
-                   mpi_request->VF_ID);
+               mpt2sas_base_put_smid_hi_priority(ioc, smid);
                break;
        }
        case MPI2_FUNCTION_SMP_PASSTHROUGH:
@@ -781,7 +786,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
                        ioc->ioc_link_reset_in_progress = 1;
                        ioc->ignore_loginfos = 1;
                }
-               mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID);
+               mpt2sas_base_put_smid_default(ioc, smid);
                break;
        }
        case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL:
@@ -795,11 +800,11 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
                        ioc->ioc_link_reset_in_progress = 1;
                        ioc->ignore_loginfos = 1;
                }
-               mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID);
+               mpt2sas_base_put_smid_default(ioc, smid);
                break;
        }
        default:
-               mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID);
+               mpt2sas_base_put_smid_default(ioc, smid);
                break;
        }
 
@@ -807,6 +812,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
                timeout = MPT2_IOCTL_DEFAULT_TIMEOUT;
        else
                timeout = karg.timeout;
+       init_completion(&ioc->ctl_cmds.done);
        timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done,
            timeout*HZ);
        if (mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) {
@@ -1371,6 +1377,8 @@ _ctl_diag_register(void __user *arg, enum block_state state)
        mpi_request->Flags = cpu_to_le32(karg.diagnostic_flags);
        mpi_request->BufferAddress = cpu_to_le64(request_data_dma);
        mpi_request->BufferLength = cpu_to_le32(request_data_sz);
+       mpi_request->VF_ID = 0; /* TODO */
+       mpi_request->VP_ID = 0;
 
        dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: diag_buffer(0x%p), "
            "dma(0x%llx), sz(%d)\n", ioc->name, __func__, request_data,
@@ -1380,7 +1388,8 @@ _ctl_diag_register(void __user *arg, enum block_state state)
                mpi_request->ProductSpecific[i] =
                        cpu_to_le32(ioc->product_specific[buffer_type][i]);
 
-       mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID);
+       mpt2sas_base_put_smid_default(ioc, smid);
+       init_completion(&ioc->ctl_cmds.done);
        timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done,
            MPT2_IOCTL_DEFAULT_TIMEOUT*HZ);
 
@@ -1643,8 +1652,11 @@ _ctl_send_release(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type, u8 *issue_reset)
 
        mpi_request->Function = MPI2_FUNCTION_DIAG_RELEASE;
        mpi_request->BufferType = buffer_type;
+       mpi_request->VF_ID = 0; /* TODO */
+       mpi_request->VP_ID = 0;
 
-       mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID);
+       mpt2sas_base_put_smid_default(ioc, smid);
+       init_completion(&ioc->ctl_cmds.done);
        timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done,
            MPT2_IOCTL_DEFAULT_TIMEOUT*HZ);
 
@@ -1902,8 +1914,11 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state)
        for (i = 0; i < MPT2_PRODUCT_SPECIFIC_DWORDS; i++)
                mpi_request->ProductSpecific[i] =
                        cpu_to_le32(ioc->product_specific[buffer_type][i]);
+       mpi_request->VF_ID = 0; /* TODO */
+       mpi_request->VP_ID = 0;
 
-       mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID);
+       mpt2sas_base_put_smid_default(ioc, smid);
+       init_completion(&ioc->ctl_cmds.done);
        timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done,
            MPT2_IOCTL_DEFAULT_TIMEOUT*HZ);
 
@@ -1963,7 +1978,6 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg)
 {
        enum block_state state;
        long ret = -EINVAL;
-       unsigned long flags;
 
        state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING :
            BLOCKING;
@@ -1989,13 +2003,8 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg)
                    !ioc)
                        return -ENODEV;
 
-               spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-               if (ioc->shost_recovery) {
-                       spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
-                           flags);
+               if (ioc->shost_recovery)
                        return -EAGAIN;
-               }
-               spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
 
                if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_command)) {
                        uarg = arg;
@@ -2075,6 +2084,7 @@ static long
 _ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        long ret;
+
        lock_kernel();
        ret = _ctl_ioctl_main(file, cmd, (void __user *)arg);
        unlock_kernel();
@@ -2098,7 +2108,6 @@ _ctl_compat_mpt_command(struct file *file, unsigned cmd, unsigned long arg)
        struct mpt2_ioctl_command karg;
        struct MPT2SAS_ADAPTER *ioc;
        enum block_state state;
-       unsigned long flags;
 
        if (_IOC_SIZE(cmd) != sizeof(struct mpt2_ioctl_command32))
                return -EINVAL;
@@ -2113,13 +2122,8 @@ _ctl_compat_mpt_command(struct file *file, unsigned cmd, unsigned long arg)
        if (_ctl_verify_adapter(karg32.hdr.ioc_number, &ioc) == -1 || !ioc)
                return -ENODEV;
 
-       spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-       if (ioc->shost_recovery) {
-               spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
-                   flags);
+       if (ioc->shost_recovery)
                return -EAGAIN;
-       }
-       spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
 
        memset(&karg, 0, sizeof(struct mpt2_ioctl_command));
        karg.hdr.ioc_number = karg32.hdr.ioc_number;
@@ -2155,6 +2159,7 @@ static long
 _ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg)
 {
        long ret;
+
        lock_kernel();
        if (cmd == MPT2COMMAND32)
                ret = _ctl_compat_mpt_command(file, cmd, arg);