This source file includes following definitions.
- mptctl_syscall_down
- mptctl_reply
- mptctl_taskmgmt_reply
- mptctl_do_taskmgmt
- mptctl_timeout_expired
- mptctl_ioc_reset
- mptctl_event_process
- mptctl_fasync
- __mptctl_ioctl
- mptctl_ioctl
- mptctl_do_reset
- mptctl_fw_download
- mptctl_do_fw_download
- kbuf_alloc_2_sgl
- kfree_sgl
- mptctl_getiocinfo
- mptctl_gettargetinfo
- mptctl_readtest
- mptctl_eventquery
- mptctl_eventenable
- mptctl_eventreport
- mptctl_replace_fw
- mptctl_mpt_command
- mptctl_do_mpt_command
- mptctl_hp_hostinfo
- mptctl_hp_targetinfo
- compat_mptfwxfer_ioctl
- compat_mpt_command
- compat_mpctl_ioctl
- mptctl_probe
- mptctl_remove
- mptctl_init
- mptctl_exit
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 
  29 
  30 
  31 
  32 
  33 
  34 
  35 
  36 
  37 
  38 
  39 
  40 
  41 
  42 
  43 
  44 
  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>        
  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 
  79 MODULE_AUTHOR(MODULEAUTHOR);
  80 MODULE_DESCRIPTION(my_NAME);
  81 MODULE_LICENSE("GPL");
  82 MODULE_VERSION(my_VERSION);
  83 
  84 
  85 
  86 static DEFINE_MUTEX(mpctl_mutex);
  87 static u8 mptctl_id = MPT_MAX_PROTOCOL_DRIVERS;
  88 static u8 mptctl_taskmgmt_id = MPT_MAX_PROTOCOL_DRIVERS;
  89 
  90 static DECLARE_WAIT_QUEUE_HEAD ( mptctl_wait );
  91 
  92 
  93 
  94 struct buflist {
  95         u8      *kptr;
  96         int      len;
  97 };
  98 
  99 
 100 
 101 
 102 
 103 static int mptctl_fw_download(MPT_ADAPTER *iocp, unsigned long arg);
 104 static int mptctl_getiocinfo(MPT_ADAPTER *iocp, unsigned long arg, unsigned int cmd);
 105 static int mptctl_gettargetinfo(MPT_ADAPTER *iocp, unsigned long arg);
 106 static int mptctl_readtest(MPT_ADAPTER *iocp, unsigned long arg);
 107 static int mptctl_mpt_command(MPT_ADAPTER *iocp, unsigned long arg);
 108 static int mptctl_eventquery(MPT_ADAPTER *iocp, unsigned long arg);
 109 static int mptctl_eventenable(MPT_ADAPTER *iocp, unsigned long arg);
 110 static int mptctl_eventreport(MPT_ADAPTER *iocp, unsigned long arg);
 111 static int mptctl_replace_fw(MPT_ADAPTER *iocp, unsigned long arg);
 112 
 113 static int mptctl_do_reset(MPT_ADAPTER *iocp, unsigned long arg);
 114 static int mptctl_hp_hostinfo(MPT_ADAPTER *iocp, unsigned long arg, unsigned int cmd);
 115 static int mptctl_hp_targetinfo(MPT_ADAPTER *iocp, unsigned long arg);
 116 
 117 static int  mptctl_probe(struct pci_dev *, const struct pci_device_id *);
 118 static void mptctl_remove(struct pci_dev *);
 119 
 120 #ifdef CONFIG_COMPAT
 121 static long compat_mpctl_ioctl(struct file *f, unsigned cmd, unsigned long arg);
 122 #endif
 123 
 124 
 125 
 126 static int mptctl_do_mpt_command(MPT_ADAPTER *iocp, struct mpt_ioctl_command karg, void __user *mfPtr);
 127 static int mptctl_do_fw_download(MPT_ADAPTER *iocp, char __user *ufwbuf, size_t fwlen);
 128 static 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);
 130 static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma,
 131                 struct buflist *buflist, MPT_ADAPTER *ioc);
 132 
 133 
 134 
 135 
 136 static int  mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);
 137 
 138 
 139 
 140 
 141 static int mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
 142 static struct fasync_struct *async_queue=NULL;
 143 
 144 
 145 
 146 
 147 
 148 
 149 #define MAX_FRAGS_SPILL1        9
 150 #define MAX_FRAGS_SPILL2        15
 151 #define FRAGS_PER_BUCKET        (MAX_FRAGS_SPILL2 + 1)
 152 
 153 
 154 
 155 #define MAX_CHAIN_FRAGS         (4 * MAX_FRAGS_SPILL2 + 1)
 156 
 157 
 158 
 159 
 160 #define MAX_SGL_BYTES           ((MAX_FRAGS_SPILL1 + 1 + (4 * FRAGS_PER_BUCKET)) * 8)
 161 
 162 
 163 #define MAX_KMALLOC_SZ          (128*1024)
 164 
 165 #define MPT_IOCTL_DEFAULT_TIMEOUT 10    
 166 
 167 
 168 
 169 
 170 
 171 
 172 
 173 
 174 
 175 
 176 
 177 
 178 static inline int
 179 mptctl_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 
 196 
 197 
 198 
 199 
 200 static int
 201 mptctl_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 
 216 
 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         
 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 
 285 static int
 286 mptctl_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 
 315 static int
 316 mptctl_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         
 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; 
 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; 
 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; 
 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 
 458 
 459 
 460 
 461 
 462 static void
 463 mptctl_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 
 518 
 519 
 520 
 521 
 522 
 523 static int
 524 mptctl_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 
 552 static int
 553 mptctl_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         
 565 
 566 
 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         
 579 
 580 
 581 
 582         if(ioc->aen_event_read_flag)
 583                 return 1;
 584 
 585         
 586 
 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 
 599 static int
 600 mptctl_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 
 617 
 618 
 619 
 620 static 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;                           
 638 
 639         
 640 
 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         
 654 
 655 
 656 
 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         
 675 
 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 
 698 static long
 699 mptctl_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 
 708 static 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 
 735 
 736 
 737 
 738 
 739 
 740 
 741 
 742 
 743 
 744 
 745 
 746 
 747 
 748 
 749 static int
 750 mptctl_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 
 768 
 769 
 770 
 771 
 772 
 773 
 774 
 775 
 776 
 777 
 778 
 779 static int
 780 mptctl_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         
 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 
 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         
 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         
 844 
 845 
 846         
 847 
 848 
 849 
 850 
 851 
 852 
 853 
 854 
 855 
 856 
 857 
 858 
 859         sgdir = 0x04000000;             
 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 
 867 
 868 
 869 
 870 
 871 
 872 
 873 
 874 
 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 
 889 
 890 
 891         ret = -EFAULT;
 892         sgIn = sgl;
 893         bl = buflist;
 894         for (i=0; i < numfrags; i++) {
 895 
 896                 
 897 
 898 
 899 
 900 
 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 
 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         
 932 retry_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 
 984 fwdl_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 
 995 
 996 
 997 
 998 
 999 
1000 
1001 
1002 
1003 
1004 
1005 
1006 
1007 static MptSge_t *
1008 kbuf_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;         
1012                                                 
1013         struct buflist  *buflist = NULL;        
1014         MptSge_t        *sgl;
1015         int              numfrags = 0;
1016         int              fragcnt = 0;
1017         int              alloc_sz = min(bytes,MAX_KMALLOC_SZ);  
1018         int              bytes_allocd = 0;
1019         int              this_alloc;
1020         dma_addr_t       pa;                                    
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         
1029         *frags = 0;
1030         *blp = NULL;
1031 
1032         
1033 
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         
1042 
1043 
1044 
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         
1056 
1057 
1058 
1059 
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                 
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                 
1107                 if (numfrags*8 > MAX_SGL_BYTES){
1108                         
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         
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 
1131 free_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 
1156 
1157 static void
1158 kfree_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)) { 
1173                 
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         
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 
1216 
1217 
1218 
1219 
1220 
1221 
1222 
1223 static int
1224 mptctl_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         
1235 
1236 
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;    
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         
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         
1269 
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                 
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                 
1300 
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         
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         
1323 
1324         karg->FWVersion = ioc->facts.FWVersion.Word;
1325         karg->BIOSVersion = ioc->biosVersion;
1326 
1327         
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         
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 
1353 
1354 
1355 
1356 
1357 
1358 
1359 
1360 static int
1361 mptctl_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         
1385 
1386 
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         
1399 
1400 
1401 
1402         
1403 
1404 
1405 
1406 
1407 
1408 
1409 
1410 
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         
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         
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         
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 
1470 
1471 
1472 
1473 
1474 
1475 
1476 static int
1477 mptctl_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         
1492 
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         
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 
1520 
1521 
1522 
1523 
1524 
1525 
1526 
1527 
1528 static int
1529 mptctl_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         
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 
1558 static int
1559 mptctl_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                 
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         
1590 
1591         ioc->eventTypes = karg.eventTypes;
1592 
1593         return 0;
1594 }
1595 
1596 
1597 static int
1598 mptctl_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         
1621 
1622 
1623         if ((max < 1) || !ioc->events)
1624                 return -ENODATA;
1625 
1626         
1627         ioc->aen_event_read_flag=0;
1628 
1629         
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 
1643 static int
1644 mptctl_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         
1660 
1661         if (ioc->cached_fw == NULL)
1662                 return 0;
1663 
1664         mpt_free_fw_memory(ioc);
1665 
1666         
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         
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         
1685 
1686         ioc->facts.FWImageSize = newFwSize;
1687         return 0;
1688 }
1689 
1690 
1691 
1692 
1693 
1694 
1695 
1696 
1697 
1698 
1699 
1700 
1701 
1702 static int
1703 mptctl_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 
1724 
1725 
1726 
1727 
1728 
1729 
1730 
1731 
1732 
1733 
1734 static int
1735 mptctl_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;  
1741         struct buflist  bufOut; 
1742         dma_addr_t      dma_addr_in;
1743         dma_addr_t      dma_addr_out;
1744         int             sgSize = 0;     
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         
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         
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         
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         
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         
1803 
1804 
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         
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                         
1882 
1883 
1884 
1885 
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                         
1910 
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                 
1935 
1936 
1937 
1938 
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                 
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                         
1969 
1970 
1971 
1972 
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                         
1984 
1985 
1986                         
1987 
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                         
2028 
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 
2054 
2055 
2056 
2057 
2058 
2059 
2060 
2061 
2062 
2063 
2064 
2065 
2066 
2067                 
2068 
2069 
2070 
2071 
2072 
2073 
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         
2084 
2085 
2086 
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                 
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                                 
2119 
2120 
2121                                 ioc->add_sge(psge, flagsLength, dma_addr_out);
2122                                 psge += ioc->SGE_size;
2123 
2124                                 
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                                 
2153 
2154 
2155                                 ioc->add_sge(psge, flagsLength, dma_addr_in);
2156                         }
2157                 }
2158         } else  {
2159                 
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         
2197         timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT;
2198 retry_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         
2231 
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         
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         
2271 
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 
2286 done_free_mem:
2287 
2288         CLEAR_MGMT_STATUS(ioc->ioctl_cmds.status)
2289         SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, 0);
2290 
2291         
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         
2304 
2305 
2306         if (mf)
2307                 mpt_free_msg_frame(ioc, mf);
2308 
2309         return rc;
2310 }
2311 
2312 
2313 
2314 
2315 
2316 
2317 
2318 
2319 
2320 
2321 
2322 
2323 static int
2324 mptctl_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         
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;    
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         
2360 
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         
2372 
2373 
2374         if (ioc->sh != NULL)
2375                 karg.host_no = ioc->sh->host_no;
2376         else
2377                 karg.host_no =  -1;
2378 
2379         
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         
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;    
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                         
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 
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 
2493 retry_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 
2515 
2516 
2517 
2518 
2519 
2520 
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         
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 
2547 
2548 
2549 
2550 
2551 
2552 
2553 
2554 
2555 
2556 static int
2557 mptctl_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         
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        
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         
2638 
2639         karg.message_rejects = -1;
2640         karg.phase_errors = -1;
2641         karg.parity_errors = -1;
2642         karg.select_timeouts = -1;
2643 
2644         
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                 
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         
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 
2691 static 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 
2701 static struct miscdevice mptctl_miscdev = {
2702         MPT_MINOR,
2703         MYNAM,
2704         &mptctl_fops
2705 };
2706 
2707 
2708 
2709 #ifdef CONFIG_COMPAT
2710 
2711 static int
2712 compat_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         
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 
2751 static int
2752 compat_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         
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         
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         
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 
2805 static 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 
2843 
2844 
2845 
2846 
2847 
2848 
2849 static int
2850 mptctl_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 
2862 
2863 
2864 
2865 
2866 static void
2867 mptctl_remove(struct pci_dev *pdev)
2868 {
2869 }
2870 
2871 static struct mpt_pci_driver mptctl_driver = {
2872   .probe                = mptctl_probe,
2873   .remove               = mptctl_remove,
2874 };
2875 
2876 
2877 static 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         
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 
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 
2924 out_fail:
2925 
2926         mpt_device_driver_deregister(MPTCTL_DRIVER);
2927 
2928         return err;
2929 }
2930 
2931 
2932 static 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         
2939         mpt_event_deregister(mptctl_id);
2940 
2941         
2942         mpt_reset_deregister(mptctl_id);
2943 
2944         
2945         mpt_deregister(mptctl_taskmgmt_id);
2946         mpt_deregister(mptctl_id);
2947 
2948         mpt_device_driver_deregister(MPTCTL_DRIVER);
2949 
2950 }
2951 
2952 
2953 
2954 module_init(mptctl_init);
2955 module_exit(mptctl_exit);