ieee1394: add preprocessor constant for invalid csr address
[linux-2.6/mini2440.git] / drivers / message / fusion / mptctl.c
blobb4967bb8a7d64521b23207520fa22702fbce034d
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.
7 * Copyright (c) 1999-2005 LSI Logic Corporation
8 * (mailto:mpt_linux_developer@lsil.com)
11 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
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.
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.
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.
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
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
46 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
48 #include <linux/kernel.h>
49 #include <linux/module.h>
50 #include <linux/errno.h>
51 #include <linux/init.h>
52 #include <linux/slab.h>
53 #include <linux/types.h>
54 #include <linux/pci.h>
55 #include <linux/delay.h> /* for mdelay */
56 #include <linux/miscdevice.h>
57 #include <linux/smp_lock.h>
58 #include <linux/compat.h>
60 #include <asm/io.h>
61 #include <asm/uaccess.h>
63 #include <scsi/scsi.h>
64 #include <scsi/scsi_cmnd.h>
65 #include <scsi/scsi_device.h>
66 #include <scsi/scsi_host.h>
67 #include <scsi/scsi_tcq.h>
69 #define COPYRIGHT "Copyright (c) 1999-2005 LSI Logic Corporation"
70 #define MODULEAUTHOR "LSI Logic Corporation"
71 #include "mptbase.h"
72 #include "mptctl.h"
74 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
75 #define my_NAME "Fusion MPT misc device (ioctl) driver"
76 #define my_VERSION MPT_LINUX_VERSION_COMMON
77 #define MYNAM "mptctl"
79 MODULE_AUTHOR(MODULEAUTHOR);
80 MODULE_DESCRIPTION(my_NAME);
81 MODULE_LICENSE("GPL");
83 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
85 static int mptctl_id = -1;
87 static DECLARE_WAIT_QUEUE_HEAD ( mptctl_wait );
89 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
91 struct buflist {
92 u8 *kptr;
93 int len;
97 * Function prototypes. Called from OS entry point mptctl_ioctl.
98 * arg contents specific to function.
100 static int mptctl_fw_download(unsigned long arg);
101 static int mptctl_getiocinfo(unsigned long arg, unsigned int cmd);
102 static int mptctl_gettargetinfo(unsigned long arg);
103 static int mptctl_readtest(unsigned long arg);
104 static int mptctl_mpt_command(unsigned long arg);
105 static int mptctl_eventquery(unsigned long arg);
106 static int mptctl_eventenable(unsigned long arg);
107 static int mptctl_eventreport(unsigned long arg);
108 static int mptctl_replace_fw(unsigned long arg);
110 static int mptctl_do_reset(unsigned long arg);
111 static int mptctl_hp_hostinfo(unsigned long arg, unsigned int cmd);
112 static int mptctl_hp_targetinfo(unsigned long arg);
114 static int mptctl_probe(struct pci_dev *, const struct pci_device_id *);
115 static void mptctl_remove(struct pci_dev *);
117 #ifdef CONFIG_COMPAT
118 static long compat_mpctl_ioctl(struct file *f, unsigned cmd, unsigned long arg);
119 #endif
121 * Private function calls.
123 static int mptctl_do_mpt_command(struct mpt_ioctl_command karg, void __user *mfPtr);
124 static int mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen);
125 static MptSge_t *kbuf_alloc_2_sgl(int bytes, u32 dir, int sge_offset, int *frags,
126 struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc);
127 static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma,
128 struct buflist *buflist, MPT_ADAPTER *ioc);
129 static void mptctl_timeout_expired (MPT_IOCTL *ioctl);
130 static int mptctl_bus_reset(MPT_IOCTL *ioctl);
131 static int mptctl_set_tm_flags(MPT_SCSI_HOST *hd);
132 static void mptctl_free_tm_flags(MPT_ADAPTER *ioc);
135 * Reset Handler cleanup function
137 static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);
140 * Event Handler function
142 static int mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
143 static struct fasync_struct *async_queue=NULL;
145 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
147 * Scatter gather list (SGL) sizes and limits...
149 //#define MAX_SCSI_FRAGS 9
150 #define MAX_FRAGS_SPILL1 9
151 #define MAX_FRAGS_SPILL2 15
152 #define FRAGS_PER_BUCKET (MAX_FRAGS_SPILL2 + 1)
154 //#define MAX_CHAIN_FRAGS 64
155 //#define MAX_CHAIN_FRAGS (15+15+15+16)
156 #define MAX_CHAIN_FRAGS (4 * MAX_FRAGS_SPILL2 + 1)
158 // Define max sg LIST bytes ( == (#frags + #chains) * 8 bytes each)
159 // Works out to: 592d bytes! (9+1)*8 + 4*(15+1)*8
160 // ^----------------- 80 + 512
161 #define MAX_SGL_BYTES ((MAX_FRAGS_SPILL1 + 1 + (4 * FRAGS_PER_BUCKET)) * 8)
163 /* linux only seems to ever give 128kB MAX contiguous (GFP_USER) mem bytes */
164 #define MAX_KMALLOC_SZ (128*1024)
166 #define MPT_IOCTL_DEFAULT_TIMEOUT 10 /* Default timeout value (seconds) */
168 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
170 * mptctl_syscall_down - Down the MPT adapter syscall semaphore.
171 * @ioc: Pointer to MPT adapter
172 * @nonblock: boolean, non-zero if O_NONBLOCK is set
174 * All of the ioctl commands can potentially sleep, which is illegal
175 * with a spinlock held, thus we perform mutual exclusion here.
177 * Returns negative errno on error, or zero for success.
179 static inline int
180 mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock)
182 int rc = 0;
183 dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down(%p,%d) called\n", ioc, nonblock));
185 if (nonblock) {
186 if (!mutex_trylock(&ioc->ioctl->ioctl_mutex))
187 rc = -EAGAIN;
188 } else {
189 if (mutex_lock_interruptible(&ioc->ioctl->ioctl_mutex))
190 rc = -ERESTARTSYS;
192 dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down return %d\n", rc));
193 return rc;
196 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
198 * This is the callback for any message we have posted. The message itself
199 * will be returned to the message pool when we return from the IRQ
201 * This runs in irq context so be short and sweet.
203 static int
204 mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
206 char *sense_data;
207 int sz, req_index;
208 u16 iocStatus;
209 u8 cmd;
211 dctlprintk(("mptctl_reply()!\n"));
212 if (req)
213 cmd = req->u.hdr.Function;
214 else
215 return 1;
217 if (ioc->ioctl) {
219 if (reply==NULL) {
221 dctlprintk(("mptctl_reply() NULL Reply "
222 "Function=%x!\n", cmd));
224 ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
225 ioc->ioctl->reset &= ~MPTCTL_RESET_OK;
227 /* We are done, issue wake up
229 ioc->ioctl->wait_done = 1;
230 wake_up (&mptctl_wait);
231 return 1;
235 dctlprintk(("mptctl_reply() with req=%p "
236 "reply=%p Function=%x!\n", req, reply, cmd));
238 /* Copy the reply frame (which much exist
239 * for non-SCSI I/O) to the IOC structure.
241 dctlprintk(("Copying Reply Frame @%p to ioc%d!\n",
242 reply, ioc->id));
243 memcpy(ioc->ioctl->ReplyFrame, reply,
244 min(ioc->reply_sz, 4*reply->u.reply.MsgLength));
245 ioc->ioctl->status |= MPT_IOCTL_STATUS_RF_VALID;
247 /* Set the command status to GOOD if IOC Status is GOOD
248 * OR if SCSI I/O cmd and data underrun or recovered error.
250 iocStatus = le16_to_cpu(reply->u.reply.IOCStatus) & MPI_IOCSTATUS_MASK;
251 if (iocStatus == MPI_IOCSTATUS_SUCCESS)
252 ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
254 if ((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
255 (cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
256 ioc->ioctl->reset &= ~MPTCTL_RESET_OK;
258 if ((iocStatus == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN) ||
259 (iocStatus == MPI_IOCSTATUS_SCSI_RECOVERED_ERROR)) {
260 ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
264 /* Copy the sense data - if present
266 if ((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) &&
267 (reply->u.sreply.SCSIState &
268 MPI_SCSI_STATE_AUTOSENSE_VALID)){
269 sz = req->u.scsireq.SenseBufferLength;
270 req_index =
271 le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
272 sense_data =
273 ((u8 *)ioc->sense_buf_pool +
274 (req_index * MPT_SENSE_BUFFER_ALLOC));
275 memcpy(ioc->ioctl->sense, sense_data, sz);
276 ioc->ioctl->status |= MPT_IOCTL_STATUS_SENSE_VALID;
279 if (cmd == MPI_FUNCTION_SCSI_TASK_MGMT)
280 mptctl_free_tm_flags(ioc);
282 /* We are done, issue wake up
284 ioc->ioctl->wait_done = 1;
285 wake_up (&mptctl_wait);
287 return 1;
290 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
291 /* mptctl_timeout_expired
293 * Expecting an interrupt, however timed out.
296 static void mptctl_timeout_expired (MPT_IOCTL *ioctl)
298 int rc = 1;
300 dctlprintk((KERN_NOTICE MYNAM ": Timeout Expired! Host %d\n",
301 ioctl->ioc->id));
302 if (ioctl == NULL)
303 return;
305 ioctl->wait_done = 0;
306 if (ioctl->reset & MPTCTL_RESET_OK)
307 rc = mptctl_bus_reset(ioctl);
309 if (rc) {
310 /* Issue a reset for this device.
311 * The IOC is not responding.
313 dctlprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
314 ioctl->ioc->name));
315 mpt_HardResetHandler(ioctl->ioc, NO_SLEEP);
317 return;
321 /* mptctl_bus_reset
323 * Bus reset code.
326 static int mptctl_bus_reset(MPT_IOCTL *ioctl)
328 MPT_FRAME_HDR *mf;
329 SCSITaskMgmt_t *pScsiTm;
330 MPT_SCSI_HOST *hd;
331 int ii;
332 int retval;
335 ioctl->reset &= ~MPTCTL_RESET_OK;
337 if (ioctl->ioc->sh == NULL)
338 return -EPERM;
340 hd = (MPT_SCSI_HOST *) ioctl->ioc->sh->hostdata;
341 if (hd == NULL)
342 return -EPERM;
344 /* Single threading ....
346 if (mptctl_set_tm_flags(hd) != 0)
347 return -EPERM;
349 /* Send request
351 if ((mf = mpt_get_msg_frame(mptctl_id, ioctl->ioc)) == NULL) {
352 dctlprintk((MYIOC_s_WARN_FMT "IssueTaskMgmt, no msg frames!!\n",
353 ioctl->ioc->name));
355 mptctl_free_tm_flags(ioctl->ioc);
356 return -ENOMEM;
359 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
360 ioctl->ioc->name, mf));
362 pScsiTm = (SCSITaskMgmt_t *) mf;
363 pScsiTm->TargetID = ioctl->target;
364 pScsiTm->Bus = hd->port; /* 0 */
365 pScsiTm->ChainOffset = 0;
366 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
367 pScsiTm->Reserved = 0;
368 pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;
369 pScsiTm->Reserved1 = 0;
370 pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
372 for (ii= 0; ii < 8; ii++)
373 pScsiTm->LUN[ii] = 0;
375 for (ii=0; ii < 7; ii++)
376 pScsiTm->Reserved2[ii] = 0;
378 pScsiTm->TaskMsgContext = 0;
379 dtmprintk((MYIOC_s_INFO_FMT
380 "mptctl_bus_reset: issued.\n", ioctl->ioc->name));
382 DBG_DUMP_TM_REQUEST_FRAME((u32 *)mf);
384 ioctl->wait_done=0;
385 if ((retval = mpt_send_handshake_request(mptctl_id, ioctl->ioc,
386 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP)) != 0) {
387 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
388 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
389 hd->ioc, mf));
390 goto mptctl_bus_reset_done;
393 /* Now wait for the command to complete */
394 ii = wait_event_timeout(mptctl_wait,
395 ioctl->wait_done == 1,
396 HZ*5 /* 5 second timeout */);
398 if(ii <=0 && (ioctl->wait_done != 1 )) {
399 mpt_free_msg_frame(hd->ioc, mf);
400 ioctl->wait_done = 0;
401 retval = -1; /* return failure */
404 mptctl_bus_reset_done:
406 mptctl_free_tm_flags(ioctl->ioc);
407 return retval;
410 static int
411 mptctl_set_tm_flags(MPT_SCSI_HOST *hd) {
412 unsigned long flags;
414 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
416 if (hd->tmState == TM_STATE_NONE) {
417 hd->tmState = TM_STATE_IN_PROGRESS;
418 hd->tmPending = 1;
419 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
420 } else {
421 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
422 return -EBUSY;
425 return 0;
428 static void
429 mptctl_free_tm_flags(MPT_ADAPTER *ioc)
431 MPT_SCSI_HOST * hd;
432 unsigned long flags;
434 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
435 if (hd == NULL)
436 return;
438 spin_lock_irqsave(&ioc->FreeQlock, flags);
440 hd->tmState = TM_STATE_NONE;
441 hd->tmPending = 0;
442 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
444 return;
447 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
448 /* mptctl_ioc_reset
450 * Clean-up functionality. Used only if there has been a
451 * reload of the FW due.
454 static int
455 mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
457 MPT_IOCTL *ioctl = ioc->ioctl;
458 dctlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to IOCTL driver!\n",
459 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
460 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
462 if(ioctl == NULL)
463 return 1;
465 switch(reset_phase) {
466 case MPT_IOC_SETUP_RESET:
467 ioctl->status |= MPT_IOCTL_STATUS_DID_IOCRESET;
468 break;
469 case MPT_IOC_POST_RESET:
470 ioctl->status &= ~MPT_IOCTL_STATUS_DID_IOCRESET;
471 break;
472 case MPT_IOC_PRE_RESET:
473 default:
474 break;
477 return 1;
480 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
481 /* ASYNC Event Notification Support */
482 static int
483 mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
485 u8 event;
487 event = le32_to_cpu(pEvReply->Event) & 0xFF;
489 dctlprintk(("%s() called\n", __FUNCTION__));
490 if(async_queue == NULL)
491 return 1;
493 /* Raise SIGIO for persistent events.
494 * TODO - this define is not in MPI spec yet,
495 * but they plan to set it to 0x21
497 if (event == 0x21 ) {
498 ioc->aen_event_read_flag=1;
499 dctlprintk(("Raised SIGIO to application\n"));
500 devtverboseprintk(("Raised SIGIO to application\n"));
501 kill_fasync(&async_queue, SIGIO, POLL_IN);
502 return 1;
505 /* This flag is set after SIGIO was raised, and
506 * remains set until the application has read
507 * the event log via ioctl=MPTEVENTREPORT
509 if(ioc->aen_event_read_flag)
510 return 1;
512 /* Signal only for the events that are
513 * requested for by the application
515 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
516 ioc->aen_event_read_flag=1;
517 dctlprintk(("Raised SIGIO to application\n"));
518 devtverboseprintk(("Raised SIGIO to application\n"));
519 kill_fasync(&async_queue, SIGIO, POLL_IN);
521 return 1;
524 static int
525 mptctl_fasync(int fd, struct file *filep, int mode)
527 MPT_ADAPTER *ioc;
529 list_for_each_entry(ioc, &ioc_list, list)
530 ioc->aen_event_read_flag=0;
532 dctlprintk(("%s() called\n", __FUNCTION__));
533 return fasync_helper(fd, filep, mode, &async_queue);
536 static int
537 mptctl_release(struct inode *inode, struct file *filep)
539 dctlprintk(("%s() called\n", __FUNCTION__));
540 return fasync_helper(-1, filep, 0, &async_queue);
543 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
545 * MPT ioctl handler
546 * cmd - specify the particular IOCTL command to be issued
547 * arg - data specific to the command. Must not be null.
549 static long
550 __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
552 mpt_ioctl_header __user *uhdr = (void __user *) arg;
553 mpt_ioctl_header khdr;
554 int iocnum;
555 unsigned iocnumX;
556 int nonblock = (file->f_flags & O_NONBLOCK);
557 int ret;
558 MPT_ADAPTER *iocp = NULL;
560 dctlprintk(("mptctl_ioctl() called\n"));
562 if (copy_from_user(&khdr, uhdr, sizeof(khdr))) {
563 printk(KERN_ERR "%s::mptctl_ioctl() @%d - "
564 "Unable to copy mpt_ioctl_header data @ %p\n",
565 __FILE__, __LINE__, uhdr);
566 return -EFAULT;
568 ret = -ENXIO; /* (-6) No such device or address */
570 /* Verify intended MPT adapter - set iocnum and the adapter
571 * pointer (iocp)
573 iocnumX = khdr.iocnum & 0xFF;
574 if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
575 (iocp == NULL)) {
576 dctlprintk((KERN_ERR "%s::mptctl_ioctl() @%d - ioc%d not found!\n",
577 __FILE__, __LINE__, iocnumX));
578 return -ENODEV;
581 if (!iocp->active) {
582 printk(KERN_ERR "%s::mptctl_ioctl() @%d - Controller disabled.\n",
583 __FILE__, __LINE__);
584 return -EFAULT;
587 /* Handle those commands that are just returning
588 * information stored in the driver.
589 * These commands should never time out and are unaffected
590 * by TM and FW reloads.
592 if ((cmd & ~IOCSIZE_MASK) == (MPTIOCINFO & ~IOCSIZE_MASK)) {
593 return mptctl_getiocinfo(arg, _IOC_SIZE(cmd));
594 } else if (cmd == MPTTARGETINFO) {
595 return mptctl_gettargetinfo(arg);
596 } else if (cmd == MPTTEST) {
597 return mptctl_readtest(arg);
598 } else if (cmd == MPTEVENTQUERY) {
599 return mptctl_eventquery(arg);
600 } else if (cmd == MPTEVENTENABLE) {
601 return mptctl_eventenable(arg);
602 } else if (cmd == MPTEVENTREPORT) {
603 return mptctl_eventreport(arg);
604 } else if (cmd == MPTFWREPLACE) {
605 return mptctl_replace_fw(arg);
608 /* All of these commands require an interrupt or
609 * are unknown/illegal.
611 if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
612 return ret;
614 dctlprintk((MYIOC_s_INFO_FMT ": mptctl_ioctl()\n", iocp->name));
616 if (cmd == MPTFWDOWNLOAD)
617 ret = mptctl_fw_download(arg);
618 else if (cmd == MPTCOMMAND)
619 ret = mptctl_mpt_command(arg);
620 else if (cmd == MPTHARDRESET)
621 ret = mptctl_do_reset(arg);
622 else if ((cmd & ~IOCSIZE_MASK) == (HP_GETHOSTINFO & ~IOCSIZE_MASK))
623 ret = mptctl_hp_hostinfo(arg, _IOC_SIZE(cmd));
624 else if (cmd == HP_GETTARGETINFO)
625 ret = mptctl_hp_targetinfo(arg);
626 else
627 ret = -EINVAL;
629 mutex_unlock(&iocp->ioctl->ioctl_mutex);
631 return ret;
634 static long
635 mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
637 long ret;
638 lock_kernel();
639 ret = __mptctl_ioctl(file, cmd, arg);
640 unlock_kernel();
641 return ret;
644 static int mptctl_do_reset(unsigned long arg)
646 struct mpt_ioctl_diag_reset __user *urinfo = (void __user *) arg;
647 struct mpt_ioctl_diag_reset krinfo;
648 MPT_ADAPTER *iocp;
650 dctlprintk((KERN_INFO "mptctl_do_reset called.\n"));
652 if (copy_from_user(&krinfo, urinfo, sizeof(struct mpt_ioctl_diag_reset))) {
653 printk(KERN_ERR "%s@%d::mptctl_do_reset - "
654 "Unable to copy mpt_ioctl_diag_reset struct @ %p\n",
655 __FILE__, __LINE__, urinfo);
656 return -EFAULT;
659 if (mpt_verify_adapter(krinfo.hdr.iocnum, &iocp) < 0) {
660 dctlprintk((KERN_ERR "%s@%d::mptctl_do_reset - ioc%d not found!\n",
661 __FILE__, __LINE__, krinfo.hdr.iocnum));
662 return -ENODEV; /* (-6) No such device or address */
665 if (mpt_HardResetHandler(iocp, CAN_SLEEP) != 0) {
666 printk (KERN_ERR "%s@%d::mptctl_do_reset - reset failed.\n",
667 __FILE__, __LINE__);
668 return -1;
671 return 0;
674 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
676 * MPT FW download function. Cast the arg into the mpt_fw_xfer structure.
677 * This structure contains: iocnum, firmware length (bytes),
678 * pointer to user space memory where the fw image is stored.
680 * Outputs: None.
681 * Return: 0 if successful
682 * -EFAULT if data unavailable
683 * -ENXIO if no such device
684 * -EAGAIN if resource problem
685 * -ENOMEM if no memory for SGE
686 * -EMLINK if too many chain buffers required
687 * -EBADRQC if adapter does not support FW download
688 * -EBUSY if adapter is busy
689 * -ENOMSG if FW upload returned bad status
691 static int
692 mptctl_fw_download(unsigned long arg)
694 struct mpt_fw_xfer __user *ufwdl = (void __user *) arg;
695 struct mpt_fw_xfer kfwdl;
697 dctlprintk((KERN_INFO "mptctl_fwdl called. mptctl_id = %xh\n", mptctl_id)); //tc
698 if (copy_from_user(&kfwdl, ufwdl, sizeof(struct mpt_fw_xfer))) {
699 printk(KERN_ERR "%s@%d::_ioctl_fwdl - "
700 "Unable to copy mpt_fw_xfer struct @ %p\n",
701 __FILE__, __LINE__, ufwdl);
702 return -EFAULT;
705 return mptctl_do_fw_download(kfwdl.iocnum, kfwdl.bufp, kfwdl.fwlen);
708 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
710 * FW Download engine.
711 * Outputs: None.
712 * Return: 0 if successful
713 * -EFAULT if data unavailable
714 * -ENXIO if no such device
715 * -EAGAIN if resource problem
716 * -ENOMEM if no memory for SGE
717 * -EMLINK if too many chain buffers required
718 * -EBADRQC if adapter does not support FW download
719 * -EBUSY if adapter is busy
720 * -ENOMSG if FW upload returned bad status
722 static int
723 mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
725 FWDownload_t *dlmsg;
726 MPT_FRAME_HDR *mf;
727 MPT_ADAPTER *iocp;
728 FWDownloadTCSGE_t *ptsge;
729 MptSge_t *sgl, *sgIn;
730 char *sgOut;
731 struct buflist *buflist;
732 struct buflist *bl;
733 dma_addr_t sgl_dma;
734 int ret;
735 int numfrags = 0;
736 int maxfrags;
737 int n = 0;
738 u32 sgdir;
739 u32 nib;
740 int fw_bytes_copied = 0;
741 int i;
742 int sge_offset = 0;
743 u16 iocstat;
744 pFWDownloadReply_t ReplyMsg = NULL;
746 dctlprintk(("mptctl_do_fwdl called. mptctl_id = %xh.\n", mptctl_id));
748 dctlprintk(("DbG: kfwdl.bufp = %p\n", ufwbuf));
749 dctlprintk(("DbG: kfwdl.fwlen = %d\n", (int)fwlen));
750 dctlprintk(("DbG: kfwdl.ioc = %04xh\n", ioc));
752 if (mpt_verify_adapter(ioc, &iocp) < 0) {
753 dctlprintk(("ioctl_fwdl - ioc%d not found!\n",
754 ioc));
755 return -ENODEV; /* (-6) No such device or address */
756 } else {
758 /* Valid device. Get a message frame and construct the FW download message.
760 if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
761 return -EAGAIN;
763 dlmsg = (FWDownload_t*) mf;
764 ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL;
765 sgOut = (char *) (ptsge + 1);
768 * Construct f/w download request
770 dlmsg->ImageType = MPI_FW_DOWNLOAD_ITYPE_FW;
771 dlmsg->Reserved = 0;
772 dlmsg->ChainOffset = 0;
773 dlmsg->Function = MPI_FUNCTION_FW_DOWNLOAD;
774 dlmsg->Reserved1[0] = dlmsg->Reserved1[1] = dlmsg->Reserved1[2] = 0;
775 if (iocp->facts.MsgVersion >= MPI_VERSION_01_05)
776 dlmsg->MsgFlags = MPI_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT;
777 else
778 dlmsg->MsgFlags = 0;
781 /* Set up the Transaction SGE.
783 ptsge->Reserved = 0;
784 ptsge->ContextSize = 0;
785 ptsge->DetailsLength = 12;
786 ptsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
787 ptsge->Reserved_0100_Checksum = 0;
788 ptsge->ImageOffset = 0;
789 ptsge->ImageSize = cpu_to_le32(fwlen);
791 /* Add the SGL
795 * Need to kmalloc area(s) for holding firmware image bytes.
796 * But we need to do it piece meal, using a proper
797 * scatter gather list (with 128kB MAX hunks).
799 * A practical limit here might be # of sg hunks that fit into
800 * a single IOC request frame; 12 or 8 (see below), so:
801 * For FC9xx: 12 x 128kB == 1.5 mB (max)
802 * For C1030: 8 x 128kB == 1 mB (max)
803 * We could support chaining, but things get ugly(ier:)
805 * Set the sge_offset to the start of the sgl (bytes).
807 sgdir = 0x04000000; /* IOC will READ from sys mem */
808 sge_offset = sizeof(MPIHeader_t) + sizeof(FWDownloadTCSGE_t);
809 if ((sgl = kbuf_alloc_2_sgl(fwlen, sgdir, sge_offset,
810 &numfrags, &buflist, &sgl_dma, iocp)) == NULL)
811 return -ENOMEM;
814 * We should only need SGL with 2 simple_32bit entries (up to 256 kB)
815 * for FC9xx f/w image, but calculate max number of sge hunks
816 * we can fit into a request frame, and limit ourselves to that.
817 * (currently no chain support)
818 * maxfrags = (Request Size - FWdownload Size ) / Size of 32 bit SGE
819 * Request maxfrags
820 * 128 12
821 * 96 8
822 * 64 4
824 maxfrags = (iocp->req_sz - sizeof(MPIHeader_t) - sizeof(FWDownloadTCSGE_t))
825 / (sizeof(dma_addr_t) + sizeof(u32));
826 if (numfrags > maxfrags) {
827 ret = -EMLINK;
828 goto fwdl_out;
831 dctlprintk(("DbG: sgl buffer = %p, sgfrags = %d\n", sgl, numfrags));
834 * Parse SG list, copying sgl itself,
835 * plus f/w image hunks from user space as we go...
837 ret = -EFAULT;
838 sgIn = sgl;
839 bl = buflist;
840 for (i=0; i < numfrags; i++) {
842 /* Get the SGE type: 0 - TCSGE, 3 - Chain, 1 - Simple SGE
843 * Skip everything but Simple. If simple, copy from
844 * user space into kernel space.
845 * Note: we should not have anything but Simple as
846 * Chain SGE are illegal.
848 nib = (sgIn->FlagsLength & 0x30000000) >> 28;
849 if (nib == 0 || nib == 3) {
851 } else if (sgIn->Address) {
852 mpt_add_sge(sgOut, sgIn->FlagsLength, sgIn->Address);
853 n++;
854 if (copy_from_user(bl->kptr, ufwbuf+fw_bytes_copied, bl->len)) {
855 printk(KERN_ERR "%s@%d::_ioctl_fwdl - "
856 "Unable to copy f/w buffer hunk#%d @ %p\n",
857 __FILE__, __LINE__, n, ufwbuf);
858 goto fwdl_out;
860 fw_bytes_copied += bl->len;
862 sgIn++;
863 bl++;
864 sgOut += (sizeof(dma_addr_t) + sizeof(u32));
867 #ifdef MPT_DEBUG
869 u32 *m = (u32 *)mf;
870 printk(KERN_INFO MYNAM ": F/W download request:\n" KERN_INFO " ");
871 for (i=0; i < 7+numfrags*2; i++)
872 printk(" %08x", le32_to_cpu(m[i]));
873 printk("\n");
875 #endif
878 * Finally, perform firmware download.
880 ReplyMsg = NULL;
881 mpt_put_msg_frame(mptctl_id, iocp, mf);
883 /* Now wait for the command to complete */
884 ret = wait_event_timeout(mptctl_wait,
885 iocp->ioctl->wait_done == 1,
886 HZ*60);
888 if(ret <=0 && (iocp->ioctl->wait_done != 1 )) {
889 /* Now we need to reset the board */
890 mptctl_timeout_expired(iocp->ioctl);
891 ret = -ENODATA;
892 goto fwdl_out;
895 if (sgl)
896 kfree_sgl(sgl, sgl_dma, buflist, iocp);
898 ReplyMsg = (pFWDownloadReply_t)iocp->ioctl->ReplyFrame;
899 iocstat = le16_to_cpu(ReplyMsg->IOCStatus) & MPI_IOCSTATUS_MASK;
900 if (iocstat == MPI_IOCSTATUS_SUCCESS) {
901 printk(KERN_INFO MYNAM ": F/W update successfully sent to %s!\n", iocp->name);
902 return 0;
903 } else if (iocstat == MPI_IOCSTATUS_INVALID_FUNCTION) {
904 printk(KERN_WARNING MYNAM ": ?Hmmm... %s says it doesn't support F/W download!?!\n",
905 iocp->name);
906 printk(KERN_WARNING MYNAM ": (time to go bang on somebodies door)\n");
907 return -EBADRQC;
908 } else if (iocstat == MPI_IOCSTATUS_BUSY) {
909 printk(KERN_WARNING MYNAM ": Warning! %s says: IOC_BUSY!\n", iocp->name);
910 printk(KERN_WARNING MYNAM ": (try again later?)\n");
911 return -EBUSY;
912 } else {
913 printk(KERN_WARNING MYNAM "::ioctl_fwdl() ERROR! %s returned [bad] status = %04xh\n",
914 iocp->name, iocstat);
915 printk(KERN_WARNING MYNAM ": (bad VooDoo)\n");
916 return -ENOMSG;
918 return 0;
920 fwdl_out:
921 kfree_sgl(sgl, sgl_dma, buflist, iocp);
922 return ret;
925 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
927 * SGE Allocation routine
929 * Inputs: bytes - number of bytes to be transferred
930 * sgdir - data direction
931 * sge_offset - offset (in bytes) from the start of the request
932 * frame to the first SGE
933 * ioc - pointer to the mptadapter
934 * Outputs: frags - number of scatter gather elements
935 * blp - point to the buflist pointer
936 * sglbuf_dma - pointer to the (dma) sgl
937 * Returns: Null if failes
938 * pointer to the (virtual) sgl if successful.
940 static MptSge_t *
941 kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags,
942 struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc)
944 MptSge_t *sglbuf = NULL; /* pointer to array of SGE */
945 /* and chain buffers */
946 struct buflist *buflist = NULL; /* kernel routine */
947 MptSge_t *sgl;
948 int numfrags = 0;
949 int fragcnt = 0;
950 int alloc_sz = min(bytes,MAX_KMALLOC_SZ); // avoid kernel warning msg!
951 int bytes_allocd = 0;
952 int this_alloc;
953 dma_addr_t pa; // phys addr
954 int i, buflist_ent;
955 int sg_spill = MAX_FRAGS_SPILL1;
956 int dir;
957 /* initialization */
958 *frags = 0;
959 *blp = NULL;
961 /* Allocate and initialize an array of kernel
962 * structures for the SG elements.
964 i = MAX_SGL_BYTES / 8;
965 buflist = kmalloc(i, GFP_USER);
966 if (buflist == NULL)
967 return NULL;
968 memset(buflist, 0, i);
969 buflist_ent = 0;
971 /* Allocate a single block of memory to store the sg elements and
972 * the chain buffers. The calling routine is responsible for
973 * copying the data in this array into the correct place in the
974 * request and chain buffers.
976 sglbuf = pci_alloc_consistent(ioc->pcidev, MAX_SGL_BYTES, sglbuf_dma);
977 if (sglbuf == NULL)
978 goto free_and_fail;
980 if (sgdir & 0x04000000)
981 dir = PCI_DMA_TODEVICE;
982 else
983 dir = PCI_DMA_FROMDEVICE;
985 /* At start:
986 * sgl = sglbuf = point to beginning of sg buffer
987 * buflist_ent = 0 = first kernel structure
988 * sg_spill = number of SGE that can be written before the first
989 * chain element.
992 sgl = sglbuf;
993 sg_spill = ((ioc->req_sz - sge_offset)/(sizeof(dma_addr_t) + sizeof(u32))) - 1;
994 while (bytes_allocd < bytes) {
995 this_alloc = min(alloc_sz, bytes-bytes_allocd);
996 buflist[buflist_ent].len = this_alloc;
997 buflist[buflist_ent].kptr = pci_alloc_consistent(ioc->pcidev,
998 this_alloc,
999 &pa);
1000 if (buflist[buflist_ent].kptr == NULL) {
1001 alloc_sz = alloc_sz / 2;
1002 if (alloc_sz == 0) {
1003 printk(KERN_WARNING MYNAM "-SG: No can do - "
1004 "not enough memory! :-(\n");
1005 printk(KERN_WARNING MYNAM "-SG: (freeing %d frags)\n",
1006 numfrags);
1007 goto free_and_fail;
1009 continue;
1010 } else {
1011 dma_addr_t dma_addr;
1013 bytes_allocd += this_alloc;
1014 sgl->FlagsLength = (0x10000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|this_alloc);
1015 dma_addr = pci_map_single(ioc->pcidev, buflist[buflist_ent].kptr, this_alloc, dir);
1016 sgl->Address = dma_addr;
1018 fragcnt++;
1019 numfrags++;
1020 sgl++;
1021 buflist_ent++;
1024 if (bytes_allocd >= bytes)
1025 break;
1027 /* Need to chain? */
1028 if (fragcnt == sg_spill) {
1029 printk(KERN_WARNING MYNAM "-SG: No can do - " "Chain required! :-(\n");
1030 printk(KERN_WARNING MYNAM "(freeing %d frags)\n", numfrags);
1031 goto free_and_fail;
1034 /* overflow check... */
1035 if (numfrags*8 > MAX_SGL_BYTES){
1036 /* GRRRRR... */
1037 printk(KERN_WARNING MYNAM "-SG: No can do - "
1038 "too many SG frags! :-(\n");
1039 printk(KERN_WARNING MYNAM "-SG: (freeing %d frags)\n",
1040 numfrags);
1041 goto free_and_fail;
1045 /* Last sge fixup: set LE+eol+eob bits */
1046 sgl[-1].FlagsLength |= 0xC1000000;
1048 *frags = numfrags;
1049 *blp = buflist;
1051 dctlprintk((KERN_INFO MYNAM "-SG: kbuf_alloc_2_sgl() - "
1052 "%d SG frags generated!\n",
1053 numfrags));
1055 dctlprintk((KERN_INFO MYNAM "-SG: kbuf_alloc_2_sgl() - "
1056 "last (big) alloc_sz=%d\n",
1057 alloc_sz));
1059 return sglbuf;
1061 free_and_fail:
1062 if (sglbuf != NULL) {
1063 int i;
1065 for (i = 0; i < numfrags; i++) {
1066 dma_addr_t dma_addr;
1067 u8 *kptr;
1068 int len;
1070 if ((sglbuf[i].FlagsLength >> 24) == 0x30)
1071 continue;
1073 dma_addr = sglbuf[i].Address;
1074 kptr = buflist[i].kptr;
1075 len = buflist[i].len;
1077 pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
1079 pci_free_consistent(ioc->pcidev, MAX_SGL_BYTES, sglbuf, *sglbuf_dma);
1081 kfree(buflist);
1082 return NULL;
1085 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1087 * Routine to free the SGL elements.
1089 static void
1090 kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma, struct buflist *buflist, MPT_ADAPTER *ioc)
1092 MptSge_t *sg = sgl;
1093 struct buflist *bl = buflist;
1094 u32 nib;
1095 int dir;
1096 int n = 0;
1098 if (sg->FlagsLength & 0x04000000)
1099 dir = PCI_DMA_TODEVICE;
1100 else
1101 dir = PCI_DMA_FROMDEVICE;
1103 nib = (sg->FlagsLength & 0xF0000000) >> 28;
1104 while (! (nib & 0x4)) { /* eob */
1105 /* skip ignore/chain. */
1106 if (nib == 0 || nib == 3) {
1108 } else if (sg->Address) {
1109 dma_addr_t dma_addr;
1110 void *kptr;
1111 int len;
1113 dma_addr = sg->Address;
1114 kptr = bl->kptr;
1115 len = bl->len;
1116 pci_unmap_single(ioc->pcidev, dma_addr, len, dir);
1117 pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
1118 n++;
1120 sg++;
1121 bl++;
1122 nib = (le32_to_cpu(sg->FlagsLength) & 0xF0000000) >> 28;
1125 /* we're at eob! */
1126 if (sg->Address) {
1127 dma_addr_t dma_addr;
1128 void *kptr;
1129 int len;
1131 dma_addr = sg->Address;
1132 kptr = bl->kptr;
1133 len = bl->len;
1134 pci_unmap_single(ioc->pcidev, dma_addr, len, dir);
1135 pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
1136 n++;
1139 pci_free_consistent(ioc->pcidev, MAX_SGL_BYTES, sgl, sgl_dma);
1140 kfree(buflist);
1141 dctlprintk((KERN_INFO MYNAM "-SG: Free'd 1 SGL buf + %d kbufs!\n", n));
1144 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1146 * mptctl_getiocinfo - Query the host adapter for IOC information.
1147 * @arg: User space argument
1149 * Outputs: None.
1150 * Return: 0 if successful
1151 * -EFAULT if data unavailable
1152 * -ENODEV if no such device/adapter
1154 static int
1155 mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
1157 struct mpt_ioctl_iocinfo __user *uarg = (void __user *) arg;
1158 struct mpt_ioctl_iocinfo *karg;
1159 MPT_ADAPTER *ioc;
1160 struct pci_dev *pdev;
1161 struct Scsi_Host *sh;
1162 MPT_SCSI_HOST *hd;
1163 int iocnum;
1164 int numDevices = 0;
1165 unsigned int max_id;
1166 int ii;
1167 unsigned int port;
1168 int cim_rev;
1169 u8 revision;
1171 dctlprintk((": mptctl_getiocinfo called.\n"));
1172 /* Add of PCI INFO results in unaligned access for
1173 * IA64 and Sparc. Reset long to int. Return no PCI
1174 * data for obsolete format.
1176 if (data_size == sizeof(struct mpt_ioctl_iocinfo_rev0))
1177 cim_rev = 0;
1178 else if (data_size == sizeof(struct mpt_ioctl_iocinfo_rev1))
1179 cim_rev = 1;
1180 else if (data_size == sizeof(struct mpt_ioctl_iocinfo))
1181 cim_rev = 2;
1182 else if (data_size == (sizeof(struct mpt_ioctl_iocinfo_rev0)+12))
1183 cim_rev = 0; /* obsolete */
1184 else
1185 return -EFAULT;
1187 karg = kmalloc(data_size, GFP_KERNEL);
1188 if (karg == NULL) {
1189 printk(KERN_ERR "%s::mpt_ioctl_iocinfo() @%d - no memory available!\n",
1190 __FILE__, __LINE__);
1191 return -ENOMEM;
1194 if (copy_from_user(karg, uarg, data_size)) {
1195 printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
1196 "Unable to read in mpt_ioctl_iocinfo struct @ %p\n",
1197 __FILE__, __LINE__, uarg);
1198 kfree(karg);
1199 return -EFAULT;
1202 if (((iocnum = mpt_verify_adapter(karg->hdr.iocnum, &ioc)) < 0) ||
1203 (ioc == NULL)) {
1204 dctlprintk((KERN_ERR "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n",
1205 __FILE__, __LINE__, iocnum));
1206 kfree(karg);
1207 return -ENODEV;
1210 /* Verify the data transfer size is correct. */
1211 if (karg->hdr.maxDataSize != data_size) {
1212 printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
1213 "Structure size mismatch. Command not completed.\n",
1214 __FILE__, __LINE__);
1215 kfree(karg);
1216 return -EFAULT;
1219 /* Fill in the data and return the structure to the calling
1220 * program
1222 if (ioc->bus_type == SAS)
1223 karg->adapterType = MPT_IOCTL_INTERFACE_SAS;
1224 else if (ioc->bus_type == FC)
1225 karg->adapterType = MPT_IOCTL_INTERFACE_FC;
1226 else
1227 karg->adapterType = MPT_IOCTL_INTERFACE_SCSI;
1229 if (karg->hdr.port > 1)
1230 return -EINVAL;
1231 port = karg->hdr.port;
1233 karg->port = port;
1234 pdev = (struct pci_dev *) ioc->pcidev;
1236 karg->pciId = pdev->device;
1237 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1238 karg->hwRev = revision;
1239 karg->subSystemDevice = pdev->subsystem_device;
1240 karg->subSystemVendor = pdev->subsystem_vendor;
1242 if (cim_rev == 1) {
1243 /* Get the PCI bus, device, and function numbers for the IOC
1245 karg->pciInfo.u.bits.busNumber = pdev->bus->number;
1246 karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
1247 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1248 } else if (cim_rev == 2) {
1249 /* Get the PCI bus, device, function and segment ID numbers
1250 for the IOC */
1251 karg->pciInfo.u.bits.busNumber = pdev->bus->number;
1252 karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
1253 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1254 karg->pciInfo.segmentID = pci_domain_nr(pdev->bus);
1257 /* Get number of devices
1259 if ((sh = ioc->sh) != NULL) {
1260 /* sh->max_id = maximum target ID + 1
1262 max_id = sh->max_id - 1;
1263 hd = (MPT_SCSI_HOST *) sh->hostdata;
1265 /* Check all of the target structures and
1266 * keep a counter.
1268 if (hd && hd->Targets) {
1269 for (ii = 0; ii <= max_id; ii++) {
1270 if (hd->Targets[ii])
1271 numDevices++;
1275 karg->numDevices = numDevices;
1277 /* Set the BIOS and FW Version
1279 karg->FWVersion = ioc->facts.FWVersion.Word;
1280 karg->BIOSVersion = ioc->biosVersion;
1282 /* Set the Version Strings.
1284 strncpy (karg->driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH);
1285 karg->driverVersion[MPT_IOCTL_VERSION_LENGTH-1]='\0';
1287 karg->busChangeEvent = 0;
1288 karg->hostId = ioc->pfacts[port].PortSCSIID;
1289 karg->rsvd[0] = karg->rsvd[1] = 0;
1291 /* Copy the data from kernel memory to user memory
1293 if (copy_to_user((char __user *)arg, karg, data_size)) {
1294 printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
1295 "Unable to write out mpt_ioctl_iocinfo struct @ %p\n",
1296 __FILE__, __LINE__, uarg);
1297 kfree(karg);
1298 return -EFAULT;
1301 kfree(karg);
1302 return 0;
1305 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1307 * mptctl_gettargetinfo - Query the host adapter for target information.
1308 * @arg: User space argument
1310 * Outputs: None.
1311 * Return: 0 if successful
1312 * -EFAULT if data unavailable
1313 * -ENODEV if no such device/adapter
1315 static int
1316 mptctl_gettargetinfo (unsigned long arg)
1318 struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg;
1319 struct mpt_ioctl_targetinfo karg;
1320 MPT_ADAPTER *ioc;
1321 struct Scsi_Host *sh;
1322 MPT_SCSI_HOST *hd;
1323 VirtTarget *vdev;
1324 char *pmem;
1325 int *pdata;
1326 IOCPage2_t *pIoc2;
1327 IOCPage3_t *pIoc3;
1328 int iocnum;
1329 int numDevices = 0;
1330 unsigned int max_id;
1331 int id, jj, indexed_lun, lun_index;
1332 u32 lun;
1333 int maxWordsLeft;
1334 int numBytes;
1335 u8 port, devType, bus_id;
1337 dctlprintk(("mptctl_gettargetinfo called.\n"));
1338 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
1339 printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
1340 "Unable to read in mpt_ioctl_targetinfo struct @ %p\n",
1341 __FILE__, __LINE__, uarg);
1342 return -EFAULT;
1345 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1346 (ioc == NULL)) {
1347 dctlprintk((KERN_ERR "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n",
1348 __FILE__, __LINE__, iocnum));
1349 return -ENODEV;
1352 /* Get the port number and set the maximum number of bytes
1353 * in the returned structure.
1354 * Ignore the port setting.
1356 numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
1357 maxWordsLeft = numBytes/sizeof(int);
1358 port = karg.hdr.port;
1360 if (maxWordsLeft <= 0) {
1361 printk(KERN_ERR "%s::mptctl_gettargetinfo() @%d - no memory available!\n",
1362 __FILE__, __LINE__);
1363 return -ENOMEM;
1366 /* Fill in the data and return the structure to the calling
1367 * program
1370 /* struct mpt_ioctl_targetinfo does not contain sufficient space
1371 * for the target structures so when the IOCTL is called, there is
1372 * not sufficient stack space for the structure. Allocate memory,
1373 * populate the memory, copy back to the user, then free memory.
1374 * targetInfo format:
1375 * bits 31-24: reserved
1376 * 23-16: LUN
1377 * 15- 8: Bus Number
1378 * 7- 0: Target ID
1380 pmem = kmalloc(numBytes, GFP_KERNEL);
1381 if (pmem == NULL) {
1382 printk(KERN_ERR "%s::mptctl_gettargetinfo() @%d - no memory available!\n",
1383 __FILE__, __LINE__);
1384 return -ENOMEM;
1386 memset(pmem, 0, numBytes);
1387 pdata = (int *) pmem;
1389 /* Get number of devices
1391 if ((sh = ioc->sh) != NULL) {
1393 max_id = sh->max_id - 1;
1394 hd = (MPT_SCSI_HOST *) sh->hostdata;
1396 /* Check all of the target structures.
1397 * Save the Id and increment the counter,
1398 * if ptr non-null.
1399 * sh->max_id = maximum target ID + 1
1401 if (hd && hd->Targets) {
1402 mpt_findImVolumes(ioc);
1403 pIoc2 = ioc->raid_data.pIocPg2;
1404 for ( id = 0; id <= max_id; ) {
1405 if ( pIoc2 && pIoc2->NumActiveVolumes ) {
1406 if ( id == pIoc2->RaidVolume[0].VolumeID ) {
1407 if (maxWordsLeft <= 0) {
1408 printk(KERN_ERR "mptctl_gettargetinfo - "
1409 "buffer is full but volume is available on ioc %d\n, numDevices=%d", iocnum, numDevices);
1410 goto data_space_full;
1412 if ( ( pIoc2->RaidVolume[0].Flags & MPI_IOCPAGE2_FLAG_VOLUME_INACTIVE ) == 0 )
1413 devType = 0x80;
1414 else
1415 devType = 0xC0;
1416 bus_id = pIoc2->RaidVolume[0].VolumeBus;
1417 numDevices++;
1418 *pdata = ( (devType << 24) | (bus_id << 8) | id );
1419 dctlprintk((KERN_ERR "mptctl_gettargetinfo - "
1420 "volume ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata));
1421 pdata++;
1422 --maxWordsLeft;
1423 goto next_id;
1424 } else {
1425 pIoc3 = ioc->raid_data.pIocPg3;
1426 for ( jj = 0; jj < pIoc3->NumPhysDisks; jj++ ) {
1427 if ( pIoc3->PhysDisk[jj].PhysDiskID == id )
1428 goto next_id;
1432 if ( (vdev = hd->Targets[id]) ) {
1433 for (jj = 0; jj <= MPT_LAST_LUN; jj++) {
1434 lun_index = (jj >> 5);
1435 indexed_lun = (jj % 32);
1436 lun = (1 << indexed_lun);
1437 if (vdev->luns[lun_index] & lun) {
1438 if (maxWordsLeft <= 0) {
1439 printk(KERN_ERR "mptctl_gettargetinfo - "
1440 "buffer is full but more targets are available on ioc %d numDevices=%d\n", iocnum, numDevices);
1441 goto data_space_full;
1443 bus_id = vdev->bus_id;
1444 numDevices++;
1445 *pdata = ( (jj << 16) | (bus_id << 8) | id );
1446 dctlprintk((KERN_ERR "mptctl_gettargetinfo - "
1447 "target ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata));
1448 pdata++;
1449 --maxWordsLeft;
1453 next_id:
1454 id++;
1458 data_space_full:
1459 karg.numDevices = numDevices;
1461 /* Copy part of the data from kernel memory to user memory
1463 if (copy_to_user((char __user *)arg, &karg,
1464 sizeof(struct mpt_ioctl_targetinfo))) {
1465 printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
1466 "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
1467 __FILE__, __LINE__, uarg);
1468 kfree(pmem);
1469 return -EFAULT;
1472 /* Copy the remaining data from kernel memory to user memory
1474 if (copy_to_user(uarg->targetInfo, pmem, numBytes)) {
1475 printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
1476 "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
1477 __FILE__, __LINE__, pdata);
1478 kfree(pmem);
1479 return -EFAULT;
1482 kfree(pmem);
1484 return 0;
1487 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1488 /* MPT IOCTL Test function.
1490 * Outputs: None.
1491 * Return: 0 if successful
1492 * -EFAULT if data unavailable
1493 * -ENODEV if no such device/adapter
1495 static int
1496 mptctl_readtest (unsigned long arg)
1498 struct mpt_ioctl_test __user *uarg = (void __user *) arg;
1499 struct mpt_ioctl_test karg;
1500 MPT_ADAPTER *ioc;
1501 int iocnum;
1503 dctlprintk(("mptctl_readtest called.\n"));
1504 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) {
1505 printk(KERN_ERR "%s@%d::mptctl_readtest - "
1506 "Unable to read in mpt_ioctl_test struct @ %p\n",
1507 __FILE__, __LINE__, uarg);
1508 return -EFAULT;
1511 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1512 (ioc == NULL)) {
1513 dctlprintk((KERN_ERR "%s::mptctl_readtest() @%d - ioc%d not found!\n",
1514 __FILE__, __LINE__, iocnum));
1515 return -ENODEV;
1518 /* Fill in the data and return the structure to the calling
1519 * program
1522 #ifdef MFCNT
1523 karg.chip_type = ioc->mfcnt;
1524 #else
1525 karg.chip_type = ioc->pcidev->device;
1526 #endif
1527 strncpy (karg.name, ioc->name, MPT_MAX_NAME);
1528 karg.name[MPT_MAX_NAME-1]='\0';
1529 strncpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH);
1530 karg.product[MPT_PRODUCT_LENGTH-1]='\0';
1532 /* Copy the data from kernel memory to user memory
1534 if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_test))) {
1535 printk(KERN_ERR "%s@%d::mptctl_readtest - "
1536 "Unable to write out mpt_ioctl_test struct @ %p\n",
1537 __FILE__, __LINE__, uarg);
1538 return -EFAULT;
1541 return 0;
1544 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1546 * mptctl_eventquery - Query the host adapter for the event types
1547 * that are being logged.
1548 * @arg: User space argument
1550 * Outputs: None.
1551 * Return: 0 if successful
1552 * -EFAULT if data unavailable
1553 * -ENODEV if no such device/adapter
1555 static int
1556 mptctl_eventquery (unsigned long arg)
1558 struct mpt_ioctl_eventquery __user *uarg = (void __user *) arg;
1559 struct mpt_ioctl_eventquery karg;
1560 MPT_ADAPTER *ioc;
1561 int iocnum;
1563 dctlprintk(("mptctl_eventquery called.\n"));
1564 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) {
1565 printk(KERN_ERR "%s@%d::mptctl_eventquery - "
1566 "Unable to read in mpt_ioctl_eventquery struct @ %p\n",
1567 __FILE__, __LINE__, uarg);
1568 return -EFAULT;
1571 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1572 (ioc == NULL)) {
1573 dctlprintk((KERN_ERR "%s::mptctl_eventquery() @%d - ioc%d not found!\n",
1574 __FILE__, __LINE__, iocnum));
1575 return -ENODEV;
1578 karg.eventEntries = MPTCTL_EVENT_LOG_SIZE;
1579 karg.eventTypes = ioc->eventTypes;
1581 /* Copy the data from kernel memory to user memory
1583 if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) {
1584 printk(KERN_ERR "%s@%d::mptctl_eventquery - "
1585 "Unable to write out mpt_ioctl_eventquery struct @ %p\n",
1586 __FILE__, __LINE__, uarg);
1587 return -EFAULT;
1589 return 0;
1592 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1593 static int
1594 mptctl_eventenable (unsigned long arg)
1596 struct mpt_ioctl_eventenable __user *uarg = (void __user *) arg;
1597 struct mpt_ioctl_eventenable karg;
1598 MPT_ADAPTER *ioc;
1599 int iocnum;
1601 dctlprintk(("mptctl_eventenable called.\n"));
1602 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) {
1603 printk(KERN_ERR "%s@%d::mptctl_eventenable - "
1604 "Unable to read in mpt_ioctl_eventenable struct @ %p\n",
1605 __FILE__, __LINE__, uarg);
1606 return -EFAULT;
1609 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1610 (ioc == NULL)) {
1611 dctlprintk((KERN_ERR "%s::mptctl_eventenable() @%d - ioc%d not found!\n",
1612 __FILE__, __LINE__, iocnum));
1613 return -ENODEV;
1616 if (ioc->events == NULL) {
1617 /* Have not yet allocated memory - do so now.
1619 int sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
1620 ioc->events = kmalloc(sz, GFP_KERNEL);
1621 if (ioc->events == NULL) {
1622 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1623 return -ENOMEM;
1625 memset(ioc->events, 0, sz);
1626 ioc->alloc_total += sz;
1628 ioc->eventContext = 0;
1631 /* Update the IOC event logging flag.
1633 ioc->eventTypes = karg.eventTypes;
1635 return 0;
1638 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1639 static int
1640 mptctl_eventreport (unsigned long arg)
1642 struct mpt_ioctl_eventreport __user *uarg = (void __user *) arg;
1643 struct mpt_ioctl_eventreport karg;
1644 MPT_ADAPTER *ioc;
1645 int iocnum;
1646 int numBytes, maxEvents, max;
1648 dctlprintk(("mptctl_eventreport called.\n"));
1649 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) {
1650 printk(KERN_ERR "%s@%d::mptctl_eventreport - "
1651 "Unable to read in mpt_ioctl_eventreport struct @ %p\n",
1652 __FILE__, __LINE__, uarg);
1653 return -EFAULT;
1656 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1657 (ioc == NULL)) {
1658 dctlprintk((KERN_ERR "%s::mptctl_eventreport() @%d - ioc%d not found!\n",
1659 __FILE__, __LINE__, iocnum));
1660 return -ENODEV;
1663 numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
1664 maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS);
1667 max = MPTCTL_EVENT_LOG_SIZE < maxEvents ? MPTCTL_EVENT_LOG_SIZE : maxEvents;
1669 /* If fewer than 1 event is requested, there must have
1670 * been some type of error.
1672 if ((max < 1) || !ioc->events)
1673 return -ENODATA;
1675 /* reset this flag so SIGIO can restart */
1676 ioc->aen_event_read_flag=0;
1678 /* Copy the data from kernel memory to user memory
1680 numBytes = max * sizeof(MPT_IOCTL_EVENTS);
1681 if (copy_to_user(uarg->eventData, ioc->events, numBytes)) {
1682 printk(KERN_ERR "%s@%d::mptctl_eventreport - "
1683 "Unable to write out mpt_ioctl_eventreport struct @ %p\n",
1684 __FILE__, __LINE__, ioc->events);
1685 return -EFAULT;
1688 return 0;
1691 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1692 static int
1693 mptctl_replace_fw (unsigned long arg)
1695 struct mpt_ioctl_replace_fw __user *uarg = (void __user *) arg;
1696 struct mpt_ioctl_replace_fw karg;
1697 MPT_ADAPTER *ioc;
1698 int iocnum;
1699 int newFwSize;
1701 dctlprintk(("mptctl_replace_fw called.\n"));
1702 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
1703 printk(KERN_ERR "%s@%d::mptctl_replace_fw - "
1704 "Unable to read in mpt_ioctl_replace_fw struct @ %p\n",
1705 __FILE__, __LINE__, uarg);
1706 return -EFAULT;
1709 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1710 (ioc == NULL)) {
1711 dctlprintk((KERN_ERR "%s::mptctl_replace_fw() @%d - ioc%d not found!\n",
1712 __FILE__, __LINE__, iocnum));
1713 return -ENODEV;
1716 /* If caching FW, Free the old FW image
1718 if (ioc->cached_fw == NULL)
1719 return 0;
1721 mpt_free_fw_memory(ioc);
1723 /* Allocate memory for the new FW image
1725 newFwSize = karg.newImageSize;
1727 if (newFwSize & 0x01)
1728 newFwSize += 1;
1729 if (newFwSize & 0x02)
1730 newFwSize += 2;
1732 mpt_alloc_fw_memory(ioc, newFwSize);
1733 if (ioc->cached_fw == NULL)
1734 return -ENOMEM;
1736 /* Copy the data from user memory to kernel space
1738 if (copy_from_user(ioc->cached_fw, uarg->newImage, newFwSize)) {
1739 printk(KERN_ERR "%s@%d::mptctl_replace_fw - "
1740 "Unable to read in mpt_ioctl_replace_fw image "
1741 "@ %p\n", __FILE__, __LINE__, uarg);
1742 mpt_free_fw_memory(ioc);
1743 return -EFAULT;
1746 /* Update IOCFactsReply
1748 ioc->facts.FWImageSize = newFwSize;
1749 return 0;
1752 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1753 /* MPT IOCTL MPTCOMMAND function.
1754 * Cast the arg into the mpt_ioctl_mpt_command structure.
1756 * Outputs: None.
1757 * Return: 0 if successful
1758 * -EBUSY if previous command timout and IOC reset is not complete.
1759 * -EFAULT if data unavailable
1760 * -ENODEV if no such device/adapter
1761 * -ETIME if timer expires
1762 * -ENOMEM if memory allocation error
1764 static int
1765 mptctl_mpt_command (unsigned long arg)
1767 struct mpt_ioctl_command __user *uarg = (void __user *) arg;
1768 struct mpt_ioctl_command karg;
1769 MPT_ADAPTER *ioc;
1770 int iocnum;
1771 int rc;
1773 dctlprintk(("mptctl_command called.\n"));
1775 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_command))) {
1776 printk(KERN_ERR "%s@%d::mptctl_mpt_command - "
1777 "Unable to read in mpt_ioctl_command struct @ %p\n",
1778 __FILE__, __LINE__, uarg);
1779 return -EFAULT;
1782 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1783 (ioc == NULL)) {
1784 dctlprintk((KERN_ERR "%s::mptctl_mpt_command() @%d - ioc%d not found!\n",
1785 __FILE__, __LINE__, iocnum));
1786 return -ENODEV;
1789 rc = mptctl_do_mpt_command (karg, &uarg->MF);
1791 return rc;
1794 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1795 /* Worker routine for the IOCTL MPTCOMMAND and MPTCOMMAND32 (sparc) commands.
1797 * Outputs: None.
1798 * Return: 0 if successful
1799 * -EBUSY if previous command timout and IOC reset is not complete.
1800 * -EFAULT if data unavailable
1801 * -ENODEV if no such device/adapter
1802 * -ETIME if timer expires
1803 * -ENOMEM if memory allocation error
1804 * -EPERM if SCSI I/O and target is untagged
1806 static int
1807 mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
1809 MPT_ADAPTER *ioc;
1810 MPT_FRAME_HDR *mf = NULL;
1811 MPIHeader_t *hdr;
1812 char *psge;
1813 struct buflist bufIn; /* data In buffer */
1814 struct buflist bufOut; /* data Out buffer */
1815 dma_addr_t dma_addr_in;
1816 dma_addr_t dma_addr_out;
1817 int sgSize = 0; /* Num SG elements */
1818 int iocnum, flagsLength;
1819 int sz, rc = 0;
1820 int msgContext;
1821 u16 req_idx;
1822 ulong timeout;
1824 dctlprintk(("mptctl_do_mpt_command called.\n"));
1825 bufIn.kptr = bufOut.kptr = NULL;
1827 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1828 (ioc == NULL)) {
1829 dctlprintk((KERN_ERR "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n",
1830 __FILE__, __LINE__, iocnum));
1831 return -ENODEV;
1833 if (!ioc->ioctl) {
1834 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1835 "No memory available during driver init.\n",
1836 __FILE__, __LINE__);
1837 return -ENOMEM;
1838 } else if (ioc->ioctl->status & MPT_IOCTL_STATUS_DID_IOCRESET) {
1839 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1840 "Busy with IOC Reset \n", __FILE__, __LINE__);
1841 return -EBUSY;
1844 /* Verify that the final request frame will not be too large.
1846 sz = karg.dataSgeOffset * 4;
1847 if (karg.dataInSize > 0)
1848 sz += sizeof(dma_addr_t) + sizeof(u32);
1849 if (karg.dataOutSize > 0)
1850 sz += sizeof(dma_addr_t) + sizeof(u32);
1852 if (sz > ioc->req_sz) {
1853 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1854 "Request frame too large (%d) maximum (%d)\n",
1855 __FILE__, __LINE__, sz, ioc->req_sz);
1856 return -EFAULT;
1859 /* Get a free request frame and save the message context.
1861 if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL)
1862 return -EAGAIN;
1864 hdr = (MPIHeader_t *) mf;
1865 msgContext = le32_to_cpu(hdr->MsgContext);
1866 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1868 /* Copy the request frame
1869 * Reset the saved message context.
1870 * Request frame in user space
1872 if (copy_from_user(mf, mfPtr, karg.dataSgeOffset * 4)) {
1873 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1874 "Unable to read MF from mpt_ioctl_command struct @ %p\n",
1875 __FILE__, __LINE__, mfPtr);
1876 rc = -EFAULT;
1877 goto done_free_mem;
1879 hdr->MsgContext = cpu_to_le32(msgContext);
1882 /* Verify that this request is allowed.
1884 switch (hdr->Function) {
1885 case MPI_FUNCTION_IOC_FACTS:
1886 case MPI_FUNCTION_PORT_FACTS:
1887 karg.dataOutSize = karg.dataInSize = 0;
1888 break;
1890 case MPI_FUNCTION_CONFIG:
1891 case MPI_FUNCTION_FC_COMMON_TRANSPORT_SEND:
1892 case MPI_FUNCTION_FC_EX_LINK_SRVC_SEND:
1893 case MPI_FUNCTION_FW_UPLOAD:
1894 case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR:
1895 case MPI_FUNCTION_FW_DOWNLOAD:
1896 case MPI_FUNCTION_FC_PRIMITIVE_SEND:
1897 case MPI_FUNCTION_TOOLBOX:
1898 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
1899 break;
1901 case MPI_FUNCTION_SCSI_IO_REQUEST:
1902 if (ioc->sh) {
1903 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
1904 VirtTarget *pTarget = NULL;
1905 MPT_SCSI_HOST *hd = NULL;
1906 int qtag = MPI_SCSIIO_CONTROL_UNTAGGED;
1907 int scsidir = 0;
1908 int target = (int) pScsiReq->TargetID;
1909 int dataSize;
1911 if ((target < 0) || (target >= ioc->sh->max_id)) {
1912 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1913 "Target ID out of bounds. \n",
1914 __FILE__, __LINE__);
1915 rc = -ENODEV;
1916 goto done_free_mem;
1919 pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
1920 pScsiReq->MsgFlags |= mpt_msg_flags();
1923 /* verify that app has not requested
1924 * more sense data than driver
1925 * can provide, if so, reset this parameter
1926 * set the sense buffer pointer low address
1927 * update the control field to specify Q type
1929 if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
1930 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1931 else
1932 pScsiReq->SenseBufferLength = karg.maxSenseBytes;
1934 pScsiReq->SenseBufferLowAddr =
1935 cpu_to_le32(ioc->sense_buf_low_dma
1936 + (req_idx * MPT_SENSE_BUFFER_ALLOC));
1938 if ((hd = (MPT_SCSI_HOST *) ioc->sh->hostdata)) {
1939 if (hd->Targets)
1940 pTarget = hd->Targets[target];
1943 if (pTarget &&(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
1944 qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
1946 /* Have the IOCTL driver set the direction based
1947 * on the dataOutSize (ordering issue with Sparc).
1949 if (karg.dataOutSize > 0) {
1950 scsidir = MPI_SCSIIO_CONTROL_WRITE;
1951 dataSize = karg.dataOutSize;
1952 } else {
1953 scsidir = MPI_SCSIIO_CONTROL_READ;
1954 dataSize = karg.dataInSize;
1957 pScsiReq->Control = cpu_to_le32(scsidir | qtag);
1958 pScsiReq->DataLength = cpu_to_le32(dataSize);
1960 ioc->ioctl->reset = MPTCTL_RESET_OK;
1961 ioc->ioctl->target = target;
1963 } else {
1964 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1965 "SCSI driver is not loaded. \n",
1966 __FILE__, __LINE__);
1967 rc = -EFAULT;
1968 goto done_free_mem;
1970 break;
1972 case MPI_FUNCTION_SMP_PASSTHROUGH:
1973 /* Check mf->PassthruFlags to determine if
1974 * transfer is ImmediateMode or not.
1975 * Immediate mode returns data in the ReplyFrame.
1976 * Else, we are sending request and response data
1977 * in two SGLs at the end of the mf.
1979 break;
1981 case MPI_FUNCTION_SATA_PASSTHROUGH:
1982 if (!ioc->sh) {
1983 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1984 "SCSI driver is not loaded. \n",
1985 __FILE__, __LINE__);
1986 rc = -EFAULT;
1987 goto done_free_mem;
1989 break;
1991 case MPI_FUNCTION_RAID_ACTION:
1992 /* Just add a SGE
1994 break;
1996 case MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
1997 if (ioc->sh) {
1998 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
1999 int qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
2000 int scsidir = MPI_SCSIIO_CONTROL_READ;
2001 int dataSize;
2003 pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
2004 pScsiReq->MsgFlags |= mpt_msg_flags();
2007 /* verify that app has not requested
2008 * more sense data than driver
2009 * can provide, if so, reset this parameter
2010 * set the sense buffer pointer low address
2011 * update the control field to specify Q type
2013 if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
2014 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
2015 else
2016 pScsiReq->SenseBufferLength = karg.maxSenseBytes;
2018 pScsiReq->SenseBufferLowAddr =
2019 cpu_to_le32(ioc->sense_buf_low_dma
2020 + (req_idx * MPT_SENSE_BUFFER_ALLOC));
2022 /* All commands to physical devices are tagged
2025 /* Have the IOCTL driver set the direction based
2026 * on the dataOutSize (ordering issue with Sparc).
2028 if (karg.dataOutSize > 0) {
2029 scsidir = MPI_SCSIIO_CONTROL_WRITE;
2030 dataSize = karg.dataOutSize;
2031 } else {
2032 scsidir = MPI_SCSIIO_CONTROL_READ;
2033 dataSize = karg.dataInSize;
2036 pScsiReq->Control = cpu_to_le32(scsidir | qtag);
2037 pScsiReq->DataLength = cpu_to_le32(dataSize);
2039 ioc->ioctl->reset = MPTCTL_RESET_OK;
2040 ioc->ioctl->target = pScsiReq->TargetID;
2041 } else {
2042 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2043 "SCSI driver is not loaded. \n",
2044 __FILE__, __LINE__);
2045 rc = -EFAULT;
2046 goto done_free_mem;
2048 break;
2050 case MPI_FUNCTION_SCSI_TASK_MGMT:
2052 MPT_SCSI_HOST *hd = NULL;
2053 if ((ioc->sh == NULL) || ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL)) {
2054 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2055 "SCSI driver not loaded or SCSI host not found. \n",
2056 __FILE__, __LINE__);
2057 rc = -EFAULT;
2058 goto done_free_mem;
2059 } else if (mptctl_set_tm_flags(hd) != 0) {
2060 rc = -EPERM;
2061 goto done_free_mem;
2064 break;
2066 case MPI_FUNCTION_IOC_INIT:
2068 IOCInit_t *pInit = (IOCInit_t *) mf;
2069 u32 high_addr, sense_high;
2071 /* Verify that all entries in the IOC INIT match
2072 * existing setup (and in LE format).
2074 if (sizeof(dma_addr_t) == sizeof(u64)) {
2075 high_addr = cpu_to_le32((u32)((u64)ioc->req_frames_dma >> 32));
2076 sense_high= cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2077 } else {
2078 high_addr = 0;
2079 sense_high= 0;
2082 if ((pInit->Flags != 0) || (pInit->MaxDevices != ioc->facts.MaxDevices) ||
2083 (pInit->MaxBuses != ioc->facts.MaxBuses) ||
2084 (pInit->ReplyFrameSize != cpu_to_le16(ioc->reply_sz)) ||
2085 (pInit->HostMfaHighAddr != high_addr) ||
2086 (pInit->SenseBufferHighAddr != sense_high)) {
2087 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2088 "IOC_INIT issued with 1 or more incorrect parameters. Rejected.\n",
2089 __FILE__, __LINE__);
2090 rc = -EFAULT;
2091 goto done_free_mem;
2094 break;
2095 default:
2097 * MPI_FUNCTION_PORT_ENABLE
2098 * MPI_FUNCTION_TARGET_CMD_BUFFER_POST
2099 * MPI_FUNCTION_TARGET_ASSIST
2100 * MPI_FUNCTION_TARGET_STATUS_SEND
2101 * MPI_FUNCTION_TARGET_MODE_ABORT
2102 * MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
2103 * MPI_FUNCTION_IO_UNIT_RESET
2104 * MPI_FUNCTION_HANDSHAKE
2105 * MPI_FUNCTION_REPLY_FRAME_REMOVAL
2106 * MPI_FUNCTION_EVENT_NOTIFICATION
2107 * (driver handles event notification)
2108 * MPI_FUNCTION_EVENT_ACK
2111 /* What to do with these??? CHECK ME!!!
2112 MPI_FUNCTION_FC_LINK_SRVC_BUF_POST
2113 MPI_FUNCTION_FC_LINK_SRVC_RSP
2114 MPI_FUNCTION_FC_ABORT
2115 MPI_FUNCTION_LAN_SEND
2116 MPI_FUNCTION_LAN_RECEIVE
2117 MPI_FUNCTION_LAN_RESET
2120 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2121 "Illegal request (function 0x%x) \n",
2122 __FILE__, __LINE__, hdr->Function);
2123 rc = -EFAULT;
2124 goto done_free_mem;
2127 /* Add the SGL ( at most one data in SGE and one data out SGE )
2128 * In the case of two SGE's - the data out (write) will always
2129 * preceede the data in (read) SGE. psgList is used to free the
2130 * allocated memory.
2132 psge = (char *) (((int *) mf) + karg.dataSgeOffset);
2133 flagsLength = 0;
2135 /* bufIn and bufOut are used for user to kernel space transfers
2137 bufIn.kptr = bufOut.kptr = NULL;
2138 bufIn.len = bufOut.len = 0;
2140 if (karg.dataOutSize > 0)
2141 sgSize ++;
2143 if (karg.dataInSize > 0)
2144 sgSize ++;
2146 if (sgSize > 0) {
2148 /* Set up the dataOut memory allocation */
2149 if (karg.dataOutSize > 0) {
2150 if (karg.dataInSize > 0) {
2151 flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2152 MPI_SGE_FLAGS_END_OF_BUFFER |
2153 MPI_SGE_FLAGS_DIRECTION |
2154 mpt_addr_size() )
2155 << MPI_SGE_FLAGS_SHIFT;
2156 } else {
2157 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
2159 flagsLength |= karg.dataOutSize;
2160 bufOut.len = karg.dataOutSize;
2161 bufOut.kptr = pci_alloc_consistent(
2162 ioc->pcidev, bufOut.len, &dma_addr_out);
2164 if (bufOut.kptr == NULL) {
2165 rc = -ENOMEM;
2166 goto done_free_mem;
2167 } else {
2168 /* Set up this SGE.
2169 * Copy to MF and to sglbuf
2171 mpt_add_sge(psge, flagsLength, dma_addr_out);
2172 psge += (sizeof(u32) + sizeof(dma_addr_t));
2174 /* Copy user data to kernel space.
2176 if (copy_from_user(bufOut.kptr,
2177 karg.dataOutBufPtr,
2178 bufOut.len)) {
2179 printk(KERN_ERR
2180 "%s@%d::mptctl_do_mpt_command - Unable "
2181 "to read user data "
2182 "struct @ %p\n",
2183 __FILE__, __LINE__,karg.dataOutBufPtr);
2184 rc = -EFAULT;
2185 goto done_free_mem;
2190 if (karg.dataInSize > 0) {
2191 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
2192 flagsLength |= karg.dataInSize;
2194 bufIn.len = karg.dataInSize;
2195 bufIn.kptr = pci_alloc_consistent(ioc->pcidev,
2196 bufIn.len, &dma_addr_in);
2198 if (bufIn.kptr == NULL) {
2199 rc = -ENOMEM;
2200 goto done_free_mem;
2201 } else {
2202 /* Set up this SGE
2203 * Copy to MF and to sglbuf
2205 mpt_add_sge(psge, flagsLength, dma_addr_in);
2208 } else {
2209 /* Add a NULL SGE
2211 mpt_add_sge(psge, flagsLength, (dma_addr_t) -1);
2214 ioc->ioctl->wait_done = 0;
2215 if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
2217 DBG_DUMP_TM_REQUEST_FRAME((u32 *)mf);
2219 if (mpt_send_handshake_request(mptctl_id, ioc,
2220 sizeof(SCSITaskMgmt_t), (u32*)mf,
2221 CAN_SLEEP) != 0) {
2222 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
2223 " (ioc %p, mf %p) \n", ioc->name,
2224 ioc, mf));
2225 mptctl_free_tm_flags(ioc);
2226 rc = -ENODATA;
2227 goto done_free_mem;
2230 } else
2231 mpt_put_msg_frame(mptctl_id, ioc, mf);
2233 /* Now wait for the command to complete */
2234 timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT;
2235 timeout = wait_event_timeout(mptctl_wait,
2236 ioc->ioctl->wait_done == 1,
2237 HZ*timeout);
2239 if(timeout <=0 && (ioc->ioctl->wait_done != 1 )) {
2240 /* Now we need to reset the board */
2242 if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT)
2243 mptctl_free_tm_flags(ioc);
2245 mptctl_timeout_expired(ioc->ioctl);
2246 rc = -ENODATA;
2247 goto done_free_mem;
2250 mf = NULL;
2252 /* If a valid reply frame, copy to the user.
2253 * Offset 2: reply length in U32's
2255 if (ioc->ioctl->status & MPT_IOCTL_STATUS_RF_VALID) {
2256 if (karg.maxReplyBytes < ioc->reply_sz) {
2257 sz = min(karg.maxReplyBytes, 4*ioc->ioctl->ReplyFrame[2]);
2258 } else {
2259 sz = min(ioc->reply_sz, 4*ioc->ioctl->ReplyFrame[2]);
2262 if (sz > 0) {
2263 if (copy_to_user(karg.replyFrameBufPtr,
2264 &ioc->ioctl->ReplyFrame, sz)){
2265 printk(KERN_ERR
2266 "%s@%d::mptctl_do_mpt_command - "
2267 "Unable to write out reply frame %p\n",
2268 __FILE__, __LINE__, karg.replyFrameBufPtr);
2269 rc = -ENODATA;
2270 goto done_free_mem;
2275 /* If valid sense data, copy to user.
2277 if (ioc->ioctl->status & MPT_IOCTL_STATUS_SENSE_VALID) {
2278 sz = min(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE);
2279 if (sz > 0) {
2280 if (copy_to_user(karg.senseDataPtr, ioc->ioctl->sense, sz)) {
2281 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2282 "Unable to write sense data to user %p\n",
2283 __FILE__, __LINE__,
2284 karg.senseDataPtr);
2285 rc = -ENODATA;
2286 goto done_free_mem;
2291 /* If the overall status is _GOOD and data in, copy data
2292 * to user.
2294 if ((ioc->ioctl->status & MPT_IOCTL_STATUS_COMMAND_GOOD) &&
2295 (karg.dataInSize > 0) && (bufIn.kptr)) {
2297 if (copy_to_user(karg.dataInBufPtr,
2298 bufIn.kptr, karg.dataInSize)) {
2299 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2300 "Unable to write data to user %p\n",
2301 __FILE__, __LINE__,
2302 karg.dataInBufPtr);
2303 rc = -ENODATA;
2307 done_free_mem:
2309 ioc->ioctl->status &= ~(MPT_IOCTL_STATUS_COMMAND_GOOD |
2310 MPT_IOCTL_STATUS_SENSE_VALID |
2311 MPT_IOCTL_STATUS_RF_VALID );
2313 /* Free the allocated memory.
2315 if (bufOut.kptr != NULL) {
2316 pci_free_consistent(ioc->pcidev,
2317 bufOut.len, (void *) bufOut.kptr, dma_addr_out);
2320 if (bufIn.kptr != NULL) {
2321 pci_free_consistent(ioc->pcidev,
2322 bufIn.len, (void *) bufIn.kptr, dma_addr_in);
2325 /* mf is null if command issued successfully
2326 * otherwise, failure occured after mf acquired.
2328 if (mf)
2329 mpt_free_msg_frame(ioc, mf);
2331 return rc;
2334 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2335 /* Prototype Routine for the HP HOST INFO command.
2337 * Outputs: None.
2338 * Return: 0 if successful
2339 * -EFAULT if data unavailable
2340 * -EBUSY if previous command timout and IOC reset is not complete.
2341 * -ENODEV if no such device/adapter
2342 * -ETIME if timer expires
2343 * -ENOMEM if memory allocation error
2345 static int
2346 mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
2348 hp_host_info_t __user *uarg = (void __user *) arg;
2349 MPT_ADAPTER *ioc;
2350 struct pci_dev *pdev;
2351 char *pbuf=NULL;
2352 dma_addr_t buf_dma;
2353 hp_host_info_t karg;
2354 CONFIGPARMS cfg;
2355 ConfigPageHeader_t hdr;
2356 int iocnum;
2357 int rc, cim_rev;
2358 ToolboxIstwiReadWriteRequest_t *IstwiRWRequest;
2359 MPT_FRAME_HDR *mf = NULL;
2360 MPIHeader_t *mpi_hdr;
2362 dctlprintk((": mptctl_hp_hostinfo called.\n"));
2363 /* Reset long to int. Should affect IA64 and SPARC only
2365 if (data_size == sizeof(hp_host_info_t))
2366 cim_rev = 1;
2367 else if (data_size == sizeof(hp_host_info_rev0_t))
2368 cim_rev = 0; /* obsolete */
2369 else
2370 return -EFAULT;
2372 if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) {
2373 printk(KERN_ERR "%s@%d::mptctl_hp_host_info - "
2374 "Unable to read in hp_host_info struct @ %p\n",
2375 __FILE__, __LINE__, uarg);
2376 return -EFAULT;
2379 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
2380 (ioc == NULL)) {
2381 dctlprintk((KERN_ERR "%s::mptctl_hp_hostinfo() @%d - ioc%d not found!\n",
2382 __FILE__, __LINE__, iocnum));
2383 return -ENODEV;
2386 /* Fill in the data and return the structure to the calling
2387 * program
2389 pdev = (struct pci_dev *) ioc->pcidev;
2391 karg.vendor = pdev->vendor;
2392 karg.device = pdev->device;
2393 karg.subsystem_id = pdev->subsystem_device;
2394 karg.subsystem_vendor = pdev->subsystem_vendor;
2395 karg.devfn = pdev->devfn;
2396 karg.bus = pdev->bus->number;
2398 /* Save the SCSI host no. if
2399 * SCSI driver loaded
2401 if (ioc->sh != NULL)
2402 karg.host_no = ioc->sh->host_no;
2403 else
2404 karg.host_no = -1;
2406 /* Reformat the fw_version into a string
2408 karg.fw_version[0] = ioc->facts.FWVersion.Struct.Major >= 10 ?
2409 ((ioc->facts.FWVersion.Struct.Major / 10) + '0') : '0';
2410 karg.fw_version[1] = (ioc->facts.FWVersion.Struct.Major % 10 ) + '0';
2411 karg.fw_version[2] = '.';
2412 karg.fw_version[3] = ioc->facts.FWVersion.Struct.Minor >= 10 ?
2413 ((ioc->facts.FWVersion.Struct.Minor / 10) + '0') : '0';
2414 karg.fw_version[4] = (ioc->facts.FWVersion.Struct.Minor % 10 ) + '0';
2415 karg.fw_version[5] = '.';
2416 karg.fw_version[6] = ioc->facts.FWVersion.Struct.Unit >= 10 ?
2417 ((ioc->facts.FWVersion.Struct.Unit / 10) + '0') : '0';
2418 karg.fw_version[7] = (ioc->facts.FWVersion.Struct.Unit % 10 ) + '0';
2419 karg.fw_version[8] = '.';
2420 karg.fw_version[9] = ioc->facts.FWVersion.Struct.Dev >= 10 ?
2421 ((ioc->facts.FWVersion.Struct.Dev / 10) + '0') : '0';
2422 karg.fw_version[10] = (ioc->facts.FWVersion.Struct.Dev % 10 ) + '0';
2423 karg.fw_version[11] = '\0';
2425 /* Issue a config request to get the device serial number
2427 hdr.PageVersion = 0;
2428 hdr.PageLength = 0;
2429 hdr.PageNumber = 0;
2430 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
2431 cfg.cfghdr.hdr = &hdr;
2432 cfg.physAddr = -1;
2433 cfg.pageAddr = 0;
2434 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2435 cfg.dir = 0; /* read */
2436 cfg.timeout = 10;
2438 strncpy(karg.serial_number, " ", 24);
2439 if (mpt_config(ioc, &cfg) == 0) {
2440 if (cfg.cfghdr.hdr->PageLength > 0) {
2441 /* Issue the second config page request */
2442 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2444 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
2445 if (pbuf) {
2446 cfg.physAddr = buf_dma;
2447 if (mpt_config(ioc, &cfg) == 0) {
2448 ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf;
2449 if (strlen(pdata->BoardTracerNumber) > 1) {
2450 strncpy(karg.serial_number, pdata->BoardTracerNumber, 24);
2451 karg.serial_number[24-1]='\0';
2454 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
2455 pbuf = NULL;
2459 rc = mpt_GetIocState(ioc, 1);
2460 switch (rc) {
2461 case MPI_IOC_STATE_OPERATIONAL:
2462 karg.ioc_status = HP_STATUS_OK;
2463 break;
2465 case MPI_IOC_STATE_FAULT:
2466 karg.ioc_status = HP_STATUS_FAILED;
2467 break;
2469 case MPI_IOC_STATE_RESET:
2470 case MPI_IOC_STATE_READY:
2471 default:
2472 karg.ioc_status = HP_STATUS_OTHER;
2473 break;
2476 karg.base_io_addr = pci_resource_start(pdev, 0);
2478 if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))
2479 karg.bus_phys_width = HP_BUS_WIDTH_UNK;
2480 else
2481 karg.bus_phys_width = HP_BUS_WIDTH_16;
2483 karg.hard_resets = 0;
2484 karg.soft_resets = 0;
2485 karg.timeouts = 0;
2486 if (ioc->sh != NULL) {
2487 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2489 if (hd && (cim_rev == 1)) {
2490 karg.hard_resets = hd->hard_resets;
2491 karg.soft_resets = hd->soft_resets;
2492 karg.timeouts = hd->timeouts;
2497 * Gather ISTWI(Industry Standard Two Wire Interface) Data
2499 if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) {
2500 dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
2501 ioc->name,__FUNCTION__));
2502 goto out;
2505 IstwiRWRequest = (ToolboxIstwiReadWriteRequest_t *)mf;
2506 mpi_hdr = (MPIHeader_t *) mf;
2507 memset(IstwiRWRequest,0,sizeof(ToolboxIstwiReadWriteRequest_t));
2508 IstwiRWRequest->Function = MPI_FUNCTION_TOOLBOX;
2509 IstwiRWRequest->Tool = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
2510 IstwiRWRequest->MsgContext = mpi_hdr->MsgContext;
2511 IstwiRWRequest->Flags = MPI_TB_ISTWI_FLAGS_READ;
2512 IstwiRWRequest->NumAddressBytes = 0x01;
2513 IstwiRWRequest->DataLength = cpu_to_le16(0x04);
2514 if (pdev->devfn & 1)
2515 IstwiRWRequest->DeviceAddr = 0xB2;
2516 else
2517 IstwiRWRequest->DeviceAddr = 0xB0;
2519 pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma);
2520 if (!pbuf)
2521 goto out;
2522 mpt_add_sge((char *)&IstwiRWRequest->SGL,
2523 (MPT_SGE_FLAGS_SSIMPLE_READ|4), buf_dma);
2525 ioc->ioctl->wait_done = 0;
2526 mpt_put_msg_frame(mptctl_id, ioc, mf);
2528 rc = wait_event_timeout(mptctl_wait,
2529 ioc->ioctl->wait_done == 1,
2530 HZ*MPT_IOCTL_DEFAULT_TIMEOUT /* 10 sec */);
2532 if(rc <=0 && (ioc->ioctl->wait_done != 1 )) {
2534 * Now we need to reset the board
2536 mpt_free_msg_frame(ioc, mf);
2537 mptctl_timeout_expired(ioc->ioctl);
2538 goto out;
2542 *ISTWI Data Definition
2543 * pbuf[0] = FW_VERSION = 0x4
2544 * pbuf[1] = Bay Count = 6 or 4 or 2, depending on
2545 * the config, you should be seeing one out of these three values
2546 * pbuf[2] = Drive Installed Map = bit pattern depend on which
2547 * bays have drives in them
2548 * pbuf[3] = Checksum (0x100 = (byte0 + byte2 + byte3)
2550 if (ioc->ioctl->status & MPT_IOCTL_STATUS_RF_VALID)
2551 karg.rsvd = *(u32 *)pbuf;
2553 out:
2554 if (pbuf)
2555 pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma);
2557 /* Copy the data from kernel memory to user memory
2559 if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) {
2560 printk(KERN_ERR "%s@%d::mptctl_hpgethostinfo - "
2561 "Unable to write out hp_host_info @ %p\n",
2562 __FILE__, __LINE__, uarg);
2563 return -EFAULT;
2566 return 0;
2570 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2571 /* Prototype Routine for the HP TARGET INFO command.
2573 * Outputs: None.
2574 * Return: 0 if successful
2575 * -EFAULT if data unavailable
2576 * -EBUSY if previous command timout and IOC reset is not complete.
2577 * -ENODEV if no such device/adapter
2578 * -ETIME if timer expires
2579 * -ENOMEM if memory allocation error
2581 static int
2582 mptctl_hp_targetinfo(unsigned long arg)
2584 hp_target_info_t __user *uarg = (void __user *) arg;
2585 SCSIDevicePage0_t *pg0_alloc;
2586 SCSIDevicePage3_t *pg3_alloc;
2587 MPT_ADAPTER *ioc;
2588 MPT_SCSI_HOST *hd = NULL;
2589 hp_target_info_t karg;
2590 int iocnum;
2591 int data_sz;
2592 dma_addr_t page_dma;
2593 CONFIGPARMS cfg;
2594 ConfigPageHeader_t hdr;
2595 int tmp, np, rc = 0;
2597 dctlprintk((": mptctl_hp_targetinfo called.\n"));
2598 if (copy_from_user(&karg, uarg, sizeof(hp_target_info_t))) {
2599 printk(KERN_ERR "%s@%d::mptctl_hp_targetinfo - "
2600 "Unable to read in hp_host_targetinfo struct @ %p\n",
2601 __FILE__, __LINE__, uarg);
2602 return -EFAULT;
2605 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
2606 (ioc == NULL)) {
2607 dctlprintk((KERN_ERR "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n",
2608 __FILE__, __LINE__, iocnum));
2609 return -ENODEV;
2612 /* There is nothing to do for FCP parts.
2614 if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))
2615 return 0;
2617 if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL))
2618 return 0;
2620 if (ioc->sh->host_no != karg.hdr.host)
2621 return -ENODEV;
2623 /* Get the data transfer speeds
2625 data_sz = ioc->spi_data.sdp0length * 4;
2626 pg0_alloc = (SCSIDevicePage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
2627 if (pg0_alloc) {
2628 hdr.PageVersion = ioc->spi_data.sdp0version;
2629 hdr.PageLength = data_sz;
2630 hdr.PageNumber = 0;
2631 hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
2633 cfg.cfghdr.hdr = &hdr;
2634 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2635 cfg.dir = 0;
2636 cfg.timeout = 0;
2637 cfg.physAddr = page_dma;
2639 cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
2641 if ((rc = mpt_config(ioc, &cfg)) == 0) {
2642 np = le32_to_cpu(pg0_alloc->NegotiatedParameters);
2643 karg.negotiated_width = np & MPI_SCSIDEVPAGE0_NP_WIDE ?
2644 HP_BUS_WIDTH_16 : HP_BUS_WIDTH_8;
2646 if (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) {
2647 tmp = (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
2648 if (tmp < 0x09)
2649 karg.negotiated_speed = HP_DEV_SPEED_ULTRA320;
2650 else if (tmp <= 0x09)
2651 karg.negotiated_speed = HP_DEV_SPEED_ULTRA160;
2652 else if (tmp <= 0x0A)
2653 karg.negotiated_speed = HP_DEV_SPEED_ULTRA2;
2654 else if (tmp <= 0x0C)
2655 karg.negotiated_speed = HP_DEV_SPEED_ULTRA;
2656 else if (tmp <= 0x25)
2657 karg.negotiated_speed = HP_DEV_SPEED_FAST;
2658 else
2659 karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
2660 } else
2661 karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
2664 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg0_alloc, page_dma);
2667 /* Set defaults
2669 karg.message_rejects = -1;
2670 karg.phase_errors = -1;
2671 karg.parity_errors = -1;
2672 karg.select_timeouts = -1;
2674 /* Get the target error parameters
2676 hdr.PageVersion = 0;
2677 hdr.PageLength = 0;
2678 hdr.PageNumber = 3;
2679 hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
2681 cfg.cfghdr.hdr = &hdr;
2682 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2683 cfg.dir = 0;
2684 cfg.timeout = 0;
2685 cfg.physAddr = -1;
2686 if ((mpt_config(ioc, &cfg) == 0) && (cfg.cfghdr.hdr->PageLength > 0)) {
2687 /* Issue the second config page request */
2688 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2689 data_sz = (int) cfg.cfghdr.hdr->PageLength * 4;
2690 pg3_alloc = (SCSIDevicePage3_t *) pci_alloc_consistent(
2691 ioc->pcidev, data_sz, &page_dma);
2692 if (pg3_alloc) {
2693 cfg.physAddr = page_dma;
2694 cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
2695 if ((rc = mpt_config(ioc, &cfg)) == 0) {
2696 karg.message_rejects = (u32) le16_to_cpu(pg3_alloc->MsgRejectCount);
2697 karg.phase_errors = (u32) le16_to_cpu(pg3_alloc->PhaseErrorCount);
2698 karg.parity_errors = (u32) le16_to_cpu(pg3_alloc->ParityErrorCount);
2700 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg3_alloc, page_dma);
2703 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2704 if (hd != NULL)
2705 karg.select_timeouts = hd->sel_timeout[karg.hdr.id];
2707 /* Copy the data from kernel memory to user memory
2709 if (copy_to_user((char __user *)arg, &karg, sizeof(hp_target_info_t))) {
2710 printk(KERN_ERR "%s@%d::mptctl_hp_target_info - "
2711 "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
2712 __FILE__, __LINE__, uarg);
2713 return -EFAULT;
2716 return 0;
2719 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2721 static struct file_operations mptctl_fops = {
2722 .owner = THIS_MODULE,
2723 .llseek = no_llseek,
2724 .release = mptctl_release,
2725 .fasync = mptctl_fasync,
2726 .unlocked_ioctl = mptctl_ioctl,
2727 #ifdef CONFIG_COMPAT
2728 .compat_ioctl = compat_mpctl_ioctl,
2729 #endif
2732 static struct miscdevice mptctl_miscdev = {
2733 MPT_MINOR,
2734 MYNAM,
2735 &mptctl_fops
2738 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2740 #ifdef CONFIG_COMPAT
2742 static int
2743 compat_mptfwxfer_ioctl(struct file *filp, unsigned int cmd,
2744 unsigned long arg)
2746 struct mpt_fw_xfer32 kfw32;
2747 struct mpt_fw_xfer kfw;
2748 MPT_ADAPTER *iocp = NULL;
2749 int iocnum, iocnumX;
2750 int nonblock = (filp->f_flags & O_NONBLOCK);
2751 int ret;
2753 dctlprintk((KERN_INFO MYNAM "::compat_mptfwxfer_ioctl() called\n"));
2755 if (copy_from_user(&kfw32, (char __user *)arg, sizeof(kfw32)))
2756 return -EFAULT;
2758 /* Verify intended MPT adapter */
2759 iocnumX = kfw32.iocnum & 0xFF;
2760 if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
2761 (iocp == NULL)) {
2762 dctlprintk((KERN_ERR MYNAM "::compat_mptfwxfer_ioctl @%d - ioc%d not found!\n",
2763 __LINE__, iocnumX));
2764 return -ENODEV;
2767 if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
2768 return ret;
2770 kfw.iocnum = iocnum;
2771 kfw.fwlen = kfw32.fwlen;
2772 kfw.bufp = compat_ptr(kfw32.bufp);
2774 ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);
2776 mutex_unlock(&iocp->ioctl->ioctl_mutex);
2778 return ret;
2781 static int
2782 compat_mpt_command(struct file *filp, unsigned int cmd,
2783 unsigned long arg)
2785 struct mpt_ioctl_command32 karg32;
2786 struct mpt_ioctl_command32 __user *uarg = (struct mpt_ioctl_command32 __user *) arg;
2787 struct mpt_ioctl_command karg;
2788 MPT_ADAPTER *iocp = NULL;
2789 int iocnum, iocnumX;
2790 int nonblock = (filp->f_flags & O_NONBLOCK);
2791 int ret;
2793 dctlprintk((KERN_INFO MYNAM "::compat_mpt_command() called\n"));
2795 if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32)))
2796 return -EFAULT;
2798 /* Verify intended MPT adapter */
2799 iocnumX = karg32.hdr.iocnum & 0xFF;
2800 if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
2801 (iocp == NULL)) {
2802 dctlprintk((KERN_ERR MYNAM "::compat_mpt_command @%d - ioc%d not found!\n",
2803 __LINE__, iocnumX));
2804 return -ENODEV;
2807 if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
2808 return ret;
2810 /* Copy data to karg */
2811 karg.hdr.iocnum = karg32.hdr.iocnum;
2812 karg.hdr.port = karg32.hdr.port;
2813 karg.timeout = karg32.timeout;
2814 karg.maxReplyBytes = karg32.maxReplyBytes;
2816 karg.dataInSize = karg32.dataInSize;
2817 karg.dataOutSize = karg32.dataOutSize;
2818 karg.maxSenseBytes = karg32.maxSenseBytes;
2819 karg.dataSgeOffset = karg32.dataSgeOffset;
2821 karg.replyFrameBufPtr = (char __user *)(unsigned long)karg32.replyFrameBufPtr;
2822 karg.dataInBufPtr = (char __user *)(unsigned long)karg32.dataInBufPtr;
2823 karg.dataOutBufPtr = (char __user *)(unsigned long)karg32.dataOutBufPtr;
2824 karg.senseDataPtr = (char __user *)(unsigned long)karg32.senseDataPtr;
2826 /* Pass new structure to do_mpt_command
2828 ret = mptctl_do_mpt_command (karg, &uarg->MF);
2830 mutex_unlock(&iocp->ioctl->ioctl_mutex);
2832 return ret;
2835 static long compat_mpctl_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
2837 long ret;
2838 lock_kernel();
2839 switch (cmd) {
2840 case MPTIOCINFO:
2841 case MPTIOCINFO1:
2842 case MPTIOCINFO2:
2843 case MPTTARGETINFO:
2844 case MPTEVENTQUERY:
2845 case MPTEVENTENABLE:
2846 case MPTEVENTREPORT:
2847 case MPTHARDRESET:
2848 case HP_GETHOSTINFO:
2849 case HP_GETTARGETINFO:
2850 case MPTTEST:
2851 ret = __mptctl_ioctl(f, cmd, arg);
2852 break;
2853 case MPTCOMMAND32:
2854 ret = compat_mpt_command(f, cmd, arg);
2855 break;
2856 case MPTFWDOWNLOAD32:
2857 ret = compat_mptfwxfer_ioctl(f, cmd, arg);
2858 break;
2859 default:
2860 ret = -ENOIOCTLCMD;
2861 break;
2863 unlock_kernel();
2864 return ret;
2867 #endif
2870 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2872 * mptctl_probe - Installs ioctl devices per bus.
2873 * @pdev: Pointer to pci_dev structure
2875 * Returns 0 for success, non-zero for failure.
2879 static int
2880 mptctl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2882 int err;
2883 int sz;
2884 u8 *mem;
2885 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2888 * Allocate and inite a MPT_IOCTL structure
2890 sz = sizeof (MPT_IOCTL);
2891 mem = kmalloc(sz, GFP_KERNEL);
2892 if (mem == NULL) {
2893 err = -ENOMEM;
2894 goto out_fail;
2897 memset(mem, 0, sz);
2898 ioc->ioctl = (MPT_IOCTL *) mem;
2899 ioc->ioctl->ioc = ioc;
2900 mutex_init(&ioc->ioctl->ioctl_mutex);
2901 return 0;
2903 out_fail:
2905 mptctl_remove(pdev);
2906 return err;
2909 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2911 * mptctl_remove - Removed ioctl devices
2912 * @pdev: Pointer to pci_dev structure
2916 static void
2917 mptctl_remove(struct pci_dev *pdev)
2919 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2921 kfree ( ioc->ioctl );
2924 static struct mpt_pci_driver mptctl_driver = {
2925 .probe = mptctl_probe,
2926 .remove = mptctl_remove,
2929 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2930 static int __init mptctl_init(void)
2932 int err;
2933 int where = 1;
2935 show_mptmod_ver(my_NAME, my_VERSION);
2937 if(mpt_device_driver_register(&mptctl_driver,
2938 MPTCTL_DRIVER) != 0 ) {
2939 dprintk((KERN_INFO MYNAM
2940 ": failed to register dd callbacks\n"));
2943 /* Register this device */
2944 err = misc_register(&mptctl_miscdev);
2945 if (err < 0) {
2946 printk(KERN_ERR MYNAM ": Can't register misc device [minor=%d].\n", MPT_MINOR);
2947 goto out_fail;
2949 printk(KERN_INFO MYNAM ": Registered with Fusion MPT base driver\n");
2950 printk(KERN_INFO MYNAM ": /dev/%s @ (major,minor=%d,%d)\n",
2951 mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
2954 * Install our handler
2956 ++where;
2957 if ((mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER)) < 0) {
2958 printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
2959 misc_deregister(&mptctl_miscdev);
2960 err = -EBUSY;
2961 goto out_fail;
2964 if (mpt_reset_register(mptctl_id, mptctl_ioc_reset) == 0) {
2965 dprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
2966 } else {
2967 /* FIXME! */
2970 if (mpt_event_register(mptctl_id, mptctl_event_process) == 0) {
2971 devtverboseprintk((KERN_INFO MYNAM
2972 ": Registered for IOC event notifications\n"));
2975 return 0;
2977 out_fail:
2979 mpt_device_driver_deregister(MPTCTL_DRIVER);
2981 return err;
2984 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2985 static void mptctl_exit(void)
2987 misc_deregister(&mptctl_miscdev);
2988 printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n",
2989 mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
2991 /* De-register reset handler from base module */
2992 mpt_reset_deregister(mptctl_id);
2993 dprintk((KERN_INFO MYNAM ": Deregistered for IOC reset notifications\n"));
2995 /* De-register callback handler from base module */
2996 mpt_deregister(mptctl_id);
2997 printk(KERN_INFO MYNAM ": Deregistered from Fusion MPT base driver\n");
2999 mpt_device_driver_deregister(MPTCTL_DRIVER);
3003 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3005 module_init(mptctl_init);
3006 module_exit(mptctl_exit);