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