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