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