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