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