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