2 * linux/drivers/message/fusion/mptctl.c
3 * Fusion MPT misc device (ioctl) driver.
4 * For use with PCI chip/adapter(s):
5 * LSIFC9xx/LSI409xx Fibre Channel
6 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
9 * This driver would not exist if not for Alan Cox's development
10 * of the linux i2o driver.
12 * A special thanks to Pamela Delaney (LSI Logic) for tons of work
13 * and countless enhancements while adding support for the 1030
14 * chip family. Pam has been instrumental in the development of
15 * of the 2.xx.xx series fusion drivers, and her contributions are
16 * far too numerous to hope to list in one place.
18 * A huge debt of gratitude is owed to David S. Miller (DaveM)
19 * for fixing much of the stupid and broken stuff in the early
20 * driver while porting to sparc64 platform. THANK YOU!
22 * A big THANKS to Eddie C. Dost for fixing the ioctl path
23 * and most importantly f/w download on sparc64 platform!
24 * (plus Eddie's other helpful hints and insights)
26 * Thanks to Arnaldo Carvalho de Melo for finding and patching
27 * a potential memory leak in mptctl_do_fw_download(),
28 * and for some kmalloc insight:-)
30 * (see also mptbase.c)
32 * Copyright (c) 1999-2004 LSI Logic Corporation
33 * Originally By: Steven J. Ralston, Noah Romer
34 * (mailto:sjralston1@netscape.net)
35 * (mailto:mpt_linux_developer@lsil.com)
37 * $Id: mptctl.c,v 1.63 2002/12/03 21:26:33 pdelaney Exp $
39 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
41 This program is free software; you can redistribute it and/or modify
42 it under the terms of the GNU General Public License as published by
43 the Free Software Foundation; version 2 of the License.
45 This program is distributed in the hope that it will be useful,
46 but WITHOUT ANY WARRANTY; without even the implied warranty of
47 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
48 GNU General Public License for more details.
51 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
52 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
53 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
54 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
55 solely responsible for determining the appropriateness of using and
56 distributing the Program and assumes all risks associated with its
57 exercise of rights under this Agreement, including but not limited to
58 the risks and costs of program errors, damage to or loss of data,
59 programs or equipment, and unavailability or interruption of operations.
61 DISCLAIMER OF LIABILITY
62 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
63 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
65 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
66 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
67 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
68 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
70 You should have received a copy of the GNU General Public License
71 along with this program; if not, write to the Free Software
72 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
74 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
76 #include <linux/version.h>
77 #include <linux/kernel.h>
78 #include <linux/module.h>
79 #include <linux/errno.h>
80 #include <linux/init.h>
81 #include <linux/slab.h>
82 #include <linux/types.h>
83 #include <linux/pci.h>
84 #include <linux/miscdevice.h>
85 #include <linux/smp_lock.h>
88 #include <asm/uaccess.h>
89 #include <linux/compat.h>
91 #include <linux/kdev_t.h> /* needed for access to Scsi_Host struct */
92 #include <linux/blkdev.h>
93 #include "../../scsi/scsi.h"
94 #include <scsi/scsi_host.h>
96 #define COPYRIGHT "Copyright (c) 1999-2004 LSI Logic Corporation"
97 #define MODULEAUTHOR "Steven J. Ralston, Noah Romer, Pamela Delaney"
101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
102 #define my_NAME "Fusion MPT misc device (ioctl) driver"
103 #define my_VERSION MPT_LINUX_VERSION_COMMON
104 #define MYNAM "mptctl"
106 MODULE_AUTHOR(MODULEAUTHOR);
107 MODULE_DESCRIPTION(my_NAME);
108 MODULE_LICENSE("GPL");
110 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
112 static int mptctl_id = -1;
113 static struct semaphore mptctl_syscall_sem_ioc[MPT_MAX_ADAPTERS];
115 static DECLARE_WAIT_QUEUE_HEAD ( mptctl_wait );
117 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
125 * Function prototypes. Called from OS entry point mptctl_ioctl.
126 * arg contents specific to function.
128 static int mptctl_fw_download(unsigned long arg);
129 static int mptctl_getiocinfo (unsigned long arg, unsigned int cmd);
130 static int mptctl_gettargetinfo (unsigned long arg);
131 static int mptctl_readtest (unsigned long arg);
132 static int mptctl_mpt_command (unsigned long arg);
133 static int mptctl_eventquery (unsigned long arg);
134 static int mptctl_eventenable (unsigned long arg);
135 static int mptctl_eventreport (unsigned long arg);
136 static int mptctl_replace_fw (unsigned long arg);
138 static int mptctl_do_reset(unsigned long arg);
139 static int mptctl_hp_hostinfo(unsigned long arg, unsigned int cmd);
140 static int mptctl_hp_targetinfo(unsigned long arg);
143 * Private function calls.
145 static int mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr);
146 static int mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen);
147 static MptSge_t *kbuf_alloc_2_sgl( int bytes, u32 dir, int sge_offset, int *frags,
148 struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc);
149 static void kfree_sgl( MptSge_t *sgl, dma_addr_t sgl_dma,
150 struct buflist *buflist, MPT_ADAPTER *ioc);
151 static void mptctl_timer_expired (unsigned long data);
152 static int mptctl_bus_reset(MPT_IOCTL *ioctl);
153 static int mptctl_set_tm_flags(MPT_SCSI_HOST *hd);
154 static void mptctl_free_tm_flags(MPT_ADAPTER *ioc);
157 * Reset Handler cleanup function
159 static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);
161 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
163 * Scatter gather list (SGL) sizes and limits...
165 //#define MAX_SCSI_FRAGS 9
166 #define MAX_FRAGS_SPILL1 9
167 #define MAX_FRAGS_SPILL2 15
168 #define FRAGS_PER_BUCKET (MAX_FRAGS_SPILL2 + 1)
170 //#define MAX_CHAIN_FRAGS 64
171 //#define MAX_CHAIN_FRAGS (15+15+15+16)
172 #define MAX_CHAIN_FRAGS (4 * MAX_FRAGS_SPILL2 + 1)
174 // Define max sg LIST bytes ( == (#frags + #chains) * 8 bytes each)
175 // Works out to: 592d bytes! (9+1)*8 + 4*(15+1)*8
176 // ^----------------- 80 + 512
177 #define MAX_SGL_BYTES ((MAX_FRAGS_SPILL1 + 1 + (4 * FRAGS_PER_BUCKET)) * 8)
179 /* linux only seems to ever give 128kB MAX contiguous (GFP_USER) mem bytes */
180 #define MAX_KMALLOC_SZ (128*1024)
182 #define MPT_IOCTL_DEFAULT_TIMEOUT 10 /* Default timeout value (seconds) */
184 static u32 fwReplyBuffer[16];
185 static pMPIDefaultReply_t ReplyMsg = NULL;
187 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
189 * mptctl_syscall_down - Down the MPT adapter syscall semaphore.
190 * @ioc: Pointer to MPT adapter
191 * @nonblock: boolean, non-zero if O_NONBLOCK is set
193 * All of the ioctl commands can potentially sleep, which is illegal
194 * with a spinlock held, thus we perform mutual exclusion here.
196 * Returns negative errno on error, or zero for success.
199 mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock)
202 dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down(%p,%d) called\n", ioc, nonblock));
204 if (ioc->ioctl->tmPtr != NULL) {
205 dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down BUSY\n"));
210 if (down_trylock(&mptctl_syscall_sem_ioc[ioc->id]))
213 if (down_interruptible(&mptctl_syscall_sem_ioc[ioc->id]))
216 dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down return %d\n", rc));
220 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
222 * This is the callback for any message we have posted. The message itself
223 * will be returned to the message pool when we return from the IRQ
225 * This runs in irq context so be short and sweet.
228 mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
235 dctlprintk((MYIOC_s_INFO_FMT ": mptctl_reply()!\n", ioc->name));
237 cmd = req->u.hdr.Function;
242 /* If timer is not running, then an error occurred.
243 * A timeout will call the reset routine to reload the messaging
245 * Main callback will free message and reply frames.
247 if (reply && (cmd == MPI_FUNCTION_SCSI_TASK_MGMT) &&
248 (ioc->ioctl->status & MPT_IOCTL_STATUS_TMTIMER_ACTIVE)) {
249 /* This is internally generated TM
251 del_timer (&ioc->ioctl->TMtimer);
252 ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TMTIMER_ACTIVE;
254 mptctl_free_tm_flags(ioc);
256 /* If TM failed, reset the timer on the existing command,
257 * will trigger an adapter reset.
259 iocStatus = reply->u.reply.IOCStatus & MPI_IOCSTATUS_MASK;
260 if (iocStatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED) {
261 if (ioc->ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE) {
262 ioc->ioctl->reset &= ~MPTCTL_RESET_OK;
263 del_timer (&ioc->ioctl->timer);
264 ioc->ioctl->timer.expires = jiffies + HZ;
265 add_timer(&ioc->ioctl->timer);
268 ioc->ioctl->tmPtr = NULL;
270 } else if (ioc->ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE) {
273 del_timer (&ioc->ioctl->timer);
274 ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TIMER_ACTIVE;
276 /* Set the overall status byte. Good if:
277 * IOC status is good OR if no reply and a SCSI IO request
280 /* Copy the reply frame (which much exist
281 * for non-SCSI I/O) to the IOC structure.
283 dctlprintk((MYIOC_s_INFO_FMT ": Copying Reply Frame @%p to IOC!\n",
285 memcpy(ioc->ioctl->ReplyFrame, reply,
286 min(ioc->reply_sz, 4*reply->u.reply.MsgLength));
287 ioc->ioctl->status |= MPT_IOCTL_STATUS_RF_VALID;
289 /* Set the command status to GOOD if IOC Status is GOOD
290 * OR if SCSI I/O cmd and data underrun or recovered error.
292 iocStatus = reply->u.reply.IOCStatus & MPI_IOCSTATUS_MASK;
293 if (iocStatus == MPI_IOCSTATUS_SUCCESS)
294 ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
296 if ((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
297 (cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
298 ioc->ioctl->reset &= ~MPTCTL_RESET_OK;
300 if ((iocStatus == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN) ||
301 (iocStatus == MPI_IOCSTATUS_SCSI_RECOVERED_ERROR)) {
302 ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
306 /* Copy the sense data - if present
308 if ((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) &&
309 (reply->u.sreply.SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)){
311 sz = req->u.scsireq.SenseBufferLength;
312 req_index = le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
313 sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
314 memcpy(ioc->ioctl->sense, sense_data, sz);
315 ioc->ioctl->status |= MPT_IOCTL_STATUS_SENSE_VALID;
318 if (cmd == MPI_FUNCTION_SCSI_TASK_MGMT)
319 mptctl_free_tm_flags(ioc);
322 } else if ((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
323 (cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
324 ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
325 ioc->ioctl->reset &= ~MPTCTL_RESET_OK;
328 /* We are done, issue wake up
330 ioc->ioctl->wait_done = 1;
331 wake_up (&mptctl_wait);
332 } else if (reply && cmd == MPI_FUNCTION_FW_DOWNLOAD) {
333 /* Two paths to FW DOWNLOAD! */
334 // NOTE: Expects/requires non-Turbo reply!
335 dctlprintk((MYIOC_s_INFO_FMT ":Caching MPI_FUNCTION_FW_DOWNLOAD reply!\n",
337 memcpy(fwReplyBuffer, reply, min_t(int, sizeof(fwReplyBuffer), 4*reply->u.reply.MsgLength));
338 ReplyMsg = (pMPIDefaultReply_t) fwReplyBuffer;
344 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
345 /* mptctl_timer_expired
347 * Call back for timer process. Used only for ioctl functionality.
350 static void mptctl_timer_expired (unsigned long data)
352 MPT_IOCTL *ioctl = (MPT_IOCTL *) data;
355 dctlprintk((KERN_NOTICE MYNAM ": Timer Expired! Host %d\n",
360 if (ioctl->reset & MPTCTL_RESET_OK)
361 rc = mptctl_bus_reset(ioctl);
364 /* Issue a reset for this device.
365 * The IOC is not responding.
367 mpt_HardResetHandler(ioctl->ioc, NO_SLEEP);
378 static int mptctl_bus_reset(MPT_IOCTL *ioctl)
381 SCSITaskMgmt_t *pScsiTm;
387 ioctl->reset &= ~MPTCTL_RESET_OK;
389 if (ioctl->ioc->sh == NULL)
392 hd = (MPT_SCSI_HOST *) ioctl->ioc->sh->hostdata;
396 /* Single threading ....
398 if (mptctl_set_tm_flags(hd) != 0)
403 if ((mf = mpt_get_msg_frame(mptctl_id, ioctl->ioc->id)) == NULL) {
404 dctlprintk((MYIOC_s_WARN_FMT "IssueTaskMgmt, no msg frames!!\n",
407 mptctl_free_tm_flags(ioctl->ioc);
411 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
412 ioctl->ioc->name, mf));
414 pScsiTm = (SCSITaskMgmt_t *) mf;
415 pScsiTm->TargetID = ioctl->target;
416 pScsiTm->Bus = hd->port; /* 0 */
417 pScsiTm->ChainOffset = 0;
418 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
419 pScsiTm->Reserved = 0;
420 pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;
421 pScsiTm->Reserved1 = 0;
422 pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
424 for (ii= 0; ii < 8; ii++)
425 pScsiTm->LUN[ii] = 0;
427 for (ii=0; ii < 7; ii++)
428 pScsiTm->Reserved2[ii] = 0;
430 pScsiTm->TaskMsgContext = 0;
431 dtmprintk((MYIOC_s_INFO_FMT "mptctl_bus_reset: issued.\n", ioctl->ioc->name));
434 ioctl->TMtimer.expires = jiffies + HZ * 20; /* 20 seconds */
435 ioctl->status |= MPT_IOCTL_STATUS_TMTIMER_ACTIVE;
436 add_timer(&ioctl->TMtimer);
438 retval = mpt_send_handshake_request(mptctl_id, ioctl->ioc->id,
439 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, NO_SLEEP);
442 dtmprintk((MYIOC_s_WARN_FMT "_send_handshake FAILED!"
443 " (hd %p, ioc %p, mf %p) \n", ioctl->ioc->name, hd, hd->ioc, mf));
445 mptctl_free_tm_flags(ioctl->ioc);
446 del_timer(&ioctl->TMtimer);
447 mpt_free_msg_frame(mptctl_id, ioctl->ioc->id, mf);
455 mptctl_set_tm_flags(MPT_SCSI_HOST *hd) {
458 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
460 if (hd->tmState == TM_STATE_NONE) {
461 hd->tmState = TM_STATE_IN_PROGRESS;
463 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
465 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
473 mptctl_free_tm_flags(MPT_ADAPTER *ioc)
478 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
482 spin_lock_irqsave(&ioc->FreeQlock, flags);
484 hd->tmState = TM_STATE_ERROR;
486 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
492 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
495 * Clean-up functionality. Used only if there has been a
496 * reload of the FW due.
500 mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
502 MPT_IOCTL *ioctl = ioc->ioctl;
503 dctlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to IOCTL driver!\n",
504 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
505 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
507 if (reset_phase == MPT_IOC_SETUP_RESET){
509 } else if (reset_phase == MPT_IOC_PRE_RESET){
511 /* Someone has called the reset handler to
512 * do a hard reset. No more replies from the FW.
513 * Delete the timer. TM flags cleaned up by SCSI driver.
514 * Do not need to free msg frame, as re-initialized
516 if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE)){
517 del_timer(&ioctl->timer);
519 if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TMTIMER_ACTIVE)){
520 ioctl->status &= ~MPT_IOCTL_STATUS_TMTIMER_ACTIVE;
521 del_timer(&ioctl->TMtimer);
522 mpt_free_msg_frame(mptctl_id, ioc->id, ioctl->tmPtr);
528 /* Set the status and continue IOCTL
529 * processing. All memory will be free'd
530 * by originating thread after wake_up is
533 if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE)){
534 ioctl->status |= MPT_IOCTL_STATUS_DID_IOCRESET;
536 /* Wake up the calling process
538 ioctl->wait_done = 1;
539 wake_up(&mptctl_wait);
546 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
549 * cmd - specify the particular IOCTL command to be issued
550 * arg - data specific to the command. Must not be null.
553 mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
555 mpt_ioctl_header __user *uhdr = (void __user *) arg;
556 mpt_ioctl_header khdr;
559 int nonblock = (file->f_flags & O_NONBLOCK);
561 MPT_ADAPTER *iocp = NULL;
563 dctlprintk(("mptctl_ioctl() called\n"));
565 if (copy_from_user(&khdr, uhdr, sizeof(khdr))) {
566 printk(KERN_ERR "%s::mptctl_ioctl() @%d - "
567 "Unable to copy mpt_ioctl_header data @ %p\n",
568 __FILE__, __LINE__, uhdr);
571 ret = -ENXIO; /* (-6) No such device or address */
573 /* Verify intended MPT adapter - set iocnum and the adapter
576 iocnumX = khdr.iocnum & 0xFF;
577 if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
579 dctlprintk((KERN_ERR "%s::mptctl_ioctl() @%d - ioc%d not found!\n",
580 __FILE__, __LINE__, iocnumX));
585 printk(KERN_ERR "%s::mptctl_ioctl() @%d - Controller disabled.\n",
590 /* Handle those commands that are just returning
591 * information stored in the driver.
592 * These commands should never time out and are unaffected
593 * by TM and FW reloads.
595 if ((cmd & ~IOCSIZE_MASK) == (MPTIOCINFO & ~IOCSIZE_MASK)) {
596 return mptctl_getiocinfo(arg, _IOC_SIZE(cmd));
597 } else if (cmd == MPTTARGETINFO) {
598 return mptctl_gettargetinfo(arg);
599 } else if (cmd == MPTTEST) {
600 return mptctl_readtest(arg);
601 } else if (cmd == MPTEVENTQUERY) {
602 return mptctl_eventquery(arg);
603 } else if (cmd == MPTEVENTENABLE) {
604 return mptctl_eventenable(arg);
605 } else if (cmd == MPTEVENTREPORT) {
606 return mptctl_eventreport(arg);
607 } else if (cmd == MPTFWREPLACE) {
608 return mptctl_replace_fw(arg);
611 /* All of these commands require an interrupt or
612 * are unknown/illegal.
614 if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
617 dctlprintk((MYIOC_s_INFO_FMT ": mptctl_ioctl()\n", iocp->name));
619 if (cmd == MPTFWDOWNLOAD)
620 ret = mptctl_fw_download(arg);
621 else if (cmd == MPTCOMMAND)
622 ret = mptctl_mpt_command(arg);
623 else if (cmd == MPTHARDRESET)
624 ret = mptctl_do_reset(arg);
625 else if ((cmd & ~IOCSIZE_MASK) == (HP_GETHOSTINFO & ~IOCSIZE_MASK))
626 ret = mptctl_hp_hostinfo(arg, _IOC_SIZE(cmd));
627 else if (cmd == HP_GETTARGETINFO)
628 ret = mptctl_hp_targetinfo(arg);
633 up(&mptctl_syscall_sem_ioc[iocp->id]);
638 static int mptctl_do_reset(unsigned long arg)
640 struct mpt_ioctl_diag_reset __user *urinfo = (void __user *) arg;
641 struct mpt_ioctl_diag_reset krinfo;
644 dctlprintk((KERN_INFO "mptctl_do_reset called.\n"));
646 if (copy_from_user(&krinfo, urinfo, sizeof(struct mpt_ioctl_diag_reset))) {
647 printk(KERN_ERR "%s@%d::mptctl_do_reset - "
648 "Unable to copy mpt_ioctl_diag_reset struct @ %p\n",
649 __FILE__, __LINE__, urinfo);
653 if (mpt_verify_adapter(krinfo.hdr.iocnum, &iocp) < 0) {
654 dctlprintk((KERN_ERR "%s@%d::mptctl_do_reset - ioc%d not found!\n",
655 __FILE__, __LINE__, krinfo.hdr.iocnum));
656 return -ENODEV; /* (-6) No such device or address */
659 if (mpt_HardResetHandler(iocp, CAN_SLEEP) != 0) {
660 printk (KERN_ERR "%s@%d::mptctl_do_reset - reset failed.\n",
668 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
670 * MPT FW download function. Cast the arg into the mpt_fw_xfer structure.
671 * This structure contains: iocnum, firmware length (bytes),
672 * pointer to user space memory where the fw image is stored.
675 * Return: 0 if successful
676 * -EFAULT if data unavailable
677 * -ENXIO if no such device
678 * -EAGAIN if resource problem
679 * -ENOMEM if no memory for SGE
680 * -EMLINK if too many chain buffers required
681 * -EBADRQC if adapter does not support FW download
682 * -EBUSY if adapter is busy
683 * -ENOMSG if FW upload returned bad status
686 mptctl_fw_download(unsigned long arg)
688 struct mpt_fw_xfer __user *ufwdl = (void __user *) arg;
689 struct mpt_fw_xfer kfwdl;
691 dctlprintk((KERN_INFO "mptctl_fwdl called. mptctl_id = %xh\n", mptctl_id)); //tc
692 if (copy_from_user(&kfwdl, ufwdl, sizeof(struct mpt_fw_xfer))) {
693 printk(KERN_ERR "%s@%d::_ioctl_fwdl - "
694 "Unable to copy mpt_fw_xfer struct @ %p\n",
695 __FILE__, __LINE__, ufwdl);
699 return mptctl_do_fw_download(kfwdl.iocnum, kfwdl.bufp, kfwdl.fwlen);
702 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
704 * FW Download engine.
706 * Return: 0 if successful
707 * -EFAULT if data unavailable
708 * -ENXIO if no such device
709 * -EAGAIN if resource problem
710 * -ENOMEM if no memory for SGE
711 * -EMLINK if too many chain buffers required
712 * -EBADRQC if adapter does not support FW download
713 * -EBUSY if adapter is busy
714 * -ENOMSG if FW upload returned bad status
717 mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
722 FWDownloadTCSGE_t *ptsge;
723 MptSge_t *sgl, *sgIn;
725 struct buflist *buflist;
734 int fw_bytes_copied = 0;
740 dctlprintk((KERN_INFO "mptctl_do_fwdl called. mptctl_id = %xh.\n", mptctl_id));
742 dctlprintk((KERN_INFO "DbG: kfwdl.bufp = %p\n", ufwbuf));
743 dctlprintk((KERN_INFO "DbG: kfwdl.fwlen = %d\n", (int)fwlen));
744 dctlprintk((KERN_INFO "DbG: kfwdl.ioc = %04xh\n", ioc));
746 if ((ioc = mpt_verify_adapter(ioc, &iocp)) < 0) {
747 dctlprintk(("%s@%d::_ioctl_fwdl - ioc%d not found!\n",
748 __FILE__, __LINE__, ioc));
749 return -ENODEV; /* (-6) No such device or address */
752 /* Valid device. Get a message frame and construct the FW download message.
754 if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL)
756 dlmsg = (FWDownload_t*) mf;
757 ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL;
758 sgOut = (char *) (ptsge + 1);
761 * Construct f/w download request
763 dlmsg->ImageType = MPI_FW_DOWNLOAD_ITYPE_FW;
765 dlmsg->ChainOffset = 0;
766 dlmsg->Function = MPI_FUNCTION_FW_DOWNLOAD;
767 dlmsg->Reserved1[0] = dlmsg->Reserved1[1] = dlmsg->Reserved1[2] = 0;
770 /* Set up the Transaction SGE.
773 ptsge->ContextSize = 0;
774 ptsge->DetailsLength = 12;
775 ptsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
776 ptsge->Reserved_0100_Checksum = 0;
777 ptsge->ImageOffset = 0;
778 ptsge->ImageSize = cpu_to_le32(fwlen);
784 * Need to kmalloc area(s) for holding firmware image bytes.
785 * But we need to do it piece meal, using a proper
786 * scatter gather list (with 128kB MAX hunks).
788 * A practical limit here might be # of sg hunks that fit into
789 * a single IOC request frame; 12 or 8 (see below), so:
790 * For FC9xx: 12 x 128kB == 1.5 mB (max)
791 * For C1030: 8 x 128kB == 1 mB (max)
792 * We could support chaining, but things get ugly(ier:)
794 * Set the sge_offset to the start of the sgl (bytes).
796 sgdir = 0x04000000; /* IOC will READ from sys mem */
797 sge_offset = sizeof(MPIHeader_t) + sizeof(FWDownloadTCSGE_t);
798 if ((sgl = kbuf_alloc_2_sgl(fwlen, sgdir, sge_offset,
799 &numfrags, &buflist, &sgl_dma, iocp)) == NULL)
803 * We should only need SGL with 2 simple_32bit entries (up to 256 kB)
804 * for FC9xx f/w image, but calculate max number of sge hunks
805 * we can fit into a request frame, and limit ourselves to that.
806 * (currently no chain support)
807 * maxfrags = (Request Size - FWdownload Size ) / Size of 32 bit SGE
813 maxfrags = (iocp->req_sz - sizeof(MPIHeader_t) - sizeof(FWDownloadTCSGE_t))
814 / (sizeof(dma_addr_t) + sizeof(u32));
815 if (numfrags > maxfrags) {
820 dctlprintk((KERN_INFO "DbG: sgl buffer = %p, sgfrags = %d\n", sgl, numfrags));
823 * Parse SG list, copying sgl itself,
824 * plus f/w image hunks from user space as we go...
829 for (i=0; i < numfrags; i++) {
831 /* Get the SGE type: 0 - TCSGE, 3 - Chain, 1 - Simple SGE
832 * Skip everything but Simple. If simple, copy from
833 * user space into kernel space.
834 * Note: we should not have anything but Simple as
835 * Chain SGE are illegal.
837 nib = (sgIn->FlagsLength & 0x30000000) >> 28;
838 if (nib == 0 || nib == 3) {
840 } else if (sgIn->Address) {
841 mpt_add_sge(sgOut, sgIn->FlagsLength, sgIn->Address);
843 if (copy_from_user(bl->kptr, ufwbuf+fw_bytes_copied, bl->len)) {
844 printk(KERN_ERR "%s@%d::_ioctl_fwdl - "
845 "Unable to copy f/w buffer hunk#%d @ %p\n",
846 __FILE__, __LINE__, n, ufwbuf);
849 fw_bytes_copied += bl->len;
853 sgOut += (sizeof(dma_addr_t) + sizeof(u32));
859 printk(KERN_INFO MYNAM ": F/W download request:\n" KERN_INFO " ");
860 for (i=0; i < 7+numfrags*2; i++)
861 printk(" %08x", le32_to_cpu(m[i]));
867 * Finally, perform firmware download.
870 mpt_put_msg_frame(mptctl_id, ioc, mf);
873 * Wait until the reply has been received
875 for (cntdn=HZ*60, i=1; ReplyMsg == NULL; cntdn--, i++) {
882 dctlprintk((KERN_INFO "DbG::_do_fwdl: "
883 "In ReplyMsg loop - iteration %d\n",
887 set_current_state(TASK_INTERRUPTIBLE);
892 kfree_sgl(sgl, sgl_dma, buflist, iocp);
894 iocstat = le16_to_cpu(ReplyMsg->IOCStatus) & MPI_IOCSTATUS_MASK;
895 if (iocstat == MPI_IOCSTATUS_SUCCESS) {
896 printk(KERN_INFO MYNAM ": F/W update successfully sent to %s!\n", iocp->name);
898 } else if (iocstat == MPI_IOCSTATUS_INVALID_FUNCTION) {
899 printk(KERN_WARNING MYNAM ": ?Hmmm... %s says it doesn't support F/W download!?!\n",
901 printk(KERN_WARNING MYNAM ": (time to go bang on somebodies door)\n");
903 } else if (iocstat == MPI_IOCSTATUS_BUSY) {
904 printk(KERN_WARNING MYNAM ": Warning! %s says: IOC_BUSY!\n", iocp->name);
905 printk(KERN_WARNING MYNAM ": (try again later?)\n");
908 printk(KERN_WARNING MYNAM "::ioctl_fwdl() ERROR! %s returned [bad] status = %04xh\n",
909 iocp->name, iocstat);
910 printk(KERN_WARNING MYNAM ": (bad VooDoo)\n");
916 kfree_sgl(sgl, sgl_dma, buflist, iocp);
920 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
922 * SGE Allocation routine
924 * Inputs: bytes - number of bytes to be transferred
925 * sgdir - data direction
926 * sge_offset - offset (in bytes) from the start of the request
927 * frame to the first SGE
928 * ioc - pointer to the mptadapter
929 * Outputs: frags - number of scatter gather elements
930 * blp - point to the buflist pointer
931 * sglbuf_dma - pointer to the (dma) sgl
932 * Returns: Null if failes
933 * pointer to the (virtual) sgl if successful.
936 kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags,
937 struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc)
939 MptSge_t *sglbuf = NULL; /* pointer to array of SGE */
940 /* and chain buffers */
941 struct buflist *buflist = NULL; /* kernel routine */
945 int alloc_sz = min(bytes,MAX_KMALLOC_SZ); // avoid kernel warning msg!
946 int bytes_allocd = 0;
948 dma_addr_t pa; // phys addr
950 int sg_spill = MAX_FRAGS_SPILL1;
956 /* Allocate and initialize an array of kernel
957 * structures for the SG elements.
959 i = MAX_SGL_BYTES / 8;
960 buflist = kmalloc(i, GFP_USER);
963 memset(buflist, 0, i);
966 /* Allocate a single block of memory to store the sg elements and
967 * the chain buffers. The calling routine is responsible for
968 * copying the data in this array into the correct place in the
969 * request and chain buffers.
971 sglbuf = pci_alloc_consistent(ioc->pcidev, MAX_SGL_BYTES, sglbuf_dma);
975 if (sgdir & 0x04000000)
976 dir = PCI_DMA_TODEVICE;
978 dir = PCI_DMA_FROMDEVICE;
981 * sgl = sglbuf = point to beginning of sg buffer
982 * buflist_ent = 0 = first kernel structure
983 * sg_spill = number of SGE that can be written before the first
988 sg_spill = ((ioc->req_sz - sge_offset)/(sizeof(dma_addr_t) + sizeof(u32))) - 1;
989 while (bytes_allocd < bytes) {
990 this_alloc = min(alloc_sz, bytes-bytes_allocd);
991 buflist[buflist_ent].len = this_alloc;
992 buflist[buflist_ent].kptr = pci_alloc_consistent(ioc->pcidev,
995 if (buflist[buflist_ent].kptr == NULL) {
996 alloc_sz = alloc_sz / 2;
998 printk(KERN_WARNING MYNAM "-SG: No can do - "
999 "not enough memory! :-(\n");
1000 printk(KERN_WARNING MYNAM "-SG: (freeing %d frags)\n",
1006 dma_addr_t dma_addr;
1008 bytes_allocd += this_alloc;
1009 sgl->FlagsLength = (0x10000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|this_alloc);
1010 dma_addr = pci_map_single(ioc->pcidev, buflist[buflist_ent].kptr, this_alloc, dir);
1011 sgl->Address = dma_addr;
1019 if (bytes_allocd >= bytes)
1022 /* Need to chain? */
1023 if (fragcnt == sg_spill) {
1024 printk(KERN_WARNING MYNAM "-SG: No can do - " "Chain required! :-(\n");
1025 printk(KERN_WARNING MYNAM "(freeing %d frags)\n", numfrags);
1029 /* overflow check... */
1030 if (numfrags*8 > MAX_SGL_BYTES){
1032 printk(KERN_WARNING MYNAM "-SG: No can do - "
1033 "too many SG frags! :-(\n");
1034 printk(KERN_WARNING MYNAM "-SG: (freeing %d frags)\n",
1040 /* Last sge fixup: set LE+eol+eob bits */
1041 sgl[-1].FlagsLength |= 0xC1000000;
1046 dctlprintk((KERN_INFO MYNAM "-SG: kbuf_alloc_2_sgl() - "
1047 "%d SG frags generated!\n",
1050 dctlprintk((KERN_INFO MYNAM "-SG: kbuf_alloc_2_sgl() - "
1051 "last (big) alloc_sz=%d\n",
1057 if (sglbuf != NULL) {
1060 for (i = 0; i < numfrags; i++) {
1061 dma_addr_t dma_addr;
1065 if ((sglbuf[i].FlagsLength >> 24) == 0x30)
1068 dma_addr = sglbuf[i].Address;
1069 kptr = buflist[i].kptr;
1070 len = buflist[i].len;
1072 pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
1074 pci_free_consistent(ioc->pcidev, MAX_SGL_BYTES, sglbuf, *sglbuf_dma);
1080 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1082 * Routine to free the SGL elements.
1085 kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma, struct buflist *buflist, MPT_ADAPTER *ioc)
1088 struct buflist *bl = buflist;
1093 if (sg->FlagsLength & 0x04000000)
1094 dir = PCI_DMA_TODEVICE;
1096 dir = PCI_DMA_FROMDEVICE;
1098 nib = (sg->FlagsLength & 0xF0000000) >> 28;
1099 while (! (nib & 0x4)) { /* eob */
1100 /* skip ignore/chain. */
1101 if (nib == 0 || nib == 3) {
1103 } else if (sg->Address) {
1104 dma_addr_t dma_addr;
1108 dma_addr = sg->Address;
1111 pci_unmap_single(ioc->pcidev, dma_addr, len, dir);
1112 pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
1117 nib = (le32_to_cpu(sg->FlagsLength) & 0xF0000000) >> 28;
1122 dma_addr_t dma_addr;
1126 dma_addr = sg->Address;
1129 pci_unmap_single(ioc->pcidev, dma_addr, len, dir);
1130 pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
1134 pci_free_consistent(ioc->pcidev, MAX_SGL_BYTES, sgl, sgl_dma);
1136 dctlprintk((KERN_INFO MYNAM "-SG: Free'd 1 SGL buf + %d kbufs!\n", n));
1139 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1141 * mptctl_getiocinfo - Query the host adapter for IOC information.
1142 * @arg: User space argument
1145 * Return: 0 if successful
1146 * -EFAULT if data unavailable
1147 * -ENODEV if no such device/adapter
1150 mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
1152 struct mpt_ioctl_iocinfo __user *uarg = (void __user *) arg;
1153 struct mpt_ioctl_iocinfo *karg;
1155 struct pci_dev *pdev;
1156 struct Scsi_Host *sh;
1160 unsigned int max_id;
1166 dctlprintk((": mptctl_getiocinfo called.\n"));
1167 /* Add of PCI INFO results in unaligned access for
1168 * IA64 and Sparc. Reset long to int. Return no PCI
1169 * data for obsolete format.
1171 if (data_size == sizeof(struct mpt_ioctl_iocinfo_rev0))
1173 else if (data_size == sizeof(struct mpt_ioctl_iocinfo_rev1))
1175 else if (data_size == sizeof(struct mpt_ioctl_iocinfo))
1177 else if (data_size == (sizeof(struct mpt_ioctl_iocinfo_rev0)+12))
1178 cim_rev = 0; /* obsolete */
1182 karg = kmalloc(data_size, GFP_KERNEL);
1184 printk(KERN_ERR "%s::mpt_ioctl_iocinfo() @%d - no memory available!\n",
1185 __FILE__, __LINE__);
1189 if (copy_from_user(karg, uarg, data_size)) {
1190 printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
1191 "Unable to read in mpt_ioctl_iocinfo struct @ %p\n",
1192 __FILE__, __LINE__, uarg);
1197 if (((iocnum = mpt_verify_adapter(karg->hdr.iocnum, &ioc)) < 0) ||
1199 dctlprintk((KERN_ERR "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n",
1200 __FILE__, __LINE__, iocnum));
1205 /* Verify the data transfer size is correct.
1206 * Ignore the port setting.
1208 if (karg->hdr.maxDataSize != data_size) {
1209 printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
1210 "Structure size mismatch. Command not completed.\n",
1211 __FILE__, __LINE__);
1216 /* Fill in the data and return the structure to the calling
1219 if ((int)ioc->chip_type <= (int) FC929)
1220 karg->adapterType = MPT_IOCTL_INTERFACE_FC;
1222 karg->adapterType = MPT_IOCTL_INTERFACE_SCSI;
1224 port = karg->hdr.port;
1227 pdev = (struct pci_dev *) ioc->pcidev;
1229 karg->pciId = pdev->device;
1230 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1231 karg->hwRev = revision;
1232 karg->subSystemDevice = pdev->subsystem_device;
1233 karg->subSystemVendor = pdev->subsystem_vendor;
1236 /* Get the PCI bus, device, and function numbers for the IOC
1238 karg->pciInfo.u.bits.busNumber = pdev->bus->number;
1239 karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
1240 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1241 } else if (cim_rev == 2) {
1242 /* Get the PCI bus, device, function and segment ID numbers
1244 karg->pciInfo.u.bits.busNumber = pdev->bus->number;
1245 karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
1246 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1247 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1248 karg->pciInfo.segmentID = pci_domain_nr(pdev->bus);
1251 /* Get number of devices
1253 if ((sh = ioc->sh) != NULL) {
1254 /* sh->max_id = maximum target ID + 1
1256 max_id = sh->max_id - 1;
1257 hd = (MPT_SCSI_HOST *) sh->hostdata;
1259 /* Check all of the target structures and
1262 if (hd && hd->Targets) {
1263 for (ii = 0; ii <= max_id; ii++) {
1264 if (hd->Targets[ii])
1269 karg->numDevices = numDevices;
1271 /* Set the BIOS and FW Version
1273 karg->FWVersion = ioc->facts.FWVersion.Word;
1274 karg->BIOSVersion = ioc->biosVersion;
1276 /* Set the Version Strings.
1278 strncpy (karg->driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH);
1279 karg->driverVersion[MPT_IOCTL_VERSION_LENGTH-1]='\0';
1281 karg->busChangeEvent = 0;
1282 karg->hostId = ioc->pfacts[port].PortSCSIID;
1283 karg->rsvd[0] = karg->rsvd[1] = 0;
1285 /* Copy the data from kernel memory to user memory
1287 if (copy_to_user((char __user *)arg, karg, data_size)) {
1288 printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
1289 "Unable to write out mpt_ioctl_iocinfo struct @ %p\n",
1290 __FILE__, __LINE__, uarg);
1299 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1301 * mptctl_gettargetinfo - Query the host adapter for target information.
1302 * @arg: User space argument
1305 * Return: 0 if successful
1306 * -EFAULT if data unavailable
1307 * -ENODEV if no such device/adapter
1310 mptctl_gettargetinfo (unsigned long arg)
1312 struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg;
1313 struct mpt_ioctl_targetinfo karg;
1315 struct Scsi_Host *sh;
1323 unsigned int max_id;
1324 int id, jj, indexed_lun, lun_index;
1328 u8 port, devType, bus_id;
1330 dctlprintk(("mptctl_gettargetinfo called.\n"));
1331 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
1332 printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
1333 "Unable to read in mpt_ioctl_targetinfo struct @ %p\n",
1334 __FILE__, __LINE__, uarg);
1338 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1340 dctlprintk((KERN_ERR "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n",
1341 __FILE__, __LINE__, iocnum));
1345 /* Get the port number and set the maximum number of bytes
1346 * in the returned structure.
1347 * Ignore the port setting.
1349 numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
1350 maxWordsLeft = numBytes/sizeof(int);
1351 port = karg.hdr.port;
1353 if (maxWordsLeft <= 0) {
1354 printk(KERN_ERR "%s::mptctl_gettargetinfo() @%d - no memory available!\n",
1355 __FILE__, __LINE__);
1359 /* Fill in the data and return the structure to the calling
1363 /* struct mpt_ioctl_targetinfo does not contain sufficient space
1364 * for the target structures so when the IOCTL is called, there is
1365 * not sufficient stack space for the structure. Allocate memory,
1366 * populate the memory, copy back to the user, then free memory.
1367 * targetInfo format:
1368 * bits 31-24: reserved
1373 pmem = kmalloc(numBytes, GFP_KERNEL);
1375 printk(KERN_ERR "%s::mptctl_gettargetinfo() @%d - no memory available!\n",
1376 __FILE__, __LINE__);
1379 memset(pmem, 0, numBytes);
1380 pdata = (int *) pmem;
1382 /* Get number of devices
1384 if ((sh = ioc->sh) != NULL) {
1386 max_id = sh->max_id - 1;
1387 hd = (MPT_SCSI_HOST *) sh->hostdata;
1389 /* Check all of the target structures.
1390 * Save the Id and increment the counter,
1392 * sh->max_id = maximum target ID + 1
1394 if (hd && hd->Targets) {
1395 mpt_findImVolumes(ioc);
1396 pIoc2 = ioc->spi_data.pIocPg2;
1397 for ( id = 0; id <= max_id; id++ ) {
1398 if ( pIoc2 && pIoc2->NumActiveVolumes &&
1399 ( id == pIoc2->RaidVolume[0].VolumeID ) ) {
1400 if (maxWordsLeft <= 0) {
1401 printk(KERN_ERR "mptctl_gettargetinfo - "
1402 "buffer is full but volume is available on ioc %d\n, numDevices=%d", iocnum, numDevices);
1403 goto data_space_full;
1405 if ( ( pIoc2->RaidVolume[0].Flags & MPI_IOCPAGE2_FLAG_VOLUME_INACTIVE ) == 0 )
1409 bus_id = pIoc2->RaidVolume[0].VolumeBus;
1411 *pdata = ( (devType << 24) | (bus_id << 8) | id );
1412 dctlprintk((KERN_ERR "mptctl_gettargetinfo - "
1413 "volume ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata));
1417 vdev = hd->Targets[id];
1419 for (jj = 0; jj <= MPT_LAST_LUN; jj++) {
1420 lun_index = (jj >> 5);
1421 indexed_lun = (jj % 32);
1422 lun = (1 << indexed_lun);
1423 if (vdev->luns[lun_index] & lun) {
1424 if (maxWordsLeft <= 0) {
1426 "mptctl_gettargetinfo - "
1427 "buffer is full but more targets are available on ioc %d numDevices=%d\n",
1428 iocnum, numDevices);
1429 goto data_space_full;
1431 bus_id = vdev->bus_id;
1433 *pdata = ( (jj << 16) | (bus_id << 8) | id );
1434 dctlprintk((KERN_ERR
1435 "mptctl_gettargetinfo - "
1436 "target ioc=%d target=%x numDevices=%d pdata=%p\n",
1437 iocnum, *pdata, numDevices, pdata));
1448 karg.numDevices = numDevices;
1450 /* Copy part of the data from kernel memory to user memory
1452 if (copy_to_user((char __user *)arg, &karg,
1453 sizeof(struct mpt_ioctl_targetinfo))) {
1454 printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
1455 "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
1456 __FILE__, __LINE__, uarg);
1461 /* Copy the remaining data from kernel memory to user memory
1463 if (copy_to_user(uarg->targetInfo, pmem, numBytes)) {
1464 printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
1465 "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
1466 __FILE__, __LINE__, pdata);
1476 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1477 /* MPT IOCTL Test function.
1480 * Return: 0 if successful
1481 * -EFAULT if data unavailable
1482 * -ENODEV if no such device/adapter
1485 mptctl_readtest (unsigned long arg)
1487 struct mpt_ioctl_test __user *uarg = (void __user *) arg;
1488 struct mpt_ioctl_test karg;
1492 dctlprintk(("mptctl_readtest called.\n"));
1493 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) {
1494 printk(KERN_ERR "%s@%d::mptctl_readtest - "
1495 "Unable to read in mpt_ioctl_test struct @ %p\n",
1496 __FILE__, __LINE__, uarg);
1500 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1502 dctlprintk((KERN_ERR "%s::mptctl_readtest() @%d - ioc%d not found!\n",
1503 __FILE__, __LINE__, iocnum));
1507 /* Fill in the data and return the structure to the calling
1512 karg.chip_type = ioc->mfcnt;
1514 karg.chip_type = ioc->chip_type;
1516 strncpy (karg.name, ioc->name, MPT_MAX_NAME);
1517 karg.name[MPT_MAX_NAME-1]='\0';
1518 strncpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH);
1519 karg.product[MPT_PRODUCT_LENGTH-1]='\0';
1521 /* Copy the data from kernel memory to user memory
1523 if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_test))) {
1524 printk(KERN_ERR "%s@%d::mptctl_readtest - "
1525 "Unable to write out mpt_ioctl_test struct @ %p\n",
1526 __FILE__, __LINE__, uarg);
1533 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1535 * mptctl_eventquery - Query the host adapter for the event types
1536 * that are being logged.
1537 * @arg: User space argument
1540 * Return: 0 if successful
1541 * -EFAULT if data unavailable
1542 * -ENODEV if no such device/adapter
1545 mptctl_eventquery (unsigned long arg)
1547 struct mpt_ioctl_eventquery __user *uarg = (void __user *) arg;
1548 struct mpt_ioctl_eventquery karg;
1552 dctlprintk(("mptctl_eventquery called.\n"));
1553 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) {
1554 printk(KERN_ERR "%s@%d::mptctl_eventquery - "
1555 "Unable to read in mpt_ioctl_eventquery struct @ %p\n",
1556 __FILE__, __LINE__, uarg);
1560 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1562 dctlprintk((KERN_ERR "%s::mptctl_eventquery() @%d - ioc%d not found!\n",
1563 __FILE__, __LINE__, iocnum));
1567 karg.eventEntries = ioc->eventLogSize;
1568 karg.eventTypes = ioc->eventTypes;
1570 /* Copy the data from kernel memory to user memory
1572 if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) {
1573 printk(KERN_ERR "%s@%d::mptctl_eventquery - "
1574 "Unable to write out mpt_ioctl_eventquery struct @ %p\n",
1575 __FILE__, __LINE__, uarg);
1581 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1583 mptctl_eventenable (unsigned long arg)
1585 struct mpt_ioctl_eventenable __user *uarg = (void __user *) arg;
1586 struct mpt_ioctl_eventenable karg;
1590 dctlprintk(("mptctl_eventenable called.\n"));
1591 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) {
1592 printk(KERN_ERR "%s@%d::mptctl_eventenable - "
1593 "Unable to read in mpt_ioctl_eventenable struct @ %p\n",
1594 __FILE__, __LINE__, uarg);
1598 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1600 dctlprintk((KERN_ERR "%s::mptctl_eventenable() @%d - ioc%d not found!\n",
1601 __FILE__, __LINE__, iocnum));
1605 if (ioc->events == NULL) {
1606 /* Have not yet allocated memory - do so now.
1608 int sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
1609 ioc->events = kmalloc(sz, GFP_KERNEL);
1610 if (ioc->events == NULL) {
1611 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1614 memset(ioc->events, 0, sz);
1615 ioc->alloc_total += sz;
1617 ioc->eventLogSize = MPTCTL_EVENT_LOG_SIZE;
1618 ioc->eventContext = 0;
1621 /* Update the IOC event logging flag.
1623 ioc->eventTypes = karg.eventTypes;
1628 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1630 mptctl_eventreport (unsigned long arg)
1632 struct mpt_ioctl_eventreport __user *uarg = (void __user *) arg;
1633 struct mpt_ioctl_eventreport karg;
1636 int numBytes, maxEvents, max;
1638 dctlprintk(("mptctl_eventreport called.\n"));
1639 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) {
1640 printk(KERN_ERR "%s@%d::mptctl_eventreport - "
1641 "Unable to read in mpt_ioctl_eventreport struct @ %p\n",
1642 __FILE__, __LINE__, uarg);
1646 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1648 dctlprintk((KERN_ERR "%s::mptctl_eventreport() @%d - ioc%d not found!\n",
1649 __FILE__, __LINE__, iocnum));
1653 numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
1654 maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS);
1657 max = ioc->eventLogSize < maxEvents ? ioc->eventLogSize : maxEvents;
1659 /* If fewer than 1 event is requested, there must have
1660 * been some type of error.
1662 if ((max < 1) || !ioc->events)
1665 /* Copy the data from kernel memory to user memory
1667 numBytes = max * sizeof(MPT_IOCTL_EVENTS);
1668 if (copy_to_user(uarg->eventData, ioc->events, numBytes)) {
1669 printk(KERN_ERR "%s@%d::mptctl_eventreport - "
1670 "Unable to write out mpt_ioctl_eventreport struct @ %p\n",
1671 __FILE__, __LINE__, ioc->events);
1678 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1680 mptctl_replace_fw (unsigned long arg)
1682 struct mpt_ioctl_replace_fw __user *uarg = (void __user *) arg;
1683 struct mpt_ioctl_replace_fw karg;
1685 fw_image_t **fwmem = NULL;
1688 int num_frags, alloc_sz;
1692 dctlprintk(("mptctl_replace_fw called.\n"));
1693 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
1694 printk(KERN_ERR "%s@%d::mptctl_replace_fw - "
1695 "Unable to read in mpt_ioctl_replace_fw struct @ %p\n",
1696 __FILE__, __LINE__, uarg);
1700 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1702 dctlprintk((KERN_ERR "%s::mptctl_replace_fw() @%d - ioc%d not found!\n",
1703 __FILE__, __LINE__, iocnum));
1707 /* If not caching FW, return 0
1709 if ((ioc->cached_fw == NULL) && (ioc->alt_ioc) && (ioc->alt_ioc->cached_fw == NULL))
1712 /* Allocate memory for the new FW image
1714 newFwSize = karg.newImageSize;
1715 fwmem = mpt_alloc_fw_memory(ioc, newFwSize, &num_frags, &alloc_sz);
1720 for (ii = 0; ii < num_frags; ii++) {
1721 /* Copy the data from user memory to kernel space
1723 if (copy_from_user(fwmem[ii]->fw, uarg->newImage + offset, fwmem[ii]->size)) {
1724 printk(KERN_ERR "%s@%d::mptctl_replace_fw - "
1725 "Unable to read in mpt_ioctl_replace_fw image @ %p\n",
1726 __FILE__, __LINE__, uarg);
1728 mpt_free_fw_memory(ioc, fwmem);
1731 offset += fwmem[ii]->size;
1735 /* Free the old FW image
1737 if (ioc->cached_fw) {
1738 mpt_free_fw_memory(ioc, 0);
1739 ioc->cached_fw = fwmem;
1740 ioc->alloc_total += alloc_sz;
1741 } else if ((ioc->alt_ioc) && (ioc->alt_ioc->cached_fw)) {
1742 mpt_free_fw_memory(ioc->alt_ioc, 0);
1743 ioc->alt_ioc->cached_fw = fwmem;
1744 ioc->alt_ioc->alloc_total += alloc_sz;
1747 /* Update IOCFactsReply
1749 ioc->facts.FWImageSize = newFwSize;
1751 ioc->alt_ioc->facts.FWImageSize = newFwSize;
1756 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1757 /* MPT IOCTL MPTCOMMAND function.
1758 * Cast the arg into the mpt_ioctl_mpt_command structure.
1761 * Return: 0 if successful
1762 * -EBUSY if previous command timout and IOC reset is not complete.
1763 * -EFAULT if data unavailable
1764 * -ENODEV if no such device/adapter
1765 * -ETIME if timer expires
1766 * -ENOMEM if memory allocation error
1769 mptctl_mpt_command (unsigned long arg)
1771 struct mpt_ioctl_command __user *uarg = (void __user *) arg;
1772 struct mpt_ioctl_command karg;
1777 dctlprintk(("mptctl_command called.\n"));
1779 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_command))) {
1780 printk(KERN_ERR "%s@%d::mptctl_mpt_command - "
1781 "Unable to read in mpt_ioctl_command struct @ %p\n",
1782 __FILE__, __LINE__, uarg);
1786 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1788 dctlprintk((KERN_ERR "%s::mptctl_mpt_command() @%d - ioc%d not found!\n",
1789 __FILE__, __LINE__, iocnum));
1793 rc = mptctl_do_mpt_command (karg, &uarg->MF);
1798 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1799 /* Worker routine for the IOCTL MPTCOMMAND and MPTCOMMAND32 (sparc) commands.
1802 * Return: 0 if successful
1803 * -EBUSY if previous command timout and IOC reset is not complete.
1804 * -EFAULT if data unavailable
1805 * -ENODEV if no such device/adapter
1806 * -ETIME if timer expires
1807 * -ENOMEM if memory allocation error
1808 * -EPERM if SCSI I/O and target is untagged
1811 mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
1814 MPT_FRAME_HDR *mf = NULL;
1817 struct buflist bufIn; /* data In buffer */
1818 struct buflist bufOut; /* data Out buffer */
1819 dma_addr_t dma_addr_in;
1820 dma_addr_t dma_addr_out;
1821 int dir; /* PCI data direction */
1822 int sgSize = 0; /* Num SG elements */
1823 int iocnum, flagsLength;
1826 int tm_flags_set = 0;
1829 dctlprintk(("mptctl_do_mpt_command called.\n"));
1830 bufIn.kptr = bufOut.kptr = NULL;
1832 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1834 dctlprintk((KERN_ERR "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n",
1835 __FILE__, __LINE__, iocnum));
1839 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1840 "No memory available during driver init.\n",
1841 __FILE__, __LINE__);
1843 } else if (ioc->ioctl->status & MPT_IOCTL_STATUS_DID_IOCRESET) {
1844 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1845 "Busy with IOC Reset \n", __FILE__, __LINE__);
1849 /* Verify that the final request frame will not be too large.
1851 sz = karg.dataSgeOffset * 4;
1852 if (karg.dataInSize > 0)
1853 sz += sizeof(dma_addr_t) + sizeof(u32);
1854 if (karg.dataOutSize > 0)
1855 sz += sizeof(dma_addr_t) + sizeof(u32);
1857 if (sz > ioc->req_sz) {
1858 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1859 "Request frame too large (%d) maximum (%d)\n",
1860 __FILE__, __LINE__, sz, ioc->req_sz);
1864 /* Get a free request frame and save the message context.
1866 if ((mf = mpt_get_msg_frame(mptctl_id, ioc->id)) == NULL)
1869 hdr = (MPIHeader_t *) mf;
1870 msgContext = le32_to_cpu(hdr->MsgContext);
1871 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1873 /* Copy the request frame
1874 * Reset the saved message context.
1875 * Request frame in user space
1877 if (copy_from_user(mf, mfPtr, karg.dataSgeOffset * 4)) {
1878 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1879 "Unable to read MF from mpt_ioctl_command struct @ %p\n",
1880 __FILE__, __LINE__, mfPtr);
1884 hdr->MsgContext = cpu_to_le32(msgContext);
1887 /* Verify that this request is allowed.
1889 switch (hdr->Function) {
1890 case MPI_FUNCTION_IOC_FACTS:
1891 case MPI_FUNCTION_PORT_FACTS:
1892 karg.dataOutSize = karg.dataInSize = 0;
1895 case MPI_FUNCTION_CONFIG:
1896 case MPI_FUNCTION_FC_COMMON_TRANSPORT_SEND:
1897 case MPI_FUNCTION_FC_EX_LINK_SRVC_SEND:
1898 case MPI_FUNCTION_FW_UPLOAD:
1899 case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR:
1900 case MPI_FUNCTION_FW_DOWNLOAD:
1901 case MPI_FUNCTION_FC_PRIMITIVE_SEND:
1904 case MPI_FUNCTION_SCSI_IO_REQUEST:
1906 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
1907 VirtDevice *pTarget = NULL;
1908 MPT_SCSI_HOST *hd = NULL;
1909 int qtag = MPI_SCSIIO_CONTROL_UNTAGGED;
1911 int target = (int) pScsiReq->TargetID;
1914 if ((target < 0) || (target >= ioc->sh->max_id)) {
1915 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1916 "Target ID out of bounds. \n",
1917 __FILE__, __LINE__);
1922 pScsiReq->MsgFlags = mpt_msg_flags();
1924 /* verify that app has not requested
1925 * more sense data than driver
1926 * can provide, if so, reset this parameter
1927 * set the sense buffer pointer low address
1928 * update the control field to specify Q type
1930 if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
1931 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1933 pScsiReq->SenseBufferLength = karg.maxSenseBytes;
1935 pScsiReq->SenseBufferLowAddr =
1936 cpu_to_le32(ioc->sense_buf_low_dma
1937 + (req_idx * MPT_SENSE_BUFFER_ALLOC));
1939 if ((hd = (MPT_SCSI_HOST *) ioc->sh->hostdata)) {
1941 pTarget = hd->Targets[target];
1944 if (pTarget &&(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
1945 qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
1947 /* Have the IOCTL driver set the direction based
1948 * on the dataOutSize (ordering issue with Sparc).
1950 if (karg.dataOutSize > 0) {
1951 scsidir = MPI_SCSIIO_CONTROL_WRITE;
1952 dataSize = karg.dataOutSize;
1954 scsidir = MPI_SCSIIO_CONTROL_READ;
1955 dataSize = karg.dataInSize;
1958 pScsiReq->Control = cpu_to_le32(scsidir | qtag);
1959 pScsiReq->DataLength = cpu_to_le32(dataSize);
1961 ioc->ioctl->reset = MPTCTL_RESET_OK;
1962 ioc->ioctl->target = target;
1965 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1966 "SCSI driver is not loaded. \n",
1967 __FILE__, __LINE__);
1973 case MPI_FUNCTION_RAID_ACTION:
1978 case MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
1980 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
1981 int qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
1982 int scsidir = MPI_SCSIIO_CONTROL_READ;
1985 pScsiReq->MsgFlags = mpt_msg_flags();
1987 /* verify that app has not requested
1988 * more sense data than driver
1989 * can provide, if so, reset this parameter
1990 * set the sense buffer pointer low address
1991 * update the control field to specify Q type
1993 if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
1994 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1996 pScsiReq->SenseBufferLength = karg.maxSenseBytes;
1998 pScsiReq->SenseBufferLowAddr =
1999 cpu_to_le32(ioc->sense_buf_low_dma
2000 + (req_idx * MPT_SENSE_BUFFER_ALLOC));
2002 /* All commands to physical devices are tagged
2005 /* Have the IOCTL driver set the direction based
2006 * on the dataOutSize (ordering issue with Sparc).
2008 if (karg.dataOutSize > 0) {
2009 scsidir = MPI_SCSIIO_CONTROL_WRITE;
2010 dataSize = karg.dataOutSize;
2012 scsidir = MPI_SCSIIO_CONTROL_READ;
2013 dataSize = karg.dataInSize;
2016 pScsiReq->Control = cpu_to_le32(scsidir | qtag);
2017 pScsiReq->DataLength = cpu_to_le32(dataSize);
2019 ioc->ioctl->reset = MPTCTL_RESET_OK;
2020 ioc->ioctl->target = pScsiReq->TargetID;
2022 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2023 "SCSI driver is not loaded. \n",
2024 __FILE__, __LINE__);
2030 case MPI_FUNCTION_SCSI_TASK_MGMT:
2032 MPT_SCSI_HOST *hd = NULL;
2033 if ((ioc->sh == NULL) || ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL)) {
2034 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2035 "SCSI driver not loaded or SCSI host not found. \n",
2036 __FILE__, __LINE__);
2039 } else if (mptctl_set_tm_flags(hd) != 0) {
2047 case MPI_FUNCTION_IOC_INIT:
2049 IOCInit_t *pInit = (IOCInit_t *) mf;
2050 u32 high_addr, sense_high;
2052 /* Verify that all entries in the IOC INIT match
2053 * existing setup (and in LE format).
2055 if (sizeof(dma_addr_t) == sizeof(u64)) {
2056 high_addr = cpu_to_le32((u32)((u64)ioc->req_frames_dma >> 32));
2057 sense_high= cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2063 if ((pInit->Flags != 0) || (pInit->MaxDevices != ioc->facts.MaxDevices) ||
2064 (pInit->MaxBuses != ioc->facts.MaxBuses) ||
2065 (pInit->ReplyFrameSize != cpu_to_le16(ioc->reply_sz)) ||
2066 (pInit->HostMfaHighAddr != high_addr) ||
2067 (pInit->SenseBufferHighAddr != sense_high)) {
2068 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2069 "IOC_INIT issued with 1 or more incorrect parameters. Rejected.\n",
2070 __FILE__, __LINE__);
2078 * MPI_FUNCTION_PORT_ENABLE
2079 * MPI_FUNCTION_TARGET_CMD_BUFFER_POST
2080 * MPI_FUNCTION_TARGET_ASSIST
2081 * MPI_FUNCTION_TARGET_STATUS_SEND
2082 * MPI_FUNCTION_TARGET_MODE_ABORT
2083 * MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
2084 * MPI_FUNCTION_IO_UNIT_RESET
2085 * MPI_FUNCTION_HANDSHAKE
2086 * MPI_FUNCTION_REPLY_FRAME_REMOVAL
2087 * MPI_FUNCTION_EVENT_NOTIFICATION
2088 * (driver handles event notification)
2089 * MPI_FUNCTION_EVENT_ACK
2092 /* What to do with these??? CHECK ME!!!
2093 MPI_FUNCTION_FC_LINK_SRVC_BUF_POST
2094 MPI_FUNCTION_FC_LINK_SRVC_RSP
2095 MPI_FUNCTION_FC_ABORT
2096 MPI_FUNCTION_LAN_SEND
2097 MPI_FUNCTION_LAN_RECEIVE
2098 MPI_FUNCTION_LAN_RESET
2101 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2102 "Illegal request (function 0x%x) \n",
2103 __FILE__, __LINE__, hdr->Function);
2108 /* Add the SGL ( at most one data in SGE and one data out SGE )
2109 * In the case of two SGE's - the data out (write) will always
2110 * preceede the data in (read) SGE. psgList is used to free the
2113 psge = (char *) (((int *) mf) + karg.dataSgeOffset);
2116 /* bufIn and bufOut are used for user to kernel space transfers
2118 bufIn.kptr = bufOut.kptr = NULL;
2119 bufIn.len = bufOut.len = 0;
2121 if (karg.dataOutSize > 0)
2124 if (karg.dataInSize > 0)
2129 /* Set up the dataOut memory allocation */
2130 if (karg.dataOutSize > 0) {
2131 dir = PCI_DMA_TODEVICE;
2132 if (karg.dataInSize > 0) {
2133 flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2134 MPI_SGE_FLAGS_DIRECTION |
2136 << MPI_SGE_FLAGS_SHIFT;
2138 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
2140 flagsLength |= karg.dataOutSize;
2141 bufOut.len = karg.dataOutSize;
2142 bufOut.kptr = pci_alloc_consistent(
2143 ioc->pcidev, bufOut.len, &dma_addr_out);
2145 if (bufOut.kptr == NULL) {
2150 * Copy to MF and to sglbuf
2152 mpt_add_sge(psge, flagsLength, dma_addr_out);
2153 psge += (sizeof(u32) + sizeof(dma_addr_t));
2155 /* Copy user data to kernel space.
2157 if (copy_from_user(bufOut.kptr,
2161 "%s@%d::mptctl_do_mpt_command - Unable "
2162 "to read user data "
2164 __FILE__, __LINE__,karg.dataOutBufPtr);
2171 if (karg.dataInSize > 0) {
2172 dir = PCI_DMA_FROMDEVICE;
2173 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
2174 flagsLength |= karg.dataInSize;
2176 bufIn.len = karg.dataInSize;
2177 bufIn.kptr = pci_alloc_consistent(ioc->pcidev,
2178 bufIn.len, &dma_addr_in);
2180 if (bufIn.kptr == NULL) {
2185 * Copy to MF and to sglbuf
2187 mpt_add_sge(psge, flagsLength, dma_addr_in);
2193 mpt_add_sge(psge, flagsLength, (dma_addr_t) -1);
2196 /* The request is complete. Set the timer parameters
2197 * and issue the request.
2199 if (karg.timeout > 0) {
2200 ioc->ioctl->timer.expires = jiffies + HZ*karg.timeout;
2202 ioc->ioctl->timer.expires = jiffies + HZ*MPT_IOCTL_DEFAULT_TIMEOUT;
2205 ioc->ioctl->wait_done = 0;
2206 ioc->ioctl->status |= MPT_IOCTL_STATUS_TIMER_ACTIVE;
2207 add_timer(&ioc->ioctl->timer);
2209 if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
2210 rc = mpt_send_handshake_request(mptctl_id, ioc->id,
2211 sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP);
2213 wait_event(mptctl_wait, ioc->ioctl->wait_done);
2215 mptctl_free_tm_flags(ioc);
2217 del_timer(&ioc->ioctl->timer);
2218 ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TIMER_ACTIVE;
2219 ioc->ioctl->status |= MPT_IOCTL_STATUS_TM_FAILED;
2220 mpt_free_msg_frame(mptctl_id, ioc->id, mf);
2223 mpt_put_msg_frame(mptctl_id, ioc->id, mf);
2224 wait_event(mptctl_wait, ioc->ioctl->wait_done);
2230 * If command failed and failure triggered a diagnostic reset
2231 * OR a diagnostic reset happens during command processing,
2232 * no data, messaging queues are reset (mf cannot be accessed),
2233 * and status is DID_IOCRESET
2235 * If a user-requested bus reset fails to be handshaked, then
2236 * mf is returned to free queue and status is TM_FAILED.
2238 * Otherise, the command completed and the mf was freed
2239 # by ISR (mf cannot be touched).
2241 if (ioc->ioctl->status & MPT_IOCTL_STATUS_DID_IOCRESET) {
2242 /* The timer callback deleted the
2243 * timer and reset the adapter queues.
2245 printk(KERN_WARNING "%s@%d::mptctl_do_mpt_command - "
2246 "Timeout Occurred on IOCTL! Reset IOC.\n", __FILE__, __LINE__);
2249 } else if (ioc->ioctl->status & MPT_IOCTL_STATUS_TM_FAILED) {
2250 /* User TM request failed! mf has not been freed.
2254 /* If a valid reply frame, copy to the user.
2255 * Offset 2: reply length in U32's
2257 if (ioc->ioctl->status & MPT_IOCTL_STATUS_RF_VALID) {
2258 if (karg.maxReplyBytes < ioc->reply_sz) {
2259 sz = min(karg.maxReplyBytes, 4*ioc->ioctl->ReplyFrame[2]);
2261 sz = min(ioc->reply_sz, 4*ioc->ioctl->ReplyFrame[2]);
2265 if (copy_to_user(karg.replyFrameBufPtr,
2266 &ioc->ioctl->ReplyFrame, sz)){
2268 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2269 "Unable to write out reply frame %p\n",
2270 __FILE__, __LINE__, karg.replyFrameBufPtr);
2277 /* If valid sense data, copy to user.
2279 if (ioc->ioctl->status & MPT_IOCTL_STATUS_SENSE_VALID) {
2280 sz = min(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE);
2282 if (copy_to_user(karg.senseDataPtr, ioc->ioctl->sense, sz)) {
2283 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2284 "Unable to write sense data to user %p\n",
2293 /* If the overall status is _GOOD and data in, copy data
2296 if ((ioc->ioctl->status & MPT_IOCTL_STATUS_COMMAND_GOOD) &&
2297 (karg.dataInSize > 0) && (bufIn.kptr)) {
2299 if (copy_to_user(karg.dataInBufPtr,
2300 bufIn.kptr, karg.dataInSize)) {
2301 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2302 "Unable to write data to user %p\n",
2311 /* Clear all status bits except TMTIMER_ACTIVE, this bit is cleared
2312 * upon completion of the TM command.
2313 * ioc->ioctl->status = 0;
2315 ioc->ioctl->status &= ~(MPT_IOCTL_STATUS_TIMER_ACTIVE | MPT_IOCTL_STATUS_TM_FAILED |
2316 MPT_IOCTL_STATUS_COMMAND_GOOD | MPT_IOCTL_STATUS_SENSE_VALID |
2317 MPT_IOCTL_STATUS_RF_VALID | MPT_IOCTL_STATUS_DID_IOCRESET);
2320 mptctl_free_tm_flags(ioc);
2322 /* Free the allocated memory.
2324 if (bufOut.kptr != NULL) {
2325 pci_free_consistent(ioc->pcidev,
2326 bufOut.len, (void *) bufOut.kptr, dma_addr_out);
2329 if (bufIn.kptr != NULL) {
2330 pci_free_consistent(ioc->pcidev,
2331 bufIn.len, (void *) bufIn.kptr, dma_addr_in);
2334 /* mf is null if command issued successfully
2335 * otherwise, failure occured after mf acquired.
2338 mpt_free_msg_frame(mptctl_id, ioc->id, mf);
2343 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2344 /* Prototype Routine for the HP HOST INFO command.
2347 * Return: 0 if successful
2348 * -EFAULT if data unavailable
2349 * -EBUSY if previous command timout and IOC reset is not complete.
2350 * -ENODEV if no such device/adapter
2351 * -ETIME if timer expires
2352 * -ENOMEM if memory allocation error
2355 mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
2357 hp_host_info_t __user *uarg = (void __user *) arg;
2359 struct pci_dev *pdev;
2362 hp_host_info_t karg;
2364 ConfigPageHeader_t hdr;
2368 dctlprintk((": mptctl_hp_hostinfo called.\n"));
2369 /* Reset long to int. Should affect IA64 and SPARC only
2371 if (data_size == sizeof(hp_host_info_t))
2373 else if (data_size == sizeof(hp_host_info_rev0_t))
2374 cim_rev = 0; /* obsolete */
2378 if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) {
2379 printk(KERN_ERR "%s@%d::mptctl_hp_host_info - "
2380 "Unable to read in hp_host_info struct @ %p\n",
2381 __FILE__, __LINE__, uarg);
2385 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
2387 dctlprintk((KERN_ERR "%s::mptctl_hp_hostinfo() @%d - ioc%d not found!\n",
2388 __FILE__, __LINE__, iocnum));
2392 /* Fill in the data and return the structure to the calling
2395 pdev = (struct pci_dev *) ioc->pcidev;
2397 karg.vendor = pdev->vendor;
2398 karg.device = pdev->device;
2399 karg.subsystem_id = pdev->subsystem_device;
2400 karg.subsystem_vendor = pdev->subsystem_vendor;
2401 karg.devfn = pdev->devfn;
2402 karg.bus = pdev->bus->number;
2404 /* Save the SCSI host no. if
2405 * SCSI driver loaded
2407 if (ioc->sh != NULL)
2408 karg.host_no = ioc->sh->host_no;
2412 /* Reformat the fw_version into a string
2414 karg.fw_version[0] = ioc->facts.FWVersion.Struct.Major >= 10 ?
2415 ((ioc->facts.FWVersion.Struct.Major / 10) + '0') : '0';
2416 karg.fw_version[1] = (ioc->facts.FWVersion.Struct.Major % 10 ) + '0';
2417 karg.fw_version[2] = '.';
2418 karg.fw_version[3] = ioc->facts.FWVersion.Struct.Minor >= 10 ?
2419 ((ioc->facts.FWVersion.Struct.Minor / 10) + '0') : '0';
2420 karg.fw_version[4] = (ioc->facts.FWVersion.Struct.Minor % 10 ) + '0';
2421 karg.fw_version[5] = '.';
2422 karg.fw_version[6] = ioc->facts.FWVersion.Struct.Unit >= 10 ?
2423 ((ioc->facts.FWVersion.Struct.Unit / 10) + '0') : '0';
2424 karg.fw_version[7] = (ioc->facts.FWVersion.Struct.Unit % 10 ) + '0';
2425 karg.fw_version[8] = '.';
2426 karg.fw_version[9] = ioc->facts.FWVersion.Struct.Dev >= 10 ?
2427 ((ioc->facts.FWVersion.Struct.Dev / 10) + '0') : '0';
2428 karg.fw_version[10] = (ioc->facts.FWVersion.Struct.Dev % 10 ) + '0';
2429 karg.fw_version[11] = '\0';
2431 /* Issue a config request to get the device serial number
2433 hdr.PageVersion = 0;
2436 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
2440 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2441 cfg.dir = 0; /* read */
2444 strncpy(karg.serial_number, " ", 24);
2445 if (mpt_config(ioc, &cfg) == 0) {
2446 if (cfg.hdr->PageLength > 0) {
2447 /* Issue the second config page request */
2448 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2450 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
2452 cfg.physAddr = buf_dma;
2453 if (mpt_config(ioc, &cfg) == 0) {
2454 ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf;
2455 if (strlen(pdata->BoardTracerNumber) > 1) {
2456 strncpy(karg.serial_number, pdata->BoardTracerNumber, 24);
2457 karg.serial_number[24-1]='\0';
2460 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
2465 rc = mpt_GetIocState(ioc, 1);
2467 case MPI_IOC_STATE_OPERATIONAL:
2468 karg.ioc_status = HP_STATUS_OK;
2471 case MPI_IOC_STATE_FAULT:
2472 karg.ioc_status = HP_STATUS_FAILED;
2475 case MPI_IOC_STATE_RESET:
2476 case MPI_IOC_STATE_READY:
2478 karg.ioc_status = HP_STATUS_OTHER;
2482 karg.base_io_addr = pci_resource_start(pdev, 0);
2484 if ((int)ioc->chip_type <= (int) FC929)
2485 karg.bus_phys_width = HP_BUS_WIDTH_UNK;
2487 karg.bus_phys_width = HP_BUS_WIDTH_16;
2489 karg.hard_resets = 0;
2490 karg.soft_resets = 0;
2492 if (ioc->sh != NULL) {
2493 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2495 if (hd && (cim_rev == 1)) {
2496 karg.hard_resets = hd->hard_resets;
2497 karg.soft_resets = hd->soft_resets;
2498 karg.timeouts = hd->timeouts;
2503 cfg.action = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
2504 cfg.dir = MPI_TB_ISTWI_FLAGS_READ;
2506 pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma);
2508 cfg.physAddr = buf_dma;
2509 if ((mpt_toolbox(ioc, &cfg)) == 0) {
2510 karg.rsvd = *(u32 *)pbuf;
2512 pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma);
2516 /* Copy the data from kernel memory to user memory
2518 if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) {
2519 printk(KERN_ERR "%s@%d::mptctl_hpgethostinfo - "
2520 "Unable to write out hp_host_info @ %p\n",
2521 __FILE__, __LINE__, uarg);
2529 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2530 /* Prototype Routine for the HP TARGET INFO command.
2533 * Return: 0 if successful
2534 * -EFAULT if data unavailable
2535 * -EBUSY if previous command timout and IOC reset is not complete.
2536 * -ENODEV if no such device/adapter
2537 * -ETIME if timer expires
2538 * -ENOMEM if memory allocation error
2541 mptctl_hp_targetinfo(unsigned long arg)
2543 hp_target_info_t __user *uarg = (void __user *) arg;
2544 SCSIDevicePage0_t *pg0_alloc;
2545 SCSIDevicePage3_t *pg3_alloc;
2547 MPT_SCSI_HOST *hd = NULL;
2548 hp_target_info_t karg;
2551 dma_addr_t page_dma;
2553 ConfigPageHeader_t hdr;
2554 int tmp, np, rc = 0;
2556 dctlprintk((": mptctl_hp_targetinfo called.\n"));
2557 if (copy_from_user(&karg, uarg, sizeof(hp_target_info_t))) {
2558 printk(KERN_ERR "%s@%d::mptctl_hp_targetinfo - "
2559 "Unable to read in hp_host_targetinfo struct @ %p\n",
2560 __FILE__, __LINE__, uarg);
2564 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
2566 dctlprintk((KERN_ERR "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n",
2567 __FILE__, __LINE__, iocnum));
2571 /* There is nothing to do for FCP parts.
2573 if ((int) ioc->chip_type <= (int) FC929)
2576 if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL))
2579 if (ioc->sh->host_no != karg.hdr.host)
2582 /* Get the data transfer speeds
2584 data_sz = ioc->spi_data.sdp0length * 4;
2585 pg0_alloc = (SCSIDevicePage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
2587 hdr.PageVersion = ioc->spi_data.sdp0version;
2588 hdr.PageLength = data_sz;
2590 hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
2593 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2596 cfg.physAddr = page_dma;
2598 cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
2600 if ((rc = mpt_config(ioc, &cfg)) == 0) {
2601 np = le32_to_cpu(pg0_alloc->NegotiatedParameters);
2602 karg.negotiated_width = np & MPI_SCSIDEVPAGE0_NP_WIDE ?
2603 HP_BUS_WIDTH_16 : HP_BUS_WIDTH_8;
2605 if (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) {
2606 tmp = (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
2608 karg.negotiated_speed = HP_DEV_SPEED_ULTRA320;
2609 else if (tmp <= 0x09)
2610 karg.negotiated_speed = HP_DEV_SPEED_ULTRA160;
2611 else if (tmp <= 0x0A)
2612 karg.negotiated_speed = HP_DEV_SPEED_ULTRA2;
2613 else if (tmp <= 0x0C)
2614 karg.negotiated_speed = HP_DEV_SPEED_ULTRA;
2615 else if (tmp <= 0x25)
2616 karg.negotiated_speed = HP_DEV_SPEED_FAST;
2618 karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
2620 karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
2623 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg0_alloc, page_dma);
2628 karg.message_rejects = -1;
2629 karg.phase_errors = -1;
2630 karg.parity_errors = -1;
2631 karg.select_timeouts = -1;
2633 /* Get the target error parameters
2635 hdr.PageVersion = 0;
2638 hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
2641 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2645 if ((mpt_config(ioc, &cfg) == 0) && (cfg.hdr->PageLength > 0)) {
2646 /* Issue the second config page request */
2647 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2648 data_sz = (int) cfg.hdr->PageLength * 4;
2649 pg3_alloc = (SCSIDevicePage3_t *) pci_alloc_consistent(
2650 ioc->pcidev, data_sz, &page_dma);
2652 cfg.physAddr = page_dma;
2653 cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
2654 if ((rc = mpt_config(ioc, &cfg)) == 0) {
2655 karg.message_rejects = (u32) le16_to_cpu(pg3_alloc->MsgRejectCount);
2656 karg.phase_errors = (u32) le16_to_cpu(pg3_alloc->PhaseErrorCount);
2657 karg.parity_errors = (u32) le16_to_cpu(pg3_alloc->ParityErrorCount);
2659 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg3_alloc, page_dma);
2662 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2664 karg.select_timeouts = hd->sel_timeout[karg.hdr.id];
2666 /* Copy the data from kernel memory to user memory
2668 if (copy_to_user((char __user *)arg, &karg, sizeof(hp_target_info_t))) {
2669 printk(KERN_ERR "%s@%d::mptctl_hp_target_info - "
2670 "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
2671 __FILE__, __LINE__, uarg);
2678 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2680 static struct file_operations mptctl_fops = {
2681 .owner = THIS_MODULE,
2682 .llseek = no_llseek,
2683 .ioctl = mptctl_ioctl,
2686 static struct miscdevice mptctl_miscdev = {
2692 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2694 #ifdef CONFIG_COMPAT
2696 #include <linux/ioctl32.h>
2698 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2699 /* compat_XXX functions are used to provide a conversion between
2700 * pointers and u32's. If the arg does not contain any pointers, then
2701 * a specialized function (compat_XXX) is not needed. If the arg
2702 * does contain pointer(s), then the specialized function is used
2703 * to ensure the structure contents is properly processed by mptctl.
2706 compat_mptctl_ioctl(unsigned int fd, unsigned int cmd,
2707 unsigned long arg, struct file *filp)
2712 dctlprintk((KERN_INFO MYNAM "::compat_mptctl_ioctl() called\n"));
2713 ret = mptctl_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
2719 compat_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd,
2720 unsigned long arg, struct file *filp)
2722 struct mpt_fw_xfer32 kfw32;
2723 struct mpt_fw_xfer kfw;
2724 MPT_ADAPTER *iocp = NULL;
2725 int iocnum, iocnumX;
2726 int nonblock = (filp->f_flags & O_NONBLOCK);
2729 dctlprintk((KERN_INFO MYNAM "::compat_mptfwxfer_ioctl() called\n"));
2731 if (copy_from_user(&kfw32, (char __user *)arg, sizeof(kfw32)))
2734 /* Verify intended MPT adapter */
2735 iocnumX = kfw32.iocnum & 0xFF;
2736 if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
2738 dctlprintk((KERN_ERR MYNAM "::compat_mptfwxfer_ioctl @%d - ioc%d not found!\n",
2739 __LINE__, iocnumX));
2743 if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
2746 kfw.iocnum = iocnum;
2747 kfw.fwlen = kfw32.fwlen;
2748 kfw.bufp = compat_ptr(kfw32.bufp);
2750 ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);
2752 up(&mptctl_syscall_sem_ioc[iocp->id]);
2758 compat_mpt_command(unsigned int fd, unsigned int cmd,
2759 unsigned long arg, struct file *filp)
2761 struct mpt_ioctl_command32 karg32;
2762 struct mpt_ioctl_command32 __user *uarg = (struct mpt_ioctl_command32 __user *) arg;
2763 struct mpt_ioctl_command karg;
2764 MPT_ADAPTER *iocp = NULL;
2765 int iocnum, iocnumX;
2766 int nonblock = (filp->f_flags & O_NONBLOCK);
2769 dctlprintk((KERN_INFO MYNAM "::compat_mpt_command() called\n"));
2771 if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32)))
2774 /* Verify intended MPT adapter */
2775 iocnumX = karg32.hdr.iocnum & 0xFF;
2776 if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
2778 dctlprintk((KERN_ERR MYNAM "::compat_mpt_command @%d - ioc%d not found!\n",
2779 __LINE__, iocnumX));
2783 if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
2786 /* Copy data to karg */
2787 karg.hdr.iocnum = karg32.hdr.iocnum;
2788 karg.hdr.port = karg32.hdr.port;
2789 karg.timeout = karg32.timeout;
2790 karg.maxReplyBytes = karg32.maxReplyBytes;
2792 karg.dataInSize = karg32.dataInSize;
2793 karg.dataOutSize = karg32.dataOutSize;
2794 karg.maxSenseBytes = karg32.maxSenseBytes;
2795 karg.dataSgeOffset = karg32.dataSgeOffset;
2797 karg.replyFrameBufPtr = (char __user *)(unsigned long)karg32.replyFrameBufPtr;
2798 karg.dataInBufPtr = (char __user *)(unsigned long)karg32.dataInBufPtr;
2799 karg.dataOutBufPtr = (char __user *)(unsigned long)karg32.dataOutBufPtr;
2800 karg.senseDataPtr = (char __user *)(unsigned long)karg32.senseDataPtr;
2802 /* Pass new structure to do_mpt_command
2804 ret = mptctl_do_mpt_command (karg, &uarg->MF);
2806 up(&mptctl_syscall_sem_ioc[iocp->id]);
2813 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2814 int __init mptctl_init(void)
2821 MPT_ADAPTER *ioc = NULL;
2824 show_mptmod_ver(my_NAME, my_VERSION);
2826 for (i=0; i<MPT_MAX_ADAPTERS; i++) {
2827 sema_init(&mptctl_syscall_sem_ioc[i], 1);
2830 if (((iocnum = mpt_verify_adapter(i, &ioc)) < 0) ||
2835 /* This adapter instance is found.
2836 * Allocate and inite a MPT_IOCTL structure
2838 sz = sizeof (MPT_IOCTL);
2839 mem = kmalloc(sz, GFP_KERNEL);
2846 ioc->ioctl = (MPT_IOCTL *) mem;
2847 ioc->ioctl->ioc = ioc;
2848 init_timer (&ioc->ioctl->timer);
2849 ioc->ioctl->timer.data = (unsigned long) ioc->ioctl;
2850 ioc->ioctl->timer.function = mptctl_timer_expired;
2851 init_timer (&ioc->ioctl->TMtimer);
2852 ioc->ioctl->TMtimer.data = (unsigned long) ioc->ioctl;
2853 ioc->ioctl->TMtimer.function = mptctl_timer_expired;
2857 #ifdef CONFIG_COMPAT
2858 err = register_ioctl32_conversion(MPTIOCINFO, compat_mptctl_ioctl);
2859 if (++where && err) goto out_fail;
2860 err = register_ioctl32_conversion(MPTIOCINFO1, compat_mptctl_ioctl);
2861 if (++where && err) goto out_fail;
2862 err = register_ioctl32_conversion(MPTIOCINFO2, compat_mptctl_ioctl);
2863 if (++where && err) goto out_fail;
2864 err = register_ioctl32_conversion(MPTTARGETINFO, compat_mptctl_ioctl);
2865 if (++where && err) goto out_fail;
2866 err = register_ioctl32_conversion(MPTTEST, compat_mptctl_ioctl);
2867 if (++where && err) goto out_fail;
2868 err = register_ioctl32_conversion(MPTEVENTQUERY, compat_mptctl_ioctl);
2869 if (++where && err) goto out_fail;
2870 err = register_ioctl32_conversion(MPTEVENTENABLE, compat_mptctl_ioctl);
2871 if (++where && err) goto out_fail;
2872 err = register_ioctl32_conversion(MPTEVENTREPORT, compat_mptctl_ioctl);
2873 if (++where && err) goto out_fail;
2874 err = register_ioctl32_conversion(MPTHARDRESET, compat_mptctl_ioctl);
2875 if (++where && err) goto out_fail;
2876 err = register_ioctl32_conversion(MPTCOMMAND32, compat_mpt_command);
2877 if (++where && err) goto out_fail;
2878 err = register_ioctl32_conversion(MPTFWDOWNLOAD32,
2879 compat_mptfwxfer_ioctl);
2880 if (++where && err) goto out_fail;
2881 err = register_ioctl32_conversion(HP_GETHOSTINFO, compat_mptctl_ioctl);
2882 if (++where && err) goto out_fail;
2883 err = register_ioctl32_conversion(HP_GETTARGETINFO, compat_mptctl_ioctl);
2884 if (++where && err) goto out_fail;
2887 /* Register this device */
2888 err = misc_register(&mptctl_miscdev);
2890 printk(KERN_ERR MYNAM ": Can't register misc device [minor=%d].\n", MPT_MINOR);
2893 printk(KERN_INFO MYNAM ": Registered with Fusion MPT base driver\n");
2894 printk(KERN_INFO MYNAM ": /dev/%s @ (major,minor=%d,%d)\n",
2895 mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
2898 * Install our handler
2901 if ((mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER)) < 0) {
2902 printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
2903 misc_deregister(&mptctl_miscdev);
2908 if (mpt_reset_register(mptctl_id, mptctl_ioc_reset) == 0) {
2909 dprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
2918 #ifdef CONFIG_COMPAT
2919 printk(KERN_ERR MYNAM ": ERROR: Failed to register ioctl32_conversion!"
2920 " (%d:err=%d)\n", where, err);
2921 unregister_ioctl32_conversion(MPTIOCINFO);
2922 unregister_ioctl32_conversion(MPTIOCINFO1);
2923 unregister_ioctl32_conversion(MPTIOCINFO2);
2924 unregister_ioctl32_conversion(MPTTARGETINFO);
2925 unregister_ioctl32_conversion(MPTTEST);
2926 unregister_ioctl32_conversion(MPTEVENTQUERY);
2927 unregister_ioctl32_conversion(MPTEVENTENABLE);
2928 unregister_ioctl32_conversion(MPTEVENTREPORT);
2929 unregister_ioctl32_conversion(MPTHARDRESET);
2930 unregister_ioctl32_conversion(MPTCOMMAND32);
2931 unregister_ioctl32_conversion(MPTFWDOWNLOAD32);
2932 unregister_ioctl32_conversion(HP_GETHOSTINFO);
2933 unregister_ioctl32_conversion(HP_GETTARGETINFO);
2936 for (i=0; i<MPT_MAX_ADAPTERS; i++) {
2938 if (((iocnum = mpt_verify_adapter(i, &ioc)) < 0) ||
2944 kfree ( ioc->ioctl );
2952 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2953 void mptctl_exit(void)
2959 misc_deregister(&mptctl_miscdev);
2960 printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n",
2961 mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
2963 /* De-register reset handler from base module */
2964 mpt_reset_deregister(mptctl_id);
2965 dprintk((KERN_INFO MYNAM ": Deregistered for IOC reset notifications\n"));
2967 /* De-register callback handler from base module */
2968 mpt_deregister(mptctl_id);
2969 printk(KERN_INFO MYNAM ": Deregistered from Fusion MPT base driver\n");
2971 #ifdef CONFIG_COMPAT
2972 unregister_ioctl32_conversion(MPTIOCINFO);
2973 unregister_ioctl32_conversion(MPTIOCINFO1);
2974 unregister_ioctl32_conversion(MPTIOCINFO2);
2975 unregister_ioctl32_conversion(MPTTARGETINFO);
2976 unregister_ioctl32_conversion(MPTTEST);
2977 unregister_ioctl32_conversion(MPTEVENTQUERY);
2978 unregister_ioctl32_conversion(MPTEVENTENABLE);
2979 unregister_ioctl32_conversion(MPTEVENTREPORT);
2980 unregister_ioctl32_conversion(MPTHARDRESET);
2981 unregister_ioctl32_conversion(MPTCOMMAND32);
2982 unregister_ioctl32_conversion(MPTFWDOWNLOAD32);
2983 unregister_ioctl32_conversion(HP_GETHOSTINFO);
2984 unregister_ioctl32_conversion(HP_GETTARGETINFO);
2987 /* Free allocated memory */
2988 for (i=0; i<MPT_MAX_ADAPTERS; i++) {
2990 if (((iocnum = mpt_verify_adapter(i, &ioc)) < 0) ||
2996 kfree ( ioc->ioctl );
3003 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3005 module_init(mptctl_init);
3006 module_exit(mptctl_exit);