1 /*
2  *  linux/drivers/message/fusion/mptctl.c
3  *      Fusion MPT misc device (ioctl) driver.
4  *      For use with PCI chip/adapter(s):
5  *          LSIFC9xx/LSI409xx Fibre Channel
6  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
7  *
8  *  Credits:
9  *      This driver would not exist if not for Alan Cox's development
10  *      of the linux i2o driver.
11  *
12  *      A special thanks to Pamela Delaney (LSI Logic) for tons of work
13  *      and countless enhancements while adding support for the 1030
14  *      chip family.  Pam has been instrumental in the development of
15  *      of the 2.xx.xx series fusion drivers, and her contributions are
16  *      far too numerous to hope to list in one place.
17  *
18  *      A huge debt of gratitude is owed to David S. Miller (DaveM)
19  *      for fixing much of the stupid and broken stuff in the early
20  *      driver while porting to sparc64 platform.  THANK YOU!
21  *
22  *      A big THANKS to Eddie C. Dost for fixing the ioctl path
23  *      and most importantly f/w download on sparc64 platform!
24  *      (plus Eddie's other helpful hints and insights)
25  *
26  *      Thanks to Arnaldo Carvalho de Melo for finding and patching
27  *      a potential memory leak in mptctl_do_fw_download(),
28  *      and for some kmalloc insight:-)
29  *
30  *      (see also mptbase.c)
31  *
32  *  Copyright (c) 1999-2004 LSI Logic Corporation
33  *  Originally By: Steven J. Ralston, Noah Romer
34  *  (mailto:sjralston1@netscape.net)
35  *  (mailto:mpt_linux_developer@lsil.com)
36  *
37  *  $Id: mptctl.c,v 1.66 2003/05/07 14:08:32 pdelaney Exp $
38  */
39 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
40 /*
41     This program is free software; you can redistribute it and/or modify
42     it under the terms of the GNU General Public License as published by
43     the Free Software Foundation; version 2 of the License.
44 
45     This program is distributed in the hope that it will be useful,
46     but WITHOUT ANY WARRANTY; without even the implied warranty of
47     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
48     GNU General Public License for more details.
49 
50     NO WARRANTY
51     THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
52     CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
53     LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
54     MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
55     solely responsible for determining the appropriateness of using and
56     distributing the Program and assumes all risks associated with its
57     exercise of rights under this Agreement, including but not limited to
58     the risks and costs of program errors, damage to or loss of data,
59     programs or equipment, and unavailability or interruption of operations.
60 
61     DISCLAIMER OF LIABILITY
62     NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
63     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64     DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
65     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
66     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
67     USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
68     HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
69 
70     You should have received a copy of the GNU General Public License
71     along with this program; if not, write to the Free Software
72     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
73 */
74 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
75 
76 #include <linux/version.h>
77 #include <linux/kernel.h>
78 #include <linux/module.h>
79 #include <linux/errno.h>
80 #include <linux/init.h>
81 #include <linux/slab.h>
82 #include <linux/types.h>
83 #include <linux/pci.h>
84 #include <linux/miscdevice.h>
85 #include <linux/smp_lock.h>
86 
87 #include <asm/io.h>
88 #include <asm/uaccess.h>
89 
90 #include <linux/kdev_t.h>	/* needed for access to Scsi_Host struct */
91 #include <linux/blkdev.h>
92 #include <linux/blk.h>          /* for io_request_lock (spinlock) decl */
93 #include "../../scsi/scsi.h"
94 #include "../../scsi/hosts.h"
95 
96 #define COPYRIGHT	"Copyright (c) 1999-2004 LSI Logic Corporation"
97 #define MODULEAUTHOR	"Steven J. Ralston, Noah Romer, Pamela Delaney"
98 #include "mptbase.h"
99 #include "mptctl.h"
100 
101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
102 #define my_NAME		"Fusion MPT misc device (ioctl) driver"
103 #define my_VERSION	MPT_LINUX_VERSION_COMMON
104 #define MYNAM		"mptctl"
105 
106 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,62)
107 EXPORT_NO_SYMBOLS;
108 #endif
109 MODULE_AUTHOR(MODULEAUTHOR);
110 MODULE_DESCRIPTION(my_NAME);
111 MODULE_LICENSE("GPL");
112 
113 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
114 
115 static int mptctl_id = -1;
116 static struct semaphore mptctl_syscall_sem_ioc[MPT_MAX_ADAPTERS];
117 
118 static DECLARE_WAIT_QUEUE_HEAD ( mptctl_wait );
119 
120 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
121 
122 struct buflist {
123 	u8	*kptr;
124 	int	 len;
125 };
126 
127 /*
128  * Function prototypes. Called from OS entry point mptctl_ioctl.
129  * arg contents specific to function.
130  */
131 static int mptctl_fw_download(unsigned long arg);
132 static int mptctl_getiocinfo (unsigned long arg, unsigned int cmd);
133 static int mptctl_gettargetinfo (unsigned long arg);
134 static int mptctl_readtest (unsigned long arg);
135 static int mptctl_mpt_command (unsigned long arg);
136 static int mptctl_eventquery (unsigned long arg);
137 static int mptctl_eventenable (unsigned long arg);
138 static int mptctl_eventreport (unsigned long arg);
139 static int mptctl_replace_fw (unsigned long arg);
140 
141 static int mptctl_do_reset(unsigned long arg);
142 static int mptctl_hp_hostinfo(unsigned long arg, unsigned int cmd);
143 static int mptctl_hp_targetinfo(unsigned long arg);
144 
145 /*
146  * Private function calls.
147  */
148 static int mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local);
149 static int mptctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen);
150 static MptSge_t *kbuf_alloc_2_sgl( int bytes, u32 dir, int sge_offset, int *frags,
151 		struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc);
152 static void kfree_sgl( MptSge_t *sgl, dma_addr_t sgl_dma,
153 		struct buflist *buflist, MPT_ADAPTER *ioc);
154 static void mptctl_timer_expired (unsigned long data);
155 static int  mptctl_bus_reset(MPT_IOCTL *ioctl);
156 static int mptctl_set_tm_flags(MPT_SCSI_HOST *hd);
157 static void mptctl_free_tm_flags(MPT_ADAPTER *ioc);
158 
159 /*
160  * Reset Handler cleanup function
161  */
162 static int  mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);
163 
164 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
165 /*
166  * Scatter gather list (SGL) sizes and limits...
167  */
168 //#define MAX_SCSI_FRAGS	9
169 #define MAX_FRAGS_SPILL1	9
170 #define MAX_FRAGS_SPILL2	15
171 #define FRAGS_PER_BUCKET	(MAX_FRAGS_SPILL2 + 1)
172 
173 //#define MAX_CHAIN_FRAGS	64
174 //#define MAX_CHAIN_FRAGS	(15+15+15+16)
175 #define MAX_CHAIN_FRAGS		(4 * MAX_FRAGS_SPILL2 + 1)
176 
177 //  Define max sg LIST bytes ( == (#frags + #chains) * 8 bytes each)
178 //  Works out to: 592d bytes!     (9+1)*8 + 4*(15+1)*8
179 //                  ^----------------- 80 + 512
180 #define MAX_SGL_BYTES		((MAX_FRAGS_SPILL1 + 1 + (4 * FRAGS_PER_BUCKET)) * 8)
181 
182 /* linux only seems to ever give 128kB MAX contiguous (GFP_USER) mem bytes */
183 #define MAX_KMALLOC_SZ		(128*1024)
184 
185 #define MPT_IOCTL_DEFAULT_TIMEOUT 10	/* Default timeout value (seconds) */
186 
187 static u32 fwReplyBuffer[16];
188 static pMPIDefaultReply_t ReplyMsg = NULL;
189 
190 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
191 /**
192  *	mptctl_syscall_down - Down the MPT adapter syscall semaphore.
193  *	@ioc: Pointer to MPT adapter
194  *	@nonblock: boolean, non-zero if O_NONBLOCK is set
195  *
196  *	All of the ioctl commands can potentially sleep, which is illegal
197  *	with a spinlock held, thus we perform mutual exclusion here.
198  *
199  *	Returns negative errno on error, or zero for success.
200  */
201 static inline int
mptctl_syscall_down(MPT_ADAPTER * ioc,int nonblock)202 mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock)
203 {
204 	int rc = 0;
205 	dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down(%p,%d) called\n", ioc, nonblock));
206 
207 	if (ioc->ioctl->tmPtr != NULL) {
208 		dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down BUSY\n"));
209 		return -EBUSY;
210 	}
211 
212 #ifdef MPT_CONFIG_COMPAT
213 	if (!nonblock) {
214 		if (down_interruptible(&mptctl_syscall_sem_ioc[ioc->id]))
215 			rc = -ERESTARTSYS;
216 	} else {
217 		rc = -EPERM;
218 	}
219 #else
220 	if (nonblock) {
221 		if (down_trylock(&mptctl_syscall_sem_ioc[ioc->id]))
222 			rc = -EAGAIN;
223 	} else {
224 		if (down_interruptible(&mptctl_syscall_sem_ioc[ioc->id]))
225 			rc = -ERESTARTSYS;
226 	}
227 #endif
228 	dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down return %d\n", rc));
229 	return rc;
230 }
231 
232 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
233 /*
234  *  This is the callback for any message we have posted. The message itself
235  *  will be returned to the message pool when we return from the IRQ
236  *
237  *  This runs in irq context so be short and sweet.
238  */
239 static int
mptctl_reply(MPT_ADAPTER * ioc,MPT_FRAME_HDR * req,MPT_FRAME_HDR * reply)240 mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
241 {
242 	char *sense_data;
243 	int sz, req_index;
244 	u16 iocStatus;
245 	u8 cmd;
246 
247 	dctlprintk((MYIOC_s_INFO_FMT ": mptctl_reply()!\n", ioc->name));
248 	if (req)
249 		 cmd = req->u.hdr.Function;
250 	else
251 		return 1;
252 
253 	if (ioc->ioctl) {
254 		/* If timer is not running, then an error occurred.
255 		 * A timeout will call the reset routine to reload the messaging
256 		 * queues.
257 		 * Main callback will free message and reply frames.
258 		 */
259 		if (reply && (cmd == MPI_FUNCTION_SCSI_TASK_MGMT) &&
260 		    (ioc->ioctl->status & MPT_IOCTL_STATUS_TMTIMER_ACTIVE)) {
261 			/* This is internally generated TM
262 			 */
263 			del_timer (&ioc->ioctl->TMtimer);
264 			ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TMTIMER_ACTIVE;
265 
266 			mptctl_free_tm_flags(ioc);
267 
268 			/* If TM failed, reset the timer on the existing command,
269 			 * will trigger an adapter reset.
270 			 */
271 			iocStatus = reply->u.reply.IOCStatus & MPI_IOCSTATUS_MASK;
272 			if (iocStatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED) {
273 				if (ioc->ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE) {
274 					ioc->ioctl->reset &= ~MPTCTL_RESET_OK;
275 					del_timer (&ioc->ioctl->timer);
276 					ioc->ioctl->timer.expires = jiffies + HZ;
277 					add_timer(&ioc->ioctl->timer);
278 				}
279 			}
280 			ioc->ioctl->tmPtr = NULL;
281 
282 		} else if (ioc->ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE) {
283 			/* Delete this timer
284 			 */
285 			del_timer (&ioc->ioctl->timer);
286 			ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TIMER_ACTIVE;
287 
288 			/* Set the overall status byte.  Good if:
289 			 * IOC status is good OR if no reply and a SCSI IO request
290 			 */
291 			if (reply) {
292 				/* Copy the reply frame (which much exist
293 				 * for non-SCSI I/O) to the IOC structure.
294 				 */
295 				dctlprintk((MYIOC_s_INFO_FMT ": Copying Reply Frame @%p to IOC!\n",
296 						ioc->name, reply));
297 				memcpy(ioc->ioctl->ReplyFrame, reply,
298 					MIN(ioc->reply_sz, 4*reply->u.reply.MsgLength));
299 				ioc->ioctl->status |= MPT_IOCTL_STATUS_RF_VALID;
300 
301 				/* Set the command status to GOOD if IOC Status is GOOD
302 				 * OR if SCSI I/O cmd and data underrun or recovered error.
303 				 */
304 				iocStatus = reply->u.reply.IOCStatus & MPI_IOCSTATUS_MASK;
305 				if (iocStatus  == MPI_IOCSTATUS_SUCCESS)
306 					ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
307 
308 				if ((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
309 					(cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
310 					ioc->ioctl->reset &= ~MPTCTL_RESET_OK;
311 
312 					if ((iocStatus == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN) ||
313 						(iocStatus == MPI_IOCSTATUS_SCSI_RECOVERED_ERROR)) {
314 						ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
315 					}
316 				}
317 
318 				/* Copy the sense data - if present
319 				 */
320 				if ((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) &&
321 					(reply->u.sreply.SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)){
322 
323 					sz = req->u.scsireq.SenseBufferLength;
324 					req_index = le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
325 					sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
326 					memcpy(ioc->ioctl->sense, sense_data, sz);
327 					ioc->ioctl->status |= MPT_IOCTL_STATUS_SENSE_VALID;
328 				}
329 
330 				if (cmd == MPI_FUNCTION_SCSI_TASK_MGMT)
331 					mptctl_free_tm_flags(ioc);
332 
333 
334 			} else if ((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
335 					(cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
336 				ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
337 				ioc->ioctl->reset &= ~MPTCTL_RESET_OK;
338 			}
339 
340 			/* We are done, issue wake up
341 			 */
342 			ioc->ioctl->wait_done = 1;
343 			wake_up (&mptctl_wait);
344 
345 		} else if (reply && cmd == MPI_FUNCTION_FW_DOWNLOAD) {
346 			/* Two paths to FW DOWNLOAD! */
347 			// NOTE: Expects/requires non-Turbo reply!
348 			dctlprintk((MYIOC_s_INFO_FMT ":Caching MPI_FUNCTION_FW_DOWNLOAD reply!\n",
349 				ioc->name));
350 			memcpy(fwReplyBuffer, reply, MIN(sizeof(fwReplyBuffer), 4*reply->u.reply.MsgLength));
351 			ReplyMsg = (pMPIDefaultReply_t) fwReplyBuffer;
352 		}
353 	}
354 	return 1;
355 }
356 
357 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
358 /* mptctl_timer_expired
359  *
360  * Call back for timer process. Used only for ioctl functionality.
361  *
362  */
mptctl_timer_expired(unsigned long data)363 static void mptctl_timer_expired (unsigned long data)
364 {
365 	MPT_IOCTL *ioctl = (MPT_IOCTL *) data;
366 	int rc = 1;
367 
368 	dctlprintk((KERN_NOTICE MYNAM ": Timer Expired! Host %d\n",
369 				ioctl->ioc->id));
370 	if (ioctl == NULL)
371 		return;
372 
373 	if (ioctl->reset & MPTCTL_RESET_OK)
374 		rc = mptctl_bus_reset(ioctl);
375 
376 	if (rc) {
377 		/* Issue a reset for this device.
378 		 * The IOC is not responding.
379 		 */
380 		mpt_HardResetHandler(ioctl->ioc, NO_SLEEP);
381 	}
382 	return;
383 
384 }
385 
386 /* mptctl_bus_reset
387  *
388  * Bus reset code.
389  *
390  */
mptctl_bus_reset(MPT_IOCTL * ioctl)391 static int mptctl_bus_reset(MPT_IOCTL *ioctl)
392 {
393 	MPT_FRAME_HDR	*mf;
394 	SCSITaskMgmt_t	*pScsiTm;
395 	MPT_SCSI_HOST	*hd;
396 	int		 ii;
397 	int		 retval;
398 
399 
400 	ioctl->reset &= ~MPTCTL_RESET_OK;
401 
402 	if (ioctl->ioc->sh == NULL)
403 		return -EPERM;
404 
405 	hd = (MPT_SCSI_HOST *) ioctl->ioc->sh->hostdata;
406 	if (hd == NULL)
407 		return -EPERM;
408 
409 	/* Single threading ....
410 	 */
411 	if (mptctl_set_tm_flags(hd) != 0)
412 		return -EPERM;
413 
414 	/* Send request
415 	 */
416 	if ((mf = mpt_get_msg_frame(mptctl_id, ioctl->ioc->id)) == NULL) {
417 		dctlprintk((MYIOC_s_WARN_FMT "IssueTaskMgmt, no msg frames!!\n",
418 				ioctl->ioc->name));
419 
420 		mptctl_free_tm_flags(ioctl->ioc);
421 		return -ENOMEM;
422 	}
423 
424 	dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
425 			ioctl->ioc->name, mf));
426 
427 	pScsiTm = (SCSITaskMgmt_t *) mf;
428 	pScsiTm->TargetID = ioctl->target;
429 	pScsiTm->Bus = hd->port;	/* 0 */
430 	pScsiTm->ChainOffset = 0;
431 	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
432 	pScsiTm->Reserved = 0;
433 	pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;
434 	pScsiTm->Reserved1 = 0;
435 	pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
436 
437 	for (ii= 0; ii < 8; ii++)
438 		pScsiTm->LUN[ii] = 0;
439 
440 	for (ii=0; ii < 7; ii++)
441 		pScsiTm->Reserved2[ii] = 0;
442 
443 	pScsiTm->TaskMsgContext = 0;
444 	dtmprintk((MYIOC_s_INFO_FMT "mptctl_bus_reset: issued.\n", ioctl->ioc->name));
445 
446 	ioctl->tmPtr = mf;
447 	ioctl->TMtimer.expires = jiffies + HZ * 20;	/* 20 seconds */
448 	ioctl->status |= MPT_IOCTL_STATUS_TMTIMER_ACTIVE;
449 	add_timer(&ioctl->TMtimer);
450 
451 	retval = mpt_send_handshake_request(mptctl_id, ioctl->ioc->id,
452 			sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, NO_SLEEP);
453 
454 	if (retval != 0) {
455 		dtmprintk((MYIOC_s_WARN_FMT "_send_handshake FAILED!"
456 			" (hd %p, ioc %p, mf %p) \n", ioctl->ioc->name, hd, hd->ioc, mf));
457 
458 		mptctl_free_tm_flags(ioctl->ioc);
459 		del_timer(&ioctl->TMtimer);
460 		mpt_free_msg_frame(mptctl_id, ioctl->ioc->id, mf);
461 		ioctl->tmPtr = NULL;
462 	}
463 
464 	return retval;
465 }
466 
467 static int
mptctl_set_tm_flags(MPT_SCSI_HOST * hd)468 mptctl_set_tm_flags(MPT_SCSI_HOST *hd) {
469 	unsigned long flags;
470 
471 	spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
472 #ifdef MPT_SCSI_USE_NEW_EH
473 	if (hd->tmState == TM_STATE_NONE) {
474 		hd->tmState = TM_STATE_IN_PROGRESS;
475 		hd->tmPending = 1;
476 		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
477 	} else {
478 		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
479 		return -EBUSY;
480 	}
481 #else
482 	if (hd->tmPending) {
483 		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
484 		return -EBUSY;
485 	} else {
486 		hd->tmPending = 1;
487 		spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
488 	}
489 #endif
490 	return 0;
491 }
492 
493 static void
mptctl_free_tm_flags(MPT_ADAPTER * ioc)494 mptctl_free_tm_flags(MPT_ADAPTER *ioc)
495 {
496 	MPT_SCSI_HOST * hd;
497 	unsigned long flags;
498 
499 	hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
500 	if (hd == NULL)
501 		return;
502 
503 	spin_lock_irqsave(&ioc->FreeQlock, flags);
504 #ifdef MPT_SCSI_USE_NEW_EH
505 	hd->tmState = TM_STATE_ERROR;
506 	hd->tmPending = 0;
507 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
508 #else
509 	hd->tmPending = 0;
510 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
511 #endif
512 
513 	return;
514 }
515 
516 
517 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
518 /* mptctl_ioc_reset
519  *
520  * Clean-up functionality. Used only if there has been a
521  * reload of the FW due.
522  *
523  */
524 static int
mptctl_ioc_reset(MPT_ADAPTER * ioc,int reset_phase)525 mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
526 {
527 	MPT_IOCTL *ioctl = ioc->ioctl;
528 	dctlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to IOCTL driver!\n",
529 			reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
530 			reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
531 
532 	if (reset_phase == MPT_IOC_SETUP_RESET){
533 		;
534 	} else if (reset_phase == MPT_IOC_PRE_RESET){
535 
536 		/* Someone has called the reset handler to
537 		 * do a hard reset. No more replies from the FW.
538 		 * Delete the timer. TM flags cleaned up by SCSI driver.
539 		 * Do not need to free msg frame, as re-initialized
540 		 */
541 		if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE)){
542 			del_timer(&ioctl->timer);
543 		}
544 		if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TMTIMER_ACTIVE)){
545 			ioctl->status &= ~MPT_IOCTL_STATUS_TMTIMER_ACTIVE;
546 			del_timer(&ioctl->TMtimer);
547 			mpt_free_msg_frame(mptctl_id, ioc->id, ioctl->tmPtr);
548 		}
549 
550 	} else {
551 		ioctl->tmPtr = NULL;
552 
553 		/* Set the status and continue IOCTL
554 		 * processing. All memory will be free'd
555 		 * by originating thread after wake_up is
556 		 * called.
557 		 */
558 		if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE)){
559 			ioctl->status |= MPT_IOCTL_STATUS_DID_IOCRESET;
560 
561 			/* Wake up the calling process
562 			 */
563 			ioctl->wait_done = 1;
564 			wake_up(&mptctl_wait);
565 		}
566 	}
567 
568 	return 1;
569 }
570 
571 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
572 /*
573  *  struct file_operations functionality.
574  *  Members:
575  *	llseek, write, read, ioctl, open, release
576  */
577 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
578 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9)
579 static loff_t
mptctl_llseek(struct file * file,loff_t offset,int origin)580 mptctl_llseek(struct file *file, loff_t offset, int origin)
581 {
582 	return -ESPIPE;
583 }
584 #define no_llseek mptctl_llseek
585 #endif
586 
587 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
588 static ssize_t
mptctl_write(struct file * file,const char * buf,size_t count,loff_t * ppos)589 mptctl_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
590 {
591 	printk(KERN_ERR MYNAM ": ioctl WRITE not yet supported\n");
592 	return 0;
593 }
594 
595 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
596 static ssize_t
mptctl_read(struct file * file,char * buf,size_t count,loff_t * ptr)597 mptctl_read(struct file *file, char *buf, size_t count, loff_t *ptr)
598 {
599 	printk(KERN_ERR MYNAM ": ioctl READ not yet supported\n");
600 	return 0;
601 }
602 
603 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
604 /*
605  *  MPT ioctl handler
606  *  cmd - specify the particular IOCTL command to be issued
607  *  arg - data specific to the command. Must not be null.
608  */
609 static int
mptctl_ioctl(struct inode * inode,struct file * file,unsigned int cmd,unsigned long arg)610 mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
611 {
612 	mpt_ioctl_header	*uhdr = (mpt_ioctl_header *) arg;
613 	mpt_ioctl_header	 khdr;
614 	int iocnum;
615 	unsigned iocnumX;
616 	int nonblock = (file->f_flags & O_NONBLOCK);
617 	int ret;
618 	MPT_ADAPTER *iocp = NULL;
619 
620 	dctlprintk(("mptctl_ioctl() called\n"));
621 
622 	if (copy_from_user(&khdr, uhdr, sizeof(khdr))) {
623 		printk(KERN_ERR "%s::mptctl_ioctl() @%d - "
624 				"Unable to copy mpt_ioctl_header data @ %p\n",
625 				__FILE__, __LINE__, (void*)uhdr);
626 		return -EFAULT;
627 	}
628 	ret = -ENXIO;				/* (-6) No such device or address */
629 
630 	/* Verify intended MPT adapter - set iocnum and the adapter
631 	 * pointer (iocp)
632 	 */
633 	iocnumX = khdr.iocnum & 0xFF;
634 	if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
635 	    (iocp == NULL)) {
636 		dctlprintk((KERN_ERR "%s::mptctl_ioctl() @%d - ioc%d not found!\n",
637 				__FILE__, __LINE__, iocnumX));
638 		return -ENODEV;
639 	}
640 
641 	if (!iocp->active) {
642 		printk(KERN_ERR "%s::mptctl_ioctl() @%d - Controller disabled.\n",
643 				__FILE__, __LINE__);
644 		return -EFAULT;
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 	if (cmd == MPTFWDOWNLOAD)
677 		ret = mptctl_fw_download(arg);
678 	else if (cmd == MPTCOMMAND)
679 		ret = mptctl_mpt_command(arg);
680 	else if (cmd == MPTHARDRESET)
681 		ret = mptctl_do_reset(arg);
682 	else if ((cmd & ~IOCSIZE_MASK) == (HP_GETHOSTINFO & ~IOCSIZE_MASK))
683 		ret = mptctl_hp_hostinfo(arg, _IOC_SIZE(cmd));
684 	else if (cmd == HP_GETTARGETINFO)
685 		ret = mptctl_hp_targetinfo(arg);
686 	else
687 		ret = -EINVAL;
688 
689 
690 	up(&mptctl_syscall_sem_ioc[iocp->id]);
691 
692 	return ret;
693 }
694 
mptctl_do_reset(unsigned long arg)695 static 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 		dctlprintk((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, CAN_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 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
mptctl_open(struct inode * inode,struct file * file)726 static int mptctl_open(struct inode *inode, struct file *file)
727 {
728 	/*
729 	 * Should support multiple management users
730 	 */
731 	return 0;
732 }
733 
734 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
mptctl_release(struct inode * inode,struct file * file)735 static 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  */
757 static int
mptctl_fw_download(unsigned long arg)758 mptctl_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  */
788 static int
mptctl_do_fw_download(int ioc,char * ufwbuf,size_t fwlen)789 mptctl_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 		dctlprintk(("%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 
987 fwdl_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  */
1007 static MptSge_t *
kbuf_alloc_2_sgl(int bytes,u32 sgdir,int sge_offset,int * frags,struct buflist ** blp,dma_addr_t * sglbuf_dma,MPT_ADAPTER * ioc)1008 kbuf_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 
1128 free_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  */
1156 static void
kfree_sgl(MptSge_t * sgl,dma_addr_t sgl_dma,struct buflist * buflist,MPT_ADAPTER * ioc)1157 kfree_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  */
1221 static int
mptctl_getiocinfo(unsigned long arg,unsigned int data_size)1222 mptctl_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 	/* Add of PCI INFO results in unaligned access for
1240 	 * IA64 and Sparc. Reset long to int. Return no PCI
1241 	 * data for obsolete format.
1242 	 */
1243 	if (data_size == sizeof(struct mpt_ioctl_iocinfo_rev0))
1244 		cim_rev = 0;
1245 	else if (data_size == sizeof(struct mpt_ioctl_iocinfo))
1246 		cim_rev = 1;
1247 	else if (data_size == (sizeof(struct mpt_ioctl_iocinfo_rev0)+12))
1248 		cim_rev = 0;	/* obsolete */
1249 	else
1250 		return -EFAULT;
1251 
1252 	if (copy_from_user(&karg, uarg, data_size)) {
1253 		printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
1254 			"Unable to read in mpt_ioctl_iocinfo struct @ %p\n",
1255 				__FILE__, __LINE__, (void*)uarg);
1256 		return -EFAULT;
1257 	}
1258 
1259 	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1260 	    (ioc == NULL)) {
1261 		dctlprintk((KERN_ERR "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n",
1262 				__FILE__, __LINE__, iocnum));
1263 		return -ENODEV;
1264 	}
1265 
1266 	/* Verify the data transfer size is correct.
1267 	 * Ignore the port setting.
1268 	 */
1269 	if (karg.hdr.maxDataSize != data_size) {
1270 		printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
1271 			"Structure size mismatch. Command not completed.\n",
1272 				__FILE__, __LINE__);
1273 		return -EFAULT;
1274 	}
1275 
1276 	/* Fill in the data and return the structure to the calling
1277 	 * program
1278 	 */
1279 	if ((int)ioc->chip_type <= (int) FC929)
1280 		karg.adapterType = MPT_IOCTL_INTERFACE_FC;
1281 	else
1282 		karg.adapterType = MPT_IOCTL_INTERFACE_SCSI;
1283 
1284 	port = karg.hdr.port;
1285 
1286 	karg.port = port;
1287 	pdev = (struct pci_dev *) ioc->pcidev;
1288 
1289 	karg.pciId = pdev->device;
1290 	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1291 	karg.hwRev = revision;
1292 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1293 	karg.subSystemDevice = pdev->subsystem_device;
1294 	karg.subSystemVendor = pdev->subsystem_vendor;
1295 #endif
1296 
1297 	if (cim_rev == 1) {
1298 		/* Get the PCI bus, device, and function numbers for the IOC
1299 		 */
1300 		karg.pciInfo.u.bits.busNumber = pdev->bus->number;
1301 		karg.pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
1302 		karg.pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1303 	}
1304 
1305 	/* Get number of devices
1306          */
1307 	if ((sh = ioc->sh) != NULL) {
1308 		 /* sh->max_id = maximum target ID + 1
1309 		 */
1310 		max_id = sh->max_id - 1;
1311 		hd = (MPT_SCSI_HOST *) sh->hostdata;
1312 
1313 		/* Check all of the target structures and
1314 		 * keep a counter.
1315 		 */
1316 		if (hd && hd->Targets) {
1317 			for (ii = 0; ii <= max_id; ii++) {
1318 				if (hd->Targets[ii])
1319 					numDevices++;
1320 			}
1321 		}
1322 	}
1323 	karg.numDevices = numDevices;
1324 
1325 	/* Set the BIOS and FW Version
1326 	 */
1327 	karg.FWVersion = ioc->facts.FWVersion.Word;
1328 	karg.BIOSVersion = ioc->biosVersion;
1329 
1330 	/* Set the Version Strings.
1331 	 */
1332 	strncpy (karg.driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH);
1333 	karg.driverVersion[MPT_IOCTL_VERSION_LENGTH-1]='\0';
1334 
1335 	karg.busChangeEvent = 0;
1336 	karg.hostId = ioc->pfacts[port].PortSCSIID;
1337 	karg.rsvd[0] = karg.rsvd[1] = 0;
1338 
1339 	/* Copy the data from kernel memory to user memory
1340 	 */
1341 	if (copy_to_user((char *)arg, &karg, data_size)) {
1342 		printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
1343 			"Unable to write out mpt_ioctl_iocinfo struct @ %p\n",
1344 				__FILE__, __LINE__, (void*)uarg);
1345 		return -EFAULT;
1346 	}
1347 
1348 	return 0;
1349 }
1350 
1351 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1352 /*
1353  *	mptctl_gettargetinfo - Query the host adapter for target information.
1354  *	@arg: User space argument
1355  *
1356  * Outputs:	None.
1357  * Return:	0 if successful
1358  *		-EFAULT if data unavailable
1359  *		-ENODEV  if no such device/adapter
1360  */
1361 static int
mptctl_gettargetinfo(unsigned long arg)1362 mptctl_gettargetinfo (unsigned long arg)
1363 {
1364 	struct mpt_ioctl_targetinfo *uarg = (struct mpt_ioctl_targetinfo *) arg;
1365 	struct mpt_ioctl_targetinfo karg;
1366 	MPT_ADAPTER		*ioc;
1367 	struct Scsi_Host	*sh;
1368 	MPT_SCSI_HOST		*hd;
1369 	VirtDevice		*vdev;
1370 	char			*pmem;
1371 	int			*pdata;
1372 	IOCPage2_t		*pIoc2;
1373 	IOCPage3_t		*pIoc3;
1374 	int			iocnum;
1375 	int			numDevices = 0;
1376 	unsigned int		max_id;
1377 	int			id, jj, indexed_lun, lun_index;
1378 	u32			lun;
1379 	int			maxWordsLeft;
1380 	int			numBytes;
1381 	u8			port, devType, bus_id;
1382 
1383 	dctlprintk(("mptctl_gettargetinfo called.\n"));
1384 	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
1385 		printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
1386 			"Unable to read in mpt_ioctl_targetinfo struct @ %p\n",
1387 				__FILE__, __LINE__, (void*)uarg);
1388 		return -EFAULT;
1389 	}
1390 
1391 	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1392 	    (ioc == NULL)) {
1393 		dctlprintk((KERN_ERR "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n",
1394 				__FILE__, __LINE__, iocnum));
1395 		return -ENODEV;
1396 	}
1397 
1398 	/* Get the port number and set the maximum number of bytes
1399 	 * in the returned structure.
1400 	 * Ignore the port setting.
1401 	 */
1402 	numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
1403 	maxWordsLeft = numBytes/sizeof(int);
1404 	port = karg.hdr.port;
1405 
1406 	if (maxWordsLeft <= 0) {
1407 		printk(KERN_ERR "%s::mptctl_gettargetinfo() @%d - no memory available!\n",
1408 				__FILE__, __LINE__);
1409 		return -ENOMEM;
1410 	}
1411 
1412 	/* Fill in the data and return the structure to the calling
1413 	 * program
1414 	 */
1415 
1416 	/* struct mpt_ioctl_targetinfo does not contain sufficient space
1417 	 * for the target structures so when the IOCTL is called, there is
1418 	 * not sufficient stack space for the structure. Allocate memory,
1419 	 * populate the memory, copy back to the user, then free memory.
1420 	 * targetInfo format:
1421 	 * bits 31-24: reserved
1422 	 *      23-16: LUN
1423 	 *      15- 8: Bus Number
1424 	 *       7- 0: Target ID
1425 	 */
1426 	pmem = kmalloc(numBytes, GFP_KERNEL);
1427 	if (pmem == NULL) {
1428 		printk(KERN_ERR "%s::mptctl_gettargetinfo() @%d - no memory available!\n",
1429 				__FILE__, __LINE__);
1430 		return -ENOMEM;
1431 	}
1432 	memset(pmem, 0, numBytes);
1433 	pdata =  (int *) pmem;
1434 
1435 	/* Get number of devices
1436          */
1437 	if ((sh = ioc->sh) != NULL) {
1438 
1439 		max_id = sh->max_id - 1;
1440 		hd = (MPT_SCSI_HOST *) sh->hostdata;
1441 
1442 		/* Check all of the target structures.
1443 		 * Save the Id and increment the counter,
1444 		 * if ptr non-null.
1445 		 * sh->max_id = maximum target ID + 1
1446 		 */
1447 		if (hd && hd->Targets) {
1448 			mpt_findImVolumes(ioc);
1449 			pIoc2 = ioc->spi_data.pIocPg2;
1450 			for ( id = 0; id <= max_id; ) {
1451 				if ( pIoc2 && pIoc2->NumActiveVolumes ) {
1452 					if ( id == pIoc2->RaidVolume[0].VolumeID ) {
1453 						if (maxWordsLeft <= 0) {
1454 							printk(KERN_ERR "mptctl_gettargetinfo - "
1455 			"buffer is full but volume is available on ioc %d\n, numDevices=%d", iocnum, numDevices);
1456 							goto data_space_full;
1457 						}
1458 						if ( ( pIoc2->RaidVolume[0].Flags & MPI_IOCPAGE2_FLAG_VOLUME_INACTIVE ) == 0 )
1459                         				devType = 0x80;
1460                     				else
1461                         				devType = 0xC0;
1462 						bus_id = pIoc2->RaidVolume[0].VolumeBus;
1463 	            				numDevices++;
1464                     				*pdata = ( (devType << 24) | (bus_id << 8) | id );
1465 						dctlprintk((KERN_ERR "mptctl_gettargetinfo - "
1466 		"volume ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata));
1467                     				pdata++;
1468 						--maxWordsLeft;
1469 						goto next_id;
1470 					} else {
1471 						pIoc3 = ioc->spi_data.pIocPg3;
1472             					for ( jj = 0; jj < pIoc3->NumPhysDisks; jj++ ) {
1473                     					if ( pIoc3->PhysDisk[jj].PhysDiskID == id )
1474 								goto next_id;
1475 						}
1476 					}
1477 				}
1478 				if ( (vdev = hd->Targets[id]) ) {
1479 					for (jj = 0; jj <= MPT_LAST_LUN; jj++) {
1480 						lun_index = (jj >> 5);
1481 						indexed_lun = (jj % 32);
1482 						lun = (1 << indexed_lun);
1483 						if (vdev->luns[lun_index] & lun) {
1484 							if (maxWordsLeft <= 0) {
1485 								printk(KERN_ERR "mptctl_gettargetinfo - "
1486 			"buffer is full but more targets are available on ioc %d numDevices=%d\n", iocnum, numDevices);
1487 								goto data_space_full;
1488 							}
1489 							bus_id = vdev->bus_id;
1490 							numDevices++;
1491                             				*pdata = ( (jj << 16) | (bus_id << 8) | id );
1492 							dctlprintk((KERN_ERR "mptctl_gettargetinfo - "
1493 		"target ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata));
1494 							pdata++;
1495 							--maxWordsLeft;
1496 						}
1497 					}
1498 				}
1499 next_id:
1500 				id++;
1501 			}
1502 		}
1503 	}
1504 data_space_full:
1505 	karg.numDevices = numDevices;
1506 
1507 	/* Copy part of the data from kernel memory to user memory
1508 	 */
1509 	if (copy_to_user((char *)arg, &karg,
1510 				sizeof(struct mpt_ioctl_targetinfo))) {
1511 		printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
1512 			"Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
1513 				__FILE__, __LINE__, (void*)uarg);
1514 		kfree(pmem);
1515 		return -EFAULT;
1516 	}
1517 
1518 	/* Copy the remaining data from kernel memory to user memory
1519 	 */
1520 	if (copy_to_user((char *) uarg->targetInfo, pmem, numBytes)) {
1521 		printk(KERN_ERR "%s@%d::mptctl_gettargetinfo - "
1522 			"Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
1523 				__FILE__, __LINE__, (void*)pdata);
1524 		kfree(pmem);
1525 		return -EFAULT;
1526 	}
1527 
1528 	kfree(pmem);
1529 
1530 	return 0;
1531 }
1532 
1533 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1534 /* MPT IOCTL Test function.
1535  *
1536  * Outputs:	None.
1537  * Return:	0 if successful
1538  *		-EFAULT if data unavailable
1539  *		-ENODEV  if no such device/adapter
1540  */
1541 static int
mptctl_readtest(unsigned long arg)1542 mptctl_readtest (unsigned long arg)
1543 {
1544 	struct mpt_ioctl_test	*uarg = (struct mpt_ioctl_test *) arg;
1545 	struct mpt_ioctl_test	 karg;
1546 	MPT_ADAPTER *ioc;
1547 	int iocnum;
1548 
1549 	dctlprintk(("mptctl_readtest called.\n"));
1550 	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) {
1551 		printk(KERN_ERR "%s@%d::mptctl_readtest - "
1552 			"Unable to read in mpt_ioctl_test struct @ %p\n",
1553 				__FILE__, __LINE__, (void*)uarg);
1554 		return -EFAULT;
1555 	}
1556 
1557 	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1558 	    (ioc == NULL)) {
1559 		dctlprintk((KERN_ERR "%s::mptctl_readtest() @%d - ioc%d not found!\n",
1560 				__FILE__, __LINE__, iocnum));
1561 		return -ENODEV;
1562 	}
1563 
1564 	/* Fill in the data and return the structure to the calling
1565 	 * program
1566 	 */
1567 
1568 #ifdef MFCNT
1569 	karg.chip_type = ioc->mfcnt;
1570 #else
1571 	karg.chip_type = ioc->chip_type;
1572 #endif
1573 	strncpy (karg.name, ioc->name, MPT_MAX_NAME);
1574 	karg.name[MPT_MAX_NAME-1]='\0';
1575 	strncpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH);
1576 	karg.product[MPT_PRODUCT_LENGTH-1]='\0';
1577 
1578 	/* Copy the data from kernel memory to user memory
1579 	 */
1580 	if (copy_to_user((char *)arg, &karg, sizeof(struct mpt_ioctl_test))) {
1581 		printk(KERN_ERR "%s@%d::mptctl_readtest - "
1582 			"Unable to write out mpt_ioctl_test struct @ %p\n",
1583 				__FILE__, __LINE__, (void*)uarg);
1584 		return -EFAULT;
1585 	}
1586 
1587 	return 0;
1588 }
1589 
1590 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1591 /*
1592  *	mptctl_eventquery - Query the host adapter for the event types
1593  *	that are being logged.
1594  *	@arg: User space argument
1595  *
1596  * Outputs:	None.
1597  * Return:	0 if successful
1598  *		-EFAULT if data unavailable
1599  *		-ENODEV  if no such device/adapter
1600  */
1601 static int
mptctl_eventquery(unsigned long arg)1602 mptctl_eventquery (unsigned long arg)
1603 {
1604 	struct mpt_ioctl_eventquery	*uarg = (struct mpt_ioctl_eventquery *) arg;
1605 	struct mpt_ioctl_eventquery	 karg;
1606 	MPT_ADAPTER *ioc;
1607 	int iocnum;
1608 
1609 	dctlprintk(("mptctl_eventquery called.\n"));
1610 	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) {
1611 		printk(KERN_ERR "%s@%d::mptctl_eventquery - "
1612 			"Unable to read in mpt_ioctl_eventquery struct @ %p\n",
1613 				__FILE__, __LINE__, (void*)uarg);
1614 		return -EFAULT;
1615 	}
1616 
1617 	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1618 	    (ioc == NULL)) {
1619 		dctlprintk((KERN_ERR "%s::mptctl_eventquery() @%d - ioc%d not found!\n",
1620 				__FILE__, __LINE__, iocnum));
1621 		return -ENODEV;
1622 	}
1623 
1624 	karg.eventEntries = ioc->eventLogSize;
1625 	karg.eventTypes = ioc->eventTypes;
1626 
1627 	/* Copy the data from kernel memory to user memory
1628 	 */
1629 	if (copy_to_user((char *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) {
1630 		printk(KERN_ERR "%s@%d::mptctl_eventquery - "
1631 			"Unable to write out mpt_ioctl_eventquery struct @ %p\n",
1632 				__FILE__, __LINE__, (void*)uarg);
1633 		return -EFAULT;
1634 	}
1635 	return 0;
1636 }
1637 
1638 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1639 static int
mptctl_eventenable(unsigned long arg)1640 mptctl_eventenable (unsigned long arg)
1641 {
1642 	struct mpt_ioctl_eventenable	*uarg = (struct mpt_ioctl_eventenable *) arg;
1643 	struct mpt_ioctl_eventenable	 karg;
1644 	MPT_ADAPTER *ioc;
1645 	int iocnum;
1646 
1647 	dctlprintk(("mptctl_eventenable called.\n"));
1648 	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) {
1649 		printk(KERN_ERR "%s@%d::mptctl_eventenable - "
1650 			"Unable to read in mpt_ioctl_eventenable 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 		dctlprintk((KERN_ERR "%s::mptctl_eventenable() @%d - ioc%d not found!\n",
1658 				__FILE__, __LINE__, iocnum));
1659 		return -ENODEV;
1660 	}
1661 
1662 	if (ioc->events == NULL) {
1663 		/* Have not yet allocated memory - do so now.
1664 		 */
1665 		int sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
1666 		ioc->events = kmalloc(sz, GFP_KERNEL);
1667 		if (ioc->events == NULL) {
1668 			printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1669 			return -ENOMEM;
1670 		}
1671 		memset(ioc->events, 0, sz);
1672 		ioc->alloc_total += sz;
1673 
1674 		ioc->eventLogSize = MPTCTL_EVENT_LOG_SIZE;
1675 		ioc->eventContext = 0;
1676         }
1677 
1678 	/* Update the IOC event logging flag.
1679 	 */
1680 	ioc->eventTypes = karg.eventTypes;
1681 
1682 	return 0;
1683 }
1684 
1685 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1686 static int
mptctl_eventreport(unsigned long arg)1687 mptctl_eventreport (unsigned long arg)
1688 {
1689 	struct mpt_ioctl_eventreport	*uarg = (struct mpt_ioctl_eventreport *) arg;
1690 	struct mpt_ioctl_eventreport	 karg;
1691 	MPT_ADAPTER		 *ioc;
1692 	int			 iocnum;
1693 	int			 numBytes, maxEvents, max;
1694 
1695 	dctlprintk(("mptctl_eventreport called.\n"));
1696 	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) {
1697 		printk(KERN_ERR "%s@%d::mptctl_eventreport - "
1698 			"Unable to read in mpt_ioctl_eventreport struct @ %p\n",
1699 				__FILE__, __LINE__, (void*)uarg);
1700 		return -EFAULT;
1701 	}
1702 
1703 	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1704 	    (ioc == NULL)) {
1705 		dctlprintk((KERN_ERR "%s::mptctl_eventreport() @%d - ioc%d not found!\n",
1706 				__FILE__, __LINE__, iocnum));
1707 		return -ENODEV;
1708 	}
1709 
1710 	numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
1711 	maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS);
1712 
1713 
1714 	max = ioc->eventLogSize < maxEvents ? ioc->eventLogSize : maxEvents;
1715 
1716 	/* If fewer than 1 event is requested, there must have
1717 	 * been some type of error.
1718 	 */
1719 	if ((max < 1) || !ioc->events)
1720 		return -ENODATA;
1721 
1722 	/* Copy the data from kernel memory to user memory
1723 	 */
1724 	numBytes = max * sizeof(MPT_IOCTL_EVENTS);
1725 	if (copy_to_user((char *) uarg->eventData, ioc->events, numBytes)) {
1726 		printk(KERN_ERR "%s@%d::mptctl_eventreport - "
1727 			"Unable to write out mpt_ioctl_eventreport struct @ %p\n",
1728 				__FILE__, __LINE__, (void*)ioc->events);
1729 		return -EFAULT;
1730 	}
1731 
1732 	return 0;
1733 }
1734 
1735 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1736 static int
mptctl_replace_fw(unsigned long arg)1737 mptctl_replace_fw (unsigned long arg)
1738 {
1739 	struct mpt_ioctl_replace_fw	*uarg = (struct mpt_ioctl_replace_fw *) arg;
1740 	struct mpt_ioctl_replace_fw	 karg;
1741 	MPT_ADAPTER		 *ioc;
1742 	u8			 *fwmem = NULL;
1743 	int			 iocnum;
1744 	int			 newFwSize;
1745 	int			 alloc_sz;
1746 	int			 ii;
1747 
1748 	dctlprintk(("mptctl_replace_fw called.\n"));
1749 	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
1750 		printk(KERN_ERR "%s@%d::mptctl_replace_fw - "
1751 			"Unable to read in mpt_ioctl_replace_fw struct @ %p\n",
1752 				__FILE__, __LINE__, (void*)uarg);
1753 		return -EFAULT;
1754 	}
1755 
1756 	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1757 	    (ioc == NULL)) {
1758 		dctlprintk((KERN_ERR "%s::mptctl_replace_fw() @%d - ioc%d not found!\n",
1759 				__FILE__, __LINE__, iocnum));
1760 		return -ENODEV;
1761 	}
1762 
1763 	/* If caching FW, Free the old FW image
1764 	 */
1765 	if (ioc->cached_fw) {
1766 		mpt_free_fw_memory(ioc);
1767 	} else
1768 		return 0;
1769 
1770 	/* Allocate memory for the new FW image
1771 	 */
1772 	newFwSize = karg.newImageSize;
1773 	if ( newFwSize & 0x01 )
1774 		newFwSize += 1;
1775 	if ( newFwSize & 0x02 )
1776 		newFwSize += 2;
1777 
1778 	mpt_alloc_fw_memory(ioc, newFwSize);
1779 	if (ioc->cached_fw == NULL)
1780 		return -ENOMEM;
1781 
1782 	/* Copy the data from user memory to kernel space
1783 	 */
1784 	if (copy_from_user(ioc->cached_fw, uarg->newImage, newFwSize)) {
1785 		printk(KERN_ERR "%s@%d::mptctl_replace_fw - "
1786 			"Unable to read in mpt_ioctl_replace_fw image @ %p\n",
1787 				__FILE__, __LINE__, (void*)uarg);
1788 
1789 		mpt_free_fw_memory(ioc);
1790 		return -EFAULT;
1791 	}
1792 
1793 	/* Update IOCFactsReply
1794 	 */
1795 	ioc->facts.FWImageSize = newFwSize;
1796 
1797 	return 0;
1798 }
1799 
1800 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1801 /* MPT IOCTL MPTCOMMAND function.
1802  * Cast the arg into the mpt_ioctl_mpt_command structure.
1803  *
1804  * Outputs:	None.
1805  * Return:	0 if successful
1806  *		-EBUSY  if previous command timout and IOC reset is not complete.
1807  *		-EFAULT if data unavailable
1808  *		-ENODEV if no such device/adapter
1809  *		-ETIME	if timer expires
1810  *		-ENOMEM if memory allocation error
1811  */
1812 static int
mptctl_mpt_command(unsigned long arg)1813 mptctl_mpt_command (unsigned long arg)
1814 {
1815 	struct mpt_ioctl_command *uarg = (struct mpt_ioctl_command *) arg;
1816 	struct mpt_ioctl_command  karg;
1817 	MPT_ADAPTER	*ioc;
1818 	int		iocnum;
1819 	int		rc;
1820 
1821 	dctlprintk(("mptctl_command called.\n"));
1822 
1823 	if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_command))) {
1824 		printk(KERN_ERR "%s@%d::mptctl_mpt_command - "
1825 			"Unable to read in mpt_ioctl_command struct @ %p\n",
1826 				__FILE__, __LINE__, (void*)uarg);
1827 		return -EFAULT;
1828 	}
1829 
1830 	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1831 	    (ioc == NULL)) {
1832 		dctlprintk((KERN_ERR "%s::mptctl_mpt_command() @%d - ioc%d not found!\n",
1833 				__FILE__, __LINE__, iocnum));
1834 		return -ENODEV;
1835 	}
1836 
1837 	rc = mptctl_do_mpt_command (karg, (char *) &uarg->MF, 0);
1838 
1839 	return rc;
1840 }
1841 
1842 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1843 /* Worker routine for the IOCTL MPTCOMMAND and MPTCOMMAND32 (sparc) commands.
1844  *
1845  * Outputs:	None.
1846  * Return:	0 if successful
1847  *		-EBUSY  if previous command timout and IOC reset is not complete.
1848  *		-EFAULT if data unavailable
1849  *		-ENODEV if no such device/adapter
1850  *		-ETIME	if timer expires
1851  *		-ENOMEM if memory allocation error
1852  *		-EPERM if SCSI I/O and target is untagged
1853  */
1854 static int
mptctl_do_mpt_command(struct mpt_ioctl_command karg,char * mfPtr,int local)1855 mptctl_do_mpt_command (struct mpt_ioctl_command karg, char *mfPtr, int local)
1856 {
1857 	MPT_ADAPTER	*ioc;
1858 	MPT_FRAME_HDR	*mf = NULL;
1859 	MPIHeader_t	*hdr;
1860 	char		*psge;
1861 	struct buflist	bufIn;	/* data In buffer */
1862 	struct buflist	bufOut; /* data Out buffer */
1863 	dma_addr_t	dma_addr_in;
1864 	dma_addr_t	dma_addr_out;
1865 	int		dir;	/* PCI data direction */
1866 	int		sgSize = 0;	/* Num SG elements */
1867 	int		iocnum, flagsLength;
1868 	int		sz, rc = 0;
1869 	int		msgContext;
1870 	int		tm_flags_set = 0;
1871 	u16		req_idx;
1872 
1873 	dctlprintk(("mptctl_do_mpt_command called.\n"));
1874 	bufIn.kptr = bufOut.kptr = NULL;
1875 
1876 	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1877 	    (ioc == NULL)) {
1878 		dctlprintk((KERN_ERR "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n",
1879 				__FILE__, __LINE__, iocnum));
1880 		return -ENODEV;
1881 	}
1882 	if (!ioc->ioctl) {
1883 		printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1884 			"No memory available during driver init.\n",
1885 				__FILE__, __LINE__);
1886 		return -ENOMEM;
1887 	} else if (ioc->ioctl->status & MPT_IOCTL_STATUS_DID_IOCRESET) {
1888 		printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1889 			"Busy with IOC Reset \n", __FILE__, __LINE__);
1890 		return -EBUSY;
1891 	}
1892 
1893 	/* Verify that the final request frame will not be too large.
1894 	 */
1895 	sz = karg.dataSgeOffset * 4;
1896 	if (karg.dataInSize > 0)
1897 		sz += sizeof(dma_addr_t) + sizeof(u32);
1898 	if (karg.dataOutSize > 0)
1899 		sz += sizeof(dma_addr_t) + sizeof(u32);
1900 
1901 	if (sz > ioc->req_sz) {
1902 		printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1903 			"Request frame too large (%d) maximum (%d)\n",
1904 				__FILE__, __LINE__, sz, ioc->req_sz);
1905 		return -EFAULT;
1906 	}
1907 
1908 	/* Get a free request frame and save the message context.
1909 	 */
1910         if ((mf = mpt_get_msg_frame(mptctl_id, ioc->id)) == NULL)
1911                 return -EAGAIN;
1912 
1913 	hdr = (MPIHeader_t *) mf;
1914 	msgContext = le32_to_cpu(hdr->MsgContext);
1915 	req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1916 
1917 	/* Copy the request frame
1918 	 * Reset the saved message context.
1919 	 */
1920         if (local) {
1921 		/* Request frame in kernel space
1922 		 */
1923 		memcpy((char *)mf, (char *) mfPtr, karg.dataSgeOffset * 4);
1924         } else {
1925 		/* Request frame in user space
1926 		 */
1927 		if (copy_from_user((char *)mf, (char *) mfPtr,
1928 					karg.dataSgeOffset * 4)){
1929 			printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1930 				"Unable to read MF from mpt_ioctl_command struct @ %p\n",
1931 				__FILE__, __LINE__, (void*)mfPtr);
1932 			rc = -EFAULT;
1933 			goto done_free_mem;
1934 		}
1935         }
1936 	hdr->MsgContext = cpu_to_le32(msgContext);
1937 
1938 
1939 	/* Verify that this request is allowed.
1940 	 */
1941 	switch (hdr->Function) {
1942 	case MPI_FUNCTION_IOC_FACTS:
1943 	case MPI_FUNCTION_PORT_FACTS:
1944 		karg.dataOutSize  = karg.dataInSize = 0;
1945 		break;
1946 
1947 	case MPI_FUNCTION_CONFIG:
1948 	case MPI_FUNCTION_FC_COMMON_TRANSPORT_SEND:
1949 	case MPI_FUNCTION_FC_EX_LINK_SRVC_SEND:
1950 	case MPI_FUNCTION_FW_UPLOAD:
1951 	case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR:
1952 	case MPI_FUNCTION_FW_DOWNLOAD:
1953 	case MPI_FUNCTION_FC_PRIMITIVE_SEND:
1954 		break;
1955 
1956 	case MPI_FUNCTION_SCSI_IO_REQUEST:
1957 		if (ioc->sh) {
1958 			SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
1959 			VirtDevice	*pTarget = NULL;
1960 			MPT_SCSI_HOST	*hd = NULL;
1961 			int qtag = MPI_SCSIIO_CONTROL_UNTAGGED;
1962 			int scsidir = 0;
1963 			int target = (int) pScsiReq->TargetID;
1964 			int dataSize;
1965 
1966 			if ((target < 0) || (target >= ioc->sh->max_id)) {
1967 				printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
1968 					"Target ID out of bounds. \n",
1969 					__FILE__, __LINE__);
1970 				rc = -ENODEV;
1971 				goto done_free_mem;
1972 			}
1973 
1974 			pScsiReq->MsgFlags = mpt_msg_flags();
1975 
1976 			/* verify that app has not requested
1977 			 *	more sense data than driver
1978 			 *	can provide, if so, reset this parameter
1979 			 * set the sense buffer pointer low address
1980 			 * update the control field to specify Q type
1981 			 */
1982 			if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
1983 				pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1984 			else
1985 				pScsiReq->SenseBufferLength = karg.maxSenseBytes;
1986 
1987 			pScsiReq->SenseBufferLowAddr =
1988 				cpu_to_le32(ioc->sense_buf_low_dma
1989 				   + (req_idx * MPT_SENSE_BUFFER_ALLOC));
1990 
1991 			if ((hd = (MPT_SCSI_HOST *) ioc->sh->hostdata)) {
1992 				if (hd->Targets)
1993 					pTarget = hd->Targets[target];
1994 			}
1995 
1996 			if (pTarget &&(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
1997 				qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
1998 
1999 			/* Have the IOCTL driver set the direction based
2000 			 * on the dataOutSize (ordering issue with Sparc).
2001 			 */
2002 			if (karg.dataOutSize > 0) {
2003 				scsidir = MPI_SCSIIO_CONTROL_WRITE;
2004 				dataSize = karg.dataOutSize;
2005 			} else {
2006 				scsidir = MPI_SCSIIO_CONTROL_READ;
2007 				dataSize = karg.dataInSize;
2008 			}
2009 
2010 			pScsiReq->Control = cpu_to_le32(scsidir | qtag);
2011 			pScsiReq->DataLength = cpu_to_le32(dataSize);
2012 
2013 			ioc->ioctl->reset = MPTCTL_RESET_OK;
2014 			ioc->ioctl->target = target;
2015 
2016 		} else {
2017 			printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2018 				"SCSI driver is not loaded. \n",
2019 					__FILE__, __LINE__);
2020 			rc = -EFAULT;
2021 			goto done_free_mem;
2022 		}
2023 		break;
2024 
2025 	case MPI_FUNCTION_RAID_ACTION:
2026 		/* Just add a SGE
2027 		 */
2028 		break;
2029 
2030 	case MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
2031 		if (ioc->sh) {
2032 			SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
2033 			int qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
2034 			int scsidir = MPI_SCSIIO_CONTROL_READ;
2035 			int dataSize;
2036 
2037 			pScsiReq->MsgFlags = mpt_msg_flags();
2038 
2039 			/* verify that app has not requested
2040 			 *	more sense data than driver
2041 			 *	can provide, if so, reset this parameter
2042 			 * set the sense buffer pointer low address
2043 			 * update the control field to specify Q type
2044 			 */
2045 			if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
2046 				pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
2047 			else
2048 				pScsiReq->SenseBufferLength = karg.maxSenseBytes;
2049 
2050 			pScsiReq->SenseBufferLowAddr =
2051 				cpu_to_le32(ioc->sense_buf_low_dma
2052 				   + (req_idx * MPT_SENSE_BUFFER_ALLOC));
2053 
2054 			/* All commands to physical devices are tagged
2055 			 */
2056 
2057 			/* Have the IOCTL driver set the direction based
2058 			 * on the dataOutSize (ordering issue with Sparc).
2059 			 */
2060 			if (karg.dataOutSize > 0) {
2061 				scsidir = MPI_SCSIIO_CONTROL_WRITE;
2062 				dataSize = karg.dataOutSize;
2063 			} else {
2064 				scsidir = MPI_SCSIIO_CONTROL_READ;
2065 				dataSize = karg.dataInSize;
2066 			}
2067 
2068 			pScsiReq->Control = cpu_to_le32(scsidir | qtag);
2069 			pScsiReq->DataLength = cpu_to_le32(dataSize);
2070 
2071 			ioc->ioctl->reset = MPTCTL_RESET_OK;
2072 			ioc->ioctl->target = pScsiReq->TargetID;
2073 		} else {
2074 			printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2075 				"SCSI driver is not loaded. \n",
2076 					__FILE__, __LINE__);
2077 			rc = -EFAULT;
2078 			goto done_free_mem;
2079 		}
2080 		break;
2081 
2082 	case MPI_FUNCTION_SCSI_TASK_MGMT:
2083 		{
2084 			MPT_SCSI_HOST *hd = NULL;
2085 			if ((ioc->sh == NULL) || ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL)) {
2086 				printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2087 					"SCSI driver not loaded or SCSI host not found. \n",
2088 					__FILE__, __LINE__);
2089 				rc = -EFAULT;
2090 				goto done_free_mem;
2091 			} else if (mptctl_set_tm_flags(hd) != 0) {
2092 				rc = -EPERM;
2093 				goto done_free_mem;
2094 			}
2095 			tm_flags_set = 1;
2096 		}
2097 		break;
2098 
2099 	case MPI_FUNCTION_IOC_INIT:
2100 		{
2101 			IOCInit_t	*pInit = (IOCInit_t *) mf;
2102 			u32		high_addr, sense_high;
2103 
2104 			/* Verify that all entries in the IOC INIT match
2105 			 * existing setup (and in LE format).
2106 			 */
2107 			if (sizeof(dma_addr_t) == sizeof(u64)) {
2108 				high_addr = cpu_to_le32((u32)((u64)ioc->req_frames_dma >> 32));
2109 				sense_high= cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2110 			} else {
2111 				high_addr = 0;
2112 				sense_high= 0;
2113 			}
2114 
2115 			if ((pInit->Flags != 0) || (pInit->MaxDevices != ioc->facts.MaxDevices) ||
2116 				(pInit->MaxBuses != ioc->facts.MaxBuses) ||
2117 				(pInit->ReplyFrameSize != cpu_to_le16(ioc->reply_sz)) ||
2118 				(pInit->HostMfaHighAddr != high_addr) ||
2119 				(pInit->SenseBufferHighAddr != sense_high)) {
2120 				printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2121 					"IOC_INIT issued with 1 or more incorrect parameters. Rejected.\n",
2122 					__FILE__, __LINE__);
2123 				rc = -EFAULT;
2124 				goto done_free_mem;
2125 			}
2126 		}
2127 		break;
2128 	default:
2129 		/*
2130 		 * MPI_FUNCTION_PORT_ENABLE
2131 		 * MPI_FUNCTION_TARGET_CMD_BUFFER_POST
2132 		 * MPI_FUNCTION_TARGET_ASSIST
2133 		 * MPI_FUNCTION_TARGET_STATUS_SEND
2134 		 * MPI_FUNCTION_TARGET_MODE_ABORT
2135 		 * MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
2136 		 * MPI_FUNCTION_IO_UNIT_RESET
2137 		 * MPI_FUNCTION_HANDSHAKE
2138 		 * MPI_FUNCTION_REPLY_FRAME_REMOVAL
2139 		 * MPI_FUNCTION_EVENT_NOTIFICATION
2140 		 *  (driver handles event notification)
2141 		 * MPI_FUNCTION_EVENT_ACK
2142 		 */
2143 
2144 		/*  What to do with these???  CHECK ME!!!
2145 			MPI_FUNCTION_FC_LINK_SRVC_BUF_POST
2146 			MPI_FUNCTION_FC_LINK_SRVC_RSP
2147 			MPI_FUNCTION_FC_ABORT
2148 			MPI_FUNCTION_LAN_SEND
2149 			MPI_FUNCTION_LAN_RECEIVE
2150 		 	MPI_FUNCTION_LAN_RESET
2151 		*/
2152 
2153 		printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2154 			"Illegal request (function 0x%x) \n",
2155 			__FILE__, __LINE__, hdr->Function);
2156 		rc = -EFAULT;
2157 		goto done_free_mem;
2158 	}
2159 
2160 	/* Add the SGL ( at most one data in SGE and one data out SGE )
2161 	 * In the case of two SGE's - the data out (write) will always
2162 	 * preceede the data in (read) SGE. psgList is used to free the
2163 	 * allocated memory.
2164 	 */
2165 	psge = (char *) (((int *) mf) + karg.dataSgeOffset);
2166 	flagsLength = 0;
2167 
2168 	/* bufIn and bufOut are used for user to kernel space transfers
2169 	 */
2170 	bufIn.kptr = bufOut.kptr = NULL;
2171 	bufIn.len = bufOut.len = 0;
2172 
2173 	if (karg.dataOutSize > 0)
2174 		sgSize ++;
2175 
2176 	if (karg.dataInSize > 0)
2177 		sgSize ++;
2178 
2179 	if (sgSize > 0) {
2180 
2181 		/* Set up the dataOut memory allocation */
2182 		if (karg.dataOutSize > 0) {
2183 			dir = PCI_DMA_TODEVICE;
2184 			if (karg.dataInSize > 0) {
2185 				flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2186 						MPI_SGE_FLAGS_DIRECTION |
2187 						mpt_addr_size() )
2188 						<< MPI_SGE_FLAGS_SHIFT;
2189 			} else {
2190 				flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
2191 			}
2192 			flagsLength |= karg.dataOutSize;
2193 			bufOut.len = karg.dataOutSize;
2194 			bufOut.kptr = pci_alloc_consistent(
2195 					ioc->pcidev, bufOut.len, &dma_addr_out);
2196 
2197 			if (bufOut.kptr == NULL) {
2198 				rc = -ENOMEM;
2199 				goto done_free_mem;
2200 			} else {
2201 				/* Set up this SGE.
2202 				 * Copy to MF and to sglbuf
2203 				 */
2204 				mpt_add_sge(psge, flagsLength, dma_addr_out);
2205 				psge += (sizeof(u32) + sizeof(dma_addr_t));
2206 
2207 				/* Copy user data to kernel space.
2208 				 */
2209 				if (copy_from_user(bufOut.kptr,
2210 						karg.dataOutBufPtr,
2211 						bufOut.len)) {
2212 					printk(KERN_ERR
2213 						"%s@%d::mptctl_do_mpt_command - Unable "
2214 						"to read user data "
2215 						"struct @ %p\n",
2216 						__FILE__, __LINE__,(void*)karg.dataOutBufPtr);
2217 					rc =  -EFAULT;
2218 					goto done_free_mem;
2219 				}
2220 			}
2221 		}
2222 
2223 		if (karg.dataInSize > 0) {
2224 			dir = PCI_DMA_FROMDEVICE;
2225 			flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
2226 			flagsLength |= karg.dataInSize;
2227 
2228 			bufIn.len = karg.dataInSize;
2229 			bufIn.kptr = pci_alloc_consistent(ioc->pcidev,
2230 					bufIn.len, &dma_addr_in);
2231 
2232 			if (bufIn.kptr == NULL) {
2233 				rc = -ENOMEM;
2234 				goto done_free_mem;
2235 			} else {
2236 				/* Set up this SGE
2237 				 * Copy to MF and to sglbuf
2238 				 */
2239 				mpt_add_sge(psge, flagsLength, dma_addr_in);
2240 			}
2241 		}
2242 	} else  {
2243 		/* Add a NULL SGE
2244 		 */
2245 		mpt_add_sge(psge, flagsLength, (dma_addr_t) -1);
2246 	}
2247 
2248 	/* The request is complete. Set the timer parameters
2249 	 * and issue the request.
2250 	 */
2251 	if (karg.timeout > 0) {
2252 		ioc->ioctl->timer.expires = jiffies + HZ*karg.timeout;
2253 	} else {
2254 		ioc->ioctl->timer.expires = jiffies + HZ*MPT_IOCTL_DEFAULT_TIMEOUT;
2255 	}
2256 
2257 	ioc->ioctl->wait_done = 0;
2258 	ioc->ioctl->status |= MPT_IOCTL_STATUS_TIMER_ACTIVE;
2259 	add_timer(&ioc->ioctl->timer);
2260 
2261 	if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
2262 		rc = mpt_send_handshake_request(mptctl_id, ioc->id,
2263 				sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP);
2264 		if (rc == 0) {
2265 			wait_event(mptctl_wait, ioc->ioctl->wait_done);
2266 		} else {
2267 			mptctl_free_tm_flags(ioc);
2268 			tm_flags_set= 0;
2269 			del_timer(&ioc->ioctl->timer);
2270 			ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TIMER_ACTIVE;
2271 			ioc->ioctl->status |= MPT_IOCTL_STATUS_TM_FAILED;
2272 			mpt_free_msg_frame(mptctl_id, ioc->id, mf);
2273 		}
2274 	} else {
2275 		mpt_put_msg_frame(mptctl_id, ioc->id, mf);
2276 		wait_event(mptctl_wait, ioc->ioctl->wait_done);
2277 	}
2278 
2279 	mf = NULL;
2280 
2281 	/* MF Cleanup:
2282 	 * If command failed and failure triggered a diagnostic reset
2283 	 * OR a diagnostic reset happens during command processing,
2284 	 * no data, messaging queues are reset (mf cannot be accessed),
2285 	 * and status is DID_IOCRESET
2286 	 *
2287 	 * If a user-requested bus reset fails to be handshaked, then
2288 	 * mf is returned to free queue and status is TM_FAILED.
2289 	 *
2290 	 * Otherise, the command completed and the mf was freed
2291 	 # by ISR (mf cannot be touched).
2292 	 */
2293 	if (ioc->ioctl->status & MPT_IOCTL_STATUS_DID_IOCRESET) {
2294 		/* The timer callback deleted the
2295 		 * timer and reset the adapter queues.
2296 		 */
2297 		printk(KERN_WARNING "%s@%d::mptctl_do_mpt_command - "
2298 			"Timeout Occurred on IOCTL! Reset IOC.\n", __FILE__, __LINE__);
2299 		tm_flags_set= 0;
2300 		rc = -ETIME;
2301 	} else if (ioc->ioctl->status & MPT_IOCTL_STATUS_TM_FAILED) {
2302 		/* User TM request failed! mf has not been freed.
2303 		 */
2304 		rc = -ENODATA;
2305 	} else {
2306 		/* If a valid reply frame, copy to the user.
2307 		 * Offset 2: reply length in U32's
2308 		 */
2309 		if (ioc->ioctl->status & MPT_IOCTL_STATUS_RF_VALID) {
2310 			if (karg.maxReplyBytes < ioc->reply_sz) {
2311 				 sz = MIN(karg.maxReplyBytes, 4*ioc->ioctl->ReplyFrame[2]);
2312 			} else {
2313 				 sz = MIN(ioc->reply_sz, 4*ioc->ioctl->ReplyFrame[2]);
2314 			}
2315 
2316 			if (sz > 0) {
2317 				if (copy_to_user((char *)karg.replyFrameBufPtr,
2318 					 &ioc->ioctl->ReplyFrame, sz)){
2319 
2320 					 printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2321 					 "Unable to write out reply frame %p\n",
2322 					 __FILE__, __LINE__, (void*)karg.replyFrameBufPtr);
2323 					 rc =  -ENODATA;
2324 					 goto done_free_mem;
2325 				}
2326 			}
2327 		}
2328 
2329 		/* If valid sense data, copy to user.
2330 		 */
2331 		if (ioc->ioctl->status & MPT_IOCTL_STATUS_SENSE_VALID) {
2332 			sz = MIN(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE);
2333 			if (sz > 0) {
2334 				if (copy_to_user((char *)karg.senseDataPtr, ioc->ioctl->sense, sz)) {
2335 					printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2336 					"Unable to write sense data to user %p\n",
2337 					__FILE__, __LINE__,
2338 					(void*)karg.senseDataPtr);
2339 					rc =  -ENODATA;
2340 					goto done_free_mem;
2341 				}
2342 			}
2343 		}
2344 
2345 		/* If the overall status is _GOOD and data in, copy data
2346 		 * to user.
2347 		 */
2348 		if ((ioc->ioctl->status & MPT_IOCTL_STATUS_COMMAND_GOOD) &&
2349 					(karg.dataInSize > 0) && (bufIn.kptr)) {
2350 
2351 			if (copy_to_user((char *)karg.dataInBufPtr,
2352 					 bufIn.kptr, karg.dataInSize)) {
2353 				printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
2354 					"Unable to write data to user %p\n",
2355 					__FILE__, __LINE__,
2356 					(void*)karg.dataInBufPtr);
2357 				rc =  -ENODATA;
2358 			}
2359 		}
2360 	}
2361 
2362 done_free_mem:
2363 	/* Clear all status bits except TMTIMER_ACTIVE, this bit is cleared
2364 	 * upon completion of the TM command.
2365 	 * ioc->ioctl->status = 0;
2366 	 */
2367 	ioc->ioctl->status &= ~(MPT_IOCTL_STATUS_TIMER_ACTIVE | MPT_IOCTL_STATUS_TM_FAILED |
2368 			MPT_IOCTL_STATUS_COMMAND_GOOD | MPT_IOCTL_STATUS_SENSE_VALID |
2369 			MPT_IOCTL_STATUS_RF_VALID | MPT_IOCTL_STATUS_DID_IOCRESET);
2370 
2371 	if (tm_flags_set)
2372 		mptctl_free_tm_flags(ioc);
2373 
2374 	/* Free the allocated memory.
2375 	 */
2376 	 if (bufOut.kptr != NULL) {
2377 		pci_free_consistent(ioc->pcidev,
2378 			bufOut.len, (void *) bufOut.kptr, dma_addr_out);
2379 	}
2380 
2381 	if (bufIn.kptr != NULL) {
2382 		pci_free_consistent(ioc->pcidev,
2383 			bufIn.len, (void *) bufIn.kptr, dma_addr_in);
2384 	}
2385 
2386 	/* mf is null if command issued successfully
2387 	 * otherwise, failure occured after mf acquired.
2388 	 */
2389 	if (mf)
2390 		mpt_free_msg_frame(mptctl_id, ioc->id, mf);
2391 
2392 	return rc;
2393 }
2394 
2395 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2396 /* Prototype Routine for the HP HOST INFO command.
2397  *
2398  * Outputs:	None.
2399  * Return:	0 if successful
2400  *		-EFAULT if data unavailable
2401  *		-EBUSY  if previous command timout and IOC reset is not complete.
2402  *		-ENODEV if no such device/adapter
2403  *		-ETIME	if timer expires
2404  *		-ENOMEM if memory allocation error
2405  */
2406 static int
mptctl_hp_hostinfo(unsigned long arg,unsigned int data_size)2407 mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
2408 {
2409 	hp_host_info_t	*uarg = (hp_host_info_t *) arg;
2410 	MPT_ADAPTER		*ioc;
2411 	struct pci_dev		*pdev;
2412 	char			*pbuf;
2413 	dma_addr_t		buf_dma;
2414 	hp_host_info_t		karg;
2415 	CONFIGPARMS		cfg;
2416 	ConfigPageHeader_t	hdr;
2417 	int			iocnum;
2418 	int			rc, cim_rev;
2419 
2420 	dctlprintk((": mptctl_hp_hostinfo called.\n"));
2421 	/* Reset long to int. Should affect IA64 and SPARC only
2422 	 */
2423 	if (data_size == sizeof(hp_host_info_t))
2424 		cim_rev = 1;
2425 	else if (data_size == sizeof(hp_host_info_rev0_t))
2426 		cim_rev = 0; /* obsolete */
2427 	else
2428 		return -EFAULT;
2429 
2430 	if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) {
2431 		printk(KERN_ERR "%s@%d::mptctl_hp_host_info - "
2432 			"Unable to read in hp_host_info struct @ %p\n",
2433 				__FILE__, __LINE__, (void*)uarg);
2434 		return -EFAULT;
2435 	}
2436 
2437 	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
2438 	    (ioc == NULL)) {
2439 		dctlprintk((KERN_ERR "%s::mptctl_hp_hostinfo() @%d - ioc%d not found!\n",
2440 				__FILE__, __LINE__, iocnum));
2441 		return -ENODEV;
2442 	}
2443 
2444 	/* Fill in the data and return the structure to the calling
2445 	 * program
2446 	 */
2447 	pdev = (struct pci_dev *) ioc->pcidev;
2448 
2449 	karg.vendor = pdev->vendor;
2450 	karg.device = pdev->device;
2451 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2452 	karg.subsystem_id = pdev->subsystem_device;
2453 	karg.subsystem_vendor = pdev->subsystem_vendor;
2454 #endif
2455 	karg.devfn = pdev->devfn;
2456 	karg.bus = pdev->bus->number;
2457 
2458 	/* Save the SCSI host no. if
2459 	 * SCSI driver loaded
2460 	 */
2461 	if (ioc->sh != NULL)
2462 		karg.host_no = ioc->sh->host_no;
2463 	else
2464 		karg.host_no =  -1;
2465 
2466 	/* Reformat the fw_version into a string
2467 	 */
2468 	karg.fw_version[0] = ioc->facts.FWVersion.Struct.Major >= 10 ?
2469 		((ioc->facts.FWVersion.Struct.Major / 10) + '0') : '0';
2470 	karg.fw_version[1] = (ioc->facts.FWVersion.Struct.Major % 10 ) + '0';
2471 	karg.fw_version[2] = '.';
2472 	karg.fw_version[3] = ioc->facts.FWVersion.Struct.Minor >= 10 ?
2473 		((ioc->facts.FWVersion.Struct.Minor / 10) + '0') : '0';
2474 	karg.fw_version[4] = (ioc->facts.FWVersion.Struct.Minor % 10 ) + '0';
2475 	karg.fw_version[5] = '.';
2476 	karg.fw_version[6] = ioc->facts.FWVersion.Struct.Unit >= 10 ?
2477 		((ioc->facts.FWVersion.Struct.Unit / 10) + '0') : '0';
2478 	karg.fw_version[7] = (ioc->facts.FWVersion.Struct.Unit % 10 ) + '0';
2479 	karg.fw_version[8] = '.';
2480 	karg.fw_version[9] = ioc->facts.FWVersion.Struct.Dev >= 10 ?
2481 		((ioc->facts.FWVersion.Struct.Dev / 10) + '0') : '0';
2482 	karg.fw_version[10] = (ioc->facts.FWVersion.Struct.Dev % 10 ) + '0';
2483 	karg.fw_version[11] = '\0';
2484 
2485 	/* Issue a config request to get the device serial number
2486 	 */
2487 	hdr.PageVersion = 0;
2488 	hdr.PageLength = 0;
2489 	hdr.PageNumber = 0;
2490 	hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
2491 	cfg.hdr = &hdr;
2492 	cfg.physAddr = -1;
2493 	cfg.pageAddr = 0;
2494 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2495 	cfg.dir = 0;	/* read */
2496 	cfg.timeout = 10;
2497 
2498 	strncpy(karg.serial_number, " ", 24);
2499 	if (mpt_config(ioc, &cfg) == 0) {
2500 		if (cfg.hdr->PageLength > 0) {
2501 			/* Issue the second config page request */
2502 			cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2503 
2504 			pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
2505 			if (pbuf) {
2506 				cfg.physAddr = buf_dma;
2507 				if (mpt_config(ioc, &cfg) == 0) {
2508 					ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf;
2509 					if (strlen(pdata->BoardTracerNumber) > 1) {
2510 						strncpy(karg.serial_number, pdata->BoardTracerNumber, 24);
2511 						karg.serial_number[24-1]='\0';
2512 					}
2513 				}
2514 				pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
2515 				pbuf = NULL;
2516 			}
2517 		}
2518 	}
2519 	rc = mpt_GetIocState(ioc, 1);
2520 	switch (rc) {
2521 	case MPI_IOC_STATE_OPERATIONAL:
2522 		karg.ioc_status =  HP_STATUS_OK;
2523 		break;
2524 
2525 	case MPI_IOC_STATE_FAULT:
2526 		karg.ioc_status =  HP_STATUS_FAILED;
2527 		break;
2528 
2529 	case MPI_IOC_STATE_RESET:
2530 	case MPI_IOC_STATE_READY:
2531 	default:
2532 		karg.ioc_status =  HP_STATUS_OTHER;
2533 		break;
2534 	}
2535 
2536 	karg.base_io_addr = pdev->PCI_BASEADDR_START(0);
2537 
2538 	if ((int)ioc->chip_type <= (int) FC929)
2539 		karg.bus_phys_width = HP_BUS_WIDTH_UNK;
2540 	else
2541 		karg.bus_phys_width = HP_BUS_WIDTH_16;
2542 
2543 	karg.hard_resets = 0;
2544 	karg.soft_resets = 0;
2545 	karg.timeouts = 0;
2546 	if (ioc->sh != NULL) {
2547 		MPT_SCSI_HOST *hd =  (MPT_SCSI_HOST *)ioc->sh->hostdata;
2548 
2549 		if (hd && (cim_rev == 1)) {
2550 			karg.hard_resets = hd->hard_resets;
2551 			karg.soft_resets = hd->soft_resets;
2552 			karg.timeouts = hd->timeouts;
2553 		}
2554 	}
2555 
2556 	cfg.pageAddr = 0;
2557 	cfg.action = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
2558 	cfg.dir = MPI_TB_ISTWI_FLAGS_READ;
2559 	cfg.timeout = 10;
2560 	pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma);
2561 	if (pbuf) {
2562 		cfg.physAddr = buf_dma;
2563 		if ((mpt_toolbox(ioc, &cfg)) == 0) {
2564 			karg.rsvd = *(u32 *)pbuf;
2565 		}
2566 		pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma);
2567 		pbuf = NULL;
2568 	}
2569 
2570 	/* Copy the data from kernel memory to user memory
2571 	 */
2572 	if (copy_to_user((char *)arg, &karg,
2573 				sizeof(hp_host_info_t))) {
2574 		printk(KERN_ERR "%s@%d::mptctl_hpgethostinfo - "
2575 			"Unable to write out hp_host_info @ %p\n",
2576 				__FILE__, __LINE__, (void*)uarg);
2577 		return -EFAULT;
2578 	}
2579 
2580 	return 0;
2581 
2582 }
2583 
2584 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2585 /* Prototype Routine for the HP TARGET INFO command.
2586  *
2587  * Outputs:	None.
2588  * Return:	0 if successful
2589  *		-EFAULT if data unavailable
2590  *		-EBUSY  if previous command timout and IOC reset is not complete.
2591  *		-ENODEV if no such device/adapter
2592  *		-ETIME	if timer expires
2593  *		-ENOMEM if memory allocation error
2594  */
2595 static int
mptctl_hp_targetinfo(unsigned long arg)2596 mptctl_hp_targetinfo(unsigned long arg)
2597 {
2598 	hp_target_info_t	*uarg = (hp_target_info_t *) arg;
2599 	SCSIDevicePage0_t	*pg0_alloc;
2600 	SCSIDevicePage3_t	*pg3_alloc;
2601 	MPT_ADAPTER		*ioc;
2602 	MPT_SCSI_HOST 		*hd = NULL;
2603 	hp_target_info_t	karg;
2604 	int			iocnum;
2605 	int			data_sz;
2606 	dma_addr_t		page_dma;
2607 	CONFIGPARMS	 	cfg;
2608 	ConfigPageHeader_t	hdr;
2609 	int			tmp, np, rc = 0;
2610 
2611 	dctlprintk((": mptctl_hp_targetinfo called.\n"));
2612 	if (copy_from_user(&karg, uarg, sizeof(hp_target_info_t))) {
2613 		printk(KERN_ERR "%s@%d::mptctl_hp_targetinfo - "
2614 			"Unable to read in hp_host_targetinfo struct @ %p\n",
2615 				__FILE__, __LINE__, (void*)uarg);
2616 		return -EFAULT;
2617 	}
2618 
2619 	if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
2620 		(ioc == NULL)) {
2621 		dctlprintk((KERN_ERR "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n",
2622 				__FILE__, __LINE__, iocnum));
2623 		return -ENODEV;
2624 	}
2625 
2626 	/*  There is nothing to do for FCP parts.
2627 	 */
2628 	if ((int) ioc->chip_type <= (int) FC929)
2629 		return 0;
2630 
2631 	if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL))
2632 		return 0;
2633 
2634 	if (ioc->sh->host_no != karg.hdr.host)
2635 		return -ENODEV;
2636 
2637        /* Get the data transfer speeds
2638         */
2639 	data_sz = ioc->spi_data.sdp0length * 4;
2640 	pg0_alloc = (SCSIDevicePage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
2641 	if (pg0_alloc) {
2642 		hdr.PageVersion = ioc->spi_data.sdp0version;
2643 		hdr.PageLength = data_sz;
2644 		hdr.PageNumber = 0;
2645 		hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
2646 
2647 		cfg.hdr = &hdr;
2648 		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2649 		cfg.dir = 0;
2650 		cfg.timeout = 0;
2651 		cfg.physAddr = page_dma;
2652 
2653 		cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
2654 
2655 		if ((rc = mpt_config(ioc, &cfg)) == 0) {
2656 			np = le32_to_cpu(pg0_alloc->NegotiatedParameters);
2657 			karg.negotiated_width = np & MPI_SCSIDEVPAGE0_NP_WIDE ?
2658 					HP_BUS_WIDTH_16 : HP_BUS_WIDTH_8;
2659 
2660 			if (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) {
2661 				tmp = (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
2662 				if (tmp < 0x09)
2663 					karg.negotiated_speed = HP_DEV_SPEED_ULTRA320;
2664 				else if (tmp <= 0x09)
2665 					karg.negotiated_speed = HP_DEV_SPEED_ULTRA160;
2666 				else if (tmp <= 0x0A)
2667 					karg.negotiated_speed = HP_DEV_SPEED_ULTRA2;
2668 				else if (tmp <= 0x0C)
2669 					karg.negotiated_speed = HP_DEV_SPEED_ULTRA;
2670 				else if (tmp <= 0x25)
2671 					karg.negotiated_speed = HP_DEV_SPEED_FAST;
2672 				else
2673 					karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
2674 			} else
2675 				karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
2676 		}
2677 
2678 		pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg0_alloc, page_dma);
2679 	}
2680 
2681 	/* Set defaults
2682 	 */
2683 	karg.message_rejects = -1;
2684 	karg.phase_errors = -1;
2685 	karg.parity_errors = -1;
2686 	karg.select_timeouts = -1;
2687 
2688 	/* Get the target error parameters
2689 	 */
2690 	hdr.PageVersion = 0;
2691 	hdr.PageLength = 0;
2692 	hdr.PageNumber = 3;
2693 	hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
2694 
2695 	cfg.hdr = &hdr;
2696 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2697 	cfg.dir = 0;
2698 	cfg.timeout = 0;
2699 	cfg.physAddr = -1;
2700 	if ((mpt_config(ioc, &cfg) == 0) && (cfg.hdr->PageLength > 0)) {
2701 		/* Issue the second config page request */
2702 		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2703 		data_sz = (int) cfg.hdr->PageLength * 4;
2704 		pg3_alloc = (SCSIDevicePage3_t *) pci_alloc_consistent(
2705 							ioc->pcidev, data_sz, &page_dma);
2706 		if (pg3_alloc) {
2707 			cfg.physAddr = page_dma;
2708 			cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
2709 			if ((rc = mpt_config(ioc, &cfg)) == 0) {
2710 				karg.message_rejects = (u32) le16_to_cpu(pg3_alloc->MsgRejectCount);
2711 				karg.phase_errors = (u32) le16_to_cpu(pg3_alloc->PhaseErrorCount);
2712 				karg.parity_errors = (u32) le16_to_cpu(pg3_alloc->ParityErrorCount);
2713 			}
2714 			pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg3_alloc, page_dma);
2715 		}
2716 	}
2717 	hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2718 	if (hd != NULL)
2719 		karg.select_timeouts = hd->sel_timeout[karg.hdr.id];
2720 
2721 	/* Copy the data from kernel memory to user memory
2722 	 */
2723 	if (copy_to_user((char *)arg, &karg, sizeof(hp_target_info_t))) {
2724 		printk(KERN_ERR "%s@%d::mptctl_hp_target_info - "
2725 			"Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
2726 				__FILE__, __LINE__, (void*)uarg);
2727 		return -EFAULT;
2728 	}
2729 
2730 	return 0;
2731 }
2732 
2733 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2734 
2735 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,51)
2736 #define	owner_THIS_MODULE  .owner = THIS_MODULE,
2737 #else
2738 #define	owner_THIS_MODULE
2739 #endif
2740 
2741 static struct file_operations mptctl_fops = {
2742 	owner_THIS_MODULE
2743 	.llseek =	no_llseek,
2744 	.read =		mptctl_read,
2745 	.write =	mptctl_write,
2746 	.ioctl =	mptctl_ioctl,
2747 	.open =		mptctl_open,
2748 	.release =	mptctl_release,
2749 };
2750 
2751 static struct miscdevice mptctl_miscdev = {
2752 	MPT_MINOR,
2753 	MYNAM,
2754 	&mptctl_fops
2755 };
2756 
2757 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2758 
2759 #ifdef MPT_CONFIG_COMPAT
2760 extern int register_ioctl32_conversion(unsigned int cmd,
2761 				       int (*handler)(unsigned int,
2762 						      unsigned int,
2763 						      unsigned long,
2764 						      struct file *));
2765 int unregister_ioctl32_conversion(unsigned int cmd);
2766 
2767 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2768 /* compat_XXX functions are used to provide a conversion between
2769  * pointers and u32's. If the arg does not contain any pointers, then
2770  * a specialized function (compat_XXX) is not needed. If the arg
2771  * does contain pointer(s), then the specialized function is used
2772  * to ensure the structure contents is properly processed by mptctl.
2773  */
2774 static int
compat_mptctl_ioctl(unsigned int fd,unsigned int cmd,unsigned long arg,struct file * filp)2775 compat_mptctl_ioctl(unsigned int fd, unsigned int cmd,
2776 			unsigned long arg, struct file *filp)
2777 {
2778 	int ret;
2779 
2780 	lock_kernel();
2781 	dctlprintk((KERN_INFO MYNAM "::compat_mptctl_ioctl() called\n"));
2782 	ret = mptctl_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
2783 	unlock_kernel();
2784 	return ret;
2785 }
2786 
2787 static int
compat_mptfwxfer_ioctl(unsigned int fd,unsigned int cmd,unsigned long arg,struct file * filp)2788 compat_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd,
2789 			unsigned long arg, struct file *filp)
2790 {
2791 	struct mpt_fw_xfer32 kfw32;
2792 	struct mpt_fw_xfer kfw;
2793 	MPT_ADAPTER *iocp = NULL;
2794 	int iocnum, iocnumX;
2795 	int nonblock = (filp->f_flags & O_NONBLOCK);
2796 	int ret;
2797 
2798 	dctlprintk((KERN_INFO MYNAM "::compat_mptfwxfer_ioctl() called\n"));
2799 
2800 	if (copy_from_user(&kfw32, (char *)arg, sizeof(kfw32)))
2801 		return -EFAULT;
2802 
2803 	/* Verify intended MPT adapter */
2804 	iocnumX = kfw32.iocnum & 0xFF;
2805 	if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
2806 	    (iocp == NULL)) {
2807 		dctlprintk((KERN_ERR MYNAM "::compat_mptfwxfer_ioctl @%d - ioc%d not found!\n",
2808 				__LINE__, iocnumX));
2809 		return -ENODEV;
2810 	}
2811 
2812 	if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
2813 		return ret;
2814 
2815 	kfw.iocnum = iocnum;
2816 	kfw.fwlen = kfw32.fwlen;
2817 	kfw.bufp = (void *)(unsigned long)kfw32.bufp;
2818 
2819 	ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);
2820 
2821 	up(&mptctl_syscall_sem_ioc[iocp->id]);
2822 
2823 	return ret;
2824 }
2825 
2826 static int
compat_mpt_command(unsigned int fd,unsigned int cmd,unsigned long arg,struct file * filp)2827 compat_mpt_command(unsigned int fd, unsigned int cmd,
2828 			unsigned long arg, struct file *filp)
2829 {
2830 	struct mpt_ioctl_command32 karg32;
2831 	struct mpt_ioctl_command32 *uarg = (struct mpt_ioctl_command32 *) arg;
2832 	struct mpt_ioctl_command karg;
2833 	MPT_ADAPTER *iocp = NULL;
2834 	int iocnum, iocnumX;
2835 	int nonblock = (filp->f_flags & O_NONBLOCK);
2836 	int ret;
2837 
2838 	dctlprintk((KERN_INFO MYNAM "::compat_mpt_command() called\n"));
2839 
2840 	if (copy_from_user(&karg32, (char *)arg, sizeof(karg32)))
2841 		return -EFAULT;
2842 
2843 	/* Verify intended MPT adapter */
2844 	iocnumX = karg32.hdr.iocnum & 0xFF;
2845 	if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
2846 	    (iocp == NULL)) {
2847 		dctlprintk((KERN_ERR MYNAM "::compat_mpt_command @%d - ioc%d not found!\n",
2848 				__LINE__, iocnumX));
2849 		return -ENODEV;
2850 	}
2851 
2852 	if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
2853 		return ret;
2854 
2855 	/* Copy data to karg */
2856 	karg.hdr.iocnum = karg32.hdr.iocnum;
2857 	karg.hdr.port = karg32.hdr.port;
2858 	karg.timeout = karg32.timeout;
2859 	karg.maxReplyBytes = karg32.maxReplyBytes;
2860 
2861 	karg.dataInSize = karg32.dataInSize;
2862 	karg.dataOutSize = karg32.dataOutSize;
2863 	karg.maxSenseBytes = karg32.maxSenseBytes;
2864 	karg.dataSgeOffset = karg32.dataSgeOffset;
2865 
2866 	karg.replyFrameBufPtr = (char *)(unsigned long)karg32.replyFrameBufPtr;
2867 	karg.dataInBufPtr = (char *)(unsigned long)karg32.dataInBufPtr;
2868 	karg.dataOutBufPtr = (char *)(unsigned long)karg32.dataOutBufPtr;
2869 	karg.senseDataPtr = (char *)(unsigned long)karg32.senseDataPtr;
2870 
2871 	/* Pass new structure to do_mpt_command
2872 	 */
2873 	ret = mptctl_do_mpt_command (karg, (char *) &uarg->MF, 0);
2874 
2875 	up(&mptctl_syscall_sem_ioc[iocp->id]);
2876 
2877 	return ret;
2878 }
2879 
2880 #endif
2881 
2882 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
mptctl_init(void)2883 int __init mptctl_init(void)
2884 {
2885 	int err;
2886 	int i;
2887 	int where = 1;
2888 	int sz;
2889 	u8 *mem;
2890 	MPT_ADAPTER *ioc = NULL;
2891 	int iocnum;
2892 
2893 	show_mptmod_ver(my_NAME, my_VERSION);
2894 
2895 	for (i=0; i<MPT_MAX_ADAPTERS; i++) {
2896 		sema_init(&mptctl_syscall_sem_ioc[i], 1);
2897 
2898 		ioc = NULL;
2899 		if (((iocnum = mpt_verify_adapter(i, &ioc)) < 0) ||
2900 		    (ioc == NULL)) {
2901 			continue;
2902 		}
2903 		else {
2904 			/* This adapter instance is found.
2905 			 * Allocate and inite a MPT_IOCTL structure
2906 			 */
2907 			sz = sizeof (MPT_IOCTL);
2908 			mem = kmalloc(sz, GFP_KERNEL);
2909 			if (mem == NULL) {
2910 				err = -ENOMEM;
2911 				goto out_fail;
2912 			}
2913 
2914 			memset(mem, 0, sz);
2915 			ioc->ioctl = (MPT_IOCTL *) mem;
2916 			ioc->ioctl->ioc = ioc;
2917 			init_timer (&ioc->ioctl->timer);
2918 			ioc->ioctl->timer.data = (unsigned long) ioc->ioctl;
2919 			ioc->ioctl->timer.function = mptctl_timer_expired;
2920 			init_timer (&ioc->ioctl->TMtimer);
2921 			ioc->ioctl->TMtimer.data = (unsigned long) ioc->ioctl;
2922 			ioc->ioctl->TMtimer.function = mptctl_timer_expired;
2923 		}
2924 	}
2925 
2926 #ifdef MPT_CONFIG_COMPAT
2927 	err = register_ioctl32_conversion(MPTIOCINFO, compat_mptctl_ioctl);
2928 	if (++where && err) goto out_fail;
2929 	err = register_ioctl32_conversion(MPTIOCINFO1, compat_mptctl_ioctl);
2930 	if (++where && err) goto out_fail;
2931 	err = register_ioctl32_conversion(MPTTARGETINFO, compat_mptctl_ioctl);
2932 	if (++where && err) goto out_fail;
2933 	err = register_ioctl32_conversion(MPTTEST, compat_mptctl_ioctl);
2934 	if (++where && err) goto out_fail;
2935 	err = register_ioctl32_conversion(MPTEVENTQUERY, compat_mptctl_ioctl);
2936 	if (++where && err) goto out_fail;
2937 	err = register_ioctl32_conversion(MPTEVENTENABLE, compat_mptctl_ioctl);
2938 	if (++where && err) goto out_fail;
2939 	err = register_ioctl32_conversion(MPTEVENTREPORT, compat_mptctl_ioctl);
2940 	if (++where && err) goto out_fail;
2941 	err = register_ioctl32_conversion(MPTHARDRESET, compat_mptctl_ioctl);
2942 	if (++where && err) goto out_fail;
2943 	err = register_ioctl32_conversion(MPTCOMMAND32, compat_mpt_command);
2944 	if (++where && err) goto out_fail;
2945 	err = register_ioctl32_conversion(MPTFWDOWNLOAD32,
2946 					  compat_mptfwxfer_ioctl);
2947 	if (++where && err) goto out_fail;
2948 	err = register_ioctl32_conversion(HP_GETHOSTINFO, compat_mptctl_ioctl);
2949 	if (++where && err) goto out_fail;
2950 	err = register_ioctl32_conversion(HP_GETTARGETINFO, compat_mptctl_ioctl);
2951 	if (++where && err) goto out_fail;
2952 #endif
2953 
2954 	/* Register this device */
2955 	err = misc_register(&mptctl_miscdev);
2956 	if (err < 0) {
2957 		printk(KERN_ERR MYNAM ": Can't register misc device [minor=%d].\n", MPT_MINOR);
2958 		goto out_fail;
2959 	}
2960 	printk(KERN_INFO MYNAM ": Registered with Fusion MPT base driver\n");
2961 	printk(KERN_INFO MYNAM ": /dev/%s @ (major,minor=%d,%d)\n",
2962 			 mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
2963 
2964 	/*
2965 	 *  Install our handler
2966 	 */
2967 	++where;
2968 	if ((mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER)) < 0) {
2969 		printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
2970 		misc_deregister(&mptctl_miscdev);
2971 		err = -EBUSY;
2972 		goto out_fail;
2973 	}
2974 
2975 	if (mpt_reset_register(mptctl_id, mptctl_ioc_reset) == 0) {
2976 		dprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
2977 	} else {
2978 		/* FIXME! */
2979 	}
2980 
2981 	return 0;
2982 
2983 out_fail:
2984 
2985 #ifdef MPT_CONFIG_COMPAT
2986 	printk(KERN_ERR MYNAM ": ERROR: Failed to register ioctl32_conversion!"
2987 			" (%d:err=%d)\n", where, err);
2988 	unregister_ioctl32_conversion(MPTIOCINFO);
2989 	unregister_ioctl32_conversion(MPTIOCINFO1);
2990 	unregister_ioctl32_conversion(MPTTARGETINFO);
2991 	unregister_ioctl32_conversion(MPTTEST);
2992 	unregister_ioctl32_conversion(MPTEVENTQUERY);
2993 	unregister_ioctl32_conversion(MPTEVENTENABLE);
2994 	unregister_ioctl32_conversion(MPTEVENTREPORT);
2995 	unregister_ioctl32_conversion(MPTHARDRESET);
2996 	unregister_ioctl32_conversion(MPTCOMMAND32);
2997 	unregister_ioctl32_conversion(MPTFWDOWNLOAD32);
2998 	unregister_ioctl32_conversion(HP_GETHOSTINFO);
2999 	unregister_ioctl32_conversion(HP_GETTARGETINFO);
3000 #endif
3001 
3002 	for (i=0; i<MPT_MAX_ADAPTERS; i++) {
3003 		ioc = NULL;
3004 		if (((iocnum = mpt_verify_adapter(i, &ioc)) < 0) ||
3005 		    (ioc == NULL)) {
3006 			continue;
3007 		}
3008 		else {
3009 			if (ioc->ioctl) {
3010 				kfree ( ioc->ioctl );
3011 				ioc->ioctl = NULL;
3012 			}
3013 		}
3014 	}
3015 	return err;
3016 }
3017 
3018 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
mptctl_exit(void)3019 void mptctl_exit(void)
3020 {
3021 	int i;
3022 	MPT_ADAPTER *ioc;
3023 	int iocnum;
3024 
3025 	misc_deregister(&mptctl_miscdev);
3026 	printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n",
3027 			 mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
3028 
3029 	/* De-register reset handler from base module */
3030 	mpt_reset_deregister(mptctl_id);
3031 	dprintk((KERN_INFO MYNAM ": Deregistered for IOC reset notifications\n"));
3032 
3033 	/* De-register callback handler from base module */
3034 	mpt_deregister(mptctl_id);
3035 	printk(KERN_INFO MYNAM ": Deregistered from Fusion MPT base driver\n");
3036 
3037 #ifdef MPT_CONFIG_COMPAT
3038 	unregister_ioctl32_conversion(MPTIOCINFO);
3039 	unregister_ioctl32_conversion(MPTIOCINFO1);
3040 	unregister_ioctl32_conversion(MPTTARGETINFO);
3041 	unregister_ioctl32_conversion(MPTTEST);
3042 	unregister_ioctl32_conversion(MPTEVENTQUERY);
3043 	unregister_ioctl32_conversion(MPTEVENTENABLE);
3044 	unregister_ioctl32_conversion(MPTEVENTREPORT);
3045 	unregister_ioctl32_conversion(MPTHARDRESET);
3046 	unregister_ioctl32_conversion(MPTCOMMAND32);
3047 	unregister_ioctl32_conversion(MPTFWDOWNLOAD32);
3048 	unregister_ioctl32_conversion(HP_GETHOSTINFO);
3049 	unregister_ioctl32_conversion(HP_GETTARGETINFO);
3050 #endif
3051 
3052 	/* Free allocated memory */
3053 	for (i=0; i<MPT_MAX_ADAPTERS; i++) {
3054 		ioc = NULL;
3055 		if (((iocnum = mpt_verify_adapter(i, &ioc)) < 0) ||
3056 		    (ioc == NULL)) {
3057 			continue;
3058 		}
3059 		else {
3060 			if (ioc->ioctl) {
3061 				kfree ( ioc->ioctl );
3062 				ioc->ioctl = NULL;
3063 			}
3064 		}
3065 	}
3066 }
3067 
3068 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3069 
3070 module_init(mptctl_init);
3071 module_exit(mptctl_exit);
3072