linux/drivers/message/fusion/mptctl.c
<<
>>
Prefs
   1/*
   2 *  linux/drivers/message/fusion/mptctl.c
   3 *      mpt Ioctl driver.
   4 *      For use with LSI PCI chip/adapters
   5 *      running LSI Fusion MPT (Message Passing Technology) firmware.
   6 *
   7 *  Copyright (c) 1999-2008 LSI Corporation
   8 *  (mailto:DL-MPTFusionLinux@lsi.com)
   9 *
  10 */
  11/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  12/*
  13    This program is free software; you can redistribute it and/or modify
  14    it under the terms of the GNU General Public License as published by
  15    the Free Software Foundation; version 2 of the License.
  16
  17    This program is distributed in the hope that it will be useful,
  18    but WITHOUT ANY WARRANTY; without even the implied warranty of
  19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20    GNU General Public License for more details.
  21
  22    NO WARRANTY
  23    THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
  24    CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
  25    LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
  26    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
  27    solely responsible for determining the appropriateness of using and
  28    distributing the Program and assumes all risks associated with its
  29    exercise of rights under this Agreement, including but not limited to
  30    the risks and costs of program errors, damage to or loss of data,
  31    programs or equipment, and unavailability or interruption of operations.
  32
  33    DISCLAIMER OF LIABILITY
  34    NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
  35    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36    DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
  37    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  38    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  39    USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
  40    HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
  41
  42    You should have received a copy of the GNU General Public License
  43    along with this program; if not, write to the Free Software
  44    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  45*/
  46/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  47
  48#include <linux/kernel.h>
  49#include <linux/module.h>
  50#include <linux/errno.h>
  51#include <linux/init.h>
  52#include <linux/slab.h>
  53#include <linux/types.h>
  54#include <linux/pci.h>
  55#include <linux/delay.h>        /* for mdelay */
  56#include <linux/miscdevice.h>
  57#include <linux/mutex.h>
  58#include <linux/compat.h>
  59
  60#include <asm/io.h>
  61#include <asm/uaccess.h>
  62
  63#include <scsi/scsi.h>
  64#include <scsi/scsi_cmnd.h>
  65#include <scsi/scsi_device.h>
  66#include <scsi/scsi_host.h>
  67#include <scsi/scsi_tcq.h>
  68
  69#define COPYRIGHT       "Copyright (c) 1999-2008 LSI Corporation"
  70#define MODULEAUTHOR    "LSI Corporation"
  71#include "mptbase.h"
  72#include "mptctl.h"
  73
  74/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  75#define my_NAME         "Fusion MPT misc device (ioctl) driver"
  76#define my_VERSION      MPT_LINUX_VERSION_COMMON
  77#define MYNAM           "mptctl"
  78
  79MODULE_AUTHOR(MODULEAUTHOR);
  80MODULE_DESCRIPTION(my_NAME);
  81MODULE_LICENSE("GPL");
  82MODULE_VERSION(my_VERSION);
  83
  84/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  85
  86static DEFINE_MUTEX(mpctl_mutex);
  87static u8 mptctl_id = MPT_MAX_PROTOCOL_DRIVERS;
  88static u8 mptctl_taskmgmt_id = MPT_MAX_PROTOCOL_DRIVERS;
  89
  90static DECLARE_WAIT_QUEUE_HEAD ( mptctl_wait );
  91
  92/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  93
  94struct buflist {
  95        u8      *kptr;
  96        int      len;
  97};
  98
  99/*
 100 * Function prototypes. Called from OS entry point mptctl_ioctl.
 101 * arg contents specific to function.
 102 */
 103static int mptctl_fw_download(unsigned long arg);
 104static int mptctl_getiocinfo(unsigned long arg, unsigned int cmd);
 105static int mptctl_gettargetinfo(unsigned long arg);
 106static int mptctl_readtest(unsigned long arg);
 107static int mptctl_mpt_command(unsigned long arg);
 108static int mptctl_eventquery(unsigned long arg);
 109static int mptctl_eventenable(unsigned long arg);
 110static int mptctl_eventreport(unsigned long arg);
 111static int mptctl_replace_fw(unsigned long arg);
 112
 113static int mptctl_do_reset(unsigned long arg);
 114static int mptctl_hp_hostinfo(unsigned long arg, unsigned int cmd);
 115static int mptctl_hp_targetinfo(unsigned long arg);
 116
 117static int  mptctl_probe(struct pci_dev *, const struct pci_device_id *);
 118static void mptctl_remove(struct pci_dev *);
 119
 120#ifdef CONFIG_COMPAT
 121static long compat_mpctl_ioctl(struct file *f, unsigned cmd, unsigned long arg);
 122#endif
 123/*
 124 * Private function calls.
 125 */
 126static int mptctl_do_mpt_command(struct mpt_ioctl_command karg, void __user *mfPtr);
 127static int mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen);
 128static MptSge_t *kbuf_alloc_2_sgl(int bytes, u32 dir, int sge_offset, int *frags,
 129                struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc);
 130static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma,
 131                struct buflist *buflist, MPT_ADAPTER *ioc);
 132
 133/*
 134 * Reset Handler cleanup function
 135 */
 136static int  mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);
 137
 138/*
 139 * Event Handler function
 140 */
 141static int mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
 142static struct fasync_struct *async_queue=NULL;
 143
 144/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 145/*
 146 * Scatter gather list (SGL) sizes and limits...
 147 */
 148//#define MAX_SCSI_FRAGS        9
 149#define MAX_FRAGS_SPILL1        9
 150#define MAX_FRAGS_SPILL2        15
 151#define FRAGS_PER_BUCKET        (MAX_FRAGS_SPILL2 + 1)
 152
 153//#define MAX_CHAIN_FRAGS       64
 154//#define MAX_CHAIN_FRAGS       (15+15+15+16)
 155#define MAX_CHAIN_FRAGS         (4 * MAX_FRAGS_SPILL2 + 1)
 156
 157//  Define max sg LIST bytes ( == (#frags + #chains) * 8 bytes each)
 158//  Works out to: 592d bytes!     (9+1)*8 + 4*(15+1)*8
 159//                  ^----------------- 80 + 512
 160#define MAX_SGL_BYTES           ((MAX_FRAGS_SPILL1 + 1 + (4 * FRAGS_PER_BUCKET)) * 8)
 161
 162/* linux only seems to ever give 128kB MAX contiguous (GFP_USER) mem bytes */
 163#define MAX_KMALLOC_SZ          (128*1024)
 164
 165#define MPT_IOCTL_DEFAULT_TIMEOUT 10    /* Default timeout value (seconds) */
 166
 167/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 168/**
 169 *      mptctl_syscall_down - Down the MPT adapter syscall semaphore.
 170 *      @ioc: Pointer to MPT adapter
 171 *      @nonblock: boolean, non-zero if O_NONBLOCK is set
 172 *
 173 *      All of the ioctl commands can potentially sleep, which is illegal
 174 *      with a spinlock held, thus we perform mutual exclusion here.
 175 *
 176 *      Returns negative errno on error, or zero for success.
 177 */
 178static inline int
 179mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock)
 180{
 181        int rc = 0;
 182
 183        if (nonblock) {
 184                if (!mutex_trylock(&ioc->ioctl_cmds.mutex))
 185                        rc = -EAGAIN;
 186        } else {
 187                if (mutex_lock_interruptible(&ioc->ioctl_cmds.mutex))
 188                        rc = -ERESTARTSYS;
 189        }
 190        return rc;
 191}
 192
 193/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 194/*
 195 *  This is the callback for any message we have posted. The message itself
 196 *  will be returned to the message pool when we return from the IRQ
 197 *
 198 *  This runs in irq context so be short and sweet.
 199 */
 200static int
 201mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
 202{
 203        char    *sense_data;
 204        int     req_index;
 205        int     sz;
 206
 207        if (!req)
 208                return 0;
 209
 210        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "completing mpi function "
 211            "(0x%02X), req=%p, reply=%p\n", ioc->name,  req->u.hdr.Function,
 212            req, reply));
 213
 214        /*
 215         * Handling continuation of the same reply. Processing the first
 216         * reply, and eating the other replys that come later.
 217         */
 218        if (ioc->ioctl_cmds.msg_context != req->u.hdr.MsgContext)
 219                goto out_continuation;
 220
 221        ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
 222
 223        if (!reply)
 224                goto out;
 225
 226        ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
 227        sz = min(ioc->reply_sz, 4*reply->u.reply.MsgLength);
 228        memcpy(ioc->ioctl_cmds.reply, reply, sz);
 229
 230        if (reply->u.reply.IOCStatus || reply->u.reply.IOCLogInfo)
 231                dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 232                    "iocstatus (0x%04X), loginfo (0x%08X)\n", ioc->name,
 233                    le16_to_cpu(reply->u.reply.IOCStatus),
 234                    le32_to_cpu(reply->u.reply.IOCLogInfo)));
 235
 236        if ((req->u.hdr.Function == MPI_FUNCTION_SCSI_IO_REQUEST) ||
 237                (req->u.hdr.Function ==
 238                 MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
 239
 240                if (reply->u.sreply.SCSIStatus || reply->u.sreply.SCSIState)
 241                        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 242                        "scsi_status (0x%02x), scsi_state (0x%02x), "
 243                        "tag = (0x%04x), transfer_count (0x%08x)\n", ioc->name,
 244                        reply->u.sreply.SCSIStatus,
 245                        reply->u.sreply.SCSIState,
 246                        le16_to_cpu(reply->u.sreply.TaskTag),
 247                        le32_to_cpu(reply->u.sreply.TransferCount)));
 248
 249                if (reply->u.sreply.SCSIState &
 250                        MPI_SCSI_STATE_AUTOSENSE_VALID) {
 251                        sz = req->u.scsireq.SenseBufferLength;
 252                        req_index =
 253                            le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
 254                        sense_data = ((u8 *)ioc->sense_buf_pool +
 255                             (req_index * MPT_SENSE_BUFFER_ALLOC));
 256                        memcpy(ioc->ioctl_cmds.sense, sense_data, sz);
 257                        ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_SENSE_VALID;
 258                }
 259        }
 260
 261 out:
 262        /* We are done, issue wake up
 263         */
 264        if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_PENDING) {
 265                if (req->u.hdr.Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
 266                        mpt_clear_taskmgmt_in_progress_flag(ioc);
 267                        ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
 268                        complete(&ioc->ioctl_cmds.done);
 269                        if (ioc->bus_type == SAS)
 270                                ioc->schedule_target_reset(ioc);
 271                } else {
 272                        ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
 273                        complete(&ioc->ioctl_cmds.done);
 274                }
 275        }
 276
 277 out_continuation:
 278        if (reply && (reply->u.reply.MsgFlags &
 279            MPI_MSGFLAGS_CONTINUATION_REPLY))
 280                return 0;
 281        return 1;
 282}
 283
 284
 285static int
 286mptctl_taskmgmt_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 287{
 288        if (!mf)
 289                return 0;
 290
 291        dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 292                "TaskMgmt completed (mf=%p, mr=%p)\n",
 293                ioc->name, mf, mr));
 294
 295        ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
 296
 297        if (!mr)
 298                goto out;
 299
 300        ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
 301        memcpy(ioc->taskmgmt_cmds.reply, mr,
 302            min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
 303 out:
 304        if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
 305                mpt_clear_taskmgmt_in_progress_flag(ioc);
 306                ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
 307                complete(&ioc->taskmgmt_cmds.done);
 308                if (ioc->bus_type == SAS)
 309                        ioc->schedule_target_reset(ioc);
 310                return 1;
 311        }
 312        return 0;
 313}
 314
 315static int
 316mptctl_do_taskmgmt(MPT_ADAPTER *ioc, u8 tm_type, u8 bus_id, u8 target_id)
 317{
 318        MPT_FRAME_HDR   *mf;
 319        SCSITaskMgmt_t  *pScsiTm;
 320        SCSITaskMgmtReply_t *pScsiTmReply;
 321        int              ii;
 322        int              retval;
 323        unsigned long    timeout;
 324        unsigned long    time_count;
 325        u16              iocstatus;
 326
 327
 328        mutex_lock(&ioc->taskmgmt_cmds.mutex);
 329        if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
 330                mutex_unlock(&ioc->taskmgmt_cmds.mutex);
 331                return -EPERM;
 332        }
 333
 334        retval = 0;
 335
 336        mf = mpt_get_msg_frame(mptctl_taskmgmt_id, ioc);
 337        if (mf == NULL) {
 338                dtmprintk(ioc,
 339                        printk(MYIOC_s_WARN_FMT "TaskMgmt, no msg frames!!\n",
 340                        ioc->name));
 341                mpt_clear_taskmgmt_in_progress_flag(ioc);
 342                retval = -ENOMEM;
 343                goto tm_done;
 344        }
 345
 346        dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
 347                ioc->name, mf));
 348
 349        pScsiTm = (SCSITaskMgmt_t *) mf;
 350        memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t));
 351        pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
 352        pScsiTm->TaskType = tm_type;
 353        if ((tm_type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) &&
 354                (ioc->bus_type == FC))
 355                pScsiTm->MsgFlags =
 356                                MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
 357        pScsiTm->TargetID = target_id;
 358        pScsiTm->Bus = bus_id;
 359        pScsiTm->ChainOffset = 0;
 360        pScsiTm->Reserved = 0;
 361        pScsiTm->Reserved1 = 0;
 362        pScsiTm->TaskMsgContext = 0;
 363        for (ii= 0; ii < 8; ii++)
 364                pScsiTm->LUN[ii] = 0;
 365        for (ii=0; ii < 7; ii++)
 366                pScsiTm->Reserved2[ii] = 0;
 367
 368        switch (ioc->bus_type) {
 369        case FC:
 370                timeout = 40;
 371                break;
 372        case SAS:
 373                timeout = 30;
 374                break;
 375        case SPI:
 376                default:
 377                timeout = 10;
 378                break;
 379        }
 380
 381        dtmprintk(ioc,
 382                printk(MYIOC_s_DEBUG_FMT "TaskMgmt type=%d timeout=%ld\n",
 383                ioc->name, tm_type, timeout));
 384
 385        INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
 386        time_count = jiffies;
 387        if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
 388            (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
 389                mpt_put_msg_frame_hi_pri(mptctl_taskmgmt_id, ioc, mf);
 390        else {
 391                retval = mpt_send_handshake_request(mptctl_taskmgmt_id, ioc,
 392                    sizeof(SCSITaskMgmt_t), (u32 *)pScsiTm, CAN_SLEEP);
 393                if (retval != 0) {
 394                        dfailprintk(ioc,
 395                                printk(MYIOC_s_ERR_FMT
 396                                "TaskMgmt send_handshake FAILED!"
 397                                " (ioc %p, mf %p, rc=%d) \n", ioc->name,
 398                                ioc, mf, retval));
 399                        mpt_free_msg_frame(ioc, mf);
 400                        mpt_clear_taskmgmt_in_progress_flag(ioc);
 401                        goto tm_done;
 402                }
 403        }
 404
 405        /* Now wait for the command to complete */
 406        ii = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done, timeout*HZ);
 407
 408        if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
 409                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 410                    "TaskMgmt failed\n", ioc->name));
 411                mpt_free_msg_frame(ioc, mf);
 412                mpt_clear_taskmgmt_in_progress_flag(ioc);
 413                if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
 414                        retval = 0;
 415                else
 416                        retval = -1; /* return failure */
 417                goto tm_done;
 418        }
 419
 420        if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
 421                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 422                    "TaskMgmt failed\n", ioc->name));
 423                retval = -1; /* return failure */
 424                goto tm_done;
 425        }
 426
 427        pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply;
 428        dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 429            "TaskMgmt fw_channel = %d, fw_id = %d, task_type=0x%02X, "
 430            "iocstatus=0x%04X\n\tloginfo=0x%08X, response_code=0x%02X, "
 431            "term_cmnds=%d\n", ioc->name, pScsiTmReply->Bus,
 432            pScsiTmReply->TargetID, tm_type,
 433            le16_to_cpu(pScsiTmReply->IOCStatus),
 434            le32_to_cpu(pScsiTmReply->IOCLogInfo),
 435            pScsiTmReply->ResponseCode,
 436            le32_to_cpu(pScsiTmReply->TerminationCount)));
 437
 438        iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
 439
 440        if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
 441           iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED ||
 442           iocstatus == MPI_IOCSTATUS_SUCCESS)
 443                retval = 0;
 444        else {
 445                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 446                    "TaskMgmt failed\n", ioc->name));
 447                retval = -1; /* return failure */
 448        }
 449
 450 tm_done:
 451        mutex_unlock(&ioc->taskmgmt_cmds.mutex);
 452        CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
 453        return retval;
 454}
 455
 456/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 457/* mptctl_timeout_expired
 458 *
 459 * Expecting an interrupt, however timed out.
 460 *
 461 */
 462static void
 463mptctl_timeout_expired(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
 464{
 465        unsigned long flags;
 466        int ret_val = -1;
 467        SCSIIORequest_t *scsi_req = (SCSIIORequest_t *) mf;
 468        u8 function = mf->u.hdr.Function;
 469
 470        dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": %s\n",
 471                ioc->name, __func__));
 472
 473        if (mpt_fwfault_debug)
 474                mpt_halt_firmware(ioc);
 475
 476        spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
 477        if (ioc->ioc_reset_in_progress) {
 478                spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
 479                CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status)
 480                mpt_free_msg_frame(ioc, mf);
 481                return;
 482        }
 483        spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
 484
 485
 486        CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status)
 487
 488        if (ioc->bus_type == SAS) {
 489                if (function == MPI_FUNCTION_SCSI_IO_REQUEST)
 490                        ret_val = mptctl_do_taskmgmt(ioc,
 491                                MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
 492                                scsi_req->Bus, scsi_req->TargetID);
 493                else if (function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)
 494                        ret_val = mptctl_do_taskmgmt(ioc,
 495                                MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
 496                                scsi_req->Bus, 0);
 497                if (!ret_val)
 498                        return;
 499        } else {
 500                if ((function == MPI_FUNCTION_SCSI_IO_REQUEST) ||
 501                        (function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH))
 502                        ret_val = mptctl_do_taskmgmt(ioc,
 503                                MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
 504                                scsi_req->Bus, 0);
 505                if (!ret_val)
 506                        return;
 507        }
 508
 509        dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling Reset! \n",
 510                 ioc->name));
 511        mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
 512        mpt_free_msg_frame(ioc, mf);
 513}
 514
 515
 516/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 517/* mptctl_ioc_reset
 518 *
 519 * Clean-up functionality. Used only if there has been a
 520 * reload of the FW due.
 521 *
 522 */
 523static int
 524mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
 525{
 526        switch(reset_phase) {
 527        case MPT_IOC_SETUP_RESET:
 528                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 529                    "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
 530                break;
 531        case MPT_IOC_PRE_RESET:
 532                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 533                    "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
 534                break;
 535        case MPT_IOC_POST_RESET:
 536                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 537                    "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
 538                if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_PENDING) {
 539                        ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_DID_IOCRESET;
 540                        complete(&ioc->ioctl_cmds.done);
 541                }
 542                break;
 543        default:
 544                break;
 545        }
 546
 547        return 1;
 548}
 549
 550/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 551/* ASYNC Event Notification Support */
 552static int
 553mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
 554{
 555        u8 event;
 556
 557        event = le32_to_cpu(pEvReply->Event) & 0xFF;
 558
 559        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s() called\n",
 560            ioc->name, __func__));
 561        if(async_queue == NULL)
 562                return 1;
 563
 564        /* Raise SIGIO for persistent events.
 565         * TODO - this define is not in MPI spec yet,
 566         * but they plan to set it to 0x21
 567         */
 568         if (event == 0x21 ) {
 569                ioc->aen_event_read_flag=1;
 570                dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Raised SIGIO to application\n",
 571                    ioc->name));
 572                devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 573                    "Raised SIGIO to application\n", ioc->name));
 574                kill_fasync(&async_queue, SIGIO, POLL_IN);
 575                return 1;
 576         }
 577
 578        /* This flag is set after SIGIO was raised, and
 579         * remains set until the application has read
 580         * the event log via ioctl=MPTEVENTREPORT
 581         */
 582        if(ioc->aen_event_read_flag)
 583                return 1;
 584
 585        /* Signal only for the events that are
 586         * requested for by the application
 587         */
 588        if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
 589                ioc->aen_event_read_flag=1;
 590                dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 591                    "Raised SIGIO to application\n", ioc->name));
 592                devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 593                    "Raised SIGIO to application\n", ioc->name));
 594                kill_fasync(&async_queue, SIGIO, POLL_IN);
 595        }
 596        return 1;
 597}
 598
 599static int
 600mptctl_release(struct inode *inode, struct file *filep)
 601{
 602        fasync_helper(-1, filep, 0, &async_queue);
 603        return 0;
 604}
 605
 606static int
 607mptctl_fasync(int fd, struct file *filep, int mode)
 608{
 609        MPT_ADAPTER     *ioc;
 610        int ret;
 611
 612        mutex_lock(&mpctl_mutex);
 613        list_for_each_entry(ioc, &ioc_list, list)
 614                ioc->aen_event_read_flag=0;
 615
 616        ret = fasync_helper(fd, filep, mode, &async_queue);
 617        mutex_unlock(&mpctl_mutex);
 618        return ret;
 619}
 620
 621/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 622/*
 623 *  MPT ioctl handler
 624 *  cmd - specify the particular IOCTL command to be issued
 625 *  arg - data specific to the command. Must not be null.
 626 */
 627static long
 628__mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 629{
 630        mpt_ioctl_header __user *uhdr = (void __user *) arg;
 631        mpt_ioctl_header         khdr;
 632        int iocnum;
 633        unsigned iocnumX;
 634        int nonblock = (file->f_flags & O_NONBLOCK);
 635        int ret;
 636        MPT_ADAPTER *iocp = NULL;
 637
 638        if (copy_from_user(&khdr, uhdr, sizeof(khdr))) {
 639                printk(KERN_ERR MYNAM "%s::mptctl_ioctl() @%d - "
 640                                "Unable to copy mpt_ioctl_header data @ %p\n",
 641                                __FILE__, __LINE__, uhdr);
 642                return -EFAULT;
 643        }
 644        ret = -ENXIO;                           /* (-6) No such device or address */
 645
 646        /* Verify intended MPT adapter - set iocnum and the adapter
 647         * pointer (iocp)
 648         */
 649        iocnumX = khdr.iocnum & 0xFF;
 650        if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
 651            (iocp == NULL))
 652                return -ENODEV;
 653
 654        if (!iocp->active) {
 655                printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - Controller disabled.\n",
 656                                __FILE__, __LINE__);
 657                return -EFAULT;
 658        }
 659
 660        /* Handle those commands that are just returning
 661         * information stored in the driver.
 662         * These commands should never time out and are unaffected
 663         * by TM and FW reloads.
 664         */
 665        if ((cmd & ~IOCSIZE_MASK) == (MPTIOCINFO & ~IOCSIZE_MASK)) {
 666                return mptctl_getiocinfo(arg, _IOC_SIZE(cmd));
 667        } else if (cmd == MPTTARGETINFO) {
 668                return mptctl_gettargetinfo(arg);
 669        } else if (cmd == MPTTEST) {
 670                return mptctl_readtest(arg);
 671        } else if (cmd == MPTEVENTQUERY) {
 672                return mptctl_eventquery(arg);
 673        } else if (cmd == MPTEVENTENABLE) {
 674                return mptctl_eventenable(arg);
 675        } else if (cmd == MPTEVENTREPORT) {
 676                return mptctl_eventreport(arg);
 677        } else if (cmd == MPTFWREPLACE) {
 678                return mptctl_replace_fw(arg);
 679        }
 680
 681        /* All of these commands require an interrupt or
 682         * are unknown/illegal.
 683         */
 684        if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
 685                return ret;
 686
 687        if (cmd == MPTFWDOWNLOAD)
 688                ret = mptctl_fw_download(arg);
 689        else if (cmd == MPTCOMMAND)
 690                ret = mptctl_mpt_command(arg);
 691        else if (cmd == MPTHARDRESET)
 692                ret = mptctl_do_reset(arg);
 693        else if ((cmd & ~IOCSIZE_MASK) == (HP_GETHOSTINFO & ~IOCSIZE_MASK))
 694                ret = mptctl_hp_hostinfo(arg, _IOC_SIZE(cmd));
 695        else if (cmd == HP_GETTARGETINFO)
 696                ret = mptctl_hp_targetinfo(arg);
 697        else
 698                ret = -EINVAL;
 699
 700        mutex_unlock(&iocp->ioctl_cmds.mutex);
 701
 702        return ret;
 703}
 704
 705static long
 706mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 707{
 708        long ret;
 709        mutex_lock(&mpctl_mutex);
 710        ret = __mptctl_ioctl(file, cmd, arg);
 711        mutex_unlock(&mpctl_mutex);
 712        return ret;
 713}
 714
 715static int mptctl_do_reset(unsigned long arg)
 716{
 717        struct mpt_ioctl_diag_reset __user *urinfo = (void __user *) arg;
 718        struct mpt_ioctl_diag_reset krinfo;
 719        MPT_ADAPTER             *iocp;
 720
 721        if (copy_from_user(&krinfo, urinfo, sizeof(struct mpt_ioctl_diag_reset))) {
 722                printk(KERN_ERR MYNAM "%s@%d::mptctl_do_reset - "
 723                                "Unable to copy mpt_ioctl_diag_reset struct @ %p\n",
 724                                __FILE__, __LINE__, urinfo);
 725                return -EFAULT;
 726        }
 727
 728        if (mpt_verify_adapter(krinfo.hdr.iocnum, &iocp) < 0) {
 729                printk(KERN_DEBUG MYNAM "%s@%d::mptctl_do_reset - ioc%d not found!\n",
 730                                __FILE__, __LINE__, krinfo.hdr.iocnum);
 731                return -ENODEV; /* (-6) No such device or address */
 732        }
 733
 734        dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "mptctl_do_reset called.\n",
 735            iocp->name));
 736
 737        if (mpt_HardResetHandler(iocp, CAN_SLEEP) != 0) {
 738                printk (MYIOC_s_ERR_FMT "%s@%d::mptctl_do_reset - reset failed.\n",
 739                        iocp->name, __FILE__, __LINE__);
 740                return -1;
 741        }
 742
 743        return 0;
 744}
 745
 746/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 747/*
 748 * MPT FW download function.  Cast the arg into the mpt_fw_xfer structure.
 749 * This structure contains: iocnum, firmware length (bytes),
 750 *      pointer to user space memory where the fw image is stored.
 751 *
 752 * Outputs:     None.
 753 * Return:      0 if successful
 754 *              -EFAULT if data unavailable
 755 *              -ENXIO  if no such device
 756 *              -EAGAIN if resource problem
 757 *              -ENOMEM if no memory for SGE
 758 *              -EMLINK if too many chain buffers required
 759 *              -EBADRQC if adapter does not support FW download
 760 *              -EBUSY if adapter is busy
 761 *              -ENOMSG if FW upload returned bad status
 762 */
 763static int
 764mptctl_fw_download(unsigned long arg)
 765{
 766        struct mpt_fw_xfer __user *ufwdl = (void __user *) arg;
 767        struct mpt_fw_xfer       kfwdl;
 768
 769        if (copy_from_user(&kfwdl, ufwdl, sizeof(struct mpt_fw_xfer))) {
 770                printk(KERN_ERR MYNAM "%s@%d::_ioctl_fwdl - "
 771                                "Unable to copy mpt_fw_xfer struct @ %p\n",
 772                                __FILE__, __LINE__, ufwdl);
 773                return -EFAULT;
 774        }
 775
 776        return mptctl_do_fw_download(kfwdl.iocnum, kfwdl.bufp, kfwdl.fwlen);
 777}
 778
 779/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 780/*
 781 * FW Download engine.
 782 * Outputs:     None.
 783 * Return:      0 if successful
 784 *              -EFAULT if data unavailable
 785 *              -ENXIO  if no such device
 786 *              -EAGAIN if resource problem
 787 *              -ENOMEM if no memory for SGE
 788 *              -EMLINK if too many chain buffers required
 789 *              -EBADRQC if adapter does not support FW download
 790 *              -EBUSY if adapter is busy
 791 *              -ENOMSG if FW upload returned bad status
 792 */
 793static int
 794mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
 795{
 796        FWDownload_t            *dlmsg;
 797        MPT_FRAME_HDR           *mf;
 798        MPT_ADAPTER             *iocp;
 799        FWDownloadTCSGE_t       *ptsge;
 800        MptSge_t                *sgl, *sgIn;
 801        char                    *sgOut;
 802        struct buflist          *buflist;
 803        struct buflist          *bl;
 804        dma_addr_t               sgl_dma;
 805        int                      ret;
 806        int                      numfrags = 0;
 807        int                      maxfrags;
 808        int                      n = 0;
 809        u32                      sgdir;
 810        u32                      nib;
 811        int                      fw_bytes_copied = 0;
 812        int                      i;
 813        int                      sge_offset = 0;
 814        u16                      iocstat;
 815        pFWDownloadReply_t       ReplyMsg = NULL;
 816        unsigned long            timeleft;
 817
 818        if (mpt_verify_adapter(ioc, &iocp) < 0) {
 819                printk(KERN_DEBUG MYNAM "ioctl_fwdl - ioc%d not found!\n",
 820                                 ioc);
 821                return -ENODEV; /* (-6) No such device or address */
 822        } else {
 823
 824                /*  Valid device. Get a message frame and construct the FW download message.
 825                */
 826                if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
 827                        return -EAGAIN;
 828        }
 829
 830        dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT
 831            "mptctl_do_fwdl called. mptctl_id = %xh.\n", iocp->name, mptctl_id));
 832        dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.bufp  = %p\n",
 833            iocp->name, ufwbuf));
 834        dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.fwlen = %d\n",
 835            iocp->name, (int)fwlen));
 836        dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.ioc   = %04xh\n",
 837            iocp->name, ioc));
 838
 839        dlmsg = (FWDownload_t*) mf;
 840        ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL;
 841        sgOut = (char *) (ptsge + 1);
 842
 843        /*
 844         * Construct f/w download request
 845         */
 846        dlmsg->ImageType = MPI_FW_DOWNLOAD_ITYPE_FW;
 847        dlmsg->Reserved = 0;
 848        dlmsg->ChainOffset = 0;
 849        dlmsg->Function = MPI_FUNCTION_FW_DOWNLOAD;
 850        dlmsg->Reserved1[0] = dlmsg->Reserved1[1] = dlmsg->Reserved1[2] = 0;
 851        if (iocp->facts.MsgVersion >= MPI_VERSION_01_05)
 852                dlmsg->MsgFlags = MPI_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT;
 853        else
 854                dlmsg->MsgFlags = 0;
 855
 856
 857        /* Set up the Transaction SGE.
 858         */
 859        ptsge->Reserved = 0;
 860        ptsge->ContextSize = 0;
 861        ptsge->DetailsLength = 12;
 862        ptsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
 863        ptsge->Reserved_0100_Checksum = 0;
 864        ptsge->ImageOffset = 0;
 865        ptsge->ImageSize = cpu_to_le32(fwlen);
 866
 867        /* Add the SGL
 868         */
 869
 870        /*
 871         * Need to kmalloc area(s) for holding firmware image bytes.
 872         * But we need to do it piece meal, using a proper
 873         * scatter gather list (with 128kB MAX hunks).
 874         *
 875         * A practical limit here might be # of sg hunks that fit into
 876         * a single IOC request frame; 12 or 8 (see below), so:
 877         * For FC9xx: 12 x 128kB == 1.5 mB (max)
 878         * For C1030:  8 x 128kB == 1   mB (max)
 879         * We could support chaining, but things get ugly(ier:)
 880         *
 881         * Set the sge_offset to the start of the sgl (bytes).
 882         */
 883        sgdir = 0x04000000;             /* IOC will READ from sys mem */
 884        sge_offset = sizeof(MPIHeader_t) + sizeof(FWDownloadTCSGE_t);
 885        if ((sgl = kbuf_alloc_2_sgl(fwlen, sgdir, sge_offset,
 886                                    &numfrags, &buflist, &sgl_dma, iocp)) == NULL)
 887                return -ENOMEM;
 888
 889        /*
 890         * We should only need SGL with 2 simple_32bit entries (up to 256 kB)
 891         * for FC9xx f/w image, but calculate max number of sge hunks
 892         * we can fit into a request frame, and limit ourselves to that.
 893         * (currently no chain support)
 894         * maxfrags = (Request Size - FWdownload Size ) / Size of 32 bit SGE
 895         *      Request         maxfrags
 896         *      128             12
 897         *      96              8
 898         *      64              4
 899         */
 900        maxfrags = (iocp->req_sz - sizeof(MPIHeader_t) -
 901                        sizeof(FWDownloadTCSGE_t))
 902                        / iocp->SGE_size;
 903        if (numfrags > maxfrags) {
 904                ret = -EMLINK;
 905                goto fwdl_out;
 906        }
 907
 908        dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: sgl buffer = %p, sgfrags = %d\n",
 909            iocp->name, sgl, numfrags));
 910
 911        /*
 912         * Parse SG list, copying sgl itself,
 913         * plus f/w image hunks from user space as we go...
 914         */
 915        ret = -EFAULT;
 916        sgIn = sgl;
 917        bl = buflist;
 918        for (i=0; i < numfrags; i++) {
 919
 920                /* Get the SGE type: 0 - TCSGE, 3 - Chain, 1 - Simple SGE
 921                 * Skip everything but Simple. If simple, copy from
 922                 *      user space into kernel space.
 923                 * Note: we should not have anything but Simple as
 924                 *      Chain SGE are illegal.
 925                 */
 926                nib = (sgIn->FlagsLength & 0x30000000) >> 28;
 927                if (nib == 0 || nib == 3) {
 928                        ;
 929                } else if (sgIn->Address) {
 930                        iocp->add_sge(sgOut, sgIn->FlagsLength, sgIn->Address);
 931                        n++;
 932                        if (copy_from_user(bl->kptr, ufwbuf+fw_bytes_copied, bl->len)) {
 933                                printk(MYIOC_s_ERR_FMT "%s@%d::_ioctl_fwdl - "
 934                                        "Unable to copy f/w buffer hunk#%d @ %p\n",
 935                                        iocp->name, __FILE__, __LINE__, n, ufwbuf);
 936                                goto fwdl_out;
 937                        }
 938                        fw_bytes_copied += bl->len;
 939                }
 940                sgIn++;
 941                bl++;
 942                sgOut += iocp->SGE_size;
 943        }
 944
 945        DBG_DUMP_FW_DOWNLOAD(iocp, (u32 *)mf, numfrags);
 946
 947        /*
 948         * Finally, perform firmware download.
 949         */
 950        ReplyMsg = NULL;
 951        SET_MGMT_MSG_CONTEXT(iocp->ioctl_cmds.msg_context, dlmsg->MsgContext);
 952        INITIALIZE_MGMT_STATUS(iocp->ioctl_cmds.status)
 953        mpt_put_msg_frame(mptctl_id, iocp, mf);
 954
 955        /* Now wait for the command to complete */
 956retry_wait:
 957        timeleft = wait_for_completion_timeout(&iocp->ioctl_cmds.done, HZ*60);
 958        if (!(iocp->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
 959                ret = -ETIME;
 960                printk(MYIOC_s_WARN_FMT "%s: failed\n", iocp->name, __func__);
 961                if (iocp->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
 962                        mpt_free_msg_frame(iocp, mf);
 963                        goto fwdl_out;
 964                }
 965                if (!timeleft) {
 966                        printk(MYIOC_s_WARN_FMT
 967                               "FW download timeout, doorbell=0x%08x\n",
 968                               iocp->name, mpt_GetIocState(iocp, 0));
 969                        mptctl_timeout_expired(iocp, mf);
 970                } else
 971                        goto retry_wait;
 972                goto fwdl_out;
 973        }
 974
 975        if (!(iocp->ioctl_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
 976                printk(MYIOC_s_WARN_FMT "%s: failed\n", iocp->name, __func__);
 977                mpt_free_msg_frame(iocp, mf);
 978                ret = -ENODATA;
 979                goto fwdl_out;
 980        }
 981
 982        if (sgl)
 983                kfree_sgl(sgl, sgl_dma, buflist, iocp);
 984
 985        ReplyMsg = (pFWDownloadReply_t)iocp->ioctl_cmds.reply;
 986        iocstat = le16_to_cpu(ReplyMsg->IOCStatus) & MPI_IOCSTATUS_MASK;
 987        if (iocstat == MPI_IOCSTATUS_SUCCESS) {
 988                printk(MYIOC_s_INFO_FMT "F/W update successful!\n", iocp->name);
 989                return 0;
 990        } else if (iocstat == MPI_IOCSTATUS_INVALID_FUNCTION) {
 991                printk(MYIOC_s_WARN_FMT "Hmmm...  F/W download not supported!?!\n",
 992                        iocp->name);
 993                printk(MYIOC_s_WARN_FMT "(time to go bang on somebodies door)\n",
 994                        iocp->name);
 995                return -EBADRQC;
 996        } else if (iocstat == MPI_IOCSTATUS_BUSY) {
 997                printk(MYIOC_s_WARN_FMT "IOC_BUSY!\n", iocp->name);
 998                printk(MYIOC_s_WARN_FMT "(try again later?)\n", iocp->name);
 999                return -EBUSY;
1000        } else {
1001                printk(MYIOC_s_WARN_FMT "ioctl_fwdl() returned [bad] status = %04xh\n",
1002                        iocp->name, iocstat);
1003                printk(MYIOC_s_WARN_FMT "(bad VooDoo)\n", iocp->name);
1004                return -ENOMSG;
1005        }
1006        return 0;
1007
1008fwdl_out:
1009
1010        CLEAR_MGMT_STATUS(iocp->ioctl_cmds.status);
1011        SET_MGMT_MSG_CONTEXT(iocp->ioctl_cmds.msg_context, 0);
1012        kfree_sgl(sgl, sgl_dma, buflist, iocp);
1013        return ret;
1014}
1015
1016/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1017/*
1018 * SGE Allocation routine
1019 *
1020 * Inputs:      bytes - number of bytes to be transferred
1021 *              sgdir - data direction
1022 *              sge_offset - offset (in bytes) from the start of the request
1023 *                      frame to the first SGE
1024 *              ioc - pointer to the mptadapter
1025 * Outputs:     frags - number of scatter gather elements
1026 *              blp - point to the buflist pointer
1027 *              sglbuf_dma - pointer to the (dma) sgl
1028 * Returns:     Null if failes
1029 *              pointer to the (virtual) sgl if successful.
1030 */
1031static MptSge_t *
1032kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags,
1033                 struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc)
1034{
1035        MptSge_t        *sglbuf = NULL;         /* pointer to array of SGE */
1036                                                /* and chain buffers */
1037        struct buflist  *buflist = NULL;        /* kernel routine */
1038        MptSge_t        *sgl;
1039        int              numfrags = 0;
1040        int              fragcnt = 0;
1041        int              alloc_sz = min(bytes,MAX_KMALLOC_SZ);  // avoid kernel warning msg!
1042        int              bytes_allocd = 0;
1043        int              this_alloc;
1044        dma_addr_t       pa;                                    // phys addr
1045        int              i, buflist_ent;
1046        int              sg_spill = MAX_FRAGS_SPILL1;
1047        int              dir;
1048        /* initialization */
1049        *frags = 0;
1050        *blp = NULL;
1051
1052        /* Allocate and initialize an array of kernel
1053         * structures for the SG elements.
1054         */
1055        i = MAX_SGL_BYTES / 8;
1056        buflist = kzalloc(i, GFP_USER);
1057        if (!buflist)
1058                return NULL;
1059        buflist_ent = 0;
1060
1061        /* Allocate a single block of memory to store the sg elements and
1062         * the chain buffers.  The calling routine is responsible for
1063         * copying the data in this array into the correct place in the
1064         * request and chain buffers.
1065         */
1066        sglbuf = pci_alloc_consistent(ioc->pcidev, MAX_SGL_BYTES, sglbuf_dma);
1067        if (sglbuf == NULL)
1068                goto free_and_fail;
1069
1070        if (sgdir & 0x04000000)
1071                dir = PCI_DMA_TODEVICE;
1072        else
1073                dir = PCI_DMA_FROMDEVICE;
1074
1075        /* At start:
1076         *      sgl = sglbuf = point to beginning of sg buffer
1077         *      buflist_ent = 0 = first kernel structure
1078         *      sg_spill = number of SGE that can be written before the first
1079         *              chain element.
1080         *
1081         */
1082        sgl = sglbuf;
1083        sg_spill = ((ioc->req_sz - sge_offset)/ioc->SGE_size) - 1;
1084        while (bytes_allocd < bytes) {
1085                this_alloc = min(alloc_sz, bytes-bytes_allocd);
1086                buflist[buflist_ent].len = this_alloc;
1087                buflist[buflist_ent].kptr = pci_alloc_consistent(ioc->pcidev,
1088                                                                 this_alloc,
1089                                                                 &pa);
1090                if (buflist[buflist_ent].kptr == NULL) {
1091                        alloc_sz = alloc_sz / 2;
1092                        if (alloc_sz == 0) {
1093                                printk(MYIOC_s_WARN_FMT "-SG: No can do - "
1094                                    "not enough memory!   :-(\n", ioc->name);
1095                                printk(MYIOC_s_WARN_FMT "-SG: (freeing %d frags)\n",
1096                                        ioc->name, numfrags);
1097                                goto free_and_fail;
1098                        }
1099                        continue;
1100                } else {
1101                        dma_addr_t dma_addr;
1102
1103                        bytes_allocd += this_alloc;
1104                        sgl->FlagsLength = (0x10000000|sgdir|this_alloc);
1105                        dma_addr = pci_map_single(ioc->pcidev,
1106                                buflist[buflist_ent].kptr, this_alloc, dir);
1107                        sgl->Address = dma_addr;
1108
1109                        fragcnt++;
1110                        numfrags++;
1111                        sgl++;
1112                        buflist_ent++;
1113                }
1114
1115                if (bytes_allocd >= bytes)
1116                        break;
1117
1118                /* Need to chain? */
1119                if (fragcnt == sg_spill) {
1120                        printk(MYIOC_s_WARN_FMT
1121                            "-SG: No can do - " "Chain required!   :-(\n", ioc->name);
1122                        printk(MYIOC_s_WARN_FMT "(freeing %d frags)\n", ioc->name, numfrags);
1123                        goto free_and_fail;
1124                }
1125
1126                /* overflow check... */
1127                if (numfrags*8 > MAX_SGL_BYTES){
1128                        /* GRRRRR... */
1129                        printk(MYIOC_s_WARN_FMT "-SG: No can do - "
1130                                "too many SG frags!   :-(\n", ioc->name);
1131                        printk(MYIOC_s_WARN_FMT "-SG: (freeing %d frags)\n",
1132                                ioc->name, numfrags);
1133                        goto free_and_fail;
1134                }
1135        }
1136
1137        /* Last sge fixup: set LE+eol+eob bits */
1138        sgl[-1].FlagsLength |= 0xC1000000;
1139
1140        *frags = numfrags;
1141        *blp = buflist;
1142
1143        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "-SG: kbuf_alloc_2_sgl() - "
1144           "%d SG frags generated!\n", ioc->name, numfrags));
1145
1146        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "-SG: kbuf_alloc_2_sgl() - "
1147           "last (big) alloc_sz=%d\n", ioc->name, alloc_sz));
1148
1149        return sglbuf;
1150
1151free_and_fail:
1152        if (sglbuf != NULL) {
1153                for (i = 0; i < numfrags; i++) {
1154                        dma_addr_t dma_addr;
1155                        u8 *kptr;
1156                        int len;
1157
1158                        if ((sglbuf[i].FlagsLength >> 24) == 0x30)
1159                                continue;
1160
1161                        dma_addr = sglbuf[i].Address;
1162                        kptr = buflist[i].kptr;
1163                        len = buflist[i].len;
1164
1165                        pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
1166                }
1167                pci_free_consistent(ioc->pcidev, MAX_SGL_BYTES, sglbuf, *sglbuf_dma);
1168        }
1169        kfree(buflist);
1170        return NULL;
1171}
1172
1173/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1174/*
1175 * Routine to free the SGL elements.
1176 */
1177static void
1178kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma, struct buflist *buflist, MPT_ADAPTER *ioc)
1179{
1180        MptSge_t        *sg = sgl;
1181        struct buflist  *bl = buflist;
1182        u32              nib;
1183        int              dir;
1184        int              n = 0;
1185
1186        if (sg->FlagsLength & 0x04000000)
1187                dir = PCI_DMA_TODEVICE;
1188        else
1189                dir = PCI_DMA_FROMDEVICE;
1190
1191        nib = (sg->FlagsLength & 0xF0000000) >> 28;
1192        while (! (nib & 0x4)) { /* eob */
1193                /* skip ignore/chain. */
1194                if (nib == 0 || nib == 3) {
1195                        ;
1196                } else if (sg->Address) {
1197                        dma_addr_t dma_addr;
1198                        void *kptr;
1199                        int len;
1200
1201                        dma_addr = sg->Address;
1202                        kptr = bl->kptr;
1203                        len = bl->len;
1204                        pci_unmap_single(ioc->pcidev, dma_addr, len, dir);
1205                        pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
1206                        n++;
1207                }
1208                sg++;
1209                bl++;
1210                nib = (le32_to_cpu(sg->FlagsLength) & 0xF0000000) >> 28;
1211        }
1212
1213        /* we're at eob! */
1214        if (sg->Address) {
1215                dma_addr_t dma_addr;
1216                void *kptr;
1217                int len;
1218
1219                dma_addr = sg->Address;
1220                kptr = bl->kptr;
1221                len = bl->len;
1222                pci_unmap_single(ioc->pcidev, dma_addr, len, dir);
1223                pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
1224                n++;
1225        }
1226
1227        pci_free_consistent(ioc->pcidev, MAX_SGL_BYTES, sgl, sgl_dma);
1228        kfree(buflist);
1229        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "-SG: Free'd 1 SGL buf + %d kbufs!\n",
1230            ioc->name, n));
1231}
1232
1233/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1234/*
1235 *      mptctl_getiocinfo - Query the host adapter for IOC information.
1236 *      @arg: User space argument
1237 *
1238 * Outputs:     None.
1239 * Return:      0 if successful
1240 *              -EFAULT if data unavailable
1241 *              -ENODEV  if no such device/adapter
1242 */
1243static int
1244mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
1245{
1246        struct mpt_ioctl_iocinfo __user *uarg = (void __user *) arg;
1247        struct mpt_ioctl_iocinfo *karg;
1248        MPT_ADAPTER             *ioc;
1249        struct pci_dev          *pdev;
1250        int                     iocnum;
1251        unsigned int            port;
1252        int                     cim_rev;
1253        struct scsi_device      *sdev;
1254        VirtDevice              *vdevice;
1255
1256        /* Add of PCI INFO results in unaligned access for
1257         * IA64 and Sparc. Reset long to int. Return no PCI
1258         * data for obsolete format.
1259         */
1260        if (data_size == sizeof(struct mpt_ioctl_iocinfo_rev0))
1261                cim_rev = 0;
1262        else if (data_size == sizeof(struct mpt_ioctl_iocinfo_rev1))
1263                cim_rev = 1;
1264        else if (data_size == sizeof(struct mpt_ioctl_iocinfo))
1265                cim_rev = 2;
1266        else if (data_size == (sizeof(struct mpt_ioctl_iocinfo_rev0)+12))
1267                cim_rev = 0;    /* obsolete */
1268        else
1269                return -EFAULT;
1270
1271        karg = kmalloc(data_size, GFP_KERNEL);
1272        if (karg == NULL) {
1273                printk(KERN_ERR MYNAM "%s::mpt_ioctl_iocinfo() @%d - no memory available!\n",
1274                                __FILE__, __LINE__);
1275                return -ENOMEM;
1276        }
1277
1278        if (copy_from_user(karg, uarg, data_size)) {
1279                printk(KERN_ERR MYNAM "%s@%d::mptctl_getiocinfo - "
1280                        "Unable to read in mpt_ioctl_iocinfo struct @ %p\n",
1281                                __FILE__, __LINE__, uarg);
1282                kfree(karg);
1283                return -EFAULT;
1284        }
1285
1286        if (((iocnum = mpt_verify_adapter(karg->hdr.iocnum, &ioc)) < 0) ||
1287            (ioc == NULL)) {
1288                printk(KERN_DEBUG MYNAM "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n",
1289                                __FILE__, __LINE__, iocnum);
1290                kfree(karg);
1291                return -ENODEV;
1292        }
1293
1294        /* Verify the data transfer size is correct. */
1295        if (karg->hdr.maxDataSize != data_size) {
1296                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - "
1297                        "Structure size mismatch. Command not completed.\n",
1298                        ioc->name, __FILE__, __LINE__);
1299                kfree(karg);
1300                return -EFAULT;
1301        }
1302
1303        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_getiocinfo called.\n",
1304            ioc->name));
1305
1306        /* Fill in the data and return the structure to the calling
1307         * program
1308         */
1309        if (ioc->bus_type == SAS)
1310                karg->adapterType = MPT_IOCTL_INTERFACE_SAS;
1311        else if (ioc->bus_type == FC)
1312                karg->adapterType = MPT_IOCTL_INTERFACE_FC;
1313        else
1314                karg->adapterType = MPT_IOCTL_INTERFACE_SCSI;
1315
1316        if (karg->hdr.port > 1) {
1317                kfree(karg);
1318                return -EINVAL;
1319        }
1320        port = karg->hdr.port;
1321
1322        karg->port = port;
1323        pdev = (struct pci_dev *) ioc->pcidev;
1324
1325        karg->pciId = pdev->device;
1326        karg->hwRev = pdev->revision;
1327        karg->subSystemDevice = pdev->subsystem_device;
1328        karg->subSystemVendor = pdev->subsystem_vendor;
1329
1330        if (cim_rev == 1) {
1331                /* Get the PCI bus, device, and function numbers for the IOC
1332                 */
1333                karg->pciInfo.u.bits.busNumber = pdev->bus->number;
1334                karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
1335                karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1336        } else if (cim_rev == 2) {
1337                /* Get the PCI bus, device, function and segment ID numbers
1338                   for the IOC */
1339                karg->pciInfo.u.bits.busNumber = pdev->bus->number;
1340                karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
1341                karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1342                karg->pciInfo.segmentID = pci_domain_nr(pdev->bus);
1343        }
1344
1345        /* Get number of devices
1346         */
1347        karg->numDevices = 0;
1348        if (ioc->sh) {
1349                shost_for_each_device(sdev, ioc->sh) {
1350                        vdevice = sdev->hostdata;
1351                        if (vdevice == NULL || vdevice->vtarget == NULL)
1352                                continue;
1353                        if (vdevice->vtarget->tflags &
1354                            MPT_TARGET_FLAGS_RAID_COMPONENT)
1355                                continue;
1356                        karg->numDevices++;
1357                }
1358        }
1359
1360        /* Set the BIOS and FW Version
1361         */
1362        karg->FWVersion = ioc->facts.FWVersion.Word;
1363        karg->BIOSVersion = ioc->biosVersion;
1364
1365        /* Set the Version Strings.
1366         */
1367        strncpy (karg->driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH);
1368        karg->driverVersion[MPT_IOCTL_VERSION_LENGTH-1]='\0';
1369
1370        karg->busChangeEvent = 0;
1371        karg->hostId = ioc->pfacts[port].PortSCSIID;
1372        karg->rsvd[0] = karg->rsvd[1] = 0;
1373
1374        /* Copy the data from kernel memory to user memory
1375         */
1376        if (copy_to_user((char __user *)arg, karg, data_size)) {
1377                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - "
1378                        "Unable to write out mpt_ioctl_iocinfo struct @ %p\n",
1379                        ioc->name, __FILE__, __LINE__, uarg);
1380                kfree(karg);
1381                return -EFAULT;
1382        }
1383
1384        kfree(karg);
1385        return 0;
1386}
1387
1388/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1389/*
1390 *      mptctl_gettargetinfo - Query the host adapter for target information.
1391 *      @arg: User space argument
1392 *
1393 * Outputs:     None.
1394 * Return:      0 if successful
1395 *              -EFAULT if data unavailable
1396 *              -ENODEV  if no such device/adapter
1397 */
1398static int
1399mptctl_gettargetinfo (unsigned long arg)
1400{
1401        struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg;
1402        struct mpt_ioctl_targetinfo karg;
1403        MPT_ADAPTER             *ioc;
1404        VirtDevice              *vdevice;
1405        char                    *pmem;
1406        int                     *pdata;
1407        int                     iocnum;
1408        int                     numDevices = 0;
1409        int                     lun;
1410        int                     maxWordsLeft;
1411        int                     numBytes;
1412        u8                      port;
1413        struct scsi_device      *sdev;
1414
1415        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
1416                printk(KERN_ERR MYNAM "%s@%d::mptctl_gettargetinfo - "
1417                        "Unable to read in mpt_ioctl_targetinfo struct @ %p\n",
1418                                __FILE__, __LINE__, uarg);
1419                return -EFAULT;
1420        }
1421
1422        if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1423            (ioc == NULL)) {
1424                printk(KERN_DEBUG MYNAM "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n",
1425                                __FILE__, __LINE__, iocnum);
1426                return -ENODEV;
1427        }
1428
1429        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_gettargetinfo called.\n",
1430            ioc->name));
1431        /* Get the port number and set the maximum number of bytes
1432         * in the returned structure.
1433         * Ignore the port setting.
1434         */
1435        numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
1436        maxWordsLeft = numBytes/sizeof(int);
1437        port = karg.hdr.port;
1438
1439        if (maxWordsLeft <= 0) {
1440                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n",
1441                        ioc->name, __FILE__, __LINE__);
1442                return -ENOMEM;
1443        }
1444
1445        /* Fill in the data and return the structure to the calling
1446         * program
1447         */
1448
1449        /* struct mpt_ioctl_targetinfo does not contain sufficient space
1450         * for the target structures so when the IOCTL is called, there is
1451         * not sufficient stack space for the structure. Allocate memory,
1452         * populate the memory, copy back to the user, then free memory.
1453         * targetInfo format:
1454         * bits 31-24: reserved
1455         *      23-16: LUN
1456         *      15- 8: Bus Number
1457         *       7- 0: Target ID
1458         */
1459        pmem = kzalloc(numBytes, GFP_KERNEL);
1460        if (!pmem) {
1461                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n",
1462                        ioc->name, __FILE__, __LINE__);
1463                return -ENOMEM;
1464        }
1465        pdata =  (int *) pmem;
1466
1467        /* Get number of devices
1468         */
1469        if (ioc->sh){
1470                shost_for_each_device(sdev, ioc->sh) {
1471                        if (!maxWordsLeft)
1472                                continue;
1473                        vdevice = sdev->hostdata;
1474                        if (vdevice == NULL || vdevice->vtarget == NULL)
1475                                continue;
1476                        if (vdevice->vtarget->tflags &
1477                            MPT_TARGET_FLAGS_RAID_COMPONENT)
1478                                continue;
1479                        lun = (vdevice->vtarget->raidVolume) ? 0x80 : vdevice->lun;
1480                        *pdata = (((u8)lun << 16) + (vdevice->vtarget->channel << 8) +
1481                            (vdevice->vtarget->id ));
1482                        pdata++;
1483                        numDevices++;
1484                        --maxWordsLeft;
1485                }
1486        }
1487        karg.numDevices = numDevices;
1488
1489        /* Copy part of the data from kernel memory to user memory
1490         */
1491        if (copy_to_user((char __user *)arg, &karg,
1492                                sizeof(struct mpt_ioctl_targetinfo))) {
1493                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo - "
1494                        "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
1495                        ioc->name, __FILE__, __LINE__, uarg);
1496                kfree(pmem);
1497                return -EFAULT;
1498        }
1499
1500        /* Copy the remaining data from kernel memory to user memory
1501         */
1502        if (copy_to_user(uarg->targetInfo, pmem, numBytes)) {
1503                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo - "
1504                        "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
1505                        ioc->name, __FILE__, __LINE__, pdata);
1506                kfree(pmem);
1507                return -EFAULT;
1508        }
1509
1510        kfree(pmem);
1511
1512        return 0;
1513}
1514
1515/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1516/* MPT IOCTL Test function.
1517 *
1518 * Outputs:     None.
1519 * Return:      0 if successful
1520 *              -EFAULT if data unavailable
1521 *              -ENODEV  if no such device/adapter
1522 */
1523static int
1524mptctl_readtest (unsigned long arg)
1525{
1526        struct mpt_ioctl_test __user *uarg = (void __user *) arg;
1527        struct mpt_ioctl_test    karg;
1528        MPT_ADAPTER *ioc;
1529        int iocnum;
1530
1531        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) {
1532                printk(KERN_ERR MYNAM "%s@%d::mptctl_readtest - "
1533                        "Unable to read in mpt_ioctl_test struct @ %p\n",
1534                                __FILE__, __LINE__, uarg);
1535                return -EFAULT;
1536        }
1537
1538        if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1539            (ioc == NULL)) {
1540                printk(KERN_DEBUG MYNAM "%s::mptctl_readtest() @%d - ioc%d not found!\n",
1541                                __FILE__, __LINE__, iocnum);
1542                return -ENODEV;
1543        }
1544
1545        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_readtest called.\n",
1546            ioc->name));
1547        /* Fill in the data and return the structure to the calling
1548         * program
1549         */
1550
1551#ifdef MFCNT
1552        karg.chip_type = ioc->mfcnt;
1553#else
1554        karg.chip_type = ioc->pcidev->device;
1555#endif
1556        strncpy (karg.name, ioc->name, MPT_MAX_NAME);
1557        karg.name[MPT_MAX_NAME-1]='\0';
1558        strncpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH);
1559        karg.product[MPT_PRODUCT_LENGTH-1]='\0';
1560
1561        /* Copy the data from kernel memory to user memory
1562         */
1563        if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_test))) {
1564                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_readtest - "
1565                        "Unable to write out mpt_ioctl_test struct @ %p\n",
1566                        ioc->name, __FILE__, __LINE__, uarg);
1567                return -EFAULT;
1568        }
1569
1570        return 0;
1571}
1572
1573/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1574/*
1575 *      mptctl_eventquery - Query the host adapter for the event types
1576 *      that are being logged.
1577 *      @arg: User space argument
1578 *
1579 * Outputs:     None.
1580 * Return:      0 if successful
1581 *              -EFAULT if data unavailable
1582 *              -ENODEV  if no such device/adapter
1583 */
1584static int
1585mptctl_eventquery (unsigned long arg)
1586{
1587        struct mpt_ioctl_eventquery __user *uarg = (void __user *) arg;
1588        struct mpt_ioctl_eventquery      karg;
1589        MPT_ADAPTER *ioc;
1590        int iocnum;
1591
1592        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) {
1593                printk(KERN_ERR MYNAM "%s@%d::mptctl_eventquery - "
1594                        "Unable to read in mpt_ioctl_eventquery struct @ %p\n",
1595                                __FILE__, __LINE__, uarg);
1596                return -EFAULT;
1597        }
1598
1599        if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1600            (ioc == NULL)) {
1601                printk(KERN_DEBUG MYNAM "%s::mptctl_eventquery() @%d - ioc%d not found!\n",
1602                                __FILE__, __LINE__, iocnum);
1603                return -ENODEV;
1604        }
1605
1606        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventquery called.\n",
1607            ioc->name));
1608        karg.eventEntries = MPTCTL_EVENT_LOG_SIZE;
1609        karg.eventTypes = ioc->eventTypes;
1610
1611        /* Copy the data from kernel memory to user memory
1612         */
1613        if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) {
1614                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_eventquery - "
1615                        "Unable to write out mpt_ioctl_eventquery struct @ %p\n",
1616                        ioc->name, __FILE__, __LINE__, uarg);
1617                return -EFAULT;
1618        }
1619        return 0;
1620}
1621
1622/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1623static int
1624mptctl_eventenable (unsigned long arg)
1625{
1626        struct mpt_ioctl_eventenable __user *uarg = (void __user *) arg;
1627        struct mpt_ioctl_eventenable     karg;
1628        MPT_ADAPTER *ioc;
1629        int iocnum;
1630
1631        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) {
1632                printk(KERN_ERR MYNAM "%s@%d::mptctl_eventenable - "
1633                        "Unable to read in mpt_ioctl_eventenable struct @ %p\n",
1634                                __FILE__, __LINE__, uarg);
1635                return -EFAULT;
1636        }
1637
1638        if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1639            (ioc == NULL)) {
1640                printk(KERN_DEBUG MYNAM "%s::mptctl_eventenable() @%d - ioc%d not found!\n",
1641                                __FILE__, __LINE__, iocnum);
1642                return -ENODEV;
1643        }
1644
1645        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventenable called.\n",
1646            ioc->name));
1647        if (ioc->events == NULL) {
1648                /* Have not yet allocated memory - do so now.
1649                 */
1650                int sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
1651                ioc->events = kzalloc(sz, GFP_KERNEL);
1652                if (!ioc->events) {
1653                        printk(MYIOC_s_ERR_FMT
1654                            ": ERROR - Insufficient memory to add adapter!\n",
1655                            ioc->name);
1656                        return -ENOMEM;
1657                }
1658                ioc->alloc_total += sz;
1659
1660                ioc->eventContext = 0;
1661        }
1662
1663        /* Update the IOC event logging flag.
1664         */
1665        ioc->eventTypes = karg.eventTypes;
1666
1667        return 0;
1668}
1669
1670/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1671static int
1672mptctl_eventreport (unsigned long arg)
1673{
1674        struct mpt_ioctl_eventreport __user *uarg = (void __user *) arg;
1675        struct mpt_ioctl_eventreport     karg;
1676        MPT_ADAPTER              *ioc;
1677        int                      iocnum;
1678        int                      numBytes, maxEvents, max;
1679
1680        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) {
1681                printk(KERN_ERR MYNAM "%s@%d::mptctl_eventreport - "
1682                        "Unable to read in mpt_ioctl_eventreport struct @ %p\n",
1683                                __FILE__, __LINE__, uarg);
1684                return -EFAULT;
1685        }
1686
1687        if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1688            (ioc == NULL)) {
1689                printk(KERN_DEBUG MYNAM "%s::mptctl_eventreport() @%d - ioc%d not found!\n",
1690                                __FILE__, __LINE__, iocnum);
1691                return -ENODEV;
1692        }
1693        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventreport called.\n",
1694            ioc->name));
1695
1696        numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
1697        maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS);
1698
1699
1700        max = MPTCTL_EVENT_LOG_SIZE < maxEvents ? MPTCTL_EVENT_LOG_SIZE : maxEvents;
1701
1702        /* If fewer than 1 event is requested, there must have
1703         * been some type of error.
1704         */
1705        if ((max < 1) || !ioc->events)
1706                return -ENODATA;
1707
1708        /* reset this flag so SIGIO can restart */
1709        ioc->aen_event_read_flag=0;
1710
1711        /* Copy the data from kernel memory to user memory
1712         */
1713        numBytes = max * sizeof(MPT_IOCTL_EVENTS);
1714        if (copy_to_user(uarg->eventData, ioc->events, numBytes)) {
1715                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_eventreport - "
1716                        "Unable to write out mpt_ioctl_eventreport struct @ %p\n",
1717                        ioc->name, __FILE__, __LINE__, ioc->events);
1718                return -EFAULT;
1719        }
1720
1721        return 0;
1722}
1723
1724/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1725static int
1726mptctl_replace_fw (unsigned long arg)
1727{
1728        struct mpt_ioctl_replace_fw __user *uarg = (void __user *) arg;
1729        struct mpt_ioctl_replace_fw      karg;
1730        MPT_ADAPTER              *ioc;
1731        int                      iocnum;
1732        int                      newFwSize;
1733
1734        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
1735                printk(KERN_ERR MYNAM "%s@%d::mptctl_replace_fw - "
1736                        "Unable to read in mpt_ioctl_replace_fw struct @ %p\n",
1737                                __FILE__, __LINE__, uarg);
1738                return -EFAULT;
1739        }
1740
1741        if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1742            (ioc == NULL)) {
1743                printk(KERN_DEBUG MYNAM "%s::mptctl_replace_fw() @%d - ioc%d not found!\n",
1744                                __FILE__, __LINE__, iocnum);
1745                return -ENODEV;
1746        }
1747
1748        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_replace_fw called.\n",
1749            ioc->name));
1750        /* If caching FW, Free the old FW image
1751         */
1752        if (ioc->cached_fw == NULL)
1753                return 0;
1754
1755        mpt_free_fw_memory(ioc);
1756
1757        /* Allocate memory for the new FW image
1758         */
1759        newFwSize = karg.newImageSize;
1760
1761        if (newFwSize & 0x01)
1762                newFwSize += 1;
1763        if (newFwSize & 0x02)
1764                newFwSize += 2;
1765
1766        mpt_alloc_fw_memory(ioc, newFwSize);
1767        if (ioc->cached_fw == NULL)
1768                return -ENOMEM;
1769
1770        /* Copy the data from user memory to kernel space
1771         */
1772        if (copy_from_user(ioc->cached_fw, uarg->newImage, newFwSize)) {
1773                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_replace_fw - "
1774                                "Unable to read in mpt_ioctl_replace_fw image "
1775                                "@ %p\n", ioc->name, __FILE__, __LINE__, uarg);
1776                mpt_free_fw_memory(ioc);
1777                return -EFAULT;
1778        }
1779
1780        /* Update IOCFactsReply
1781         */
1782        ioc->facts.FWImageSize = newFwSize;
1783        return 0;
1784}
1785
1786/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1787/* MPT IOCTL MPTCOMMAND function.
1788 * Cast the arg into the mpt_ioctl_mpt_command structure.
1789 *
1790 * Outputs:     None.
1791 * Return:      0 if successful
1792 *              -EBUSY  if previous command timeout and IOC reset is not complete.
1793 *              -EFAULT if data unavailable
1794 *              -ENODEV if no such device/adapter
1795 *              -ETIME  if timer expires
1796 *              -ENOMEM if memory allocation error
1797 */
1798static int
1799mptctl_mpt_command (unsigned long arg)
1800{
1801        struct mpt_ioctl_command __user *uarg = (void __user *) arg;
1802        struct mpt_ioctl_command  karg;
1803        MPT_ADAPTER     *ioc;
1804        int             iocnum;
1805        int             rc;
1806
1807
1808        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_command))) {
1809                printk(KERN_ERR MYNAM "%s@%d::mptctl_mpt_command - "
1810                        "Unable to read in mpt_ioctl_command struct @ %p\n",
1811                                __FILE__, __LINE__, uarg);
1812                return -EFAULT;
1813        }
1814
1815        if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1816            (ioc == NULL)) {
1817                printk(KERN_DEBUG MYNAM "%s::mptctl_mpt_command() @%d - ioc%d not found!\n",
1818                                __FILE__, __LINE__, iocnum);
1819                return -ENODEV;
1820        }
1821
1822        rc = mptctl_do_mpt_command (karg, &uarg->MF);
1823
1824        return rc;
1825}
1826
1827/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1828/* Worker routine for the IOCTL MPTCOMMAND and MPTCOMMAND32 (sparc) commands.
1829 *
1830 * Outputs:     None.
1831 * Return:      0 if successful
1832 *              -EBUSY  if previous command timeout and IOC reset is not complete.
1833 *              -EFAULT if data unavailable
1834 *              -ENODEV if no such device/adapter
1835 *              -ETIME  if timer expires
1836 *              -ENOMEM if memory allocation error
1837 *              -EPERM if SCSI I/O and target is untagged
1838 */
1839static int
1840mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
1841{
1842        MPT_ADAPTER     *ioc;
1843        MPT_FRAME_HDR   *mf = NULL;
1844        MPIHeader_t     *hdr;
1845        char            *psge;
1846        struct buflist  bufIn;  /* data In buffer */
1847        struct buflist  bufOut; /* data Out buffer */
1848        dma_addr_t      dma_addr_in;
1849        dma_addr_t      dma_addr_out;
1850        int             sgSize = 0;     /* Num SG elements */
1851        int             iocnum, flagsLength;
1852        int             sz, rc = 0;
1853        int             msgContext;
1854        u16             req_idx;
1855        ulong           timeout;
1856        unsigned long   timeleft;
1857        struct scsi_device *sdev;
1858        unsigned long    flags;
1859        u8               function;
1860
1861        /* bufIn and bufOut are used for user to kernel space transfers
1862         */
1863        bufIn.kptr = bufOut.kptr = NULL;
1864        bufIn.len = bufOut.len = 0;
1865
1866        if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1867            (ioc == NULL)) {
1868                printk(KERN_DEBUG MYNAM "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n",
1869                                __FILE__, __LINE__, iocnum);
1870                return -ENODEV;
1871        }
1872
1873        spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
1874        if (ioc->ioc_reset_in_progress) {
1875                spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
1876                printk(KERN_ERR MYNAM "%s@%d::mptctl_do_mpt_command - "
1877                        "Busy with diagnostic reset\n", __FILE__, __LINE__);
1878                return -EBUSY;
1879        }
1880        spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
1881
1882        /* Verify that the final request frame will not be too large.
1883         */
1884        sz = karg.dataSgeOffset * 4;
1885        if (karg.dataInSize > 0)
1886                sz += ioc->SGE_size;
1887        if (karg.dataOutSize > 0)
1888                sz += ioc->SGE_size;
1889
1890        if (sz > ioc->req_sz) {
1891                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1892                        "Request frame too large (%d) maximum (%d)\n",
1893                        ioc->name, __FILE__, __LINE__, sz, ioc->req_sz);
1894                return -EFAULT;
1895        }
1896
1897        /* Get a free request frame and save the message context.
1898         */
1899        if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL)
1900                return -EAGAIN;
1901
1902        hdr = (MPIHeader_t *) mf;
1903        msgContext = le32_to_cpu(hdr->MsgContext);
1904        req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1905
1906        /* Copy the request frame
1907         * Reset the saved message context.
1908         * Request frame in user space
1909         */
1910        if (copy_from_user(mf, mfPtr, karg.dataSgeOffset * 4)) {
1911                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1912                        "Unable to read MF from mpt_ioctl_command struct @ %p\n",
1913                        ioc->name, __FILE__, __LINE__, mfPtr);
1914                function = -1;
1915                rc = -EFAULT;
1916                goto done_free_mem;
1917        }
1918        hdr->MsgContext = cpu_to_le32(msgContext);
1919        function = hdr->Function;
1920
1921
1922        /* Verify that this request is allowed.
1923         */
1924        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sending mpi function (0x%02X), req=%p\n",
1925            ioc->name, hdr->Function, mf));
1926
1927        switch (function) {
1928        case MPI_FUNCTION_IOC_FACTS:
1929        case MPI_FUNCTION_PORT_FACTS:
1930                karg.dataOutSize  = karg.dataInSize = 0;
1931                break;
1932
1933        case MPI_FUNCTION_CONFIG:
1934        {
1935                Config_t *config_frame;
1936                config_frame = (Config_t *)mf;
1937                dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\ttype=0x%02x ext_type=0x%02x "
1938                    "number=0x%02x action=0x%02x\n", ioc->name,
1939                    config_frame->Header.PageType,
1940                    config_frame->ExtPageType,
1941                    config_frame->Header.PageNumber,
1942                    config_frame->Action));
1943                break;
1944        }
1945
1946        case MPI_FUNCTION_FC_COMMON_TRANSPORT_SEND:
1947        case MPI_FUNCTION_FC_EX_LINK_SRVC_SEND:
1948        case MPI_FUNCTION_FW_UPLOAD:
1949        case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR:
1950        case MPI_FUNCTION_FW_DOWNLOAD:
1951        case MPI_FUNCTION_FC_PRIMITIVE_SEND:
1952        case MPI_FUNCTION_TOOLBOX:
1953        case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
1954                break;
1955
1956        case MPI_FUNCTION_SCSI_IO_REQUEST:
1957                if (ioc->sh) {
1958                        SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
1959                        int qtag = MPI_SCSIIO_CONTROL_UNTAGGED;
1960                        int scsidir = 0;
1961                        int dataSize;
1962                        u32 id;
1963
1964                        id = (ioc->devices_per_bus == 0) ? 256 : ioc->devices_per_bus;
1965                        if (pScsiReq->TargetID > id) {
1966                                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1967                                        "Target ID out of bounds. \n",
1968                                        ioc->name, __FILE__, __LINE__);
1969                                rc = -ENODEV;
1970                                goto done_free_mem;
1971                        }
1972
1973                        if (pScsiReq->Bus >= ioc->number_of_buses) {
1974                                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1975                                        "Target Bus out of bounds. \n",
1976                                        ioc->name, __FILE__, __LINE__);
1977                                rc = -ENODEV;
1978                                goto done_free_mem;
1979                        }
1980
1981                        pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
1982                        pScsiReq->MsgFlags |= mpt_msg_flags(ioc);
1983
1984
1985                        /* verify that app has not requested
1986                         *      more sense data than driver
1987                         *      can provide, if so, reset this parameter
1988                         * set the sense buffer pointer low address
1989                         * update the control field to specify Q type
1990                         */
1991                        if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
1992                                pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1993                        else
1994                                pScsiReq->SenseBufferLength = karg.maxSenseBytes;
1995
1996                        pScsiReq->SenseBufferLowAddr =
1997                                cpu_to_le32(ioc->sense_buf_low_dma
1998                                   + (req_idx * MPT_SENSE_BUFFER_ALLOC));
1999
2000                        shost_for_each_device(sdev, ioc->sh) {
2001                                struct scsi_target *starget = scsi_target(sdev);
2002                                VirtTarget *vtarget = starget->hostdata;
2003
2004                                if (vtarget == NULL)
2005                                        continue;
2006
2007                                if ((pScsiReq->TargetID == vtarget->id) &&
2008                                    (pScsiReq->Bus == vtarget->channel) &&
2009                                    (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2010                                        qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
2011                        }
2012
2013                        /* Have the IOCTL driver set the direction based
2014                         * on the dataOutSize (ordering issue with Sparc).
2015                         */
2016                        if (karg.dataOutSize > 0) {
2017                                scsidir = MPI_SCSIIO_CONTROL_WRITE;
2018                                dataSize = karg.dataOutSize;
2019                        } else {
2020                                scsidir = MPI_SCSIIO_CONTROL_READ;
2021                                dataSize = karg.dataInSize;
2022                        }
2023
2024                        pScsiReq->Control = cpu_to_le32(scsidir | qtag);
2025                        pScsiReq->DataLength = cpu_to_le32(dataSize);
2026
2027
2028                } else {
2029                        printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2030                                "SCSI driver is not loaded. \n",
2031                                ioc->name, __FILE__, __LINE__);
2032                        rc = -EFAULT;
2033                        goto done_free_mem;
2034                }
2035                break;
2036
2037        case MPI_FUNCTION_SMP_PASSTHROUGH:
2038                /* Check mf->PassthruFlags to determine if
2039                 * transfer is ImmediateMode or not.
2040                 * Immediate mode returns data in the ReplyFrame.
2041                 * Else, we are sending request and response data
2042                 * in two SGLs at the end of the mf.
2043                 */
2044                break;
2045
2046        case MPI_FUNCTION_SATA_PASSTHROUGH:
2047                if (!ioc->sh) {
2048                        printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2049                                "SCSI driver is not loaded. \n",
2050                                ioc->name, __FILE__, __LINE__);
2051                        rc = -EFAULT;
2052                        goto done_free_mem;
2053                }
2054                break;
2055
2056        case MPI_FUNCTION_RAID_ACTION:
2057                /* Just add a SGE
2058                 */
2059                break;
2060
2061        case MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
2062                if (ioc->sh) {
2063                        SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
2064                        int qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
2065                        int scsidir = MPI_SCSIIO_CONTROL_READ;
2066                        int dataSize;
2067
2068                        pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
2069                        pScsiReq->MsgFlags |= mpt_msg_flags(ioc);
2070
2071
2072                        /* verify that app has not requested
2073                         *      more sense data than driver
2074                         *      can provide, if so, reset this parameter
2075                         * set the sense buffer pointer low address
2076                         * update the control field to specify Q type
2077                         */
2078                        if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
2079                                pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
2080                        else
2081                                pScsiReq->SenseBufferLength = karg.maxSenseBytes;
2082
2083                        pScsiReq->SenseBufferLowAddr =
2084                                cpu_to_le32(ioc->sense_buf_low_dma
2085                                   + (req_idx * MPT_SENSE_BUFFER_ALLOC));
2086
2087                        /* All commands to physical devices are tagged
2088                         */
2089
2090                        /* Have the IOCTL driver set the direction based
2091                         * on the dataOutSize (ordering issue with Sparc).
2092                         */
2093                        if (karg.dataOutSize > 0) {
2094                                scsidir = MPI_SCSIIO_CONTROL_WRITE;
2095                                dataSize = karg.dataOutSize;
2096                        } else {
2097                                scsidir = MPI_SCSIIO_CONTROL_READ;
2098                                dataSize = karg.dataInSize;
2099                        }
2100
2101                        pScsiReq->Control = cpu_to_le32(scsidir | qtag);
2102                        pScsiReq->DataLength = cpu_to_le32(dataSize);
2103
2104                } else {
2105                        printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2106                                "SCSI driver is not loaded. \n",
2107                                ioc->name, __FILE__, __LINE__);
2108                        rc = -EFAULT;
2109                        goto done_free_mem;
2110                }
2111                break;
2112
2113        case MPI_FUNCTION_SCSI_TASK_MGMT:
2114        {
2115                SCSITaskMgmt_t  *pScsiTm;
2116                pScsiTm = (SCSITaskMgmt_t *)mf;
2117                dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2118                        "\tTaskType=0x%x MsgFlags=0x%x "
2119                        "TaskMsgContext=0x%x id=%d channel=%d\n",
2120                        ioc->name, pScsiTm->TaskType, le32_to_cpu
2121                        (pScsiTm->TaskMsgContext), pScsiTm->MsgFlags,
2122                        pScsiTm->TargetID, pScsiTm->Bus));
2123                break;
2124        }
2125
2126        case MPI_FUNCTION_IOC_INIT:
2127                {
2128                        IOCInit_t       *pInit = (IOCInit_t *) mf;
2129                        u32             high_addr, sense_high;
2130
2131                        /* Verify that all entries in the IOC INIT match
2132                         * existing setup (and in LE format).
2133                         */
2134                        if (sizeof(dma_addr_t) == sizeof(u64)) {
2135                                high_addr = cpu_to_le32((u32)((u64)ioc->req_frames_dma >> 32));
2136                                sense_high= cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2137                        } else {
2138                                high_addr = 0;
2139                                sense_high= 0;
2140                        }
2141
2142                        if ((pInit->Flags != 0) || (pInit->MaxDevices != ioc->facts.MaxDevices) ||
2143                                (pInit->MaxBuses != ioc->facts.MaxBuses) ||
2144                                (pInit->ReplyFrameSize != cpu_to_le16(ioc->reply_sz)) ||
2145                                (pInit->HostMfaHighAddr != high_addr) ||
2146                                (pInit->SenseBufferHighAddr != sense_high)) {
2147                                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2148                                        "IOC_INIT issued with 1 or more incorrect parameters. Rejected.\n",
2149                                        ioc->name, __FILE__, __LINE__);
2150                                rc = -EFAULT;
2151                                goto done_free_mem;
2152                        }
2153                }
2154                break;
2155        default:
2156                /*
2157                 * MPI_FUNCTION_PORT_ENABLE
2158                 * MPI_FUNCTION_TARGET_CMD_BUFFER_POST
2159                 * MPI_FUNCTION_TARGET_ASSIST
2160                 * MPI_FUNCTION_TARGET_STATUS_SEND
2161                 * MPI_FUNCTION_TARGET_MODE_ABORT
2162                 * MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
2163                 * MPI_FUNCTION_IO_UNIT_RESET
2164                 * MPI_FUNCTION_HANDSHAKE
2165                 * MPI_FUNCTION_REPLY_FRAME_REMOVAL
2166                 * MPI_FUNCTION_EVENT_NOTIFICATION
2167                 *  (driver handles event notification)
2168                 * MPI_FUNCTION_EVENT_ACK
2169                 */
2170
2171                /*  What to do with these???  CHECK ME!!!
2172                        MPI_FUNCTION_FC_LINK_SRVC_BUF_POST
2173                        MPI_FUNCTION_FC_LINK_SRVC_RSP
2174                        MPI_FUNCTION_FC_ABORT
2175                        MPI_FUNCTION_LAN_SEND
2176                        MPI_FUNCTION_LAN_RECEIVE
2177                        MPI_FUNCTION_LAN_RESET
2178                */
2179
2180                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2181                        "Illegal request (function 0x%x) \n",
2182                        ioc->name, __FILE__, __LINE__, hdr->Function);
2183                rc = -EFAULT;
2184                goto done_free_mem;
2185        }
2186
2187        /* Add the SGL ( at most one data in SGE and one data out SGE )
2188         * In the case of two SGE's - the data out (write) will always
2189         * preceede the data in (read) SGE. psgList is used to free the
2190         * allocated memory.
2191         */
2192        psge = (char *) (((int *) mf) + karg.dataSgeOffset);
2193        flagsLength = 0;
2194
2195        if (karg.dataOutSize > 0)
2196                sgSize ++;
2197
2198        if (karg.dataInSize > 0)
2199                sgSize ++;
2200
2201        if (sgSize > 0) {
2202
2203                /* Set up the dataOut memory allocation */
2204                if (karg.dataOutSize > 0) {
2205                        if (karg.dataInSize > 0) {
2206                                flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2207                                                MPI_SGE_FLAGS_END_OF_BUFFER |
2208                                                MPI_SGE_FLAGS_DIRECTION)
2209                                                << MPI_SGE_FLAGS_SHIFT;
2210                        } else {
2211                                flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
2212                        }
2213                        flagsLength |= karg.dataOutSize;
2214                        bufOut.len = karg.dataOutSize;
2215                        bufOut.kptr = pci_alloc_consistent(
2216                                        ioc->pcidev, bufOut.len, &dma_addr_out);
2217
2218                        if (bufOut.kptr == NULL) {
2219                                rc = -ENOMEM;
2220                                goto done_free_mem;
2221                        } else {
2222                                /* Set up this SGE.
2223                                 * Copy to MF and to sglbuf
2224                                 */
2225                                ioc->add_sge(psge, flagsLength, dma_addr_out);
2226                                psge += ioc->SGE_size;
2227
2228                                /* Copy user data to kernel space.
2229                                 */
2230                                if (copy_from_user(bufOut.kptr,
2231                                                karg.dataOutBufPtr,
2232                                                bufOut.len)) {
2233                                        printk(MYIOC_s_ERR_FMT
2234                                                "%s@%d::mptctl_do_mpt_command - Unable "
2235                                                "to read user data "
2236                                                "struct @ %p\n",
2237                                                ioc->name, __FILE__, __LINE__,karg.dataOutBufPtr);
2238                                        rc =  -EFAULT;
2239                                        goto done_free_mem;
2240                                }
2241                        }
2242                }
2243
2244                if (karg.dataInSize > 0) {
2245                        flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
2246                        flagsLength |= karg.dataInSize;
2247
2248                        bufIn.len = karg.dataInSize;
2249                        bufIn.kptr = pci_alloc_consistent(ioc->pcidev,
2250                                        bufIn.len, &dma_addr_in);
2251
2252                        if (bufIn.kptr == NULL) {
2253                                rc = -ENOMEM;
2254                                goto done_free_mem;
2255                        } else {
2256                                /* Set up this SGE
2257                                 * Copy to MF and to sglbuf
2258                                 */
2259                                ioc->add_sge(psge, flagsLength, dma_addr_in);
2260                        }
2261                }
2262        } else  {
2263                /* Add a NULL SGE
2264                 */
2265                ioc->add_sge(psge, flagsLength, (dma_addr_t) -1);
2266        }
2267
2268        SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, hdr->MsgContext);
2269        INITIALIZE_MGMT_STATUS(ioc->ioctl_cmds.status)
2270        if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
2271
2272                mutex_lock(&ioc->taskmgmt_cmds.mutex);
2273                if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
2274                        mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2275                        goto done_free_mem;
2276                }
2277
2278                DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
2279
2280                if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
2281                    (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
2282                        mpt_put_msg_frame_hi_pri(mptctl_id, ioc, mf);
2283                else {
2284                        rc =mpt_send_handshake_request(mptctl_id, ioc,
2285                                sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP);
2286                        if (rc != 0) {
2287                                dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2288                                    "send_handshake FAILED! (ioc %p, mf %p)\n",
2289                                    ioc->name, ioc, mf));
2290                                mpt_clear_taskmgmt_in_progress_flag(ioc);
2291                                rc = -ENODATA;
2292                                mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2293                                goto done_free_mem;
2294                        }
2295                }
2296
2297        } else
2298                mpt_put_msg_frame(mptctl_id, ioc, mf);
2299
2300        /* Now wait for the command to complete */
2301        timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT;
2302retry_wait:
2303        timeleft = wait_for_completion_timeout(&ioc->ioctl_cmds.done,
2304                                HZ*timeout);
2305        if (!(ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2306                rc = -ETIME;
2307                dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: TIMED OUT!\n",
2308                    ioc->name, __func__));
2309                if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
2310                        if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
2311                                mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2312                        goto done_free_mem;
2313                }
2314                if (!timeleft) {
2315                        printk(MYIOC_s_WARN_FMT
2316                               "mpt cmd timeout, doorbell=0x%08x"
2317                               " function=0x%x\n",
2318                               ioc->name, mpt_GetIocState(ioc, 0), function);
2319                        if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
2320                                mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2321                        mptctl_timeout_expired(ioc, mf);
2322                        mf = NULL;
2323                } else
2324                        goto retry_wait;
2325                goto done_free_mem;
2326        }
2327
2328        if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
2329                mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2330
2331
2332        mf = NULL;
2333
2334        /* If a valid reply frame, copy to the user.
2335         * Offset 2: reply length in U32's
2336         */
2337        if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_RF_VALID) {
2338                if (karg.maxReplyBytes < ioc->reply_sz) {
2339                        sz = min(karg.maxReplyBytes,
2340                                4*ioc->ioctl_cmds.reply[2]);
2341                } else {
2342                         sz = min(ioc->reply_sz, 4*ioc->ioctl_cmds.reply[2]);
2343                }
2344                if (sz > 0) {
2345                        if (copy_to_user(karg.replyFrameBufPtr,
2346                                 ioc->ioctl_cmds.reply, sz)){
2347                                 printk(MYIOC_s_ERR_FMT
2348                                     "%s@%d::mptctl_do_mpt_command - "
2349                                 "Unable to write out reply frame %p\n",
2350                                 ioc->name, __FILE__, __LINE__, karg.replyFrameBufPtr);
2351                                 rc =  -ENODATA;
2352                                 goto done_free_mem;
2353                        }
2354                }
2355        }
2356
2357        /* If valid sense data, copy to user.
2358         */
2359        if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_SENSE_VALID) {
2360                sz = min(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE);
2361                if (sz > 0) {
2362                        if (copy_to_user(karg.senseDataPtr,
2363                                ioc->ioctl_cmds.sense, sz)) {
2364                                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2365                                "Unable to write sense data to user %p\n",
2366                                ioc->name, __FILE__, __LINE__,
2367                                karg.senseDataPtr);
2368                                rc =  -ENODATA;
2369                                goto done_free_mem;
2370                        }
2371                }
2372        }
2373
2374        /* If the overall status is _GOOD and data in, copy data
2375         * to user.
2376         */
2377        if ((ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD) &&
2378                                (karg.dataInSize > 0) && (bufIn.kptr)) {
2379
2380                if (copy_to_user(karg.dataInBufPtr,
2381                                 bufIn.kptr, karg.dataInSize)) {
2382                        printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2383                                "Unable to write data to user %p\n",
2384                                ioc->name, __FILE__, __LINE__,
2385                                karg.dataInBufPtr);
2386                        rc =  -ENODATA;
2387                }
2388        }
2389
2390done_free_mem:
2391
2392        CLEAR_MGMT_STATUS(ioc->ioctl_cmds.status)
2393        SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, 0);
2394
2395        /* Free the allocated memory.
2396         */
2397        if (bufOut.kptr != NULL) {
2398                pci_free_consistent(ioc->pcidev,
2399                        bufOut.len, (void *) bufOut.kptr, dma_addr_out);
2400        }
2401
2402        if (bufIn.kptr != NULL) {
2403                pci_free_consistent(ioc->pcidev,
2404                        bufIn.len, (void *) bufIn.kptr, dma_addr_in);
2405        }
2406
2407        /* mf is null if command issued successfully
2408         * otherwise, failure occurred after mf acquired.
2409         */
2410        if (mf)
2411                mpt_free_msg_frame(ioc, mf);
2412
2413        return rc;
2414}
2415
2416/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2417/* Prototype Routine for the HOST INFO command.
2418 *
2419 * Outputs:     None.
2420 * Return:      0 if successful
2421 *              -EFAULT if data unavailable
2422 *              -EBUSY  if previous command timeout and IOC reset is not complete.
2423 *              -ENODEV if no such device/adapter
2424 *              -ETIME  if timer expires
2425 *              -ENOMEM if memory allocation error
2426 */
2427static int
2428mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
2429{
2430        hp_host_info_t  __user *uarg = (void __user *) arg;
2431        MPT_ADAPTER             *ioc;
2432        struct pci_dev          *pdev;
2433        char                    *pbuf=NULL;
2434        dma_addr_t              buf_dma;
2435        hp_host_info_t          karg;
2436        CONFIGPARMS             cfg;
2437        ConfigPageHeader_t      hdr;
2438        int                     iocnum;
2439        int                     rc, cim_rev;
2440        ToolboxIstwiReadWriteRequest_t  *IstwiRWRequest;
2441        MPT_FRAME_HDR           *mf = NULL;
2442        MPIHeader_t             *mpi_hdr;
2443        unsigned long           timeleft;
2444        int                     retval;
2445
2446        /* Reset long to int. Should affect IA64 and SPARC only
2447         */
2448        if (data_size == sizeof(hp_host_info_t))
2449                cim_rev = 1;
2450        else if (data_size == sizeof(hp_host_info_rev0_t))
2451                cim_rev = 0;    /* obsolete */
2452        else
2453                return -EFAULT;
2454
2455        if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) {
2456                printk(KERN_ERR MYNAM "%s@%d::mptctl_hp_host_info - "
2457                        "Unable to read in hp_host_info struct @ %p\n",
2458                                __FILE__, __LINE__, uarg);
2459                return -EFAULT;
2460        }
2461
2462        if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
2463            (ioc == NULL)) {
2464                printk(KERN_DEBUG MYNAM "%s::mptctl_hp_hostinfo() @%d - ioc%d not found!\n",
2465                                __FILE__, __LINE__, iocnum);
2466                return -ENODEV;
2467        }
2468        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": mptctl_hp_hostinfo called.\n",
2469            ioc->name));
2470
2471        /* Fill in the data and return the structure to the calling
2472         * program
2473         */
2474        pdev = (struct pci_dev *) ioc->pcidev;
2475
2476        karg.vendor = pdev->vendor;
2477        karg.device = pdev->device;
2478        karg.subsystem_id = pdev->subsystem_device;
2479        karg.subsystem_vendor = pdev->subsystem_vendor;
2480        karg.devfn = pdev->devfn;
2481        karg.bus = pdev->bus->number;
2482
2483        /* Save the SCSI host no. if
2484         * SCSI driver loaded
2485         */
2486        if (ioc->sh != NULL)
2487                karg.host_no = ioc->sh->host_no;
2488        else
2489                karg.host_no =  -1;
2490
2491        /* Reformat the fw_version into a string
2492         */
2493        karg.fw_version[0] = ioc->facts.FWVersion.Struct.Major >= 10 ?
2494                ((ioc->facts.FWVersion.Struct.Major / 10) + '0') : '0';
2495        karg.fw_version[1] = (ioc->facts.FWVersion.Struct.Major % 10 ) + '0';
2496        karg.fw_version[2] = '.';
2497        karg.fw_version[3] = ioc->facts.FWVersion.Struct.Minor >= 10 ?
2498                ((ioc->facts.FWVersion.Struct.Minor / 10) + '0') : '0';
2499        karg.fw_version[4] = (ioc->facts.FWVersion.Struct.Minor % 10 ) + '0';
2500        karg.fw_version[5] = '.';
2501        karg.fw_version[6] = ioc->facts.FWVersion.Struct.Unit >= 10 ?
2502                ((ioc->facts.FWVersion.Struct.Unit / 10) + '0') : '0';
2503        karg.fw_version[7] = (ioc->facts.FWVersion.Struct.Unit % 10 ) + '0';
2504        karg.fw_version[8] = '.';
2505        karg.fw_version[9] = ioc->facts.FWVersion.Struct.Dev >= 10 ?
2506                ((ioc->facts.FWVersion.Struct.Dev / 10) + '0') : '0';
2507        karg.fw_version[10] = (ioc->facts.FWVersion.Struct.Dev % 10 ) + '0';
2508        karg.fw_version[11] = '\0';
2509
2510        /* Issue a config request to get the device serial number
2511         */
2512        hdr.PageVersion = 0;
2513        hdr.PageLength = 0;
2514        hdr.PageNumber = 0;
2515        hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
2516        cfg.cfghdr.hdr = &hdr;
2517        cfg.physAddr = -1;
2518        cfg.pageAddr = 0;
2519        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2520        cfg.dir = 0;    /* read */
2521        cfg.timeout = 10;
2522
2523        strncpy(karg.serial_number, " ", 24);
2524        if (mpt_config(ioc, &cfg) == 0) {
2525                if (cfg.cfghdr.hdr->PageLength > 0) {
2526                        /* Issue the second config page request */
2527                        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2528
2529                        pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
2530                        if (pbuf) {
2531                                cfg.physAddr = buf_dma;
2532                                if (mpt_config(ioc, &cfg) == 0) {
2533                                        ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf;
2534                                        if (strlen(pdata->BoardTracerNumber) > 1) {
2535                                                strncpy(karg.serial_number,                                                                         pdata->BoardTracerNumber, 24);
2536                                                karg.serial_number[24-1]='\0';
2537                                        }
2538                                }
2539                                pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
2540                                pbuf = NULL;
2541                        }
2542                }
2543        }
2544        rc = mpt_GetIocState(ioc, 1);
2545        switch (rc) {
2546        case MPI_IOC_STATE_OPERATIONAL:
2547                karg.ioc_status =  HP_STATUS_OK;
2548                break;
2549
2550        case MPI_IOC_STATE_FAULT:
2551                karg.ioc_status =  HP_STATUS_FAILED;
2552                break;
2553
2554        case MPI_IOC_STATE_RESET:
2555        case MPI_IOC_STATE_READY:
2556        default:
2557                karg.ioc_status =  HP_STATUS_OTHER;
2558                break;
2559        }
2560
2561        karg.base_io_addr = pci_resource_start(pdev, 0);
2562
2563        if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))
2564                karg.bus_phys_width = HP_BUS_WIDTH_UNK;
2565        else
2566                karg.bus_phys_width = HP_BUS_WIDTH_16;
2567
2568        karg.hard_resets = 0;
2569        karg.soft_resets = 0;
2570        karg.timeouts = 0;
2571        if (ioc->sh != NULL) {
2572                MPT_SCSI_HOST *hd =  shost_priv(ioc->sh);
2573
2574                if (hd && (cim_rev == 1)) {
2575                        karg.hard_resets = ioc->hard_resets;
2576                        karg.soft_resets = ioc->soft_resets;
2577                        karg.timeouts = ioc->timeouts;
2578                }
2579        }
2580
2581        /* 
2582         * Gather ISTWI(Industry Standard Two Wire Interface) Data
2583         */
2584        if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) {
2585                dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
2586                        "%s, no msg frames!!\n", ioc->name, __func__));
2587                goto out;
2588        }
2589
2590        IstwiRWRequest = (ToolboxIstwiReadWriteRequest_t *)mf;
2591        mpi_hdr = (MPIHeader_t *) mf;
2592        memset(IstwiRWRequest,0,sizeof(ToolboxIstwiReadWriteRequest_t));
2593        IstwiRWRequest->Function = MPI_FUNCTION_TOOLBOX;
2594        IstwiRWRequest->Tool = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
2595        IstwiRWRequest->MsgContext = mpi_hdr->MsgContext;
2596        IstwiRWRequest->Flags = MPI_TB_ISTWI_FLAGS_READ;
2597        IstwiRWRequest->NumAddressBytes = 0x01;
2598        IstwiRWRequest->DataLength = cpu_to_le16(0x04);
2599        if (pdev->devfn & 1)
2600                IstwiRWRequest->DeviceAddr = 0xB2;
2601        else
2602                IstwiRWRequest->DeviceAddr = 0xB0;
2603
2604        pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma);
2605        if (!pbuf)
2606                goto out;
2607        ioc->add_sge((char *)&IstwiRWRequest->SGL,
2608            (MPT_SGE_FLAGS_SSIMPLE_READ|4), buf_dma);
2609
2610        retval = 0;
2611        SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context,
2612                                IstwiRWRequest->MsgContext);
2613        INITIALIZE_MGMT_STATUS(ioc->ioctl_cmds.status)
2614        mpt_put_msg_frame(mptctl_id, ioc, mf);
2615
2616retry_wait:
2617        timeleft = wait_for_completion_timeout(&ioc->ioctl_cmds.done,
2618                        HZ*MPT_IOCTL_DEFAULT_TIMEOUT);
2619        if (!(ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2620                retval = -ETIME;
2621                printk(MYIOC_s_WARN_FMT "%s: failed\n", ioc->name, __func__);
2622                if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
2623                        mpt_free_msg_frame(ioc, mf);
2624                        goto out;
2625                }
2626                if (!timeleft) {
2627                        printk(MYIOC_s_WARN_FMT
2628                               "HOST INFO command timeout, doorbell=0x%08x\n",
2629                               ioc->name, mpt_GetIocState(ioc, 0));
2630                        mptctl_timeout_expired(ioc, mf);
2631                } else
2632                        goto retry_wait;
2633                goto out;
2634        }
2635
2636        /*
2637         *ISTWI Data Definition
2638         * pbuf[0] = FW_VERSION = 0x4
2639         * pbuf[1] = Bay Count = 6 or 4 or 2, depending on
2640         *  the config, you should be seeing one out of these three values
2641         * pbuf[2] = Drive Installed Map = bit pattern depend on which
2642         *   bays have drives in them
2643         * pbuf[3] = Checksum (0x100 = (byte0 + byte2 + byte3)
2644         */
2645        if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_RF_VALID)
2646                karg.rsvd = *(u32 *)pbuf;
2647
2648 out:
2649        CLEAR_MGMT_STATUS(ioc->ioctl_cmds.status)
2650        SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, 0);
2651
2652        if (pbuf)
2653                pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma);
2654
2655        /* Copy the data from kernel memory to user memory
2656         */
2657        if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) {
2658                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_hpgethostinfo - "
2659                        "Unable to write out hp_host_info @ %p\n",
2660                        ioc->name, __FILE__, __LINE__, uarg);
2661                return -EFAULT;
2662        }
2663
2664        return 0;
2665
2666}
2667
2668/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2669/* Prototype Routine for the TARGET INFO command.
2670 *
2671 * Outputs:     None.
2672 * Return:      0 if successful
2673 *              -EFAULT if data unavailable
2674 *              -EBUSY  if previous command timeout and IOC reset is not complete.
2675 *              -ENODEV if no such device/adapter
2676 *              -ETIME  if timer expires
2677 *              -ENOMEM if memory allocation error
2678 */
2679static int
2680mptctl_hp_targetinfo(unsigned long arg)
2681{
2682        hp_target_info_t __user *uarg = (void __user *) arg;
2683        SCSIDevicePage0_t       *pg0_alloc;
2684        SCSIDevicePage3_t       *pg3_alloc;
2685        MPT_ADAPTER             *ioc;
2686        MPT_SCSI_HOST           *hd = NULL;
2687        hp_target_info_t        karg;
2688        int                     iocnum;
2689        int                     data_sz;
2690        dma_addr_t              page_dma;
2691        CONFIGPARMS             cfg;
2692        ConfigPageHeader_t      hdr;
2693        int                     tmp, np, rc = 0;
2694
2695        if (copy_from_user(&karg, uarg, sizeof(hp_target_info_t))) {
2696                printk(KERN_ERR MYNAM "%s@%d::mptctl_hp_targetinfo - "
2697                        "Unable to read in hp_host_targetinfo struct @ %p\n",
2698                                __FILE__, __LINE__, uarg);
2699                return -EFAULT;
2700        }
2701
2702        if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
2703                (ioc == NULL)) {
2704                printk(KERN_DEBUG MYNAM "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n",
2705                                __FILE__, __LINE__, iocnum);
2706                return -ENODEV;
2707        }
2708        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_hp_targetinfo called.\n",
2709            ioc->name));
2710
2711        /*  There is nothing to do for FCP parts.
2712         */
2713        if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))
2714                return 0;
2715
2716        if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL))
2717                return 0;
2718
2719        if (ioc->sh->host_no != karg.hdr.host)
2720                return -ENODEV;
2721
2722       /* Get the data transfer speeds
2723        */
2724        data_sz = ioc->spi_data.sdp0length * 4;
2725        pg0_alloc = (SCSIDevicePage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
2726        if (pg0_alloc) {
2727                hdr.PageVersion = ioc->spi_data.sdp0version;
2728                hdr.PageLength = data_sz;
2729                hdr.PageNumber = 0;
2730                hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
2731
2732                cfg.cfghdr.hdr = &hdr;
2733                cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2734                cfg.dir = 0;
2735                cfg.timeout = 0;
2736                cfg.physAddr = page_dma;
2737
2738                cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
2739
2740                if ((rc = mpt_config(ioc, &cfg)) == 0) {
2741                        np = le32_to_cpu(pg0_alloc->NegotiatedParameters);
2742                        karg.negotiated_width = np & MPI_SCSIDEVPAGE0_NP_WIDE ?
2743                                        HP_BUS_WIDTH_16 : HP_BUS_WIDTH_8;
2744
2745                        if (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) {
2746                                tmp = (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
2747                                if (tmp < 0x09)
2748                                        karg.negotiated_speed = HP_DEV_SPEED_ULTRA320;
2749                                else if (tmp <= 0x09)
2750                                        karg.negotiated_speed = HP_DEV_SPEED_ULTRA160;
2751                                else if (tmp <= 0x0A)
2752                                        karg.negotiated_speed = HP_DEV_SPEED_ULTRA2;
2753                                else if (tmp <= 0x0C)
2754                                        karg.negotiated_speed = HP_DEV_SPEED_ULTRA;
2755                                else if (tmp <= 0x25)
2756                                        karg.negotiated_speed = HP_DEV_SPEED_FAST;
2757                                else
2758                                        karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
2759                        } else
2760                                karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
2761                }
2762
2763                pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg0_alloc, page_dma);
2764        }
2765
2766        /* Set defaults
2767         */
2768        karg.message_rejects = -1;
2769        karg.phase_errors = -1;
2770        karg.parity_errors = -1;
2771        karg.select_timeouts = -1;
2772
2773        /* Get the target error parameters
2774         */
2775        hdr.PageVersion = 0;
2776        hdr.PageLength = 0;
2777        hdr.PageNumber = 3;
2778        hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
2779
2780        cfg.cfghdr.hdr = &hdr;
2781        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2782        cfg.dir = 0;
2783        cfg.timeout = 0;
2784        cfg.physAddr = -1;
2785        if ((mpt_config(ioc, &cfg) == 0) && (cfg.cfghdr.hdr->PageLength > 0)) {
2786                /* Issue the second config page request */
2787                cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2788                data_sz = (int) cfg.cfghdr.hdr->PageLength * 4;
2789                pg3_alloc = (SCSIDevicePage3_t *) pci_alloc_consistent(
2790                                                        ioc->pcidev, data_sz, &page_dma);
2791                if (pg3_alloc) {
2792                        cfg.physAddr = page_dma;
2793                        cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
2794                        if ((rc = mpt_config(ioc, &cfg)) == 0) {
2795                                karg.message_rejects = (u32) le16_to_cpu(pg3_alloc->MsgRejectCount);
2796                                karg.phase_errors = (u32) le16_to_cpu(pg3_alloc->PhaseErrorCount);
2797                                karg.parity_errors = (u32) le16_to_cpu(pg3_alloc->ParityErrorCount);
2798                        }
2799                        pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg3_alloc, page_dma);
2800                }
2801        }
2802        hd = shost_priv(ioc->sh);
2803        if (hd != NULL)
2804                karg.select_timeouts = hd->sel_timeout[karg.hdr.id];
2805
2806        /* Copy the data from kernel memory to user memory
2807         */
2808        if (copy_to_user((char __user *)arg, &karg, sizeof(hp_target_info_t))) {
2809                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_hp_target_info - "
2810                        "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
2811                        ioc->name, __FILE__, __LINE__, uarg);
2812                return -EFAULT;
2813        }
2814
2815        return 0;
2816}
2817
2818/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2819
2820static const struct file_operations mptctl_fops = {
2821        .owner =        THIS_MODULE,
2822        .llseek =       no_llseek,
2823        .fasync =       mptctl_fasync,
2824        .unlocked_ioctl = mptctl_ioctl,
2825        .release =      mptctl_release,
2826#ifdef CONFIG_COMPAT
2827        .compat_ioctl = compat_mpctl_ioctl,
2828#endif
2829};
2830
2831static struct miscdevice mptctl_miscdev = {
2832        MPT_MINOR,
2833        MYNAM,
2834        &mptctl_fops
2835};
2836
2837/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2838
2839#ifdef CONFIG_COMPAT
2840
2841static int
2842compat_mptfwxfer_ioctl(struct file *filp, unsigned int cmd,
2843                        unsigned long arg)
2844{
2845        struct mpt_fw_xfer32 kfw32;
2846        struct mpt_fw_xfer kfw;
2847        MPT_ADAPTER *iocp = NULL;
2848        int iocnum, iocnumX;
2849        int nonblock = (filp->f_flags & O_NONBLOCK);
2850        int ret;
2851
2852
2853        if (copy_from_user(&kfw32, (char __user *)arg, sizeof(kfw32)))
2854                return -EFAULT;
2855
2856        /* Verify intended MPT adapter */
2857        iocnumX = kfw32.iocnum & 0xFF;
2858        if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
2859            (iocp == NULL)) {
2860                printk(KERN_DEBUG MYNAM "::compat_mptfwxfer_ioctl @%d - ioc%d not found!\n",
2861                        __LINE__, iocnumX);
2862                return -ENODEV;
2863        }
2864
2865        if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
2866                return ret;
2867
2868        dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "compat_mptfwxfer_ioctl() called\n",
2869            iocp->name));
2870        kfw.iocnum = iocnum;
2871        kfw.fwlen = kfw32.fwlen;
2872        kfw.bufp = compat_ptr(kfw32.bufp);
2873
2874        ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);
2875
2876        mutex_unlock(&iocp->ioctl_cmds.mutex);
2877
2878        return ret;
2879}
2880
2881static int
2882compat_mpt_command(struct file *filp, unsigned int cmd,
2883                        unsigned long arg)
2884{
2885        struct mpt_ioctl_command32 karg32;
2886        struct mpt_ioctl_command32 __user *uarg = (struct mpt_ioctl_command32 __user *) arg;
2887        struct mpt_ioctl_command karg;
2888        MPT_ADAPTER *iocp = NULL;
2889        int iocnum, iocnumX;
2890        int nonblock = (filp->f_flags & O_NONBLOCK);
2891        int ret;
2892
2893        if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32)))
2894                return -EFAULT;
2895
2896        /* Verify intended MPT adapter */
2897        iocnumX = karg32.hdr.iocnum & 0xFF;
2898        if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
2899            (iocp == NULL)) {
2900                printk(KERN_DEBUG MYNAM "::compat_mpt_command @%d - ioc%d not found!\n",
2901                        __LINE__, iocnumX);
2902                return -ENODEV;
2903        }
2904
2905        if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
2906                return ret;
2907
2908        dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "compat_mpt_command() called\n",
2909            iocp->name));
2910        /* Copy data to karg */
2911        karg.hdr.iocnum = karg32.hdr.iocnum;
2912        karg.hdr.port = karg32.hdr.port;
2913        karg.timeout = karg32.timeout;
2914        karg.maxReplyBytes = karg32.maxReplyBytes;
2915
2916        karg.dataInSize = karg32.dataInSize;
2917        karg.dataOutSize = karg32.dataOutSize;
2918        karg.maxSenseBytes = karg32.maxSenseBytes;
2919        karg.dataSgeOffset = karg32.dataSgeOffset;
2920
2921        karg.replyFrameBufPtr = (char __user *)(unsigned long)karg32.replyFrameBufPtr;
2922        karg.dataInBufPtr = (char __user *)(unsigned long)karg32.dataInBufPtr;
2923        karg.dataOutBufPtr = (char __user *)(unsigned long)karg32.dataOutBufPtr;
2924        karg.senseDataPtr = (char __user *)(unsigned long)karg32.senseDataPtr;
2925
2926        /* Pass new structure to do_mpt_command
2927         */
2928        ret = mptctl_do_mpt_command (karg, &uarg->MF);
2929
2930        mutex_unlock(&iocp->ioctl_cmds.mutex);
2931
2932        return ret;
2933}
2934
2935static long compat_mpctl_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
2936{
2937        long ret;
2938        mutex_lock(&mpctl_mutex);
2939        switch (cmd) {
2940        case MPTIOCINFO:
2941        case MPTIOCINFO1:
2942        case MPTIOCINFO2:
2943        case MPTTARGETINFO:
2944        case MPTEVENTQUERY:
2945        case MPTEVENTENABLE:
2946        case MPTEVENTREPORT:
2947        case MPTHARDRESET:
2948        case HP_GETHOSTINFO:
2949        case HP_GETTARGETINFO:
2950        case MPTTEST:
2951                ret = __mptctl_ioctl(f, cmd, arg);
2952                break;
2953        case MPTCOMMAND32:
2954                ret = compat_mpt_command(f, cmd, arg);
2955                break;
2956        case MPTFWDOWNLOAD32:
2957                ret = compat_mptfwxfer_ioctl(f, cmd, arg);
2958                break;
2959        default:
2960                ret = -ENOIOCTLCMD;
2961                break;
2962        }
2963        mutex_unlock(&mpctl_mutex);
2964        return ret;
2965}
2966
2967#endif
2968
2969
2970/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2971/*
2972 *      mptctl_probe - Installs ioctl devices per bus.
2973 *      @pdev: Pointer to pci_dev structure
2974 *
2975 *      Returns 0 for success, non-zero for failure.
2976 *
2977 */
2978
2979static int
2980mptctl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2981{
2982        MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2983
2984        mutex_init(&ioc->ioctl_cmds.mutex);
2985        init_completion(&ioc->ioctl_cmds.done);
2986        return 0;
2987}
2988
2989/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2990/*
2991 *      mptctl_remove - Removed ioctl devices
2992 *      @pdev: Pointer to pci_dev structure
2993 *
2994 *
2995 */
2996static void
2997mptctl_remove(struct pci_dev *pdev)
2998{
2999}
3000
3001static struct mpt_pci_driver mptctl_driver = {
3002  .probe                = mptctl_probe,
3003  .remove               = mptctl_remove,
3004};
3005
3006/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3007static int __init mptctl_init(void)
3008{
3009        int err;
3010        int where = 1;
3011
3012        show_mptmod_ver(my_NAME, my_VERSION);
3013
3014        mpt_device_driver_register(&mptctl_driver, MPTCTL_DRIVER);
3015
3016        /* Register this device */
3017        err = misc_register(&mptctl_miscdev);
3018        if (err < 0) {
3019                printk(KERN_ERR MYNAM ": Can't register misc device [minor=%d].\n", MPT_MINOR);
3020                goto out_fail;
3021        }
3022        printk(KERN_INFO MYNAM ": Registered with Fusion MPT base driver\n");
3023        printk(KERN_INFO MYNAM ": /dev/%s @ (major,minor=%d,%d)\n",
3024                         mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
3025
3026        /*
3027         *  Install our handler
3028         */
3029        ++where;
3030        mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER,
3031            "mptctl_reply");
3032        if (!mptctl_id || mptctl_id >= MPT_MAX_PROTOCOL_DRIVERS) {
3033                printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
3034                misc_deregister(&mptctl_miscdev);
3035                err = -EBUSY;
3036                goto out_fail;
3037        }
3038
3039        mptctl_taskmgmt_id = mpt_register(mptctl_taskmgmt_reply, MPTCTL_DRIVER,
3040            "mptctl_taskmgmt_reply");
3041        if (!mptctl_taskmgmt_id || mptctl_taskmgmt_id >= MPT_MAX_PROTOCOL_DRIVERS) {
3042                printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
3043                mpt_deregister(mptctl_id);
3044                misc_deregister(&mptctl_miscdev);
3045                err = -EBUSY;
3046                goto out_fail;
3047        }
3048
3049        mpt_reset_register(mptctl_id, mptctl_ioc_reset);
3050        mpt_event_register(mptctl_id, mptctl_event_process);
3051
3052        return 0;
3053
3054out_fail:
3055
3056        mpt_device_driver_deregister(MPTCTL_DRIVER);
3057
3058        return err;
3059}
3060
3061/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3062static void mptctl_exit(void)
3063{
3064        misc_deregister(&mptctl_miscdev);
3065        printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n",
3066                         mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
3067
3068        /* De-register event handler from base module */
3069        mpt_event_deregister(mptctl_id);
3070
3071        /* De-register reset handler from base module */
3072        mpt_reset_deregister(mptctl_id);
3073
3074        /* De-register callback handler from base module */
3075        mpt_deregister(mptctl_taskmgmt_id);
3076        mpt_deregister(mptctl_id);
3077
3078        mpt_device_driver_deregister(MPTCTL_DRIVER);
3079
3080}
3081
3082/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3083
3084module_init(mptctl_init);
3085module_exit(mptctl_exit);
3086