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        u8                      revision;
1254        struct scsi_device      *sdev;
1255        VirtDevice              *vdevice;
1256
1257        /* Add of PCI INFO results in unaligned access for
1258         * IA64 and Sparc. Reset long to int. Return no PCI
1259         * data for obsolete format.
1260         */
1261        if (data_size == sizeof(struct mpt_ioctl_iocinfo_rev0))
1262                cim_rev = 0;
1263        else if (data_size == sizeof(struct mpt_ioctl_iocinfo_rev1))
1264                cim_rev = 1;
1265        else if (data_size == sizeof(struct mpt_ioctl_iocinfo))
1266                cim_rev = 2;
1267        else if (data_size == (sizeof(struct mpt_ioctl_iocinfo_rev0)+12))
1268                cim_rev = 0;    /* obsolete */
1269        else
1270                return -EFAULT;
1271
1272        karg = kmalloc(data_size, GFP_KERNEL);
1273        if (karg == NULL) {
1274                printk(KERN_ERR MYNAM "%s::mpt_ioctl_iocinfo() @%d - no memory available!\n",
1275                                __FILE__, __LINE__);
1276                return -ENOMEM;
1277        }
1278
1279        if (copy_from_user(karg, uarg, data_size)) {
1280                printk(KERN_ERR MYNAM "%s@%d::mptctl_getiocinfo - "
1281                        "Unable to read in mpt_ioctl_iocinfo struct @ %p\n",
1282                                __FILE__, __LINE__, uarg);
1283                kfree(karg);
1284                return -EFAULT;
1285        }
1286
1287        if (((iocnum = mpt_verify_adapter(karg->hdr.iocnum, &ioc)) < 0) ||
1288            (ioc == NULL)) {
1289                printk(KERN_DEBUG MYNAM "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n",
1290                                __FILE__, __LINE__, iocnum);
1291                kfree(karg);
1292                return -ENODEV;
1293        }
1294
1295        /* Verify the data transfer size is correct. */
1296        if (karg->hdr.maxDataSize != data_size) {
1297                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - "
1298                        "Structure size mismatch. Command not completed.\n",
1299                        ioc->name, __FILE__, __LINE__);
1300                kfree(karg);
1301                return -EFAULT;
1302        }
1303
1304        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_getiocinfo called.\n",
1305            ioc->name));
1306
1307        /* Fill in the data and return the structure to the calling
1308         * program
1309         */
1310        if (ioc->bus_type == SAS)
1311                karg->adapterType = MPT_IOCTL_INTERFACE_SAS;
1312        else if (ioc->bus_type == FC)
1313                karg->adapterType = MPT_IOCTL_INTERFACE_FC;
1314        else
1315                karg->adapterType = MPT_IOCTL_INTERFACE_SCSI;
1316
1317        if (karg->hdr.port > 1) {
1318                kfree(karg);
1319                return -EINVAL;
1320        }
1321        port = karg->hdr.port;
1322
1323        karg->port = port;
1324        pdev = (struct pci_dev *) ioc->pcidev;
1325
1326        karg->pciId = pdev->device;
1327        pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1328        karg->hwRev = revision;
1329        karg->subSystemDevice = pdev->subsystem_device;
1330        karg->subSystemVendor = pdev->subsystem_vendor;
1331
1332        if (cim_rev == 1) {
1333                /* Get the PCI bus, device, and function numbers for the IOC
1334                 */
1335                karg->pciInfo.u.bits.busNumber = pdev->bus->number;
1336                karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
1337                karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1338        } else if (cim_rev == 2) {
1339                /* Get the PCI bus, device, function and segment ID numbers
1340                   for the IOC */
1341                karg->pciInfo.u.bits.busNumber = pdev->bus->number;
1342                karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
1343                karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1344                karg->pciInfo.segmentID = pci_domain_nr(pdev->bus);
1345        }
1346
1347        /* Get number of devices
1348         */
1349        karg->numDevices = 0;
1350        if (ioc->sh) {
1351                shost_for_each_device(sdev, ioc->sh) {
1352                        vdevice = sdev->hostdata;
1353                        if (vdevice == NULL || vdevice->vtarget == NULL)
1354                                continue;
1355                        if (vdevice->vtarget->tflags &
1356                            MPT_TARGET_FLAGS_RAID_COMPONENT)
1357                                continue;
1358                        karg->numDevices++;
1359                }
1360        }
1361
1362        /* Set the BIOS and FW Version
1363         */
1364        karg->FWVersion = ioc->facts.FWVersion.Word;
1365        karg->BIOSVersion = ioc->biosVersion;
1366
1367        /* Set the Version Strings.
1368         */
1369        strncpy (karg->driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH);
1370        karg->driverVersion[MPT_IOCTL_VERSION_LENGTH-1]='\0';
1371
1372        karg->busChangeEvent = 0;
1373        karg->hostId = ioc->pfacts[port].PortSCSIID;
1374        karg->rsvd[0] = karg->rsvd[1] = 0;
1375
1376        /* Copy the data from kernel memory to user memory
1377         */
1378        if (copy_to_user((char __user *)arg, karg, data_size)) {
1379                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - "
1380                        "Unable to write out mpt_ioctl_iocinfo struct @ %p\n",
1381                        ioc->name, __FILE__, __LINE__, uarg);
1382                kfree(karg);
1383                return -EFAULT;
1384        }
1385
1386        kfree(karg);
1387        return 0;
1388}
1389
1390/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1391/*
1392 *      mptctl_gettargetinfo - Query the host adapter for target information.
1393 *      @arg: User space argument
1394 *
1395 * Outputs:     None.
1396 * Return:      0 if successful
1397 *              -EFAULT if data unavailable
1398 *              -ENODEV  if no such device/adapter
1399 */
1400static int
1401mptctl_gettargetinfo (unsigned long arg)
1402{
1403        struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg;
1404        struct mpt_ioctl_targetinfo karg;
1405        MPT_ADAPTER             *ioc;
1406        VirtDevice              *vdevice;
1407        char                    *pmem;
1408        int                     *pdata;
1409        int                     iocnum;
1410        int                     numDevices = 0;
1411        int                     lun;
1412        int                     maxWordsLeft;
1413        int                     numBytes;
1414        u8                      port;
1415        struct scsi_device      *sdev;
1416
1417        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
1418                printk(KERN_ERR MYNAM "%s@%d::mptctl_gettargetinfo - "
1419                        "Unable to read in mpt_ioctl_targetinfo struct @ %p\n",
1420                                __FILE__, __LINE__, uarg);
1421                return -EFAULT;
1422        }
1423
1424        if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1425            (ioc == NULL)) {
1426                printk(KERN_DEBUG MYNAM "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n",
1427                                __FILE__, __LINE__, iocnum);
1428                return -ENODEV;
1429        }
1430
1431        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_gettargetinfo called.\n",
1432            ioc->name));
1433        /* Get the port number and set the maximum number of bytes
1434         * in the returned structure.
1435         * Ignore the port setting.
1436         */
1437        numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
1438        maxWordsLeft = numBytes/sizeof(int);
1439        port = karg.hdr.port;
1440
1441        if (maxWordsLeft <= 0) {
1442                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n",
1443                        ioc->name, __FILE__, __LINE__);
1444                return -ENOMEM;
1445        }
1446
1447        /* Fill in the data and return the structure to the calling
1448         * program
1449         */
1450
1451        /* struct mpt_ioctl_targetinfo does not contain sufficient space
1452         * for the target structures so when the IOCTL is called, there is
1453         * not sufficient stack space for the structure. Allocate memory,
1454         * populate the memory, copy back to the user, then free memory.
1455         * targetInfo format:
1456         * bits 31-24: reserved
1457         *      23-16: LUN
1458         *      15- 8: Bus Number
1459         *       7- 0: Target ID
1460         */
1461        pmem = kzalloc(numBytes, GFP_KERNEL);
1462        if (!pmem) {
1463                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n",
1464                        ioc->name, __FILE__, __LINE__);
1465                return -ENOMEM;
1466        }
1467        pdata =  (int *) pmem;
1468
1469        /* Get number of devices
1470         */
1471        if (ioc->sh){
1472                shost_for_each_device(sdev, ioc->sh) {
1473                        if (!maxWordsLeft)
1474                                continue;
1475                        vdevice = sdev->hostdata;
1476                        if (vdevice == NULL || vdevice->vtarget == NULL)
1477                                continue;
1478                        if (vdevice->vtarget->tflags &
1479                            MPT_TARGET_FLAGS_RAID_COMPONENT)
1480                                continue;
1481                        lun = (vdevice->vtarget->raidVolume) ? 0x80 : vdevice->lun;
1482                        *pdata = (((u8)lun << 16) + (vdevice->vtarget->channel << 8) +
1483                            (vdevice->vtarget->id ));
1484                        pdata++;
1485                        numDevices++;
1486                        --maxWordsLeft;
1487                }
1488        }
1489        karg.numDevices = numDevices;
1490
1491        /* Copy part of the data from kernel memory to user memory
1492         */
1493        if (copy_to_user((char __user *)arg, &karg,
1494                                sizeof(struct mpt_ioctl_targetinfo))) {
1495                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo - "
1496                        "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
1497                        ioc->name, __FILE__, __LINE__, uarg);
1498                kfree(pmem);
1499                return -EFAULT;
1500        }
1501
1502        /* Copy the remaining data from kernel memory to user memory
1503         */
1504        if (copy_to_user(uarg->targetInfo, pmem, numBytes)) {
1505                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo - "
1506                        "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
1507                        ioc->name, __FILE__, __LINE__, pdata);
1508                kfree(pmem);
1509                return -EFAULT;
1510        }
1511
1512        kfree(pmem);
1513
1514        return 0;
1515}
1516
1517/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1518/* MPT IOCTL Test function.
1519 *
1520 * Outputs:     None.
1521 * Return:      0 if successful
1522 *              -EFAULT if data unavailable
1523 *              -ENODEV  if no such device/adapter
1524 */
1525static int
1526mptctl_readtest (unsigned long arg)
1527{
1528        struct mpt_ioctl_test __user *uarg = (void __user *) arg;
1529        struct mpt_ioctl_test    karg;
1530        MPT_ADAPTER *ioc;
1531        int iocnum;
1532
1533        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) {
1534                printk(KERN_ERR MYNAM "%s@%d::mptctl_readtest - "
1535                        "Unable to read in mpt_ioctl_test struct @ %p\n",
1536                                __FILE__, __LINE__, uarg);
1537                return -EFAULT;
1538        }
1539
1540        if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1541            (ioc == NULL)) {
1542                printk(KERN_DEBUG MYNAM "%s::mptctl_readtest() @%d - ioc%d not found!\n",
1543                                __FILE__, __LINE__, iocnum);
1544                return -ENODEV;
1545        }
1546
1547        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_readtest called.\n",
1548            ioc->name));
1549        /* Fill in the data and return the structure to the calling
1550         * program
1551         */
1552
1553#ifdef MFCNT
1554        karg.chip_type = ioc->mfcnt;
1555#else
1556        karg.chip_type = ioc->pcidev->device;
1557#endif
1558        strncpy (karg.name, ioc->name, MPT_MAX_NAME);
1559        karg.name[MPT_MAX_NAME-1]='\0';
1560        strncpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH);
1561        karg.product[MPT_PRODUCT_LENGTH-1]='\0';
1562
1563        /* Copy the data from kernel memory to user memory
1564         */
1565        if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_test))) {
1566                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_readtest - "
1567                        "Unable to write out mpt_ioctl_test struct @ %p\n",
1568                        ioc->name, __FILE__, __LINE__, uarg);
1569                return -EFAULT;
1570        }
1571
1572        return 0;
1573}
1574
1575/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1576/*
1577 *      mptctl_eventquery - Query the host adapter for the event types
1578 *      that are being logged.
1579 *      @arg: User space argument
1580 *
1581 * Outputs:     None.
1582 * Return:      0 if successful
1583 *              -EFAULT if data unavailable
1584 *              -ENODEV  if no such device/adapter
1585 */
1586static int
1587mptctl_eventquery (unsigned long arg)
1588{
1589        struct mpt_ioctl_eventquery __user *uarg = (void __user *) arg;
1590        struct mpt_ioctl_eventquery      karg;
1591        MPT_ADAPTER *ioc;
1592        int iocnum;
1593
1594        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) {
1595                printk(KERN_ERR MYNAM "%s@%d::mptctl_eventquery - "
1596                        "Unable to read in mpt_ioctl_eventquery struct @ %p\n",
1597                                __FILE__, __LINE__, uarg);
1598                return -EFAULT;
1599        }
1600
1601        if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1602            (ioc == NULL)) {
1603                printk(KERN_DEBUG MYNAM "%s::mptctl_eventquery() @%d - ioc%d not found!\n",
1604                                __FILE__, __LINE__, iocnum);
1605                return -ENODEV;
1606        }
1607
1608        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventquery called.\n",
1609            ioc->name));
1610        karg.eventEntries = MPTCTL_EVENT_LOG_SIZE;
1611        karg.eventTypes = ioc->eventTypes;
1612
1613        /* Copy the data from kernel memory to user memory
1614         */
1615        if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) {
1616                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_eventquery - "
1617                        "Unable to write out mpt_ioctl_eventquery struct @ %p\n",
1618                        ioc->name, __FILE__, __LINE__, uarg);
1619                return -EFAULT;
1620        }
1621        return 0;
1622}
1623
1624/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1625static int
1626mptctl_eventenable (unsigned long arg)
1627{
1628        struct mpt_ioctl_eventenable __user *uarg = (void __user *) arg;
1629        struct mpt_ioctl_eventenable     karg;
1630        MPT_ADAPTER *ioc;
1631        int iocnum;
1632
1633        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) {
1634                printk(KERN_ERR MYNAM "%s@%d::mptctl_eventenable - "
1635                        "Unable to read in mpt_ioctl_eventenable struct @ %p\n",
1636                                __FILE__, __LINE__, uarg);
1637                return -EFAULT;
1638        }
1639
1640        if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1641            (ioc == NULL)) {
1642                printk(KERN_DEBUG MYNAM "%s::mptctl_eventenable() @%d - ioc%d not found!\n",
1643                                __FILE__, __LINE__, iocnum);
1644                return -ENODEV;
1645        }
1646
1647        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventenable called.\n",
1648            ioc->name));
1649        if (ioc->events == NULL) {
1650                /* Have not yet allocated memory - do so now.
1651                 */
1652                int sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
1653                ioc->events = kzalloc(sz, GFP_KERNEL);
1654                if (!ioc->events) {
1655                        printk(MYIOC_s_ERR_FMT
1656                            ": ERROR - Insufficient memory to add adapter!\n",
1657                            ioc->name);
1658                        return -ENOMEM;
1659                }
1660                ioc->alloc_total += sz;
1661
1662                ioc->eventContext = 0;
1663        }
1664
1665        /* Update the IOC event logging flag.
1666         */
1667        ioc->eventTypes = karg.eventTypes;
1668
1669        return 0;
1670}
1671
1672/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1673static int
1674mptctl_eventreport (unsigned long arg)
1675{
1676        struct mpt_ioctl_eventreport __user *uarg = (void __user *) arg;
1677        struct mpt_ioctl_eventreport     karg;
1678        MPT_ADAPTER              *ioc;
1679        int                      iocnum;
1680        int                      numBytes, maxEvents, max;
1681
1682        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) {
1683                printk(KERN_ERR MYNAM "%s@%d::mptctl_eventreport - "
1684                        "Unable to read in mpt_ioctl_eventreport struct @ %p\n",
1685                                __FILE__, __LINE__, uarg);
1686                return -EFAULT;
1687        }
1688
1689        if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1690            (ioc == NULL)) {
1691                printk(KERN_DEBUG MYNAM "%s::mptctl_eventreport() @%d - ioc%d not found!\n",
1692                                __FILE__, __LINE__, iocnum);
1693                return -ENODEV;
1694        }
1695        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventreport called.\n",
1696            ioc->name));
1697
1698        numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
1699        maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS);
1700
1701
1702        max = MPTCTL_EVENT_LOG_SIZE < maxEvents ? MPTCTL_EVENT_LOG_SIZE : maxEvents;
1703
1704        /* If fewer than 1 event is requested, there must have
1705         * been some type of error.
1706         */
1707        if ((max < 1) || !ioc->events)
1708                return -ENODATA;
1709
1710        /* reset this flag so SIGIO can restart */
1711        ioc->aen_event_read_flag=0;
1712
1713        /* Copy the data from kernel memory to user memory
1714         */
1715        numBytes = max * sizeof(MPT_IOCTL_EVENTS);
1716        if (copy_to_user(uarg->eventData, ioc->events, numBytes)) {
1717                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_eventreport - "
1718                        "Unable to write out mpt_ioctl_eventreport struct @ %p\n",
1719                        ioc->name, __FILE__, __LINE__, ioc->events);
1720                return -EFAULT;
1721        }
1722
1723        return 0;
1724}
1725
1726/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1727static int
1728mptctl_replace_fw (unsigned long arg)
1729{
1730        struct mpt_ioctl_replace_fw __user *uarg = (void __user *) arg;
1731        struct mpt_ioctl_replace_fw      karg;
1732        MPT_ADAPTER              *ioc;
1733        int                      iocnum;
1734        int                      newFwSize;
1735
1736        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
1737                printk(KERN_ERR MYNAM "%s@%d::mptctl_replace_fw - "
1738                        "Unable to read in mpt_ioctl_replace_fw struct @ %p\n",
1739                                __FILE__, __LINE__, uarg);
1740                return -EFAULT;
1741        }
1742
1743        if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1744            (ioc == NULL)) {
1745                printk(KERN_DEBUG MYNAM "%s::mptctl_replace_fw() @%d - ioc%d not found!\n",
1746                                __FILE__, __LINE__, iocnum);
1747                return -ENODEV;
1748        }
1749
1750        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_replace_fw called.\n",
1751            ioc->name));
1752        /* If caching FW, Free the old FW image
1753         */
1754        if (ioc->cached_fw == NULL)
1755                return 0;
1756
1757        mpt_free_fw_memory(ioc);
1758
1759        /* Allocate memory for the new FW image
1760         */
1761        newFwSize = karg.newImageSize;
1762
1763        if (newFwSize & 0x01)
1764                newFwSize += 1;
1765        if (newFwSize & 0x02)
1766                newFwSize += 2;
1767
1768        mpt_alloc_fw_memory(ioc, newFwSize);
1769        if (ioc->cached_fw == NULL)
1770                return -ENOMEM;
1771
1772        /* Copy the data from user memory to kernel space
1773         */
1774        if (copy_from_user(ioc->cached_fw, uarg->newImage, newFwSize)) {
1775                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_replace_fw - "
1776                                "Unable to read in mpt_ioctl_replace_fw image "
1777                                "@ %p\n", ioc->name, __FILE__, __LINE__, uarg);
1778                mpt_free_fw_memory(ioc);
1779                return -EFAULT;
1780        }
1781
1782        /* Update IOCFactsReply
1783         */
1784        ioc->facts.FWImageSize = newFwSize;
1785        return 0;
1786}
1787
1788/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1789/* MPT IOCTL MPTCOMMAND function.
1790 * Cast the arg into the mpt_ioctl_mpt_command structure.
1791 *
1792 * Outputs:     None.
1793 * Return:      0 if successful
1794 *              -EBUSY  if previous command timeout and IOC reset is not complete.
1795 *              -EFAULT if data unavailable
1796 *              -ENODEV if no such device/adapter
1797 *              -ETIME  if timer expires
1798 *              -ENOMEM if memory allocation error
1799 */
1800static int
1801mptctl_mpt_command (unsigned long arg)
1802{
1803        struct mpt_ioctl_command __user *uarg = (void __user *) arg;
1804        struct mpt_ioctl_command  karg;
1805        MPT_ADAPTER     *ioc;
1806        int             iocnum;
1807        int             rc;
1808
1809
1810        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_command))) {
1811                printk(KERN_ERR MYNAM "%s@%d::mptctl_mpt_command - "
1812                        "Unable to read in mpt_ioctl_command struct @ %p\n",
1813                                __FILE__, __LINE__, uarg);
1814                return -EFAULT;
1815        }
1816
1817        if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1818            (ioc == NULL)) {
1819                printk(KERN_DEBUG MYNAM "%s::mptctl_mpt_command() @%d - ioc%d not found!\n",
1820                                __FILE__, __LINE__, iocnum);
1821                return -ENODEV;
1822        }
1823
1824        rc = mptctl_do_mpt_command (karg, &uarg->MF);
1825
1826        return rc;
1827}
1828
1829/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1830/* Worker routine for the IOCTL MPTCOMMAND and MPTCOMMAND32 (sparc) commands.
1831 *
1832 * Outputs:     None.
1833 * Return:      0 if successful
1834 *              -EBUSY  if previous command timeout and IOC reset is not complete.
1835 *              -EFAULT if data unavailable
1836 *              -ENODEV if no such device/adapter
1837 *              -ETIME  if timer expires
1838 *              -ENOMEM if memory allocation error
1839 *              -EPERM if SCSI I/O and target is untagged
1840 */
1841static int
1842mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
1843{
1844        MPT_ADAPTER     *ioc;
1845        MPT_FRAME_HDR   *mf = NULL;
1846        MPIHeader_t     *hdr;
1847        char            *psge;
1848        struct buflist  bufIn;  /* data In buffer */
1849        struct buflist  bufOut; /* data Out buffer */
1850        dma_addr_t      dma_addr_in;
1851        dma_addr_t      dma_addr_out;
1852        int             sgSize = 0;     /* Num SG elements */
1853        int             iocnum, flagsLength;
1854        int             sz, rc = 0;
1855        int             msgContext;
1856        u16             req_idx;
1857        ulong           timeout;
1858        unsigned long   timeleft;
1859        struct scsi_device *sdev;
1860        unsigned long    flags;
1861        u8               function;
1862
1863        /* bufIn and bufOut are used for user to kernel space transfers
1864         */
1865        bufIn.kptr = bufOut.kptr = NULL;
1866        bufIn.len = bufOut.len = 0;
1867
1868        if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1869            (ioc == NULL)) {
1870                printk(KERN_DEBUG MYNAM "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n",
1871                                __FILE__, __LINE__, iocnum);
1872                return -ENODEV;
1873        }
1874
1875        spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
1876        if (ioc->ioc_reset_in_progress) {
1877                spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
1878                printk(KERN_ERR MYNAM "%s@%d::mptctl_do_mpt_command - "
1879                        "Busy with diagnostic reset\n", __FILE__, __LINE__);
1880                return -EBUSY;
1881        }
1882        spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
1883
1884        /* Verify that the final request frame will not be too large.
1885         */
1886        sz = karg.dataSgeOffset * 4;
1887        if (karg.dataInSize > 0)
1888                sz += ioc->SGE_size;
1889        if (karg.dataOutSize > 0)
1890                sz += ioc->SGE_size;
1891
1892        if (sz > ioc->req_sz) {
1893                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1894                        "Request frame too large (%d) maximum (%d)\n",
1895                        ioc->name, __FILE__, __LINE__, sz, ioc->req_sz);
1896                return -EFAULT;
1897        }
1898
1899        /* Get a free request frame and save the message context.
1900         */
1901        if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL)
1902                return -EAGAIN;
1903
1904        hdr = (MPIHeader_t *) mf;
1905        msgContext = le32_to_cpu(hdr->MsgContext);
1906        req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1907
1908        /* Copy the request frame
1909         * Reset the saved message context.
1910         * Request frame in user space
1911         */
1912        if (copy_from_user(mf, mfPtr, karg.dataSgeOffset * 4)) {
1913                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1914                        "Unable to read MF from mpt_ioctl_command struct @ %p\n",
1915                        ioc->name, __FILE__, __LINE__, mfPtr);
1916                function = -1;
1917                rc = -EFAULT;
1918                goto done_free_mem;
1919        }
1920        hdr->MsgContext = cpu_to_le32(msgContext);
1921        function = hdr->Function;
1922
1923
1924        /* Verify that this request is allowed.
1925         */
1926        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sending mpi function (0x%02X), req=%p\n",
1927            ioc->name, hdr->Function, mf));
1928
1929        switch (function) {
1930        case MPI_FUNCTION_IOC_FACTS:
1931        case MPI_FUNCTION_PORT_FACTS:
1932                karg.dataOutSize  = karg.dataInSize = 0;
1933                break;
1934
1935        case MPI_FUNCTION_CONFIG:
1936        {
1937                Config_t *config_frame;
1938                config_frame = (Config_t *)mf;
1939                dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\ttype=0x%02x ext_type=0x%02x "
1940                    "number=0x%02x action=0x%02x\n", ioc->name,
1941                    config_frame->Header.PageType,
1942                    config_frame->ExtPageType,
1943                    config_frame->Header.PageNumber,
1944                    config_frame->Action));
1945                break;
1946        }
1947
1948        case MPI_FUNCTION_FC_COMMON_TRANSPORT_SEND:
1949        case MPI_FUNCTION_FC_EX_LINK_SRVC_SEND:
1950        case MPI_FUNCTION_FW_UPLOAD:
1951        case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR:
1952        case MPI_FUNCTION_FW_DOWNLOAD:
1953        case MPI_FUNCTION_FC_PRIMITIVE_SEND:
1954        case MPI_FUNCTION_TOOLBOX:
1955        case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
1956                break;
1957
1958        case MPI_FUNCTION_SCSI_IO_REQUEST:
1959                if (ioc->sh) {
1960                        SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
1961                        int qtag = MPI_SCSIIO_CONTROL_UNTAGGED;
1962                        int scsidir = 0;
1963                        int dataSize;
1964                        u32 id;
1965
1966                        id = (ioc->devices_per_bus == 0) ? 256 : ioc->devices_per_bus;
1967                        if (pScsiReq->TargetID > id) {
1968                                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1969                                        "Target ID out of bounds. \n",
1970                                        ioc->name, __FILE__, __LINE__);
1971                                rc = -ENODEV;
1972                                goto done_free_mem;
1973                        }
1974
1975                        if (pScsiReq->Bus >= ioc->number_of_buses) {
1976                                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1977                                        "Target Bus out of bounds. \n",
1978                                        ioc->name, __FILE__, __LINE__);
1979                                rc = -ENODEV;
1980                                goto done_free_mem;
1981                        }
1982
1983                        pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
1984                        pScsiReq->MsgFlags |= mpt_msg_flags(ioc);
1985
1986
1987                        /* verify that app has not requested
1988                         *      more sense data than driver
1989                         *      can provide, if so, reset this parameter
1990                         * set the sense buffer pointer low address
1991                         * update the control field to specify Q type
1992                         */
1993                        if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
1994                                pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1995                        else
1996                                pScsiReq->SenseBufferLength = karg.maxSenseBytes;
1997
1998                        pScsiReq->SenseBufferLowAddr =
1999                                cpu_to_le32(ioc->sense_buf_low_dma
2000                                   + (req_idx * MPT_SENSE_BUFFER_ALLOC));
2001
2002                        shost_for_each_device(sdev, ioc->sh) {
2003                                struct scsi_target *starget = scsi_target(sdev);
2004                                VirtTarget *vtarget = starget->hostdata;
2005
2006                                if (vtarget == NULL)
2007                                        continue;
2008
2009                                if ((pScsiReq->TargetID == vtarget->id) &&
2010                                    (pScsiReq->Bus == vtarget->channel) &&
2011                                    (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2012                                        qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
2013                        }
2014
2015                        /* Have the IOCTL driver set the direction based
2016                         * on the dataOutSize (ordering issue with Sparc).
2017                         */
2018                        if (karg.dataOutSize > 0) {
2019                                scsidir = MPI_SCSIIO_CONTROL_WRITE;
2020                                dataSize = karg.dataOutSize;
2021                        } else {
2022                                scsidir = MPI_SCSIIO_CONTROL_READ;
2023                                dataSize = karg.dataInSize;
2024                        }
2025
2026                        pScsiReq->Control = cpu_to_le32(scsidir | qtag);
2027                        pScsiReq->DataLength = cpu_to_le32(dataSize);
2028
2029
2030                } else {
2031                        printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2032                                "SCSI driver is not loaded. \n",
2033                                ioc->name, __FILE__, __LINE__);
2034                        rc = -EFAULT;
2035                        goto done_free_mem;
2036                }
2037                break;
2038
2039        case MPI_FUNCTION_SMP_PASSTHROUGH:
2040                /* Check mf->PassthruFlags to determine if
2041                 * transfer is ImmediateMode or not.
2042                 * Immediate mode returns data in the ReplyFrame.
2043                 * Else, we are sending request and response data
2044                 * in two SGLs at the end of the mf.
2045                 */
2046                break;
2047
2048        case MPI_FUNCTION_SATA_PASSTHROUGH:
2049                if (!ioc->sh) {
2050                        printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2051                                "SCSI driver is not loaded. \n",
2052                                ioc->name, __FILE__, __LINE__);
2053                        rc = -EFAULT;
2054                        goto done_free_mem;
2055                }
2056                break;
2057
2058        case MPI_FUNCTION_RAID_ACTION:
2059                /* Just add a SGE
2060                 */
2061                break;
2062
2063        case MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
2064                if (ioc->sh) {
2065                        SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
2066                        int qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
2067                        int scsidir = MPI_SCSIIO_CONTROL_READ;
2068                        int dataSize;
2069
2070                        pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
2071                        pScsiReq->MsgFlags |= mpt_msg_flags(ioc);
2072
2073
2074                        /* verify that app has not requested
2075                         *      more sense data than driver
2076                         *      can provide, if so, reset this parameter
2077                         * set the sense buffer pointer low address
2078                         * update the control field to specify Q type
2079                         */
2080                        if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
2081                                pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
2082                        else
2083                                pScsiReq->SenseBufferLength = karg.maxSenseBytes;
2084
2085                        pScsiReq->SenseBufferLowAddr =
2086                                cpu_to_le32(ioc->sense_buf_low_dma
2087                                   + (req_idx * MPT_SENSE_BUFFER_ALLOC));
2088
2089                        /* All commands to physical devices are tagged
2090                         */
2091
2092                        /* Have the IOCTL driver set the direction based
2093                         * on the dataOutSize (ordering issue with Sparc).
2094                         */
2095                        if (karg.dataOutSize > 0) {
2096                                scsidir = MPI_SCSIIO_CONTROL_WRITE;
2097                                dataSize = karg.dataOutSize;
2098                        } else {
2099                                scsidir = MPI_SCSIIO_CONTROL_READ;
2100                                dataSize = karg.dataInSize;
2101                        }
2102
2103                        pScsiReq->Control = cpu_to_le32(scsidir | qtag);
2104                        pScsiReq->DataLength = cpu_to_le32(dataSize);
2105
2106                } else {
2107                        printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2108                                "SCSI driver is not loaded. \n",
2109                                ioc->name, __FILE__, __LINE__);
2110                        rc = -EFAULT;
2111                        goto done_free_mem;
2112                }
2113                break;
2114
2115        case MPI_FUNCTION_SCSI_TASK_MGMT:
2116        {
2117                SCSITaskMgmt_t  *pScsiTm;
2118                pScsiTm = (SCSITaskMgmt_t *)mf;
2119                dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2120                        "\tTaskType=0x%x MsgFlags=0x%x "
2121                        "TaskMsgContext=0x%x id=%d channel=%d\n",
2122                        ioc->name, pScsiTm->TaskType, le32_to_cpu
2123                        (pScsiTm->TaskMsgContext), pScsiTm->MsgFlags,
2124                        pScsiTm->TargetID, pScsiTm->Bus));
2125                break;
2126        }
2127
2128        case MPI_FUNCTION_IOC_INIT:
2129                {
2130                        IOCInit_t       *pInit = (IOCInit_t *) mf;
2131                        u32             high_addr, sense_high;
2132
2133                        /* Verify that all entries in the IOC INIT match
2134                         * existing setup (and in LE format).
2135                         */
2136                        if (sizeof(dma_addr_t) == sizeof(u64)) {
2137                                high_addr = cpu_to_le32((u32)((u64)ioc->req_frames_dma >> 32));
2138                                sense_high= cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2139                        } else {
2140                                high_addr = 0;
2141                                sense_high= 0;
2142                        }
2143
2144                        if ((pInit->Flags != 0) || (pInit->MaxDevices != ioc->facts.MaxDevices) ||
2145                                (pInit->MaxBuses != ioc->facts.MaxBuses) ||
2146                                (pInit->ReplyFrameSize != cpu_to_le16(ioc->reply_sz)) ||
2147                                (pInit->HostMfaHighAddr != high_addr) ||
2148                                (pInit->SenseBufferHighAddr != sense_high)) {
2149                                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2150                                        "IOC_INIT issued with 1 or more incorrect parameters. Rejected.\n",
2151                                        ioc->name, __FILE__, __LINE__);
2152                                rc = -EFAULT;
2153                                goto done_free_mem;
2154                        }
2155                }
2156                break;
2157        default:
2158                /*
2159                 * MPI_FUNCTION_PORT_ENABLE
2160                 * MPI_FUNCTION_TARGET_CMD_BUFFER_POST
2161                 * MPI_FUNCTION_TARGET_ASSIST
2162                 * MPI_FUNCTION_TARGET_STATUS_SEND
2163                 * MPI_FUNCTION_TARGET_MODE_ABORT
2164                 * MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
2165                 * MPI_FUNCTION_IO_UNIT_RESET
2166                 * MPI_FUNCTION_HANDSHAKE
2167                 * MPI_FUNCTION_REPLY_FRAME_REMOVAL
2168                 * MPI_FUNCTION_EVENT_NOTIFICATION
2169                 *  (driver handles event notification)
2170                 * MPI_FUNCTION_EVENT_ACK
2171                 */
2172
2173                /*  What to do with these???  CHECK ME!!!
2174                        MPI_FUNCTION_FC_LINK_SRVC_BUF_POST
2175                        MPI_FUNCTION_FC_LINK_SRVC_RSP
2176                        MPI_FUNCTION_FC_ABORT
2177                        MPI_FUNCTION_LAN_SEND
2178                        MPI_FUNCTION_LAN_RECEIVE
2179                        MPI_FUNCTION_LAN_RESET
2180                */
2181
2182                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2183                        "Illegal request (function 0x%x) \n",
2184                        ioc->name, __FILE__, __LINE__, hdr->Function);
2185                rc = -EFAULT;
2186                goto done_free_mem;
2187        }
2188
2189        /* Add the SGL ( at most one data in SGE and one data out SGE )
2190         * In the case of two SGE's - the data out (write) will always
2191         * preceede the data in (read) SGE. psgList is used to free the
2192         * allocated memory.
2193         */
2194        psge = (char *) (((int *) mf) + karg.dataSgeOffset);
2195        flagsLength = 0;
2196
2197        if (karg.dataOutSize > 0)
2198                sgSize ++;
2199
2200        if (karg.dataInSize > 0)
2201                sgSize ++;
2202
2203        if (sgSize > 0) {
2204
2205                /* Set up the dataOut memory allocation */
2206                if (karg.dataOutSize > 0) {
2207                        if (karg.dataInSize > 0) {
2208                                flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2209                                                MPI_SGE_FLAGS_END_OF_BUFFER |
2210                                                MPI_SGE_FLAGS_DIRECTION)
2211                                                << MPI_SGE_FLAGS_SHIFT;
2212                        } else {
2213                                flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
2214                        }
2215                        flagsLength |= karg.dataOutSize;
2216                        bufOut.len = karg.dataOutSize;
2217                        bufOut.kptr = pci_alloc_consistent(
2218                                        ioc->pcidev, bufOut.len, &dma_addr_out);
2219
2220                        if (bufOut.kptr == NULL) {
2221                                rc = -ENOMEM;
2222                                goto done_free_mem;
2223                        } else {
2224                                /* Set up this SGE.
2225                                 * Copy to MF and to sglbuf
2226                                 */
2227                                ioc->add_sge(psge, flagsLength, dma_addr_out);
2228                                psge += ioc->SGE_size;
2229
2230                                /* Copy user data to kernel space.
2231                                 */
2232                                if (copy_from_user(bufOut.kptr,
2233                                                karg.dataOutBufPtr,
2234                                                bufOut.len)) {
2235                                        printk(MYIOC_s_ERR_FMT
2236                                                "%s@%d::mptctl_do_mpt_command - Unable "
2237                                                "to read user data "
2238                                                "struct @ %p\n",
2239                                                ioc->name, __FILE__, __LINE__,karg.dataOutBufPtr);
2240                                        rc =  -EFAULT;
2241                                        goto done_free_mem;
2242                                }
2243                        }
2244                }
2245
2246                if (karg.dataInSize > 0) {
2247                        flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
2248                        flagsLength |= karg.dataInSize;
2249
2250                        bufIn.len = karg.dataInSize;
2251                        bufIn.kptr = pci_alloc_consistent(ioc->pcidev,
2252                                        bufIn.len, &dma_addr_in);
2253
2254                        if (bufIn.kptr == NULL) {
2255                                rc = -ENOMEM;
2256                                goto done_free_mem;
2257                        } else {
2258                                /* Set up this SGE
2259                                 * Copy to MF and to sglbuf
2260                                 */
2261                                ioc->add_sge(psge, flagsLength, dma_addr_in);
2262                        }
2263                }
2264        } else  {
2265                /* Add a NULL SGE
2266                 */
2267                ioc->add_sge(psge, flagsLength, (dma_addr_t) -1);
2268        }
2269
2270        SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, hdr->MsgContext);
2271        INITIALIZE_MGMT_STATUS(ioc->ioctl_cmds.status)
2272        if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
2273
2274                mutex_lock(&ioc->taskmgmt_cmds.mutex);
2275                if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
2276                        mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2277                        goto done_free_mem;
2278                }
2279
2280                DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
2281
2282                if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
2283                    (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
2284                        mpt_put_msg_frame_hi_pri(mptctl_id, ioc, mf);
2285                else {
2286                        rc =mpt_send_handshake_request(mptctl_id, ioc,
2287                                sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP);
2288                        if (rc != 0) {
2289                                dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2290                                    "send_handshake FAILED! (ioc %p, mf %p)\n",
2291                                    ioc->name, ioc, mf));
2292                                mpt_clear_taskmgmt_in_progress_flag(ioc);
2293                                rc = -ENODATA;
2294                                mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2295                                goto done_free_mem;
2296                        }
2297                }
2298
2299        } else
2300                mpt_put_msg_frame(mptctl_id, ioc, mf);
2301
2302        /* Now wait for the command to complete */
2303        timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT;
2304retry_wait:
2305        timeleft = wait_for_completion_timeout(&ioc->ioctl_cmds.done,
2306                                HZ*timeout);
2307        if (!(ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2308                rc = -ETIME;
2309                dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: TIMED OUT!\n",
2310                    ioc->name, __func__));
2311                if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
2312                        if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
2313                                mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2314                        goto done_free_mem;
2315                }
2316                if (!timeleft) {
2317                        printk(MYIOC_s_WARN_FMT
2318                               "mpt cmd timeout, doorbell=0x%08x"
2319                               " function=0x%x\n",
2320                               ioc->name, mpt_GetIocState(ioc, 0), function);
2321                        if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
2322                                mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2323                        mptctl_timeout_expired(ioc, mf);
2324                        mf = NULL;
2325                } else
2326                        goto retry_wait;
2327                goto done_free_mem;
2328        }
2329
2330        if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
2331                mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2332
2333
2334        mf = NULL;
2335
2336        /* If a valid reply frame, copy to the user.
2337         * Offset 2: reply length in U32's
2338         */
2339        if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_RF_VALID) {
2340                if (karg.maxReplyBytes < ioc->reply_sz) {
2341                        sz = min(karg.maxReplyBytes,
2342                                4*ioc->ioctl_cmds.reply[2]);
2343                } else {
2344                         sz = min(ioc->reply_sz, 4*ioc->ioctl_cmds.reply[2]);
2345                }
2346                if (sz > 0) {
2347                        if (copy_to_user(karg.replyFrameBufPtr,
2348                                 ioc->ioctl_cmds.reply, sz)){
2349                                 printk(MYIOC_s_ERR_FMT
2350                                     "%s@%d::mptctl_do_mpt_command - "
2351                                 "Unable to write out reply frame %p\n",
2352                                 ioc->name, __FILE__, __LINE__, karg.replyFrameBufPtr);
2353                                 rc =  -ENODATA;
2354                                 goto done_free_mem;
2355                        }
2356                }
2357        }
2358
2359        /* If valid sense data, copy to user.
2360         */
2361        if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_SENSE_VALID) {
2362                sz = min(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE);
2363                if (sz > 0) {
2364                        if (copy_to_user(karg.senseDataPtr,
2365                                ioc->ioctl_cmds.sense, sz)) {
2366                                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2367                                "Unable to write sense data to user %p\n",
2368                                ioc->name, __FILE__, __LINE__,
2369                                karg.senseDataPtr);
2370                                rc =  -ENODATA;
2371                                goto done_free_mem;
2372                        }
2373                }
2374        }
2375
2376        /* If the overall status is _GOOD and data in, copy data
2377         * to user.
2378         */
2379        if ((ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD) &&
2380                                (karg.dataInSize > 0) && (bufIn.kptr)) {
2381
2382                if (copy_to_user(karg.dataInBufPtr,
2383                                 bufIn.kptr, karg.dataInSize)) {
2384                        printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2385                                "Unable to write data to user %p\n",
2386                                ioc->name, __FILE__, __LINE__,
2387                                karg.dataInBufPtr);
2388                        rc =  -ENODATA;
2389                }
2390        }
2391
2392done_free_mem:
2393
2394        CLEAR_MGMT_STATUS(ioc->ioctl_cmds.status)
2395        SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, 0);
2396
2397        /* Free the allocated memory.
2398         */
2399        if (bufOut.kptr != NULL) {
2400                pci_free_consistent(ioc->pcidev,
2401                        bufOut.len, (void *) bufOut.kptr, dma_addr_out);
2402        }
2403
2404        if (bufIn.kptr != NULL) {
2405                pci_free_consistent(ioc->pcidev,
2406                        bufIn.len, (void *) bufIn.kptr, dma_addr_in);
2407        }
2408
2409        /* mf is null if command issued successfully
2410         * otherwise, failure occurred after mf acquired.
2411         */
2412        if (mf)
2413                mpt_free_msg_frame(ioc, mf);
2414
2415        return rc;
2416}
2417
2418/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2419/* Prototype Routine for the HOST INFO command.
2420 *
2421 * Outputs:     None.
2422 * Return:      0 if successful
2423 *              -EFAULT if data unavailable
2424 *              -EBUSY  if previous command timeout and IOC reset is not complete.
2425 *              -ENODEV if no such device/adapter
2426 *              -ETIME  if timer expires
2427 *              -ENOMEM if memory allocation error
2428 */
2429static int
2430mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
2431{
2432        hp_host_info_t  __user *uarg = (void __user *) arg;
2433        MPT_ADAPTER             *ioc;
2434        struct pci_dev          *pdev;
2435        char                    *pbuf=NULL;
2436        dma_addr_t              buf_dma;
2437        hp_host_info_t          karg;
2438        CONFIGPARMS             cfg;
2439        ConfigPageHeader_t      hdr;
2440        int                     iocnum;
2441        int                     rc, cim_rev;
2442        ToolboxIstwiReadWriteRequest_t  *IstwiRWRequest;
2443        MPT_FRAME_HDR           *mf = NULL;
2444        MPIHeader_t             *mpi_hdr;
2445        unsigned long           timeleft;
2446        int                     retval;
2447
2448        /* Reset long to int. Should affect IA64 and SPARC only
2449         */
2450        if (data_size == sizeof(hp_host_info_t))
2451                cim_rev = 1;
2452        else if (data_size == sizeof(hp_host_info_rev0_t))
2453                cim_rev = 0;    /* obsolete */
2454        else
2455                return -EFAULT;
2456
2457        if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) {
2458                printk(KERN_ERR MYNAM "%s@%d::mptctl_hp_host_info - "
2459                        "Unable to read in hp_host_info struct @ %p\n",
2460                                __FILE__, __LINE__, uarg);
2461                return -EFAULT;
2462        }
2463
2464        if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
2465            (ioc == NULL)) {
2466                printk(KERN_DEBUG MYNAM "%s::mptctl_hp_hostinfo() @%d - ioc%d not found!\n",
2467                                __FILE__, __LINE__, iocnum);
2468                return -ENODEV;
2469        }
2470        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": mptctl_hp_hostinfo called.\n",
2471            ioc->name));
2472
2473        /* Fill in the data and return the structure to the calling
2474         * program
2475         */
2476        pdev = (struct pci_dev *) ioc->pcidev;
2477
2478        karg.vendor = pdev->vendor;
2479        karg.device = pdev->device;
2480        karg.subsystem_id = pdev->subsystem_device;
2481        karg.subsystem_vendor = pdev->subsystem_vendor;
2482        karg.devfn = pdev->devfn;
2483        karg.bus = pdev->bus->number;
2484
2485        /* Save the SCSI host no. if
2486         * SCSI driver loaded
2487         */
2488        if (ioc->sh != NULL)
2489                karg.host_no = ioc->sh->host_no;
2490        else
2491                karg.host_no =  -1;
2492
2493        /* Reformat the fw_version into a string
2494         */
2495        karg.fw_version[0] = ioc->facts.FWVersion.Struct.Major >= 10 ?
2496                ((ioc->facts.FWVersion.Struct.Major / 10) + '0') : '0';
2497        karg.fw_version[1] = (ioc->facts.FWVersion.Struct.Major % 10 ) + '0';
2498        karg.fw_version[2] = '.';
2499        karg.fw_version[3] = ioc->facts.FWVersion.Struct.Minor >= 10 ?
2500                ((ioc->facts.FWVersion.Struct.Minor / 10) + '0') : '0';
2501        karg.fw_version[4] = (ioc->facts.FWVersion.Struct.Minor % 10 ) + '0';
2502        karg.fw_version[5] = '.';
2503        karg.fw_version[6] = ioc->facts.FWVersion.Struct.Unit >= 10 ?
2504                ((ioc->facts.FWVersion.Struct.Unit / 10) + '0') : '0';
2505        karg.fw_version[7] = (ioc->facts.FWVersion.Struct.Unit % 10 ) + '0';
2506        karg.fw_version[8] = '.';
2507        karg.fw_version[9] = ioc->facts.FWVersion.Struct.Dev >= 10 ?
2508                ((ioc->facts.FWVersion.Struct.Dev / 10) + '0') : '0';
2509        karg.fw_version[10] = (ioc->facts.FWVersion.Struct.Dev % 10 ) + '0';
2510        karg.fw_version[11] = '\0';
2511
2512        /* Issue a config request to get the device serial number
2513         */
2514        hdr.PageVersion = 0;
2515        hdr.PageLength = 0;
2516        hdr.PageNumber = 0;
2517        hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
2518        cfg.cfghdr.hdr = &hdr;
2519        cfg.physAddr = -1;
2520        cfg.pageAddr = 0;
2521        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2522        cfg.dir = 0;    /* read */
2523        cfg.timeout = 10;
2524
2525        strncpy(karg.serial_number, " ", 24);
2526        if (mpt_config(ioc, &cfg) == 0) {
2527                if (cfg.cfghdr.hdr->PageLength > 0) {
2528                        /* Issue the second config page request */
2529                        cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2530
2531                        pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
2532                        if (pbuf) {
2533                                cfg.physAddr = buf_dma;
2534                                if (mpt_config(ioc, &cfg) == 0) {
2535                                        ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf;
2536                                        if (strlen(pdata->BoardTracerNumber) > 1) {
2537                                                strncpy(karg.serial_number,                                                                         pdata->BoardTracerNumber, 24);
2538                                                karg.serial_number[24-1]='\0';
2539                                        }
2540                                }
2541                                pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
2542                                pbuf = NULL;
2543                        }
2544                }
2545        }
2546        rc = mpt_GetIocState(ioc, 1);
2547        switch (rc) {
2548        case MPI_IOC_STATE_OPERATIONAL:
2549                karg.ioc_status =  HP_STATUS_OK;
2550                break;
2551
2552        case MPI_IOC_STATE_FAULT:
2553                karg.ioc_status =  HP_STATUS_FAILED;
2554                break;
2555
2556        case MPI_IOC_STATE_RESET:
2557        case MPI_IOC_STATE_READY:
2558        default:
2559                karg.ioc_status =  HP_STATUS_OTHER;
2560                break;
2561        }
2562
2563        karg.base_io_addr = pci_resource_start(pdev, 0);
2564
2565        if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))
2566                karg.bus_phys_width = HP_BUS_WIDTH_UNK;
2567        else
2568                karg.bus_phys_width = HP_BUS_WIDTH_16;
2569
2570        karg.hard_resets = 0;
2571        karg.soft_resets = 0;
2572        karg.timeouts = 0;
2573        if (ioc->sh != NULL) {
2574                MPT_SCSI_HOST *hd =  shost_priv(ioc->sh);
2575
2576                if (hd && (cim_rev == 1)) {
2577                        karg.hard_resets = ioc->hard_resets;
2578                        karg.soft_resets = ioc->soft_resets;
2579                        karg.timeouts = ioc->timeouts;
2580                }
2581        }
2582
2583        /* 
2584         * Gather ISTWI(Industry Standard Two Wire Interface) Data
2585         */
2586        if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) {
2587                dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
2588                        "%s, no msg frames!!\n", ioc->name, __func__));
2589                goto out;
2590        }
2591
2592        IstwiRWRequest = (ToolboxIstwiReadWriteRequest_t *)mf;
2593        mpi_hdr = (MPIHeader_t *) mf;
2594        memset(IstwiRWRequest,0,sizeof(ToolboxIstwiReadWriteRequest_t));
2595        IstwiRWRequest->Function = MPI_FUNCTION_TOOLBOX;
2596        IstwiRWRequest->Tool = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
2597        IstwiRWRequest->MsgContext = mpi_hdr->MsgContext;
2598        IstwiRWRequest->Flags = MPI_TB_ISTWI_FLAGS_READ;
2599        IstwiRWRequest->NumAddressBytes = 0x01;
2600        IstwiRWRequest->DataLength = cpu_to_le16(0x04);
2601        if (pdev->devfn & 1)
2602                IstwiRWRequest->DeviceAddr = 0xB2;
2603        else
2604                IstwiRWRequest->DeviceAddr = 0xB0;
2605
2606        pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma);
2607        if (!pbuf)
2608                goto out;
2609        ioc->add_sge((char *)&IstwiRWRequest->SGL,
2610            (MPT_SGE_FLAGS_SSIMPLE_READ|4), buf_dma);
2611
2612        retval = 0;
2613        SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context,
2614                                IstwiRWRequest->MsgContext);
2615        INITIALIZE_MGMT_STATUS(ioc->ioctl_cmds.status)
2616        mpt_put_msg_frame(mptctl_id, ioc, mf);
2617
2618retry_wait:
2619        timeleft = wait_for_completion_timeout(&ioc->ioctl_cmds.done,
2620                        HZ*MPT_IOCTL_DEFAULT_TIMEOUT);
2621        if (!(ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2622                retval = -ETIME;
2623                printk(MYIOC_s_WARN_FMT "%s: failed\n", ioc->name, __func__);
2624                if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
2625                        mpt_free_msg_frame(ioc, mf);
2626                        goto out;
2627                }
2628                if (!timeleft) {
2629                        printk(MYIOC_s_WARN_FMT
2630                               "HOST INFO command timeout, doorbell=0x%08x\n",
2631                               ioc->name, mpt_GetIocState(ioc, 0));
2632                        mptctl_timeout_expired(ioc, mf);
2633                } else
2634                        goto retry_wait;
2635                goto out;
2636        }
2637
2638        /*
2639         *ISTWI Data Definition
2640         * pbuf[0] = FW_VERSION = 0x4
2641         * pbuf[1] = Bay Count = 6 or 4 or 2, depending on
2642         *  the config, you should be seeing one out of these three values
2643         * pbuf[2] = Drive Installed Map = bit pattern depend on which
2644         *   bays have drives in them
2645         * pbuf[3] = Checksum (0x100 = (byte0 + byte2 + byte3)
2646         */
2647        if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_RF_VALID)
2648                karg.rsvd = *(u32 *)pbuf;
2649
2650 out:
2651        CLEAR_MGMT_STATUS(ioc->ioctl_cmds.status)
2652        SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, 0);
2653
2654        if (pbuf)
2655                pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma);
2656
2657        /* Copy the data from kernel memory to user memory
2658         */
2659        if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) {
2660                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_hpgethostinfo - "
2661                        "Unable to write out hp_host_info @ %p\n",
2662                        ioc->name, __FILE__, __LINE__, uarg);
2663                return -EFAULT;
2664        }
2665
2666        return 0;
2667
2668}
2669
2670/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2671/* Prototype Routine for the TARGET INFO command.
2672 *
2673 * Outputs:     None.
2674 * Return:      0 if successful
2675 *              -EFAULT if data unavailable
2676 *              -EBUSY  if previous command timeout and IOC reset is not complete.
2677 *              -ENODEV if no such device/adapter
2678 *              -ETIME  if timer expires
2679 *              -ENOMEM if memory allocation error
2680 */
2681static int
2682mptctl_hp_targetinfo(unsigned long arg)
2683{
2684        hp_target_info_t __user *uarg = (void __user *) arg;
2685        SCSIDevicePage0_t       *pg0_alloc;
2686        SCSIDevicePage3_t       *pg3_alloc;
2687        MPT_ADAPTER             *ioc;
2688        MPT_SCSI_HOST           *hd = NULL;
2689        hp_target_info_t        karg;
2690        int                     iocnum;
2691        int                     data_sz;
2692        dma_addr_t              page_dma;
2693        CONFIGPARMS             cfg;
2694        ConfigPageHeader_t      hdr;
2695        int                     tmp, np, rc = 0;
2696
2697        if (copy_from_user(&karg, uarg, sizeof(hp_target_info_t))) {
2698                printk(KERN_ERR MYNAM "%s@%d::mptctl_hp_targetinfo - "
2699                        "Unable to read in hp_host_targetinfo struct @ %p\n",
2700                                __FILE__, __LINE__, uarg);
2701                return -EFAULT;
2702        }
2703
2704        if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
2705                (ioc == NULL)) {
2706                printk(KERN_DEBUG MYNAM "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n",
2707                                __FILE__, __LINE__, iocnum);
2708                return -ENODEV;
2709        }
2710        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_hp_targetinfo called.\n",
2711            ioc->name));
2712
2713        /*  There is nothing to do for FCP parts.
2714         */
2715        if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))
2716                return 0;
2717
2718        if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL))
2719                return 0;
2720
2721        if (ioc->sh->host_no != karg.hdr.host)
2722                return -ENODEV;
2723
2724       /* Get the data transfer speeds
2725        */
2726        data_sz = ioc->spi_data.sdp0length * 4;
2727        pg0_alloc = (SCSIDevicePage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
2728        if (pg0_alloc) {
2729                hdr.PageVersion = ioc->spi_data.sdp0version;
2730                hdr.PageLength = data_sz;
2731                hdr.PageNumber = 0;
2732                hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
2733
2734                cfg.cfghdr.hdr = &hdr;
2735                cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2736                cfg.dir = 0;
2737                cfg.timeout = 0;
2738                cfg.physAddr = page_dma;
2739
2740                cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
2741
2742                if ((rc = mpt_config(ioc, &cfg)) == 0) {
2743                        np = le32_to_cpu(pg0_alloc->NegotiatedParameters);
2744                        karg.negotiated_width = np & MPI_SCSIDEVPAGE0_NP_WIDE ?
2745                                        HP_BUS_WIDTH_16 : HP_BUS_WIDTH_8;
2746
2747                        if (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) {
2748                                tmp = (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
2749                                if (tmp < 0x09)
2750                                        karg.negotiated_speed = HP_DEV_SPEED_ULTRA320;
2751                                else if (tmp <= 0x09)
2752                                        karg.negotiated_speed = HP_DEV_SPEED_ULTRA160;
2753                                else if (tmp <= 0x0A)
2754                                        karg.negotiated_speed = HP_DEV_SPEED_ULTRA2;
2755                                else if (tmp <= 0x0C)
2756                                        karg.negotiated_speed = HP_DEV_SPEED_ULTRA;
2757                                else if (tmp <= 0x25)
2758                                        karg.negotiated_speed = HP_DEV_SPEED_FAST;
2759                                else
2760                                        karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
2761                        } else
2762                                karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
2763                }
2764
2765                pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg0_alloc, page_dma);
2766        }
2767
2768        /* Set defaults
2769         */
2770        karg.message_rejects = -1;
2771        karg.phase_errors = -1;
2772        karg.parity_errors = -1;
2773        karg.select_timeouts = -1;
2774
2775        /* Get the target error parameters
2776         */
2777        hdr.PageVersion = 0;
2778        hdr.PageLength = 0;
2779        hdr.PageNumber = 3;
2780        hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
2781
2782        cfg.cfghdr.hdr = &hdr;
2783        cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2784        cfg.dir = 0;
2785        cfg.timeout = 0;
2786        cfg.physAddr = -1;
2787        if ((mpt_config(ioc, &cfg) == 0) && (cfg.cfghdr.hdr->PageLength > 0)) {
2788                /* Issue the second config page request */
2789                cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2790                data_sz = (int) cfg.cfghdr.hdr->PageLength * 4;
2791                pg3_alloc = (SCSIDevicePage3_t *) pci_alloc_consistent(
2792                                                        ioc->pcidev, data_sz, &page_dma);
2793                if (pg3_alloc) {
2794                        cfg.physAddr = page_dma;
2795                        cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
2796                        if ((rc = mpt_config(ioc, &cfg)) == 0) {
2797                                karg.message_rejects = (u32) le16_to_cpu(pg3_alloc->MsgRejectCount);
2798                                karg.phase_errors = (u32) le16_to_cpu(pg3_alloc->PhaseErrorCount);
2799                                karg.parity_errors = (u32) le16_to_cpu(pg3_alloc->ParityErrorCount);
2800                        }
2801                        pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg3_alloc, page_dma);
2802                }
2803        }
2804        hd = shost_priv(ioc->sh);
2805        if (hd != NULL)
2806                karg.select_timeouts = hd->sel_timeout[karg.hdr.id];
2807
2808        /* Copy the data from kernel memory to user memory
2809         */
2810        if (copy_to_user((char __user *)arg, &karg, sizeof(hp_target_info_t))) {
2811                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_hp_target_info - "
2812                        "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
2813                        ioc->name, __FILE__, __LINE__, uarg);
2814                return -EFAULT;
2815        }
2816
2817        return 0;
2818}
2819
2820/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2821
2822static const struct file_operations mptctl_fops = {
2823        .owner =        THIS_MODULE,
2824        .llseek =       no_llseek,
2825        .fasync =       mptctl_fasync,
2826        .unlocked_ioctl = mptctl_ioctl,
2827        .release =      mptctl_release,
2828#ifdef CONFIG_COMPAT
2829        .compat_ioctl = compat_mpctl_ioctl,
2830#endif
2831};
2832
2833static struct miscdevice mptctl_miscdev = {
2834        MPT_MINOR,
2835        MYNAM,
2836        &mptctl_fops
2837};
2838
2839/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2840
2841#ifdef CONFIG_COMPAT
2842
2843static int
2844compat_mptfwxfer_ioctl(struct file *filp, unsigned int cmd,
2845                        unsigned long arg)
2846{
2847        struct mpt_fw_xfer32 kfw32;
2848        struct mpt_fw_xfer kfw;
2849        MPT_ADAPTER *iocp = NULL;
2850        int iocnum, iocnumX;
2851        int nonblock = (filp->f_flags & O_NONBLOCK);
2852        int ret;
2853
2854
2855        if (copy_from_user(&kfw32, (char __user *)arg, sizeof(kfw32)))
2856                return -EFAULT;
2857
2858        /* Verify intended MPT adapter */
2859        iocnumX = kfw32.iocnum & 0xFF;
2860        if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
2861            (iocp == NULL)) {
2862                printk(KERN_DEBUG MYNAM "::compat_mptfwxfer_ioctl @%d - ioc%d not found!\n",
2863                        __LINE__, iocnumX);
2864                return -ENODEV;
2865        }
2866
2867        if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
2868                return ret;
2869
2870        dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "compat_mptfwxfer_ioctl() called\n",
2871            iocp->name));
2872        kfw.iocnum = iocnum;
2873        kfw.fwlen = kfw32.fwlen;
2874        kfw.bufp = compat_ptr(kfw32.bufp);
2875
2876        ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);
2877
2878        mutex_unlock(&iocp->ioctl_cmds.mutex);
2879
2880        return ret;
2881}
2882
2883static int
2884compat_mpt_command(struct file *filp, unsigned int cmd,
2885                        unsigned long arg)
2886{
2887        struct mpt_ioctl_command32 karg32;
2888        struct mpt_ioctl_command32 __user *uarg = (struct mpt_ioctl_command32 __user *) arg;
2889        struct mpt_ioctl_command karg;
2890        MPT_ADAPTER *iocp = NULL;
2891        int iocnum, iocnumX;
2892        int nonblock = (filp->f_flags & O_NONBLOCK);
2893        int ret;
2894
2895        if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32)))
2896                return -EFAULT;
2897
2898        /* Verify intended MPT adapter */
2899        iocnumX = karg32.hdr.iocnum & 0xFF;
2900        if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
2901            (iocp == NULL)) {
2902                printk(KERN_DEBUG MYNAM "::compat_mpt_command @%d - ioc%d not found!\n",
2903                        __LINE__, iocnumX);
2904                return -ENODEV;
2905        }
2906
2907        if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
2908                return ret;
2909
2910        dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "compat_mpt_command() called\n",
2911            iocp->name));
2912        /* Copy data to karg */
2913        karg.hdr.iocnum = karg32.hdr.iocnum;
2914        karg.hdr.port = karg32.hdr.port;
2915        karg.timeout = karg32.timeout;
2916        karg.maxReplyBytes = karg32.maxReplyBytes;
2917
2918        karg.dataInSize = karg32.dataInSize;
2919        karg.dataOutSize = karg32.dataOutSize;
2920        karg.maxSenseBytes = karg32.maxSenseBytes;
2921        karg.dataSgeOffset = karg32.dataSgeOffset;
2922
2923        karg.replyFrameBufPtr = (char __user *)(unsigned long)karg32.replyFrameBufPtr;
2924        karg.dataInBufPtr = (char __user *)(unsigned long)karg32.dataInBufPtr;
2925        karg.dataOutBufPtr = (char __user *)(unsigned long)karg32.dataOutBufPtr;
2926        karg.senseDataPtr = (char __user *)(unsigned long)karg32.senseDataPtr;
2927
2928        /* Pass new structure to do_mpt_command
2929         */
2930        ret = mptctl_do_mpt_command (karg, &uarg->MF);
2931
2932        mutex_unlock(&iocp->ioctl_cmds.mutex);
2933
2934        return ret;
2935}
2936
2937static long compat_mpctl_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
2938{
2939        long ret;
2940        mutex_lock(&mpctl_mutex);
2941        switch (cmd) {
2942        case MPTIOCINFO:
2943        case MPTIOCINFO1:
2944        case MPTIOCINFO2:
2945        case MPTTARGETINFO:
2946        case MPTEVENTQUERY:
2947        case MPTEVENTENABLE:
2948        case MPTEVENTREPORT:
2949        case MPTHARDRESET:
2950        case HP_GETHOSTINFO:
2951        case HP_GETTARGETINFO:
2952        case MPTTEST:
2953                ret = __mptctl_ioctl(f, cmd, arg);
2954                break;
2955        case MPTCOMMAND32:
2956                ret = compat_mpt_command(f, cmd, arg);
2957                break;
2958        case MPTFWDOWNLOAD32:
2959                ret = compat_mptfwxfer_ioctl(f, cmd, arg);
2960                break;
2961        default:
2962                ret = -ENOIOCTLCMD;
2963                break;
2964        }
2965        mutex_unlock(&mpctl_mutex);
2966        return ret;
2967}
2968
2969#endif
2970
2971
2972/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2973/*
2974 *      mptctl_probe - Installs ioctl devices per bus.
2975 *      @pdev: Pointer to pci_dev structure
2976 *
2977 *      Returns 0 for success, non-zero for failure.
2978 *
2979 */
2980
2981static int
2982mptctl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2983{
2984        MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2985
2986        mutex_init(&ioc->ioctl_cmds.mutex);
2987        init_completion(&ioc->ioctl_cmds.done);
2988        return 0;
2989}
2990
2991/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2992/*
2993 *      mptctl_remove - Removed ioctl devices
2994 *      @pdev: Pointer to pci_dev structure
2995 *
2996 *
2997 */
2998static void
2999mptctl_remove(struct pci_dev *pdev)
3000{
3001}
3002
3003static struct mpt_pci_driver mptctl_driver = {
3004  .probe                = mptctl_probe,
3005  .remove               = mptctl_remove,
3006};
3007
3008/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3009static int __init mptctl_init(void)
3010{
3011        int err;
3012        int where = 1;
3013
3014        show_mptmod_ver(my_NAME, my_VERSION);
3015
3016        mpt_device_driver_register(&mptctl_driver, MPTCTL_DRIVER);
3017
3018        /* Register this device */
3019        err = misc_register(&mptctl_miscdev);
3020        if (err < 0) {
3021                printk(KERN_ERR MYNAM ": Can't register misc device [minor=%d].\n", MPT_MINOR);
3022                goto out_fail;
3023        }
3024        printk(KERN_INFO MYNAM ": Registered with Fusion MPT base driver\n");
3025        printk(KERN_INFO MYNAM ": /dev/%s @ (major,minor=%d,%d)\n",
3026                         mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
3027
3028        /*
3029         *  Install our handler
3030         */
3031        ++where;
3032        mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER,
3033            "mptctl_reply");
3034        if (!mptctl_id || mptctl_id >= MPT_MAX_PROTOCOL_DRIVERS) {
3035                printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
3036                misc_deregister(&mptctl_miscdev);
3037                err = -EBUSY;
3038                goto out_fail;
3039        }
3040
3041        mptctl_taskmgmt_id = mpt_register(mptctl_taskmgmt_reply, MPTCTL_DRIVER,
3042            "mptctl_taskmgmt_reply");
3043        if (!mptctl_taskmgmt_id || mptctl_taskmgmt_id >= MPT_MAX_PROTOCOL_DRIVERS) {
3044                printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
3045                mpt_deregister(mptctl_id);
3046                misc_deregister(&mptctl_miscdev);
3047                err = -EBUSY;
3048                goto out_fail;
3049        }
3050
3051        mpt_reset_register(mptctl_id, mptctl_ioc_reset);
3052        mpt_event_register(mptctl_id, mptctl_event_process);
3053
3054        return 0;
3055
3056out_fail:
3057
3058        mpt_device_driver_deregister(MPTCTL_DRIVER);
3059
3060        return err;
3061}
3062
3063/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3064static void mptctl_exit(void)
3065{
3066        misc_deregister(&mptctl_miscdev);
3067        printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n",
3068                         mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
3069
3070        /* De-register event handler from base module */
3071        mpt_event_deregister(mptctl_id);
3072
3073        /* De-register reset handler from base module */
3074        mpt_reset_deregister(mptctl_id);
3075
3076        /* De-register callback handler from base module */
3077        mpt_deregister(mptctl_taskmgmt_id);
3078        mpt_deregister(mptctl_id);
3079
3080        mpt_device_driver_deregister(MPTCTL_DRIVER);
3081
3082}
3083
3084/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3085
3086module_init(mptctl_init);
3087module_exit(mptctl_exit);
3088