OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [message/] [fusion/] [mptctl.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.