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