1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48#include <linux/kernel.h>
49#include <linux/module.h>
50#include <linux/errno.h>
51#include <linux/init.h>
52#include <linux/slab.h>
53#include <linux/types.h>
54#include <linux/pci.h>
55#include <linux/delay.h>
56#include <linux/miscdevice.h>
57#include <linux/mutex.h>
58#include <linux/compat.h>
59
60#include <asm/io.h>
61#include <linux/uaccess.h>
62
63#include <scsi/scsi.h>
64#include <scsi/scsi_cmnd.h>
65#include <scsi/scsi_device.h>
66#include <scsi/scsi_host.h>
67#include <scsi/scsi_tcq.h>
68
69#define COPYRIGHT "Copyright (c) 1999-2008 LSI Corporation"
70#define MODULEAUTHOR "LSI Corporation"
71#include "mptbase.h"
72#include "mptctl.h"
73
74
75#define my_NAME "Fusion MPT misc device (ioctl) driver"
76#define my_VERSION MPT_LINUX_VERSION_COMMON
77#define MYNAM "mptctl"
78
79MODULE_AUTHOR(MODULEAUTHOR);
80MODULE_DESCRIPTION(my_NAME);
81MODULE_LICENSE("GPL");
82MODULE_VERSION(my_VERSION);
83
84
85
86static DEFINE_MUTEX(mpctl_mutex);
87static u8 mptctl_id = MPT_MAX_PROTOCOL_DRIVERS;
88static u8 mptctl_taskmgmt_id = MPT_MAX_PROTOCOL_DRIVERS;
89
90static DECLARE_WAIT_QUEUE_HEAD ( mptctl_wait );
91
92
93
94struct buflist {
95 u8 *kptr;
96 int len;
97};
98
99
100
101
102
103static int mptctl_fw_download(unsigned long arg);
104static int mptctl_getiocinfo(unsigned long arg, unsigned int cmd);
105static int mptctl_gettargetinfo(unsigned long arg);
106static int mptctl_readtest(unsigned long arg);
107static int mptctl_mpt_command(unsigned long arg);
108static int mptctl_eventquery(unsigned long arg);
109static int mptctl_eventenable(unsigned long arg);
110static int mptctl_eventreport(unsigned long arg);
111static int mptctl_replace_fw(unsigned long arg);
112
113static int mptctl_do_reset(unsigned long arg);
114static int mptctl_hp_hostinfo(unsigned long arg, unsigned int cmd);
115static int mptctl_hp_targetinfo(unsigned long arg);
116
117static int mptctl_probe(struct pci_dev *, const struct pci_device_id *);
118static void mptctl_remove(struct pci_dev *);
119
120#ifdef CONFIG_COMPAT
121static long compat_mpctl_ioctl(struct file *f, unsigned cmd, unsigned long arg);
122#endif
123
124
125
126static int mptctl_do_mpt_command(struct mpt_ioctl_command karg, void __user *mfPtr);
127static int mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen);
128static MptSge_t *kbuf_alloc_2_sgl(int bytes, u32 dir, int sge_offset, int *frags,
129 struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc);
130static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma,
131 struct buflist *buflist, MPT_ADAPTER *ioc);
132
133
134
135
136static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);
137
138
139
140
141static int mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
142static struct fasync_struct *async_queue=NULL;
143
144
145
146
147
148
149#define MAX_FRAGS_SPILL1 9
150#define MAX_FRAGS_SPILL2 15
151#define FRAGS_PER_BUCKET (MAX_FRAGS_SPILL2 + 1)
152
153
154
155#define MAX_CHAIN_FRAGS (4 * MAX_FRAGS_SPILL2 + 1)
156
157
158
159
160#define MAX_SGL_BYTES ((MAX_FRAGS_SPILL1 + 1 + (4 * FRAGS_PER_BUCKET)) * 8)
161
162
163#define MAX_KMALLOC_SZ (128*1024)
164
165#define MPT_IOCTL_DEFAULT_TIMEOUT 10
166
167
168
169
170
171
172
173
174
175
176
177
178static inline int
179mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock)
180{
181 int rc = 0;
182
183 if (nonblock) {
184 if (!mutex_trylock(&ioc->ioctl_cmds.mutex))
185 rc = -EAGAIN;
186 } else {
187 if (mutex_lock_interruptible(&ioc->ioctl_cmds.mutex))
188 rc = -ERESTARTSYS;
189 }
190 return rc;
191}
192
193
194
195
196
197
198
199
200static int
201mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
202{
203 char *sense_data;
204 int req_index;
205 int sz;
206
207 if (!req)
208 return 0;
209
210 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "completing mpi function "
211 "(0x%02X), req=%p, reply=%p\n", ioc->name, req->u.hdr.Function,
212 req, reply));
213
214
215
216
217
218 if (ioc->ioctl_cmds.msg_context != req->u.hdr.MsgContext)
219 goto out_continuation;
220
221 ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
222
223 if (!reply)
224 goto out;
225
226 ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
227 sz = min(ioc->reply_sz, 4*reply->u.reply.MsgLength);
228 memcpy(ioc->ioctl_cmds.reply, reply, sz);
229
230 if (reply->u.reply.IOCStatus || reply->u.reply.IOCLogInfo)
231 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
232 "iocstatus (0x%04X), loginfo (0x%08X)\n", ioc->name,
233 le16_to_cpu(reply->u.reply.IOCStatus),
234 le32_to_cpu(reply->u.reply.IOCLogInfo)));
235
236 if ((req->u.hdr.Function == MPI_FUNCTION_SCSI_IO_REQUEST) ||
237 (req->u.hdr.Function ==
238 MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
239
240 if (reply->u.sreply.SCSIStatus || reply->u.sreply.SCSIState)
241 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
242 "scsi_status (0x%02x), scsi_state (0x%02x), "
243 "tag = (0x%04x), transfer_count (0x%08x)\n", ioc->name,
244 reply->u.sreply.SCSIStatus,
245 reply->u.sreply.SCSIState,
246 le16_to_cpu(reply->u.sreply.TaskTag),
247 le32_to_cpu(reply->u.sreply.TransferCount)));
248
249 if (reply->u.sreply.SCSIState &
250 MPI_SCSI_STATE_AUTOSENSE_VALID) {
251 sz = req->u.scsireq.SenseBufferLength;
252 req_index =
253 le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
254 sense_data = ((u8 *)ioc->sense_buf_pool +
255 (req_index * MPT_SENSE_BUFFER_ALLOC));
256 memcpy(ioc->ioctl_cmds.sense, sense_data, sz);
257 ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_SENSE_VALID;
258 }
259 }
260
261 out:
262
263
264 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_PENDING) {
265 if (req->u.hdr.Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
266 mpt_clear_taskmgmt_in_progress_flag(ioc);
267 ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
268 complete(&ioc->ioctl_cmds.done);
269 if (ioc->bus_type == SAS)
270 ioc->schedule_target_reset(ioc);
271 } else {
272 ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
273 complete(&ioc->ioctl_cmds.done);
274 }
275 }
276
277 out_continuation:
278 if (reply && (reply->u.reply.MsgFlags &
279 MPI_MSGFLAGS_CONTINUATION_REPLY))
280 return 0;
281 return 1;
282}
283
284
285static int
286mptctl_taskmgmt_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
287{
288 if (!mf)
289 return 0;
290
291 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
292 "TaskMgmt completed (mf=%p, mr=%p)\n",
293 ioc->name, mf, mr));
294
295 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
296
297 if (!mr)
298 goto out;
299
300 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
301 memcpy(ioc->taskmgmt_cmds.reply, mr,
302 min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
303 out:
304 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
305 mpt_clear_taskmgmt_in_progress_flag(ioc);
306 ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
307 complete(&ioc->taskmgmt_cmds.done);
308 if (ioc->bus_type == SAS)
309 ioc->schedule_target_reset(ioc);
310 return 1;
311 }
312 return 0;
313}
314
315static int
316mptctl_do_taskmgmt(MPT_ADAPTER *ioc, u8 tm_type, u8 bus_id, u8 target_id)
317{
318 MPT_FRAME_HDR *mf;
319 SCSITaskMgmt_t *pScsiTm;
320 SCSITaskMgmtReply_t *pScsiTmReply;
321 int ii;
322 int retval;
323 unsigned long timeout;
324 unsigned long time_count;
325 u16 iocstatus;
326
327
328 mutex_lock(&ioc->taskmgmt_cmds.mutex);
329 if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
330 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
331 return -EPERM;
332 }
333
334 retval = 0;
335
336 mf = mpt_get_msg_frame(mptctl_taskmgmt_id, ioc);
337 if (mf == NULL) {
338 dtmprintk(ioc,
339 printk(MYIOC_s_WARN_FMT "TaskMgmt, no msg frames!!\n",
340 ioc->name));
341 mpt_clear_taskmgmt_in_progress_flag(ioc);
342 retval = -ENOMEM;
343 goto tm_done;
344 }
345
346 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
347 ioc->name, mf));
348
349 pScsiTm = (SCSITaskMgmt_t *) mf;
350 memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t));
351 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
352 pScsiTm->TaskType = tm_type;
353 if ((tm_type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) &&
354 (ioc->bus_type == FC))
355 pScsiTm->MsgFlags =
356 MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
357 pScsiTm->TargetID = target_id;
358 pScsiTm->Bus = bus_id;
359 pScsiTm->ChainOffset = 0;
360 pScsiTm->Reserved = 0;
361 pScsiTm->Reserved1 = 0;
362 pScsiTm->TaskMsgContext = 0;
363 for (ii= 0; ii < 8; ii++)
364 pScsiTm->LUN[ii] = 0;
365 for (ii=0; ii < 7; ii++)
366 pScsiTm->Reserved2[ii] = 0;
367
368 switch (ioc->bus_type) {
369 case FC:
370 timeout = 40;
371 break;
372 case SAS:
373 timeout = 30;
374 break;
375 case SPI:
376 default:
377 timeout = 10;
378 break;
379 }
380
381 dtmprintk(ioc,
382 printk(MYIOC_s_DEBUG_FMT "TaskMgmt type=%d timeout=%ld\n",
383 ioc->name, tm_type, timeout));
384
385 INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
386 time_count = jiffies;
387 if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
388 (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
389 mpt_put_msg_frame_hi_pri(mptctl_taskmgmt_id, ioc, mf);
390 else {
391 retval = mpt_send_handshake_request(mptctl_taskmgmt_id, ioc,
392 sizeof(SCSITaskMgmt_t), (u32 *)pScsiTm, CAN_SLEEP);
393 if (retval != 0) {
394 dfailprintk(ioc,
395 printk(MYIOC_s_ERR_FMT
396 "TaskMgmt send_handshake FAILED!"
397 " (ioc %p, mf %p, rc=%d) \n", ioc->name,
398 ioc, mf, retval));
399 mpt_free_msg_frame(ioc, mf);
400 mpt_clear_taskmgmt_in_progress_flag(ioc);
401 goto tm_done;
402 }
403 }
404
405
406 ii = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done, timeout*HZ);
407
408 if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
409 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
410 "TaskMgmt failed\n", ioc->name));
411 mpt_free_msg_frame(ioc, mf);
412 mpt_clear_taskmgmt_in_progress_flag(ioc);
413 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
414 retval = 0;
415 else
416 retval = -1;
417 goto tm_done;
418 }
419
420 if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
421 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
422 "TaskMgmt failed\n", ioc->name));
423 retval = -1;
424 goto tm_done;
425 }
426
427 pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply;
428 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
429 "TaskMgmt fw_channel = %d, fw_id = %d, task_type=0x%02X, "
430 "iocstatus=0x%04X\n\tloginfo=0x%08X, response_code=0x%02X, "
431 "term_cmnds=%d\n", ioc->name, pScsiTmReply->Bus,
432 pScsiTmReply->TargetID, tm_type,
433 le16_to_cpu(pScsiTmReply->IOCStatus),
434 le32_to_cpu(pScsiTmReply->IOCLogInfo),
435 pScsiTmReply->ResponseCode,
436 le32_to_cpu(pScsiTmReply->TerminationCount)));
437
438 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
439
440 if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
441 iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED ||
442 iocstatus == MPI_IOCSTATUS_SUCCESS)
443 retval = 0;
444 else {
445 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
446 "TaskMgmt failed\n", ioc->name));
447 retval = -1;
448 }
449
450 tm_done:
451 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
452 CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
453 return retval;
454}
455
456
457
458
459
460
461
462static void
463mptctl_timeout_expired(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
464{
465 unsigned long flags;
466 int ret_val = -1;
467 SCSIIORequest_t *scsi_req = (SCSIIORequest_t *) mf;
468 u8 function = mf->u.hdr.Function;
469
470 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": %s\n",
471 ioc->name, __func__));
472
473 if (mpt_fwfault_debug)
474 mpt_halt_firmware(ioc);
475
476 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
477 if (ioc->ioc_reset_in_progress) {
478 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
479 CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status)
480 mpt_free_msg_frame(ioc, mf);
481 return;
482 }
483 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
484
485
486 CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status)
487
488 if (ioc->bus_type == SAS) {
489 if (function == MPI_FUNCTION_SCSI_IO_REQUEST)
490 ret_val = mptctl_do_taskmgmt(ioc,
491 MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
492 scsi_req->Bus, scsi_req->TargetID);
493 else if (function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)
494 ret_val = mptctl_do_taskmgmt(ioc,
495 MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
496 scsi_req->Bus, 0);
497 if (!ret_val)
498 return;
499 } else {
500 if ((function == MPI_FUNCTION_SCSI_IO_REQUEST) ||
501 (function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH))
502 ret_val = mptctl_do_taskmgmt(ioc,
503 MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
504 scsi_req->Bus, 0);
505 if (!ret_val)
506 return;
507 }
508
509 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling Reset! \n",
510 ioc->name));
511 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
512 mpt_free_msg_frame(ioc, mf);
513}
514
515
516
517
518
519
520
521
522
523static int
524mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
525{
526 switch(reset_phase) {
527 case MPT_IOC_SETUP_RESET:
528 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
529 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
530 break;
531 case MPT_IOC_PRE_RESET:
532 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
533 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
534 break;
535 case MPT_IOC_POST_RESET:
536 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
537 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
538 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_PENDING) {
539 ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_DID_IOCRESET;
540 complete(&ioc->ioctl_cmds.done);
541 }
542 break;
543 default:
544 break;
545 }
546
547 return 1;
548}
549
550
551
552static int
553mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
554{
555 u8 event;
556
557 event = le32_to_cpu(pEvReply->Event) & 0xFF;
558
559 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s() called\n",
560 ioc->name, __func__));
561 if(async_queue == NULL)
562 return 1;
563
564
565
566
567
568 if (event == 0x21) {
569 ioc->aen_event_read_flag=1;
570 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Raised SIGIO to application\n",
571 ioc->name));
572 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
573 "Raised SIGIO to application\n", ioc->name));
574 kill_fasync(&async_queue, SIGIO, POLL_IN);
575 return 1;
576 }
577
578
579
580
581
582 if(ioc->aen_event_read_flag)
583 return 1;
584
585
586
587
588 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
589 ioc->aen_event_read_flag=1;
590 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
591 "Raised SIGIO to application\n", ioc->name));
592 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
593 "Raised SIGIO to application\n", ioc->name));
594 kill_fasync(&async_queue, SIGIO, POLL_IN);
595 }
596 return 1;
597}
598
599static int
600mptctl_fasync(int fd, struct file *filep, int mode)
601{
602 MPT_ADAPTER *ioc;
603 int ret;
604
605 mutex_lock(&mpctl_mutex);
606 list_for_each_entry(ioc, &ioc_list, list)
607 ioc->aen_event_read_flag=0;
608
609 ret = fasync_helper(fd, filep, mode, &async_queue);
610 mutex_unlock(&mpctl_mutex);
611 return ret;
612}
613
614
615
616
617
618
619
620static long
621__mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
622{
623 mpt_ioctl_header __user *uhdr = (void __user *) arg;
624 mpt_ioctl_header khdr;
625 int iocnum;
626 unsigned iocnumX;
627 int nonblock = (file->f_flags & O_NONBLOCK);
628 int ret;
629 MPT_ADAPTER *iocp = NULL;
630
631 if (copy_from_user(&khdr, uhdr, sizeof(khdr))) {
632 printk(KERN_ERR MYNAM "%s::mptctl_ioctl() @%d - "
633 "Unable to copy mpt_ioctl_header data @ %p\n",
634 __FILE__, __LINE__, uhdr);
635 return -EFAULT;
636 }
637 ret = -ENXIO;
638
639
640
641
642 iocnumX = khdr.iocnum & 0xFF;
643 if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
644 (iocp == NULL))
645 return -ENODEV;
646
647 if (!iocp->active) {
648 printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - Controller disabled.\n",
649 __FILE__, __LINE__);
650 return -EFAULT;
651 }
652
653
654
655
656
657
658 if ((cmd & ~IOCSIZE_MASK) == (MPTIOCINFO & ~IOCSIZE_MASK)) {
659 return mptctl_getiocinfo(arg, _IOC_SIZE(cmd));
660 } else if (cmd == MPTTARGETINFO) {
661 return mptctl_gettargetinfo(arg);
662 } else if (cmd == MPTTEST) {
663 return mptctl_readtest(arg);
664 } else if (cmd == MPTEVENTQUERY) {
665 return mptctl_eventquery(arg);
666 } else if (cmd == MPTEVENTENABLE) {
667 return mptctl_eventenable(arg);
668 } else if (cmd == MPTEVENTREPORT) {
669 return mptctl_eventreport(arg);
670 } else if (cmd == MPTFWREPLACE) {
671 return mptctl_replace_fw(arg);
672 }
673
674
675
676
677 if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
678 return ret;
679
680 if (cmd == MPTFWDOWNLOAD)
681 ret = mptctl_fw_download(arg);
682 else if (cmd == MPTCOMMAND)
683 ret = mptctl_mpt_command(arg);
684 else if (cmd == MPTHARDRESET)
685 ret = mptctl_do_reset(arg);
686 else if ((cmd & ~IOCSIZE_MASK) == (HP_GETHOSTINFO & ~IOCSIZE_MASK))
687 ret = mptctl_hp_hostinfo(arg, _IOC_SIZE(cmd));
688 else if (cmd == HP_GETTARGETINFO)
689 ret = mptctl_hp_targetinfo(arg);
690 else
691 ret = -EINVAL;
692
693 mutex_unlock(&iocp->ioctl_cmds.mutex);
694
695 return ret;
696}
697
698static long
699mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
700{
701 long ret;
702 mutex_lock(&mpctl_mutex);
703 ret = __mptctl_ioctl(file, cmd, arg);
704 mutex_unlock(&mpctl_mutex);
705 return ret;
706}
707
708static int mptctl_do_reset(unsigned long arg)
709{
710 struct mpt_ioctl_diag_reset __user *urinfo = (void __user *) arg;
711 struct mpt_ioctl_diag_reset krinfo;
712 MPT_ADAPTER *iocp;
713
714 if (copy_from_user(&krinfo, urinfo, sizeof(struct mpt_ioctl_diag_reset))) {
715 printk(KERN_ERR MYNAM "%s@%d::mptctl_do_reset - "
716 "Unable to copy mpt_ioctl_diag_reset struct @ %p\n",
717 __FILE__, __LINE__, urinfo);
718 return -EFAULT;
719 }
720
721 if (mpt_verify_adapter(krinfo.hdr.iocnum, &iocp) < 0) {
722 printk(KERN_DEBUG MYNAM "%s@%d::mptctl_do_reset - ioc%d not found!\n",
723 __FILE__, __LINE__, krinfo.hdr.iocnum);
724 return -ENODEV;
725 }
726
727 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "mptctl_do_reset called.\n",
728 iocp->name));
729
730 if (mpt_HardResetHandler(iocp, CAN_SLEEP) != 0) {
731 printk (MYIOC_s_ERR_FMT "%s@%d::mptctl_do_reset - reset failed.\n",
732 iocp->name, __FILE__, __LINE__);
733 return -1;
734 }
735
736 return 0;
737}
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756static int
757mptctl_fw_download(unsigned long arg)
758{
759 struct mpt_fw_xfer __user *ufwdl = (void __user *) arg;
760 struct mpt_fw_xfer kfwdl;
761
762 if (copy_from_user(&kfwdl, ufwdl, sizeof(struct mpt_fw_xfer))) {
763 printk(KERN_ERR MYNAM "%s@%d::_ioctl_fwdl - "
764 "Unable to copy mpt_fw_xfer struct @ %p\n",
765 __FILE__, __LINE__, ufwdl);
766 return -EFAULT;
767 }
768
769 return mptctl_do_fw_download(kfwdl.iocnum, kfwdl.bufp, kfwdl.fwlen);
770}
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786static int
787mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
788{
789 FWDownload_t *dlmsg;
790 MPT_FRAME_HDR *mf;
791 MPT_ADAPTER *iocp;
792 FWDownloadTCSGE_t *ptsge;
793 MptSge_t *sgl, *sgIn;
794 char *sgOut;
795 struct buflist *buflist;
796 struct buflist *bl;
797 dma_addr_t sgl_dma;
798 int ret;
799 int numfrags = 0;
800 int maxfrags;
801 int n = 0;
802 u32 sgdir;
803 u32 nib;
804 int fw_bytes_copied = 0;
805 int i;
806 int sge_offset = 0;
807 u16 iocstat;
808 pFWDownloadReply_t ReplyMsg = NULL;
809 unsigned long timeleft;
810
811 if (mpt_verify_adapter(ioc, &iocp) < 0) {
812 printk(KERN_DEBUG MYNAM "ioctl_fwdl - ioc%d not found!\n",
813 ioc);
814 return -ENODEV;
815 } else {
816
817
818
819 if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
820 return -EAGAIN;
821 }
822
823 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT
824 "mptctl_do_fwdl called. mptctl_id = %xh.\n", iocp->name, mptctl_id));
825 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.bufp = %p\n",
826 iocp->name, ufwbuf));
827 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.fwlen = %d\n",
828 iocp->name, (int)fwlen));
829 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.ioc = %04xh\n",
830 iocp->name, ioc));
831
832 dlmsg = (FWDownload_t*) mf;
833 ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL;
834 sgOut = (char *) (ptsge + 1);
835
836
837
838
839 dlmsg->ImageType = MPI_FW_DOWNLOAD_ITYPE_FW;
840 dlmsg->Reserved = 0;
841 dlmsg->ChainOffset = 0;
842 dlmsg->Function = MPI_FUNCTION_FW_DOWNLOAD;
843 dlmsg->Reserved1[0] = dlmsg->Reserved1[1] = dlmsg->Reserved1[2] = 0;
844 if (iocp->facts.MsgVersion >= MPI_VERSION_01_05)
845 dlmsg->MsgFlags = MPI_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT;
846 else
847 dlmsg->MsgFlags = 0;
848
849
850
851
852 ptsge->Reserved = 0;
853 ptsge->ContextSize = 0;
854 ptsge->DetailsLength = 12;
855 ptsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
856 ptsge->Reserved_0100_Checksum = 0;
857 ptsge->ImageOffset = 0;
858 ptsge->ImageSize = cpu_to_le32(fwlen);
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876 sgdir = 0x04000000;
877 sge_offset = sizeof(MPIHeader_t) + sizeof(FWDownloadTCSGE_t);
878 if ((sgl = kbuf_alloc_2_sgl(fwlen, sgdir, sge_offset,
879 &numfrags, &buflist, &sgl_dma, iocp)) == NULL)
880 return -ENOMEM;
881
882
883
884
885
886
887
888
889
890
891
892
893 maxfrags = (iocp->req_sz - sizeof(MPIHeader_t) -
894 sizeof(FWDownloadTCSGE_t))
895 / iocp->SGE_size;
896 if (numfrags > maxfrags) {
897 ret = -EMLINK;
898 goto fwdl_out;
899 }
900
901 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: sgl buffer = %p, sgfrags = %d\n",
902 iocp->name, sgl, numfrags));
903
904
905
906
907
908 ret = -EFAULT;
909 sgIn = sgl;
910 bl = buflist;
911 for (i=0; i < numfrags; i++) {
912
913
914
915
916
917
918
919 nib = (sgIn->FlagsLength & 0x30000000) >> 28;
920 if (nib == 0 || nib == 3) {
921 ;
922 } else if (sgIn->Address) {
923 iocp->add_sge(sgOut, sgIn->FlagsLength, sgIn->Address);
924 n++;
925 if (copy_from_user(bl->kptr, ufwbuf+fw_bytes_copied, bl->len)) {
926 printk(MYIOC_s_ERR_FMT "%s@%d::_ioctl_fwdl - "
927 "Unable to copy f/w buffer hunk#%d @ %p\n",
928 iocp->name, __FILE__, __LINE__, n, ufwbuf);
929 goto fwdl_out;
930 }
931 fw_bytes_copied += bl->len;
932 }
933 sgIn++;
934 bl++;
935 sgOut += iocp->SGE_size;
936 }
937
938 DBG_DUMP_FW_DOWNLOAD(iocp, (u32 *)mf, numfrags);
939
940
941
942
943 ReplyMsg = NULL;
944 SET_MGMT_MSG_CONTEXT(iocp->ioctl_cmds.msg_context, dlmsg->MsgContext);
945 INITIALIZE_MGMT_STATUS(iocp->ioctl_cmds.status)
946 mpt_put_msg_frame(mptctl_id, iocp, mf);
947
948
949retry_wait:
950 timeleft = wait_for_completion_timeout(&iocp->ioctl_cmds.done, HZ*60);
951 if (!(iocp->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
952 ret = -ETIME;
953 printk(MYIOC_s_WARN_FMT "%s: failed\n", iocp->name, __func__);
954 if (iocp->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
955 mpt_free_msg_frame(iocp, mf);
956 goto fwdl_out;
957 }
958 if (!timeleft) {
959 printk(MYIOC_s_WARN_FMT
960 "FW download timeout, doorbell=0x%08x\n",
961 iocp->name, mpt_GetIocState(iocp, 0));
962 mptctl_timeout_expired(iocp, mf);
963 } else
964 goto retry_wait;
965 goto fwdl_out;
966 }
967
968 if (!(iocp->ioctl_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
969 printk(MYIOC_s_WARN_FMT "%s: failed\n", iocp->name, __func__);
970 mpt_free_msg_frame(iocp, mf);
971 ret = -ENODATA;
972 goto fwdl_out;
973 }
974
975 if (sgl)
976 kfree_sgl(sgl, sgl_dma, buflist, iocp);
977
978 ReplyMsg = (pFWDownloadReply_t)iocp->ioctl_cmds.reply;
979 iocstat = le16_to_cpu(ReplyMsg->IOCStatus) & MPI_IOCSTATUS_MASK;
980 if (iocstat == MPI_IOCSTATUS_SUCCESS) {
981 printk(MYIOC_s_INFO_FMT "F/W update successful!\n", iocp->name);
982 return 0;
983 } else if (iocstat == MPI_IOCSTATUS_INVALID_FUNCTION) {
984 printk(MYIOC_s_WARN_FMT "Hmmm... F/W download not supported!?!\n",
985 iocp->name);
986 printk(MYIOC_s_WARN_FMT "(time to go bang on somebodies door)\n",
987 iocp->name);
988 return -EBADRQC;
989 } else if (iocstat == MPI_IOCSTATUS_BUSY) {
990 printk(MYIOC_s_WARN_FMT "IOC_BUSY!\n", iocp->name);
991 printk(MYIOC_s_WARN_FMT "(try again later?)\n", iocp->name);
992 return -EBUSY;
993 } else {
994 printk(MYIOC_s_WARN_FMT "ioctl_fwdl() returned [bad] status = %04xh\n",
995 iocp->name, iocstat);
996 printk(MYIOC_s_WARN_FMT "(bad VooDoo)\n", iocp->name);
997 return -ENOMSG;
998 }
999 return 0;
1000
1001fwdl_out:
1002
1003 CLEAR_MGMT_STATUS(iocp->ioctl_cmds.status);
1004 SET_MGMT_MSG_CONTEXT(iocp->ioctl_cmds.msg_context, 0);
1005 kfree_sgl(sgl, sgl_dma, buflist, iocp);
1006 return ret;
1007}
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024static MptSge_t *
1025kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags,
1026 struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc)
1027{
1028 MptSge_t *sglbuf = NULL;
1029
1030 struct buflist *buflist = NULL;
1031 MptSge_t *sgl;
1032 int numfrags = 0;
1033 int fragcnt = 0;
1034 int alloc_sz = min(bytes,MAX_KMALLOC_SZ);
1035 int bytes_allocd = 0;
1036 int this_alloc;
1037 dma_addr_t pa;
1038 int i, buflist_ent;
1039 int sg_spill = MAX_FRAGS_SPILL1;
1040 int dir;
1041
1042 if (bytes < 0)
1043 return NULL;
1044
1045
1046 *frags = 0;
1047 *blp = NULL;
1048
1049
1050
1051
1052 i = MAX_SGL_BYTES / 8;
1053 buflist = kzalloc(i, GFP_USER);
1054 if (!buflist)
1055 return NULL;
1056 buflist_ent = 0;
1057
1058
1059
1060
1061
1062
1063 sglbuf = pci_alloc_consistent(ioc->pcidev, MAX_SGL_BYTES, sglbuf_dma);
1064 if (sglbuf == NULL)
1065 goto free_and_fail;
1066
1067 if (sgdir & 0x04000000)
1068 dir = PCI_DMA_TODEVICE;
1069 else
1070 dir = PCI_DMA_FROMDEVICE;
1071
1072
1073
1074
1075
1076
1077
1078
1079 sgl = sglbuf;
1080 sg_spill = ((ioc->req_sz - sge_offset)/ioc->SGE_size) - 1;
1081 while (bytes_allocd < bytes) {
1082 this_alloc = min(alloc_sz, bytes-bytes_allocd);
1083 buflist[buflist_ent].len = this_alloc;
1084 buflist[buflist_ent].kptr = pci_alloc_consistent(ioc->pcidev,
1085 this_alloc,
1086 &pa);
1087 if (buflist[buflist_ent].kptr == NULL) {
1088 alloc_sz = alloc_sz / 2;
1089 if (alloc_sz == 0) {
1090 printk(MYIOC_s_WARN_FMT "-SG: No can do - "
1091 "not enough memory! :-(\n", ioc->name);
1092 printk(MYIOC_s_WARN_FMT "-SG: (freeing %d frags)\n",
1093 ioc->name, numfrags);
1094 goto free_and_fail;
1095 }
1096 continue;
1097 } else {
1098 dma_addr_t dma_addr;
1099
1100 bytes_allocd += this_alloc;
1101 sgl->FlagsLength = (0x10000000|sgdir|this_alloc);
1102 dma_addr = pci_map_single(ioc->pcidev,
1103 buflist[buflist_ent].kptr, this_alloc, dir);
1104 sgl->Address = dma_addr;
1105
1106 fragcnt++;
1107 numfrags++;
1108 sgl++;
1109 buflist_ent++;
1110 }
1111
1112 if (bytes_allocd >= bytes)
1113 break;
1114
1115
1116 if (fragcnt == sg_spill) {
1117 printk(MYIOC_s_WARN_FMT
1118 "-SG: No can do - " "Chain required! :-(\n", ioc->name);
1119 printk(MYIOC_s_WARN_FMT "(freeing %d frags)\n", ioc->name, numfrags);
1120 goto free_and_fail;
1121 }
1122
1123
1124 if (numfrags*8 > MAX_SGL_BYTES){
1125
1126 printk(MYIOC_s_WARN_FMT "-SG: No can do - "
1127 "too many SG frags! :-(\n", ioc->name);
1128 printk(MYIOC_s_WARN_FMT "-SG: (freeing %d frags)\n",
1129 ioc->name, numfrags);
1130 goto free_and_fail;
1131 }
1132 }
1133
1134
1135 sgl[-1].FlagsLength |= 0xC1000000;
1136
1137 *frags = numfrags;
1138 *blp = buflist;
1139
1140 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "-SG: kbuf_alloc_2_sgl() - "
1141 "%d SG frags generated!\n", ioc->name, numfrags));
1142
1143 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "-SG: kbuf_alloc_2_sgl() - "
1144 "last (big) alloc_sz=%d\n", ioc->name, alloc_sz));
1145
1146 return sglbuf;
1147
1148free_and_fail:
1149 if (sglbuf != NULL) {
1150 for (i = 0; i < numfrags; i++) {
1151 dma_addr_t dma_addr;
1152 u8 *kptr;
1153 int len;
1154
1155 if ((sglbuf[i].FlagsLength >> 24) == 0x30)
1156 continue;
1157
1158 dma_addr = sglbuf[i].Address;
1159 kptr = buflist[i].kptr;
1160 len = buflist[i].len;
1161
1162 pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
1163 }
1164 pci_free_consistent(ioc->pcidev, MAX_SGL_BYTES, sglbuf, *sglbuf_dma);
1165 }
1166 kfree(buflist);
1167 return NULL;
1168}
1169
1170
1171
1172
1173
1174static void
1175kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma, struct buflist *buflist, MPT_ADAPTER *ioc)
1176{
1177 MptSge_t *sg = sgl;
1178 struct buflist *bl = buflist;
1179 u32 nib;
1180 int dir;
1181 int n = 0;
1182
1183 if (sg->FlagsLength & 0x04000000)
1184 dir = PCI_DMA_TODEVICE;
1185 else
1186 dir = PCI_DMA_FROMDEVICE;
1187
1188 nib = (sg->FlagsLength & 0xF0000000) >> 28;
1189 while (! (nib & 0x4)) {
1190
1191 if (nib == 0 || nib == 3) {
1192 ;
1193 } else if (sg->Address) {
1194 dma_addr_t dma_addr;
1195 void *kptr;
1196 int len;
1197
1198 dma_addr = sg->Address;
1199 kptr = bl->kptr;
1200 len = bl->len;
1201 pci_unmap_single(ioc->pcidev, dma_addr, len, dir);
1202 pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
1203 n++;
1204 }
1205 sg++;
1206 bl++;
1207 nib = (le32_to_cpu(sg->FlagsLength) & 0xF0000000) >> 28;
1208 }
1209
1210
1211 if (sg->Address) {
1212 dma_addr_t dma_addr;
1213 void *kptr;
1214 int len;
1215
1216 dma_addr = sg->Address;
1217 kptr = bl->kptr;
1218 len = bl->len;
1219 pci_unmap_single(ioc->pcidev, dma_addr, len, dir);
1220 pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
1221 n++;
1222 }
1223
1224 pci_free_consistent(ioc->pcidev, MAX_SGL_BYTES, sgl, sgl_dma);
1225 kfree(buflist);
1226 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "-SG: Free'd 1 SGL buf + %d kbufs!\n",
1227 ioc->name, n));
1228}
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240static int
1241mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
1242{
1243 struct mpt_ioctl_iocinfo __user *uarg = (void __user *) arg;
1244 struct mpt_ioctl_iocinfo *karg;
1245 MPT_ADAPTER *ioc;
1246 struct pci_dev *pdev;
1247 int iocnum;
1248 unsigned int port;
1249 int cim_rev;
1250 struct scsi_device *sdev;
1251 VirtDevice *vdevice;
1252
1253
1254
1255
1256
1257 if (data_size == sizeof(struct mpt_ioctl_iocinfo_rev0))
1258 cim_rev = 0;
1259 else if (data_size == sizeof(struct mpt_ioctl_iocinfo_rev1))
1260 cim_rev = 1;
1261 else if (data_size == sizeof(struct mpt_ioctl_iocinfo))
1262 cim_rev = 2;
1263 else if (data_size == (sizeof(struct mpt_ioctl_iocinfo_rev0)+12))
1264 cim_rev = 0;
1265 else
1266 return -EFAULT;
1267
1268 karg = memdup_user(uarg, data_size);
1269 if (IS_ERR(karg)) {
1270 printk(KERN_ERR MYNAM "%s@%d::mpt_ioctl_iocinfo() - memdup_user returned error [%ld]\n",
1271 __FILE__, __LINE__, PTR_ERR(karg));
1272 return PTR_ERR(karg);
1273 }
1274
1275 if (((iocnum = mpt_verify_adapter(karg->hdr.iocnum, &ioc)) < 0) ||
1276 (ioc == NULL)) {
1277 printk(KERN_DEBUG MYNAM "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n",
1278 __FILE__, __LINE__, iocnum);
1279 kfree(karg);
1280 return -ENODEV;
1281 }
1282
1283
1284 if (karg->hdr.maxDataSize != data_size) {
1285 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - "
1286 "Structure size mismatch. Command not completed.\n",
1287 ioc->name, __FILE__, __LINE__);
1288 kfree(karg);
1289 return -EFAULT;
1290 }
1291
1292 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_getiocinfo called.\n",
1293 ioc->name));
1294
1295
1296
1297
1298 if (ioc->bus_type == SAS)
1299 karg->adapterType = MPT_IOCTL_INTERFACE_SAS;
1300 else if (ioc->bus_type == FC)
1301 karg->adapterType = MPT_IOCTL_INTERFACE_FC;
1302 else
1303 karg->adapterType = MPT_IOCTL_INTERFACE_SCSI;
1304
1305 if (karg->hdr.port > 1) {
1306 kfree(karg);
1307 return -EINVAL;
1308 }
1309 port = karg->hdr.port;
1310
1311 karg->port = port;
1312 pdev = (struct pci_dev *) ioc->pcidev;
1313
1314 karg->pciId = pdev->device;
1315 karg->hwRev = pdev->revision;
1316 karg->subSystemDevice = pdev->subsystem_device;
1317 karg->subSystemVendor = pdev->subsystem_vendor;
1318
1319 if (cim_rev == 1) {
1320
1321
1322 karg->pciInfo.u.bits.busNumber = pdev->bus->number;
1323 karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
1324 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1325 } else if (cim_rev == 2) {
1326
1327
1328 karg->pciInfo.u.bits.busNumber = pdev->bus->number;
1329 karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
1330 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1331 karg->pciInfo.segmentID = pci_domain_nr(pdev->bus);
1332 }
1333
1334
1335
1336 karg->numDevices = 0;
1337 if (ioc->sh) {
1338 shost_for_each_device(sdev, ioc->sh) {
1339 vdevice = sdev->hostdata;
1340 if (vdevice == NULL || vdevice->vtarget == NULL)
1341 continue;
1342 if (vdevice->vtarget->tflags &
1343 MPT_TARGET_FLAGS_RAID_COMPONENT)
1344 continue;
1345 karg->numDevices++;
1346 }
1347 }
1348
1349
1350
1351 karg->FWVersion = ioc->facts.FWVersion.Word;
1352 karg->BIOSVersion = ioc->biosVersion;
1353
1354
1355
1356 strncpy (karg->driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH);
1357 karg->driverVersion[MPT_IOCTL_VERSION_LENGTH-1]='\0';
1358
1359 karg->busChangeEvent = 0;
1360 karg->hostId = ioc->pfacts[port].PortSCSIID;
1361 karg->rsvd[0] = karg->rsvd[1] = 0;
1362
1363
1364
1365 if (copy_to_user((char __user *)arg, karg, data_size)) {
1366 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - "
1367 "Unable to write out mpt_ioctl_iocinfo struct @ %p\n",
1368 ioc->name, __FILE__, __LINE__, uarg);
1369 kfree(karg);
1370 return -EFAULT;
1371 }
1372
1373 kfree(karg);
1374 return 0;
1375}
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387static int
1388mptctl_gettargetinfo (unsigned long arg)
1389{
1390 struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg;
1391 struct mpt_ioctl_targetinfo karg;
1392 MPT_ADAPTER *ioc;
1393 VirtDevice *vdevice;
1394 char *pmem;
1395 int *pdata;
1396 int iocnum;
1397 int numDevices = 0;
1398 int lun;
1399 int maxWordsLeft;
1400 int numBytes;
1401 u8 port;
1402 struct scsi_device *sdev;
1403
1404 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
1405 printk(KERN_ERR MYNAM "%s@%d::mptctl_gettargetinfo - "
1406 "Unable to read in mpt_ioctl_targetinfo struct @ %p\n",
1407 __FILE__, __LINE__, uarg);
1408 return -EFAULT;
1409 }
1410
1411 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1412 (ioc == NULL)) {
1413 printk(KERN_DEBUG MYNAM "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n",
1414 __FILE__, __LINE__, iocnum);
1415 return -ENODEV;
1416 }
1417
1418 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_gettargetinfo called.\n",
1419 ioc->name));
1420
1421
1422
1423
1424 numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
1425 maxWordsLeft = numBytes/sizeof(int);
1426 port = karg.hdr.port;
1427
1428 if (maxWordsLeft <= 0) {
1429 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n",
1430 ioc->name, __FILE__, __LINE__);
1431 return -ENOMEM;
1432 }
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448 pmem = kzalloc(numBytes, GFP_KERNEL);
1449 if (!pmem) {
1450 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n",
1451 ioc->name, __FILE__, __LINE__);
1452 return -ENOMEM;
1453 }
1454 pdata = (int *) pmem;
1455
1456
1457
1458 if (ioc->sh){
1459 shost_for_each_device(sdev, ioc->sh) {
1460 if (!maxWordsLeft)
1461 continue;
1462 vdevice = sdev->hostdata;
1463 if (vdevice == NULL || vdevice->vtarget == NULL)
1464 continue;
1465 if (vdevice->vtarget->tflags &
1466 MPT_TARGET_FLAGS_RAID_COMPONENT)
1467 continue;
1468 lun = (vdevice->vtarget->raidVolume) ? 0x80 : vdevice->lun;
1469 *pdata = (((u8)lun << 16) + (vdevice->vtarget->channel << 8) +
1470 (vdevice->vtarget->id ));
1471 pdata++;
1472 numDevices++;
1473 --maxWordsLeft;
1474 }
1475 }
1476 karg.numDevices = numDevices;
1477
1478
1479
1480 if (copy_to_user((char __user *)arg, &karg,
1481 sizeof(struct mpt_ioctl_targetinfo))) {
1482 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo - "
1483 "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
1484 ioc->name, __FILE__, __LINE__, uarg);
1485 kfree(pmem);
1486 return -EFAULT;
1487 }
1488
1489
1490
1491 if (copy_to_user(uarg->targetInfo, pmem, numBytes)) {
1492 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo - "
1493 "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
1494 ioc->name, __FILE__, __LINE__, pdata);
1495 kfree(pmem);
1496 return -EFAULT;
1497 }
1498
1499 kfree(pmem);
1500
1501 return 0;
1502}
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512static int
1513mptctl_readtest (unsigned long arg)
1514{
1515 struct mpt_ioctl_test __user *uarg = (void __user *) arg;
1516 struct mpt_ioctl_test karg;
1517 MPT_ADAPTER *ioc;
1518 int iocnum;
1519
1520 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) {
1521 printk(KERN_ERR MYNAM "%s@%d::mptctl_readtest - "
1522 "Unable to read in mpt_ioctl_test struct @ %p\n",
1523 __FILE__, __LINE__, uarg);
1524 return -EFAULT;
1525 }
1526
1527 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1528 (ioc == NULL)) {
1529 printk(KERN_DEBUG MYNAM "%s::mptctl_readtest() @%d - ioc%d not found!\n",
1530 __FILE__, __LINE__, iocnum);
1531 return -ENODEV;
1532 }
1533
1534 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_readtest called.\n",
1535 ioc->name));
1536
1537
1538
1539
1540#ifdef MFCNT
1541 karg.chip_type = ioc->mfcnt;
1542#else
1543 karg.chip_type = ioc->pcidev->device;
1544#endif
1545 strncpy (karg.name, ioc->name, MPT_MAX_NAME);
1546 karg.name[MPT_MAX_NAME-1]='\0';
1547 strncpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH);
1548 karg.product[MPT_PRODUCT_LENGTH-1]='\0';
1549
1550
1551
1552 if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_test))) {
1553 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_readtest - "
1554 "Unable to write out mpt_ioctl_test struct @ %p\n",
1555 ioc->name, __FILE__, __LINE__, uarg);
1556 return -EFAULT;
1557 }
1558
1559 return 0;
1560}
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573static int
1574mptctl_eventquery (unsigned long arg)
1575{
1576 struct mpt_ioctl_eventquery __user *uarg = (void __user *) arg;
1577 struct mpt_ioctl_eventquery karg;
1578 MPT_ADAPTER *ioc;
1579 int iocnum;
1580
1581 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) {
1582 printk(KERN_ERR MYNAM "%s@%d::mptctl_eventquery - "
1583 "Unable to read in mpt_ioctl_eventquery struct @ %p\n",
1584 __FILE__, __LINE__, uarg);
1585 return -EFAULT;
1586 }
1587
1588 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1589 (ioc == NULL)) {
1590 printk(KERN_DEBUG MYNAM "%s::mptctl_eventquery() @%d - ioc%d not found!\n",
1591 __FILE__, __LINE__, iocnum);
1592 return -ENODEV;
1593 }
1594
1595 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventquery called.\n",
1596 ioc->name));
1597 karg.eventEntries = MPTCTL_EVENT_LOG_SIZE;
1598 karg.eventTypes = ioc->eventTypes;
1599
1600
1601
1602 if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) {
1603 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_eventquery - "
1604 "Unable to write out mpt_ioctl_eventquery struct @ %p\n",
1605 ioc->name, __FILE__, __LINE__, uarg);
1606 return -EFAULT;
1607 }
1608 return 0;
1609}
1610
1611
1612static int
1613mptctl_eventenable (unsigned long arg)
1614{
1615 struct mpt_ioctl_eventenable __user *uarg = (void __user *) arg;
1616 struct mpt_ioctl_eventenable karg;
1617 MPT_ADAPTER *ioc;
1618 int iocnum;
1619
1620 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) {
1621 printk(KERN_ERR MYNAM "%s@%d::mptctl_eventenable - "
1622 "Unable to read in mpt_ioctl_eventenable struct @ %p\n",
1623 __FILE__, __LINE__, uarg);
1624 return -EFAULT;
1625 }
1626
1627 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1628 (ioc == NULL)) {
1629 printk(KERN_DEBUG MYNAM "%s::mptctl_eventenable() @%d - ioc%d not found!\n",
1630 __FILE__, __LINE__, iocnum);
1631 return -ENODEV;
1632 }
1633
1634 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventenable called.\n",
1635 ioc->name));
1636 if (ioc->events == NULL) {
1637
1638
1639 int sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
1640 ioc->events = kzalloc(sz, GFP_KERNEL);
1641 if (!ioc->events) {
1642 printk(MYIOC_s_ERR_FMT
1643 ": ERROR - Insufficient memory to add adapter!\n",
1644 ioc->name);
1645 return -ENOMEM;
1646 }
1647 ioc->alloc_total += sz;
1648
1649 ioc->eventContext = 0;
1650 }
1651
1652
1653
1654 ioc->eventTypes = karg.eventTypes;
1655
1656 return 0;
1657}
1658
1659
1660static int
1661mptctl_eventreport (unsigned long arg)
1662{
1663 struct mpt_ioctl_eventreport __user *uarg = (void __user *) arg;
1664 struct mpt_ioctl_eventreport karg;
1665 MPT_ADAPTER *ioc;
1666 int iocnum;
1667 int numBytes, maxEvents, max;
1668
1669 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) {
1670 printk(KERN_ERR MYNAM "%s@%d::mptctl_eventreport - "
1671 "Unable to read in mpt_ioctl_eventreport struct @ %p\n",
1672 __FILE__, __LINE__, uarg);
1673 return -EFAULT;
1674 }
1675
1676 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1677 (ioc == NULL)) {
1678 printk(KERN_DEBUG MYNAM "%s::mptctl_eventreport() @%d - ioc%d not found!\n",
1679 __FILE__, __LINE__, iocnum);
1680 return -ENODEV;
1681 }
1682 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventreport called.\n",
1683 ioc->name));
1684
1685 numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
1686 maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS);
1687
1688
1689 max = MPTCTL_EVENT_LOG_SIZE < maxEvents ? MPTCTL_EVENT_LOG_SIZE : maxEvents;
1690
1691
1692
1693
1694 if ((max < 1) || !ioc->events)
1695 return -ENODATA;
1696
1697
1698 ioc->aen_event_read_flag=0;
1699
1700
1701
1702 numBytes = max * sizeof(MPT_IOCTL_EVENTS);
1703 if (copy_to_user(uarg->eventData, ioc->events, numBytes)) {
1704 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_eventreport - "
1705 "Unable to write out mpt_ioctl_eventreport struct @ %p\n",
1706 ioc->name, __FILE__, __LINE__, ioc->events);
1707 return -EFAULT;
1708 }
1709
1710 return 0;
1711}
1712
1713
1714static int
1715mptctl_replace_fw (unsigned long arg)
1716{
1717 struct mpt_ioctl_replace_fw __user *uarg = (void __user *) arg;
1718 struct mpt_ioctl_replace_fw karg;
1719 MPT_ADAPTER *ioc;
1720 int iocnum;
1721 int newFwSize;
1722
1723 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
1724 printk(KERN_ERR MYNAM "%s@%d::mptctl_replace_fw - "
1725 "Unable to read in mpt_ioctl_replace_fw struct @ %p\n",
1726 __FILE__, __LINE__, uarg);
1727 return -EFAULT;
1728 }
1729
1730 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1731 (ioc == NULL)) {
1732 printk(KERN_DEBUG MYNAM "%s::mptctl_replace_fw() @%d - ioc%d not found!\n",
1733 __FILE__, __LINE__, iocnum);
1734 return -ENODEV;
1735 }
1736
1737 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_replace_fw called.\n",
1738 ioc->name));
1739
1740
1741 if (ioc->cached_fw == NULL)
1742 return 0;
1743
1744 mpt_free_fw_memory(ioc);
1745
1746
1747
1748 newFwSize = ALIGN(karg.newImageSize, 4);
1749
1750 mpt_alloc_fw_memory(ioc, newFwSize);
1751 if (ioc->cached_fw == NULL)
1752 return -ENOMEM;
1753
1754
1755
1756 if (copy_from_user(ioc->cached_fw, uarg->newImage, newFwSize)) {
1757 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_replace_fw - "
1758 "Unable to read in mpt_ioctl_replace_fw image "
1759 "@ %p\n", ioc->name, __FILE__, __LINE__, uarg);
1760 mpt_free_fw_memory(ioc);
1761 return -EFAULT;
1762 }
1763
1764
1765
1766 ioc->facts.FWImageSize = newFwSize;
1767 return 0;
1768}
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782static int
1783mptctl_mpt_command (unsigned long arg)
1784{
1785 struct mpt_ioctl_command __user *uarg = (void __user *) arg;
1786 struct mpt_ioctl_command karg;
1787 MPT_ADAPTER *ioc;
1788 int iocnum;
1789 int rc;
1790
1791
1792 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_command))) {
1793 printk(KERN_ERR MYNAM "%s@%d::mptctl_mpt_command - "
1794 "Unable to read in mpt_ioctl_command struct @ %p\n",
1795 __FILE__, __LINE__, uarg);
1796 return -EFAULT;
1797 }
1798
1799 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1800 (ioc == NULL)) {
1801 printk(KERN_DEBUG MYNAM "%s::mptctl_mpt_command() @%d - ioc%d not found!\n",
1802 __FILE__, __LINE__, iocnum);
1803 return -ENODEV;
1804 }
1805
1806 rc = mptctl_do_mpt_command (karg, &uarg->MF);
1807
1808 return rc;
1809}
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823static int
1824mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
1825{
1826 MPT_ADAPTER *ioc;
1827 MPT_FRAME_HDR *mf = NULL;
1828 MPIHeader_t *hdr;
1829 char *psge;
1830 struct buflist bufIn;
1831 struct buflist bufOut;
1832 dma_addr_t dma_addr_in;
1833 dma_addr_t dma_addr_out;
1834 int sgSize = 0;
1835 int iocnum, flagsLength;
1836 int sz, rc = 0;
1837 int msgContext;
1838 u16 req_idx;
1839 ulong timeout;
1840 unsigned long timeleft;
1841 struct scsi_device *sdev;
1842 unsigned long flags;
1843 u8 function;
1844
1845
1846
1847 bufIn.kptr = bufOut.kptr = NULL;
1848 bufIn.len = bufOut.len = 0;
1849
1850 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1851 (ioc == NULL)) {
1852 printk(KERN_DEBUG MYNAM "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n",
1853 __FILE__, __LINE__, iocnum);
1854 return -ENODEV;
1855 }
1856
1857 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
1858 if (ioc->ioc_reset_in_progress) {
1859 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
1860 printk(KERN_ERR MYNAM "%s@%d::mptctl_do_mpt_command - "
1861 "Busy with diagnostic reset\n", __FILE__, __LINE__);
1862 return -EBUSY;
1863 }
1864 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
1865
1866
1867 if (karg.maxReplyBytes < 0 ||
1868 karg.dataInSize < 0 ||
1869 karg.dataOutSize < 0 ||
1870 karg.dataSgeOffset < 0 ||
1871 karg.maxSenseBytes < 0 ||
1872 karg.dataSgeOffset > ioc->req_sz / 4)
1873 return -EINVAL;
1874
1875
1876
1877 sz = karg.dataSgeOffset * 4;
1878 if (karg.dataInSize > 0)
1879 sz += ioc->SGE_size;
1880 if (karg.dataOutSize > 0)
1881 sz += ioc->SGE_size;
1882
1883 if (sz > ioc->req_sz) {
1884 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1885 "Request frame too large (%d) maximum (%d)\n",
1886 ioc->name, __FILE__, __LINE__, sz, ioc->req_sz);
1887 return -EFAULT;
1888 }
1889
1890
1891
1892 if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL)
1893 return -EAGAIN;
1894
1895 hdr = (MPIHeader_t *) mf;
1896 msgContext = le32_to_cpu(hdr->MsgContext);
1897 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1898
1899
1900
1901
1902
1903 if (copy_from_user(mf, mfPtr, karg.dataSgeOffset * 4)) {
1904 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1905 "Unable to read MF from mpt_ioctl_command struct @ %p\n",
1906 ioc->name, __FILE__, __LINE__, mfPtr);
1907 function = -1;
1908 rc = -EFAULT;
1909 goto done_free_mem;
1910 }
1911 hdr->MsgContext = cpu_to_le32(msgContext);
1912 function = hdr->Function;
1913
1914
1915
1916
1917 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sending mpi function (0x%02X), req=%p\n",
1918 ioc->name, hdr->Function, mf));
1919
1920 switch (function) {
1921 case MPI_FUNCTION_IOC_FACTS:
1922 case MPI_FUNCTION_PORT_FACTS:
1923 karg.dataOutSize = karg.dataInSize = 0;
1924 break;
1925
1926 case MPI_FUNCTION_CONFIG:
1927 {
1928 Config_t *config_frame;
1929 config_frame = (Config_t *)mf;
1930 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\ttype=0x%02x ext_type=0x%02x "
1931 "number=0x%02x action=0x%02x\n", ioc->name,
1932 config_frame->Header.PageType,
1933 config_frame->ExtPageType,
1934 config_frame->Header.PageNumber,
1935 config_frame->Action));
1936 break;
1937 }
1938
1939 case MPI_FUNCTION_FC_COMMON_TRANSPORT_SEND:
1940 case MPI_FUNCTION_FC_EX_LINK_SRVC_SEND:
1941 case MPI_FUNCTION_FW_UPLOAD:
1942 case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR:
1943 case MPI_FUNCTION_FW_DOWNLOAD:
1944 case MPI_FUNCTION_FC_PRIMITIVE_SEND:
1945 case MPI_FUNCTION_TOOLBOX:
1946 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
1947 break;
1948
1949 case MPI_FUNCTION_SCSI_IO_REQUEST:
1950 if (ioc->sh) {
1951 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
1952 int qtag = MPI_SCSIIO_CONTROL_UNTAGGED;
1953 int scsidir = 0;
1954 int dataSize;
1955 u32 id;
1956
1957 id = (ioc->devices_per_bus == 0) ? 256 : ioc->devices_per_bus;
1958 if (pScsiReq->TargetID > id) {
1959 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1960 "Target ID out of bounds. \n",
1961 ioc->name, __FILE__, __LINE__);
1962 rc = -ENODEV;
1963 goto done_free_mem;
1964 }
1965
1966 if (pScsiReq->Bus >= ioc->number_of_buses) {
1967 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1968 "Target Bus out of bounds. \n",
1969 ioc->name, __FILE__, __LINE__);
1970 rc = -ENODEV;
1971 goto done_free_mem;
1972 }
1973
1974 pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
1975 pScsiReq->MsgFlags |= mpt_msg_flags(ioc);
1976
1977
1978
1979
1980
1981
1982
1983
1984 if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
1985 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1986 else
1987 pScsiReq->SenseBufferLength = karg.maxSenseBytes;
1988
1989 pScsiReq->SenseBufferLowAddr =
1990 cpu_to_le32(ioc->sense_buf_low_dma
1991 + (req_idx * MPT_SENSE_BUFFER_ALLOC));
1992
1993 shost_for_each_device(sdev, ioc->sh) {
1994 struct scsi_target *starget = scsi_target(sdev);
1995 VirtTarget *vtarget = starget->hostdata;
1996
1997 if (vtarget == NULL)
1998 continue;
1999
2000 if ((pScsiReq->TargetID == vtarget->id) &&
2001 (pScsiReq->Bus == vtarget->channel) &&
2002 (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2003 qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
2004 }
2005
2006
2007
2008
2009 if (karg.dataOutSize > 0) {
2010 scsidir = MPI_SCSIIO_CONTROL_WRITE;
2011 dataSize = karg.dataOutSize;
2012 } else {
2013 scsidir = MPI_SCSIIO_CONTROL_READ;
2014 dataSize = karg.dataInSize;
2015 }
2016
2017 pScsiReq->Control = cpu_to_le32(scsidir | qtag);
2018 pScsiReq->DataLength = cpu_to_le32(dataSize);
2019
2020
2021 } else {
2022 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2023 "SCSI driver is not loaded. \n",
2024 ioc->name, __FILE__, __LINE__);
2025 rc = -EFAULT;
2026 goto done_free_mem;
2027 }
2028 break;
2029
2030 case MPI_FUNCTION_SMP_PASSTHROUGH:
2031
2032
2033
2034
2035
2036
2037 break;
2038
2039 case MPI_FUNCTION_SATA_PASSTHROUGH:
2040 if (!ioc->sh) {
2041 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2042 "SCSI driver is not loaded. \n",
2043 ioc->name, __FILE__, __LINE__);
2044 rc = -EFAULT;
2045 goto done_free_mem;
2046 }
2047 break;
2048
2049 case MPI_FUNCTION_RAID_ACTION:
2050
2051
2052 break;
2053
2054 case MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
2055 if (ioc->sh) {
2056 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
2057 int qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
2058 int scsidir = MPI_SCSIIO_CONTROL_READ;
2059 int dataSize;
2060
2061 pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
2062 pScsiReq->MsgFlags |= mpt_msg_flags(ioc);
2063
2064
2065
2066
2067
2068
2069
2070
2071 if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
2072 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
2073 else
2074 pScsiReq->SenseBufferLength = karg.maxSenseBytes;
2075
2076 pScsiReq->SenseBufferLowAddr =
2077 cpu_to_le32(ioc->sense_buf_low_dma
2078 + (req_idx * MPT_SENSE_BUFFER_ALLOC));
2079
2080
2081
2082
2083
2084
2085
2086 if (karg.dataOutSize > 0) {
2087 scsidir = MPI_SCSIIO_CONTROL_WRITE;
2088 dataSize = karg.dataOutSize;
2089 } else {
2090 scsidir = MPI_SCSIIO_CONTROL_READ;
2091 dataSize = karg.dataInSize;
2092 }
2093
2094 pScsiReq->Control = cpu_to_le32(scsidir | qtag);
2095 pScsiReq->DataLength = cpu_to_le32(dataSize);
2096
2097 } else {
2098 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2099 "SCSI driver is not loaded. \n",
2100 ioc->name, __FILE__, __LINE__);
2101 rc = -EFAULT;
2102 goto done_free_mem;
2103 }
2104 break;
2105
2106 case MPI_FUNCTION_SCSI_TASK_MGMT:
2107 {
2108 SCSITaskMgmt_t *pScsiTm;
2109 pScsiTm = (SCSITaskMgmt_t *)mf;
2110 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2111 "\tTaskType=0x%x MsgFlags=0x%x "
2112 "TaskMsgContext=0x%x id=%d channel=%d\n",
2113 ioc->name, pScsiTm->TaskType, le32_to_cpu
2114 (pScsiTm->TaskMsgContext), pScsiTm->MsgFlags,
2115 pScsiTm->TargetID, pScsiTm->Bus));
2116 break;
2117 }
2118
2119 case MPI_FUNCTION_IOC_INIT:
2120 {
2121 IOCInit_t *pInit = (IOCInit_t *) mf;
2122 u32 high_addr, sense_high;
2123
2124
2125
2126
2127 if (sizeof(dma_addr_t) == sizeof(u64)) {
2128 high_addr = cpu_to_le32((u32)((u64)ioc->req_frames_dma >> 32));
2129 sense_high= cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2130 } else {
2131 high_addr = 0;
2132 sense_high= 0;
2133 }
2134
2135 if ((pInit->Flags != 0) || (pInit->MaxDevices != ioc->facts.MaxDevices) ||
2136 (pInit->MaxBuses != ioc->facts.MaxBuses) ||
2137 (pInit->ReplyFrameSize != cpu_to_le16(ioc->reply_sz)) ||
2138 (pInit->HostMfaHighAddr != high_addr) ||
2139 (pInit->SenseBufferHighAddr != sense_high)) {
2140 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2141 "IOC_INIT issued with 1 or more incorrect parameters. Rejected.\n",
2142 ioc->name, __FILE__, __LINE__);
2143 rc = -EFAULT;
2144 goto done_free_mem;
2145 }
2146 }
2147 break;
2148 default:
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2174 "Illegal request (function 0x%x) \n",
2175 ioc->name, __FILE__, __LINE__, hdr->Function);
2176 rc = -EFAULT;
2177 goto done_free_mem;
2178 }
2179
2180
2181
2182
2183
2184
2185 psge = (char *) (((int *) mf) + karg.dataSgeOffset);
2186 flagsLength = 0;
2187
2188 if (karg.dataOutSize > 0)
2189 sgSize ++;
2190
2191 if (karg.dataInSize > 0)
2192 sgSize ++;
2193
2194 if (sgSize > 0) {
2195
2196
2197 if (karg.dataOutSize > 0) {
2198 if (karg.dataInSize > 0) {
2199 flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2200 MPI_SGE_FLAGS_END_OF_BUFFER |
2201 MPI_SGE_FLAGS_DIRECTION)
2202 << MPI_SGE_FLAGS_SHIFT;
2203 } else {
2204 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
2205 }
2206 flagsLength |= karg.dataOutSize;
2207 bufOut.len = karg.dataOutSize;
2208 bufOut.kptr = pci_alloc_consistent(
2209 ioc->pcidev, bufOut.len, &dma_addr_out);
2210
2211 if (bufOut.kptr == NULL) {
2212 rc = -ENOMEM;
2213 goto done_free_mem;
2214 } else {
2215
2216
2217
2218 ioc->add_sge(psge, flagsLength, dma_addr_out);
2219 psge += ioc->SGE_size;
2220
2221
2222
2223 if (copy_from_user(bufOut.kptr,
2224 karg.dataOutBufPtr,
2225 bufOut.len)) {
2226 printk(MYIOC_s_ERR_FMT
2227 "%s@%d::mptctl_do_mpt_command - Unable "
2228 "to read user data "
2229 "struct @ %p\n",
2230 ioc->name, __FILE__, __LINE__,karg.dataOutBufPtr);
2231 rc = -EFAULT;
2232 goto done_free_mem;
2233 }
2234 }
2235 }
2236
2237 if (karg.dataInSize > 0) {
2238 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
2239 flagsLength |= karg.dataInSize;
2240
2241 bufIn.len = karg.dataInSize;
2242 bufIn.kptr = pci_alloc_consistent(ioc->pcidev,
2243 bufIn.len, &dma_addr_in);
2244
2245 if (bufIn.kptr == NULL) {
2246 rc = -ENOMEM;
2247 goto done_free_mem;
2248 } else {
2249
2250
2251
2252 ioc->add_sge(psge, flagsLength, dma_addr_in);
2253 }
2254 }
2255 } else {
2256
2257
2258 ioc->add_sge(psge, flagsLength, (dma_addr_t) -1);
2259 }
2260
2261 SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, hdr->MsgContext);
2262 INITIALIZE_MGMT_STATUS(ioc->ioctl_cmds.status)
2263 if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
2264
2265 mutex_lock(&ioc->taskmgmt_cmds.mutex);
2266 if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
2267 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2268 goto done_free_mem;
2269 }
2270
2271 DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
2272
2273 if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
2274 (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
2275 mpt_put_msg_frame_hi_pri(mptctl_id, ioc, mf);
2276 else {
2277 rc =mpt_send_handshake_request(mptctl_id, ioc,
2278 sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP);
2279 if (rc != 0) {
2280 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2281 "send_handshake FAILED! (ioc %p, mf %p)\n",
2282 ioc->name, ioc, mf));
2283 mpt_clear_taskmgmt_in_progress_flag(ioc);
2284 rc = -ENODATA;
2285 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2286 goto done_free_mem;
2287 }
2288 }
2289
2290 } else
2291 mpt_put_msg_frame(mptctl_id, ioc, mf);
2292
2293
2294 timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT;
2295retry_wait:
2296 timeleft = wait_for_completion_timeout(&ioc->ioctl_cmds.done,
2297 HZ*timeout);
2298 if (!(ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2299 rc = -ETIME;
2300 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: TIMED OUT!\n",
2301 ioc->name, __func__));
2302 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
2303 if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
2304 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2305 goto done_free_mem;
2306 }
2307 if (!timeleft) {
2308 printk(MYIOC_s_WARN_FMT
2309 "mpt cmd timeout, doorbell=0x%08x"
2310 " function=0x%x\n",
2311 ioc->name, mpt_GetIocState(ioc, 0), function);
2312 if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
2313 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2314 mptctl_timeout_expired(ioc, mf);
2315 mf = NULL;
2316 } else
2317 goto retry_wait;
2318 goto done_free_mem;
2319 }
2320
2321 if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
2322 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2323
2324
2325 mf = NULL;
2326
2327
2328
2329
2330 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_RF_VALID) {
2331 if (karg.maxReplyBytes < ioc->reply_sz) {
2332 sz = min(karg.maxReplyBytes,
2333 4*ioc->ioctl_cmds.reply[2]);
2334 } else {
2335 sz = min(ioc->reply_sz, 4*ioc->ioctl_cmds.reply[2]);
2336 }
2337 if (sz > 0) {
2338 if (copy_to_user(karg.replyFrameBufPtr,
2339 ioc->ioctl_cmds.reply, sz)){
2340 printk(MYIOC_s_ERR_FMT
2341 "%s@%d::mptctl_do_mpt_command - "
2342 "Unable to write out reply frame %p\n",
2343 ioc->name, __FILE__, __LINE__, karg.replyFrameBufPtr);
2344 rc = -ENODATA;
2345 goto done_free_mem;
2346 }
2347 }
2348 }
2349
2350
2351
2352 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_SENSE_VALID) {
2353 sz = min(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE);
2354 if (sz > 0) {
2355 if (copy_to_user(karg.senseDataPtr,
2356 ioc->ioctl_cmds.sense, sz)) {
2357 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2358 "Unable to write sense data to user %p\n",
2359 ioc->name, __FILE__, __LINE__,
2360 karg.senseDataPtr);
2361 rc = -ENODATA;
2362 goto done_free_mem;
2363 }
2364 }
2365 }
2366
2367
2368
2369
2370 if ((ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD) &&
2371 (karg.dataInSize > 0) && (bufIn.kptr)) {
2372
2373 if (copy_to_user(karg.dataInBufPtr,
2374 bufIn.kptr, karg.dataInSize)) {
2375 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2376 "Unable to write data to user %p\n",
2377 ioc->name, __FILE__, __LINE__,
2378 karg.dataInBufPtr);
2379 rc = -ENODATA;
2380 }
2381 }
2382
2383done_free_mem:
2384
2385 CLEAR_MGMT_STATUS(ioc->ioctl_cmds.status)
2386 SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, 0);
2387
2388
2389
2390 if (bufOut.kptr != NULL) {
2391 pci_free_consistent(ioc->pcidev,
2392 bufOut.len, (void *) bufOut.kptr, dma_addr_out);
2393 }
2394
2395 if (bufIn.kptr != NULL) {
2396 pci_free_consistent(ioc->pcidev,
2397 bufIn.len, (void *) bufIn.kptr, dma_addr_in);
2398 }
2399
2400
2401
2402
2403 if (mf)
2404 mpt_free_msg_frame(ioc, mf);
2405
2406 return rc;
2407}
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420static int
2421mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
2422{
2423 hp_host_info_t __user *uarg = (void __user *) arg;
2424 MPT_ADAPTER *ioc;
2425 struct pci_dev *pdev;
2426 char *pbuf=NULL;
2427 dma_addr_t buf_dma;
2428 hp_host_info_t karg;
2429 CONFIGPARMS cfg;
2430 ConfigPageHeader_t hdr;
2431 int iocnum;
2432 int rc, cim_rev;
2433 ToolboxIstwiReadWriteRequest_t *IstwiRWRequest;
2434 MPT_FRAME_HDR *mf = NULL;
2435 unsigned long timeleft;
2436 int retval;
2437 u32 msgcontext;
2438
2439
2440
2441 if (data_size == sizeof(hp_host_info_t))
2442 cim_rev = 1;
2443 else if (data_size == sizeof(hp_host_info_rev0_t))
2444 cim_rev = 0;
2445 else
2446 return -EFAULT;
2447
2448 if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) {
2449 printk(KERN_ERR MYNAM "%s@%d::mptctl_hp_host_info - "
2450 "Unable to read in hp_host_info struct @ %p\n",
2451 __FILE__, __LINE__, uarg);
2452 return -EFAULT;
2453 }
2454
2455 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
2456 (ioc == NULL)) {
2457 printk(KERN_DEBUG MYNAM "%s::mptctl_hp_hostinfo() @%d - ioc%d not found!\n",
2458 __FILE__, __LINE__, iocnum);
2459 return -ENODEV;
2460 }
2461 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": mptctl_hp_hostinfo called.\n",
2462 ioc->name));
2463
2464
2465
2466
2467 pdev = (struct pci_dev *) ioc->pcidev;
2468
2469 karg.vendor = pdev->vendor;
2470 karg.device = pdev->device;
2471 karg.subsystem_id = pdev->subsystem_device;
2472 karg.subsystem_vendor = pdev->subsystem_vendor;
2473 karg.devfn = pdev->devfn;
2474 karg.bus = pdev->bus->number;
2475
2476
2477
2478
2479 if (ioc->sh != NULL)
2480 karg.host_no = ioc->sh->host_no;
2481 else
2482 karg.host_no = -1;
2483
2484
2485 snprintf(karg.fw_version, sizeof(karg.fw_version),
2486 "%.2hhu.%.2hhu.%.2hhu.%.2hhu",
2487 ioc->facts.FWVersion.Struct.Major,
2488 ioc->facts.FWVersion.Struct.Minor,
2489 ioc->facts.FWVersion.Struct.Unit,
2490 ioc->facts.FWVersion.Struct.Dev);
2491
2492
2493
2494 hdr.PageVersion = 0;
2495 hdr.PageLength = 0;
2496 hdr.PageNumber = 0;
2497 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
2498 cfg.cfghdr.hdr = &hdr;
2499 cfg.physAddr = -1;
2500 cfg.pageAddr = 0;
2501 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2502 cfg.dir = 0;
2503 cfg.timeout = 10;
2504
2505 strncpy(karg.serial_number, " ", 24);
2506 if (mpt_config(ioc, &cfg) == 0) {
2507 if (cfg.cfghdr.hdr->PageLength > 0) {
2508
2509 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2510
2511 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
2512 if (pbuf) {
2513 cfg.physAddr = buf_dma;
2514 if (mpt_config(ioc, &cfg) == 0) {
2515 ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf;
2516 if (strlen(pdata->BoardTracerNumber) > 1) {
2517 strlcpy(karg.serial_number,
2518 pdata->BoardTracerNumber, 24);
2519 }
2520 }
2521 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
2522 pbuf = NULL;
2523 }
2524 }
2525 }
2526 rc = mpt_GetIocState(ioc, 1);
2527 switch (rc) {
2528 case MPI_IOC_STATE_OPERATIONAL:
2529 karg.ioc_status = HP_STATUS_OK;
2530 break;
2531
2532 case MPI_IOC_STATE_FAULT:
2533 karg.ioc_status = HP_STATUS_FAILED;
2534 break;
2535
2536 case MPI_IOC_STATE_RESET:
2537 case MPI_IOC_STATE_READY:
2538 default:
2539 karg.ioc_status = HP_STATUS_OTHER;
2540 break;
2541 }
2542
2543 karg.base_io_addr = pci_resource_start(pdev, 0);
2544
2545 if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))
2546 karg.bus_phys_width = HP_BUS_WIDTH_UNK;
2547 else
2548 karg.bus_phys_width = HP_BUS_WIDTH_16;
2549
2550 karg.hard_resets = 0;
2551 karg.soft_resets = 0;
2552 karg.timeouts = 0;
2553 if (ioc->sh != NULL) {
2554 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
2555
2556 if (hd && (cim_rev == 1)) {
2557 karg.hard_resets = ioc->hard_resets;
2558 karg.soft_resets = ioc->soft_resets;
2559 karg.timeouts = ioc->timeouts;
2560 }
2561 }
2562
2563
2564
2565
2566 if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) {
2567 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
2568 "%s, no msg frames!!\n", ioc->name, __func__));
2569 goto out;
2570 }
2571
2572 IstwiRWRequest = (ToolboxIstwiReadWriteRequest_t *)mf;
2573 msgcontext = IstwiRWRequest->MsgContext;
2574 memset(IstwiRWRequest,0,sizeof(ToolboxIstwiReadWriteRequest_t));
2575 IstwiRWRequest->MsgContext = msgcontext;
2576 IstwiRWRequest->Function = MPI_FUNCTION_TOOLBOX;
2577 IstwiRWRequest->Tool = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
2578 IstwiRWRequest->Flags = MPI_TB_ISTWI_FLAGS_READ;
2579 IstwiRWRequest->NumAddressBytes = 0x01;
2580 IstwiRWRequest->DataLength = cpu_to_le16(0x04);
2581 if (pdev->devfn & 1)
2582 IstwiRWRequest->DeviceAddr = 0xB2;
2583 else
2584 IstwiRWRequest->DeviceAddr = 0xB0;
2585
2586 pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma);
2587 if (!pbuf)
2588 goto out;
2589 ioc->add_sge((char *)&IstwiRWRequest->SGL,
2590 (MPT_SGE_FLAGS_SSIMPLE_READ|4), buf_dma);
2591
2592 retval = 0;
2593 SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context,
2594 IstwiRWRequest->MsgContext);
2595 INITIALIZE_MGMT_STATUS(ioc->ioctl_cmds.status)
2596 mpt_put_msg_frame(mptctl_id, ioc, mf);
2597
2598retry_wait:
2599 timeleft = wait_for_completion_timeout(&ioc->ioctl_cmds.done,
2600 HZ*MPT_IOCTL_DEFAULT_TIMEOUT);
2601 if (!(ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2602 retval = -ETIME;
2603 printk(MYIOC_s_WARN_FMT "%s: failed\n", ioc->name, __func__);
2604 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
2605 mpt_free_msg_frame(ioc, mf);
2606 goto out;
2607 }
2608 if (!timeleft) {
2609 printk(MYIOC_s_WARN_FMT
2610 "HOST INFO command timeout, doorbell=0x%08x\n",
2611 ioc->name, mpt_GetIocState(ioc, 0));
2612 mptctl_timeout_expired(ioc, mf);
2613 } else
2614 goto retry_wait;
2615 goto out;
2616 }
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_RF_VALID)
2628 karg.rsvd = *(u32 *)pbuf;
2629
2630 out:
2631 CLEAR_MGMT_STATUS(ioc->ioctl_cmds.status)
2632 SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, 0);
2633
2634 if (pbuf)
2635 pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma);
2636
2637
2638
2639 if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) {
2640 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_hpgethostinfo - "
2641 "Unable to write out hp_host_info @ %p\n",
2642 ioc->name, __FILE__, __LINE__, uarg);
2643 return -EFAULT;
2644 }
2645
2646 return 0;
2647
2648}
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661static int
2662mptctl_hp_targetinfo(unsigned long arg)
2663{
2664 hp_target_info_t __user *uarg = (void __user *) arg;
2665 SCSIDevicePage0_t *pg0_alloc;
2666 SCSIDevicePage3_t *pg3_alloc;
2667 MPT_ADAPTER *ioc;
2668 MPT_SCSI_HOST *hd = NULL;
2669 hp_target_info_t karg;
2670 int iocnum;
2671 int data_sz;
2672 dma_addr_t page_dma;
2673 CONFIGPARMS cfg;
2674 ConfigPageHeader_t hdr;
2675 int tmp, np, rc = 0;
2676
2677 if (copy_from_user(&karg, uarg, sizeof(hp_target_info_t))) {
2678 printk(KERN_ERR MYNAM "%s@%d::mptctl_hp_targetinfo - "
2679 "Unable to read in hp_host_targetinfo struct @ %p\n",
2680 __FILE__, __LINE__, uarg);
2681 return -EFAULT;
2682 }
2683
2684 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
2685 (ioc == NULL)) {
2686 printk(KERN_DEBUG MYNAM "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n",
2687 __FILE__, __LINE__, iocnum);
2688 return -ENODEV;
2689 }
2690 if (karg.hdr.id >= MPT_MAX_FC_DEVICES)
2691 return -EINVAL;
2692 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_hp_targetinfo called.\n",
2693 ioc->name));
2694
2695
2696
2697 if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))
2698 return 0;
2699
2700 if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL))
2701 return 0;
2702
2703 if (ioc->sh->host_no != karg.hdr.host)
2704 return -ENODEV;
2705
2706
2707
2708 data_sz = ioc->spi_data.sdp0length * 4;
2709 pg0_alloc = (SCSIDevicePage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
2710 if (pg0_alloc) {
2711 hdr.PageVersion = ioc->spi_data.sdp0version;
2712 hdr.PageLength = data_sz;
2713 hdr.PageNumber = 0;
2714 hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
2715
2716 cfg.cfghdr.hdr = &hdr;
2717 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2718 cfg.dir = 0;
2719 cfg.timeout = 0;
2720 cfg.physAddr = page_dma;
2721
2722 cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
2723
2724 if ((rc = mpt_config(ioc, &cfg)) == 0) {
2725 np = le32_to_cpu(pg0_alloc->NegotiatedParameters);
2726 karg.negotiated_width = np & MPI_SCSIDEVPAGE0_NP_WIDE ?
2727 HP_BUS_WIDTH_16 : HP_BUS_WIDTH_8;
2728
2729 if (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) {
2730 tmp = (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
2731 if (tmp < 0x09)
2732 karg.negotiated_speed = HP_DEV_SPEED_ULTRA320;
2733 else if (tmp <= 0x09)
2734 karg.negotiated_speed = HP_DEV_SPEED_ULTRA160;
2735 else if (tmp <= 0x0A)
2736 karg.negotiated_speed = HP_DEV_SPEED_ULTRA2;
2737 else if (tmp <= 0x0C)
2738 karg.negotiated_speed = HP_DEV_SPEED_ULTRA;
2739 else if (tmp <= 0x25)
2740 karg.negotiated_speed = HP_DEV_SPEED_FAST;
2741 else
2742 karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
2743 } else
2744 karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
2745 }
2746
2747 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg0_alloc, page_dma);
2748 }
2749
2750
2751
2752 karg.message_rejects = -1;
2753 karg.phase_errors = -1;
2754 karg.parity_errors = -1;
2755 karg.select_timeouts = -1;
2756
2757
2758
2759 hdr.PageVersion = 0;
2760 hdr.PageLength = 0;
2761 hdr.PageNumber = 3;
2762 hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
2763
2764 cfg.cfghdr.hdr = &hdr;
2765 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2766 cfg.dir = 0;
2767 cfg.timeout = 0;
2768 cfg.physAddr = -1;
2769 if ((mpt_config(ioc, &cfg) == 0) && (cfg.cfghdr.hdr->PageLength > 0)) {
2770
2771 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2772 data_sz = (int) cfg.cfghdr.hdr->PageLength * 4;
2773 pg3_alloc = (SCSIDevicePage3_t *) pci_alloc_consistent(
2774 ioc->pcidev, data_sz, &page_dma);
2775 if (pg3_alloc) {
2776 cfg.physAddr = page_dma;
2777 cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
2778 if ((rc = mpt_config(ioc, &cfg)) == 0) {
2779 karg.message_rejects = (u32) le16_to_cpu(pg3_alloc->MsgRejectCount);
2780 karg.phase_errors = (u32) le16_to_cpu(pg3_alloc->PhaseErrorCount);
2781 karg.parity_errors = (u32) le16_to_cpu(pg3_alloc->ParityErrorCount);
2782 }
2783 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg3_alloc, page_dma);
2784 }
2785 }
2786 hd = shost_priv(ioc->sh);
2787 if (hd != NULL)
2788 karg.select_timeouts = hd->sel_timeout[karg.hdr.id];
2789
2790
2791
2792 if (copy_to_user((char __user *)arg, &karg, sizeof(hp_target_info_t))) {
2793 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_hp_target_info - "
2794 "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
2795 ioc->name, __FILE__, __LINE__, uarg);
2796 return -EFAULT;
2797 }
2798
2799 return 0;
2800}
2801
2802
2803
2804static const struct file_operations mptctl_fops = {
2805 .owner = THIS_MODULE,
2806 .llseek = no_llseek,
2807 .fasync = mptctl_fasync,
2808 .unlocked_ioctl = mptctl_ioctl,
2809#ifdef CONFIG_COMPAT
2810 .compat_ioctl = compat_mpctl_ioctl,
2811#endif
2812};
2813
2814static struct miscdevice mptctl_miscdev = {
2815 MPT_MINOR,
2816 MYNAM,
2817 &mptctl_fops
2818};
2819
2820
2821
2822#ifdef CONFIG_COMPAT
2823
2824static int
2825compat_mptfwxfer_ioctl(struct file *filp, unsigned int cmd,
2826 unsigned long arg)
2827{
2828 struct mpt_fw_xfer32 kfw32;
2829 struct mpt_fw_xfer kfw;
2830 MPT_ADAPTER *iocp = NULL;
2831 int iocnum, iocnumX;
2832 int nonblock = (filp->f_flags & O_NONBLOCK);
2833 int ret;
2834
2835
2836 if (copy_from_user(&kfw32, (char __user *)arg, sizeof(kfw32)))
2837 return -EFAULT;
2838
2839
2840 iocnumX = kfw32.iocnum & 0xFF;
2841 if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
2842 (iocp == NULL)) {
2843 printk(KERN_DEBUG MYNAM "::compat_mptfwxfer_ioctl @%d - ioc%d not found!\n",
2844 __LINE__, iocnumX);
2845 return -ENODEV;
2846 }
2847
2848 if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
2849 return ret;
2850
2851 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "compat_mptfwxfer_ioctl() called\n",
2852 iocp->name));
2853 kfw.iocnum = iocnum;
2854 kfw.fwlen = kfw32.fwlen;
2855 kfw.bufp = compat_ptr(kfw32.bufp);
2856
2857 ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);
2858
2859 mutex_unlock(&iocp->ioctl_cmds.mutex);
2860
2861 return ret;
2862}
2863
2864static int
2865compat_mpt_command(struct file *filp, unsigned int cmd,
2866 unsigned long arg)
2867{
2868 struct mpt_ioctl_command32 karg32;
2869 struct mpt_ioctl_command32 __user *uarg = (struct mpt_ioctl_command32 __user *) arg;
2870 struct mpt_ioctl_command karg;
2871 MPT_ADAPTER *iocp = NULL;
2872 int iocnum, iocnumX;
2873 int nonblock = (filp->f_flags & O_NONBLOCK);
2874 int ret;
2875
2876 if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32)))
2877 return -EFAULT;
2878
2879
2880 iocnumX = karg32.hdr.iocnum & 0xFF;
2881 if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
2882 (iocp == NULL)) {
2883 printk(KERN_DEBUG MYNAM "::compat_mpt_command @%d - ioc%d not found!\n",
2884 __LINE__, iocnumX);
2885 return -ENODEV;
2886 }
2887
2888 if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
2889 return ret;
2890
2891 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "compat_mpt_command() called\n",
2892 iocp->name));
2893
2894 karg.hdr.iocnum = karg32.hdr.iocnum;
2895 karg.hdr.port = karg32.hdr.port;
2896 karg.timeout = karg32.timeout;
2897 karg.maxReplyBytes = karg32.maxReplyBytes;
2898
2899 karg.dataInSize = karg32.dataInSize;
2900 karg.dataOutSize = karg32.dataOutSize;
2901 karg.maxSenseBytes = karg32.maxSenseBytes;
2902 karg.dataSgeOffset = karg32.dataSgeOffset;
2903
2904 karg.replyFrameBufPtr = (char __user *)(unsigned long)karg32.replyFrameBufPtr;
2905 karg.dataInBufPtr = (char __user *)(unsigned long)karg32.dataInBufPtr;
2906 karg.dataOutBufPtr = (char __user *)(unsigned long)karg32.dataOutBufPtr;
2907 karg.senseDataPtr = (char __user *)(unsigned long)karg32.senseDataPtr;
2908
2909
2910
2911 ret = mptctl_do_mpt_command (karg, &uarg->MF);
2912
2913 mutex_unlock(&iocp->ioctl_cmds.mutex);
2914
2915 return ret;
2916}
2917
2918static long compat_mpctl_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
2919{
2920 long ret;
2921 mutex_lock(&mpctl_mutex);
2922 switch (cmd) {
2923 case MPTIOCINFO:
2924 case MPTIOCINFO1:
2925 case MPTIOCINFO2:
2926 case MPTTARGETINFO:
2927 case MPTEVENTQUERY:
2928 case MPTEVENTENABLE:
2929 case MPTEVENTREPORT:
2930 case MPTHARDRESET:
2931 case HP_GETHOSTINFO:
2932 case HP_GETTARGETINFO:
2933 case MPTTEST:
2934 ret = __mptctl_ioctl(f, cmd, arg);
2935 break;
2936 case MPTCOMMAND32:
2937 ret = compat_mpt_command(f, cmd, arg);
2938 break;
2939 case MPTFWDOWNLOAD32:
2940 ret = compat_mptfwxfer_ioctl(f, cmd, arg);
2941 break;
2942 default:
2943 ret = -ENOIOCTLCMD;
2944 break;
2945 }
2946 mutex_unlock(&mpctl_mutex);
2947 return ret;
2948}
2949
2950#endif
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962static int
2963mptctl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2964{
2965 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2966
2967 mutex_init(&ioc->ioctl_cmds.mutex);
2968 init_completion(&ioc->ioctl_cmds.done);
2969 return 0;
2970}
2971
2972
2973
2974
2975
2976
2977
2978
2979static void
2980mptctl_remove(struct pci_dev *pdev)
2981{
2982}
2983
2984static struct mpt_pci_driver mptctl_driver = {
2985 .probe = mptctl_probe,
2986 .remove = mptctl_remove,
2987};
2988
2989
2990static int __init mptctl_init(void)
2991{
2992 int err;
2993 int where = 1;
2994
2995 show_mptmod_ver(my_NAME, my_VERSION);
2996
2997 mpt_device_driver_register(&mptctl_driver, MPTCTL_DRIVER);
2998
2999
3000 err = misc_register(&mptctl_miscdev);
3001 if (err < 0) {
3002 printk(KERN_ERR MYNAM ": Can't register misc device [minor=%d].\n", MPT_MINOR);
3003 goto out_fail;
3004 }
3005 printk(KERN_INFO MYNAM ": Registered with Fusion MPT base driver\n");
3006 printk(KERN_INFO MYNAM ": /dev/%s @ (major,minor=%d,%d)\n",
3007 mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
3008
3009
3010
3011
3012 ++where;
3013 mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER,
3014 "mptctl_reply");
3015 if (!mptctl_id || mptctl_id >= MPT_MAX_PROTOCOL_DRIVERS) {
3016 printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
3017 misc_deregister(&mptctl_miscdev);
3018 err = -EBUSY;
3019 goto out_fail;
3020 }
3021
3022 mptctl_taskmgmt_id = mpt_register(mptctl_taskmgmt_reply, MPTCTL_DRIVER,
3023 "mptctl_taskmgmt_reply");
3024 if (!mptctl_taskmgmt_id || mptctl_taskmgmt_id >= MPT_MAX_PROTOCOL_DRIVERS) {
3025 printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
3026 mpt_deregister(mptctl_id);
3027 misc_deregister(&mptctl_miscdev);
3028 err = -EBUSY;
3029 goto out_fail;
3030 }
3031
3032 mpt_reset_register(mptctl_id, mptctl_ioc_reset);
3033 mpt_event_register(mptctl_id, mptctl_event_process);
3034
3035 return 0;
3036
3037out_fail:
3038
3039 mpt_device_driver_deregister(MPTCTL_DRIVER);
3040
3041 return err;
3042}
3043
3044
3045static void mptctl_exit(void)
3046{
3047 misc_deregister(&mptctl_miscdev);
3048 printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n",
3049 mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
3050
3051
3052 mpt_event_deregister(mptctl_id);
3053
3054
3055 mpt_reset_deregister(mptctl_id);
3056
3057
3058 mpt_deregister(mptctl_taskmgmt_id);
3059 mpt_deregister(mptctl_id);
3060
3061 mpt_device_driver_deregister(MPTCTL_DRIVER);
3062
3063}
3064
3065
3066
3067module_init(mptctl_init);
3068module_exit(mptctl_exit);
3069