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 <asm/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 *frags = 0;
1043 *blp = NULL;
1044
1045
1046
1047
1048 i = MAX_SGL_BYTES / 8;
1049 buflist = kzalloc(i, GFP_USER);
1050 if (!buflist)
1051 return NULL;
1052 buflist_ent = 0;
1053
1054
1055
1056
1057
1058
1059 sglbuf = pci_alloc_consistent(ioc->pcidev, MAX_SGL_BYTES, sglbuf_dma);
1060 if (sglbuf == NULL)
1061 goto free_and_fail;
1062
1063 if (sgdir & 0x04000000)
1064 dir = PCI_DMA_TODEVICE;
1065 else
1066 dir = PCI_DMA_FROMDEVICE;
1067
1068
1069
1070
1071
1072
1073
1074
1075 sgl = sglbuf;
1076 sg_spill = ((ioc->req_sz - sge_offset)/ioc->SGE_size) - 1;
1077 while (bytes_allocd < bytes) {
1078 this_alloc = min(alloc_sz, bytes-bytes_allocd);
1079 buflist[buflist_ent].len = this_alloc;
1080 buflist[buflist_ent].kptr = pci_alloc_consistent(ioc->pcidev,
1081 this_alloc,
1082 &pa);
1083 if (buflist[buflist_ent].kptr == NULL) {
1084 alloc_sz = alloc_sz / 2;
1085 if (alloc_sz == 0) {
1086 printk(MYIOC_s_WARN_FMT "-SG: No can do - "
1087 "not enough memory! :-(\n", ioc->name);
1088 printk(MYIOC_s_WARN_FMT "-SG: (freeing %d frags)\n",
1089 ioc->name, numfrags);
1090 goto free_and_fail;
1091 }
1092 continue;
1093 } else {
1094 dma_addr_t dma_addr;
1095
1096 bytes_allocd += this_alloc;
1097 sgl->FlagsLength = (0x10000000|sgdir|this_alloc);
1098 dma_addr = pci_map_single(ioc->pcidev,
1099 buflist[buflist_ent].kptr, this_alloc, dir);
1100 sgl->Address = dma_addr;
1101
1102 fragcnt++;
1103 numfrags++;
1104 sgl++;
1105 buflist_ent++;
1106 }
1107
1108 if (bytes_allocd >= bytes)
1109 break;
1110
1111
1112 if (fragcnt == sg_spill) {
1113 printk(MYIOC_s_WARN_FMT
1114 "-SG: No can do - " "Chain required! :-(\n", ioc->name);
1115 printk(MYIOC_s_WARN_FMT "(freeing %d frags)\n", ioc->name, numfrags);
1116 goto free_and_fail;
1117 }
1118
1119
1120 if (numfrags*8 > MAX_SGL_BYTES){
1121
1122 printk(MYIOC_s_WARN_FMT "-SG: No can do - "
1123 "too many SG frags! :-(\n", ioc->name);
1124 printk(MYIOC_s_WARN_FMT "-SG: (freeing %d frags)\n",
1125 ioc->name, numfrags);
1126 goto free_and_fail;
1127 }
1128 }
1129
1130
1131 sgl[-1].FlagsLength |= 0xC1000000;
1132
1133 *frags = numfrags;
1134 *blp = buflist;
1135
1136 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "-SG: kbuf_alloc_2_sgl() - "
1137 "%d SG frags generated!\n", ioc->name, numfrags));
1138
1139 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "-SG: kbuf_alloc_2_sgl() - "
1140 "last (big) alloc_sz=%d\n", ioc->name, alloc_sz));
1141
1142 return sglbuf;
1143
1144free_and_fail:
1145 if (sglbuf != NULL) {
1146 for (i = 0; i < numfrags; i++) {
1147 dma_addr_t dma_addr;
1148 u8 *kptr;
1149 int len;
1150
1151 if ((sglbuf[i].FlagsLength >> 24) == 0x30)
1152 continue;
1153
1154 dma_addr = sglbuf[i].Address;
1155 kptr = buflist[i].kptr;
1156 len = buflist[i].len;
1157
1158 pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
1159 }
1160 pci_free_consistent(ioc->pcidev, MAX_SGL_BYTES, sglbuf, *sglbuf_dma);
1161 }
1162 kfree(buflist);
1163 return NULL;
1164}
1165
1166
1167
1168
1169
1170static void
1171kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma, struct buflist *buflist, MPT_ADAPTER *ioc)
1172{
1173 MptSge_t *sg = sgl;
1174 struct buflist *bl = buflist;
1175 u32 nib;
1176 int dir;
1177 int n = 0;
1178
1179 if (sg->FlagsLength & 0x04000000)
1180 dir = PCI_DMA_TODEVICE;
1181 else
1182 dir = PCI_DMA_FROMDEVICE;
1183
1184 nib = (sg->FlagsLength & 0xF0000000) >> 28;
1185 while (! (nib & 0x4)) {
1186
1187 if (nib == 0 || nib == 3) {
1188 ;
1189 } else if (sg->Address) {
1190 dma_addr_t dma_addr;
1191 void *kptr;
1192 int len;
1193
1194 dma_addr = sg->Address;
1195 kptr = bl->kptr;
1196 len = bl->len;
1197 pci_unmap_single(ioc->pcidev, dma_addr, len, dir);
1198 pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
1199 n++;
1200 }
1201 sg++;
1202 bl++;
1203 nib = (le32_to_cpu(sg->FlagsLength) & 0xF0000000) >> 28;
1204 }
1205
1206
1207 if (sg->Address) {
1208 dma_addr_t dma_addr;
1209 void *kptr;
1210 int len;
1211
1212 dma_addr = sg->Address;
1213 kptr = bl->kptr;
1214 len = bl->len;
1215 pci_unmap_single(ioc->pcidev, dma_addr, len, dir);
1216 pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
1217 n++;
1218 }
1219
1220 pci_free_consistent(ioc->pcidev, MAX_SGL_BYTES, sgl, sgl_dma);
1221 kfree(buflist);
1222 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "-SG: Free'd 1 SGL buf + %d kbufs!\n",
1223 ioc->name, n));
1224}
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236static int
1237mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
1238{
1239 struct mpt_ioctl_iocinfo __user *uarg = (void __user *) arg;
1240 struct mpt_ioctl_iocinfo *karg;
1241 MPT_ADAPTER *ioc;
1242 struct pci_dev *pdev;
1243 int iocnum;
1244 unsigned int port;
1245 int cim_rev;
1246 struct scsi_device *sdev;
1247 VirtDevice *vdevice;
1248
1249
1250
1251
1252
1253 if (data_size == sizeof(struct mpt_ioctl_iocinfo_rev0))
1254 cim_rev = 0;
1255 else if (data_size == sizeof(struct mpt_ioctl_iocinfo_rev1))
1256 cim_rev = 1;
1257 else if (data_size == sizeof(struct mpt_ioctl_iocinfo))
1258 cim_rev = 2;
1259 else if (data_size == (sizeof(struct mpt_ioctl_iocinfo_rev0)+12))
1260 cim_rev = 0;
1261 else
1262 return -EFAULT;
1263
1264 karg = memdup_user(uarg, data_size);
1265 if (IS_ERR(karg)) {
1266 printk(KERN_ERR MYNAM "%s@%d::mpt_ioctl_iocinfo() - memdup_user returned error [%ld]\n",
1267 __FILE__, __LINE__, PTR_ERR(karg));
1268 return PTR_ERR(karg);
1269 }
1270
1271 if (((iocnum = mpt_verify_adapter(karg->hdr.iocnum, &ioc)) < 0) ||
1272 (ioc == NULL)) {
1273 printk(KERN_DEBUG MYNAM "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n",
1274 __FILE__, __LINE__, iocnum);
1275 kfree(karg);
1276 return -ENODEV;
1277 }
1278
1279
1280 if (karg->hdr.maxDataSize != data_size) {
1281 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - "
1282 "Structure size mismatch. Command not completed.\n",
1283 ioc->name, __FILE__, __LINE__);
1284 kfree(karg);
1285 return -EFAULT;
1286 }
1287
1288 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_getiocinfo called.\n",
1289 ioc->name));
1290
1291
1292
1293
1294 if (ioc->bus_type == SAS)
1295 karg->adapterType = MPT_IOCTL_INTERFACE_SAS;
1296 else if (ioc->bus_type == FC)
1297 karg->adapterType = MPT_IOCTL_INTERFACE_FC;
1298 else
1299 karg->adapterType = MPT_IOCTL_INTERFACE_SCSI;
1300
1301 if (karg->hdr.port > 1) {
1302 kfree(karg);
1303 return -EINVAL;
1304 }
1305 port = karg->hdr.port;
1306
1307 karg->port = port;
1308 pdev = (struct pci_dev *) ioc->pcidev;
1309
1310 karg->pciId = pdev->device;
1311 karg->hwRev = pdev->revision;
1312 karg->subSystemDevice = pdev->subsystem_device;
1313 karg->subSystemVendor = pdev->subsystem_vendor;
1314
1315 if (cim_rev == 1) {
1316
1317
1318 karg->pciInfo.u.bits.busNumber = pdev->bus->number;
1319 karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
1320 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1321 } else if (cim_rev == 2) {
1322
1323
1324 karg->pciInfo.u.bits.busNumber = pdev->bus->number;
1325 karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
1326 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1327 karg->pciInfo.segmentID = pci_domain_nr(pdev->bus);
1328 }
1329
1330
1331
1332 karg->numDevices = 0;
1333 if (ioc->sh) {
1334 shost_for_each_device(sdev, ioc->sh) {
1335 vdevice = sdev->hostdata;
1336 if (vdevice == NULL || vdevice->vtarget == NULL)
1337 continue;
1338 if (vdevice->vtarget->tflags &
1339 MPT_TARGET_FLAGS_RAID_COMPONENT)
1340 continue;
1341 karg->numDevices++;
1342 }
1343 }
1344
1345
1346
1347 karg->FWVersion = ioc->facts.FWVersion.Word;
1348 karg->BIOSVersion = ioc->biosVersion;
1349
1350
1351
1352 strncpy (karg->driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH);
1353 karg->driverVersion[MPT_IOCTL_VERSION_LENGTH-1]='\0';
1354
1355 karg->busChangeEvent = 0;
1356 karg->hostId = ioc->pfacts[port].PortSCSIID;
1357 karg->rsvd[0] = karg->rsvd[1] = 0;
1358
1359
1360
1361 if (copy_to_user((char __user *)arg, karg, data_size)) {
1362 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - "
1363 "Unable to write out mpt_ioctl_iocinfo struct @ %p\n",
1364 ioc->name, __FILE__, __LINE__, uarg);
1365 kfree(karg);
1366 return -EFAULT;
1367 }
1368
1369 kfree(karg);
1370 return 0;
1371}
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383static int
1384mptctl_gettargetinfo (unsigned long arg)
1385{
1386 struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg;
1387 struct mpt_ioctl_targetinfo karg;
1388 MPT_ADAPTER *ioc;
1389 VirtDevice *vdevice;
1390 char *pmem;
1391 int *pdata;
1392 int iocnum;
1393 int numDevices = 0;
1394 int lun;
1395 int maxWordsLeft;
1396 int numBytes;
1397 u8 port;
1398 struct scsi_device *sdev;
1399
1400 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
1401 printk(KERN_ERR MYNAM "%s@%d::mptctl_gettargetinfo - "
1402 "Unable to read in mpt_ioctl_targetinfo struct @ %p\n",
1403 __FILE__, __LINE__, uarg);
1404 return -EFAULT;
1405 }
1406
1407 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1408 (ioc == NULL)) {
1409 printk(KERN_DEBUG MYNAM "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n",
1410 __FILE__, __LINE__, iocnum);
1411 return -ENODEV;
1412 }
1413
1414 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_gettargetinfo called.\n",
1415 ioc->name));
1416
1417
1418
1419
1420 numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
1421 maxWordsLeft = numBytes/sizeof(int);
1422 port = karg.hdr.port;
1423
1424 if (maxWordsLeft <= 0) {
1425 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n",
1426 ioc->name, __FILE__, __LINE__);
1427 return -ENOMEM;
1428 }
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444 pmem = kzalloc(numBytes, GFP_KERNEL);
1445 if (!pmem) {
1446 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n",
1447 ioc->name, __FILE__, __LINE__);
1448 return -ENOMEM;
1449 }
1450 pdata = (int *) pmem;
1451
1452
1453
1454 if (ioc->sh){
1455 shost_for_each_device(sdev, ioc->sh) {
1456 if (!maxWordsLeft)
1457 continue;
1458 vdevice = sdev->hostdata;
1459 if (vdevice == NULL || vdevice->vtarget == NULL)
1460 continue;
1461 if (vdevice->vtarget->tflags &
1462 MPT_TARGET_FLAGS_RAID_COMPONENT)
1463 continue;
1464 lun = (vdevice->vtarget->raidVolume) ? 0x80 : vdevice->lun;
1465 *pdata = (((u8)lun << 16) + (vdevice->vtarget->channel << 8) +
1466 (vdevice->vtarget->id ));
1467 pdata++;
1468 numDevices++;
1469 --maxWordsLeft;
1470 }
1471 }
1472 karg.numDevices = numDevices;
1473
1474
1475
1476 if (copy_to_user((char __user *)arg, &karg,
1477 sizeof(struct mpt_ioctl_targetinfo))) {
1478 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo - "
1479 "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
1480 ioc->name, __FILE__, __LINE__, uarg);
1481 kfree(pmem);
1482 return -EFAULT;
1483 }
1484
1485
1486
1487 if (copy_to_user(uarg->targetInfo, pmem, numBytes)) {
1488 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo - "
1489 "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
1490 ioc->name, __FILE__, __LINE__, pdata);
1491 kfree(pmem);
1492 return -EFAULT;
1493 }
1494
1495 kfree(pmem);
1496
1497 return 0;
1498}
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508static int
1509mptctl_readtest (unsigned long arg)
1510{
1511 struct mpt_ioctl_test __user *uarg = (void __user *) arg;
1512 struct mpt_ioctl_test karg;
1513 MPT_ADAPTER *ioc;
1514 int iocnum;
1515
1516 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) {
1517 printk(KERN_ERR MYNAM "%s@%d::mptctl_readtest - "
1518 "Unable to read in mpt_ioctl_test struct @ %p\n",
1519 __FILE__, __LINE__, uarg);
1520 return -EFAULT;
1521 }
1522
1523 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1524 (ioc == NULL)) {
1525 printk(KERN_DEBUG MYNAM "%s::mptctl_readtest() @%d - ioc%d not found!\n",
1526 __FILE__, __LINE__, iocnum);
1527 return -ENODEV;
1528 }
1529
1530 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_readtest called.\n",
1531 ioc->name));
1532
1533
1534
1535
1536#ifdef MFCNT
1537 karg.chip_type = ioc->mfcnt;
1538#else
1539 karg.chip_type = ioc->pcidev->device;
1540#endif
1541 strncpy (karg.name, ioc->name, MPT_MAX_NAME);
1542 karg.name[MPT_MAX_NAME-1]='\0';
1543 strncpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH);
1544 karg.product[MPT_PRODUCT_LENGTH-1]='\0';
1545
1546
1547
1548 if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_test))) {
1549 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_readtest - "
1550 "Unable to write out mpt_ioctl_test struct @ %p\n",
1551 ioc->name, __FILE__, __LINE__, uarg);
1552 return -EFAULT;
1553 }
1554
1555 return 0;
1556}
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569static int
1570mptctl_eventquery (unsigned long arg)
1571{
1572 struct mpt_ioctl_eventquery __user *uarg = (void __user *) arg;
1573 struct mpt_ioctl_eventquery karg;
1574 MPT_ADAPTER *ioc;
1575 int iocnum;
1576
1577 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) {
1578 printk(KERN_ERR MYNAM "%s@%d::mptctl_eventquery - "
1579 "Unable to read in mpt_ioctl_eventquery struct @ %p\n",
1580 __FILE__, __LINE__, uarg);
1581 return -EFAULT;
1582 }
1583
1584 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1585 (ioc == NULL)) {
1586 printk(KERN_DEBUG MYNAM "%s::mptctl_eventquery() @%d - ioc%d not found!\n",
1587 __FILE__, __LINE__, iocnum);
1588 return -ENODEV;
1589 }
1590
1591 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventquery called.\n",
1592 ioc->name));
1593 karg.eventEntries = MPTCTL_EVENT_LOG_SIZE;
1594 karg.eventTypes = ioc->eventTypes;
1595
1596
1597
1598 if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) {
1599 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_eventquery - "
1600 "Unable to write out mpt_ioctl_eventquery struct @ %p\n",
1601 ioc->name, __FILE__, __LINE__, uarg);
1602 return -EFAULT;
1603 }
1604 return 0;
1605}
1606
1607
1608static int
1609mptctl_eventenable (unsigned long arg)
1610{
1611 struct mpt_ioctl_eventenable __user *uarg = (void __user *) arg;
1612 struct mpt_ioctl_eventenable karg;
1613 MPT_ADAPTER *ioc;
1614 int iocnum;
1615
1616 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) {
1617 printk(KERN_ERR MYNAM "%s@%d::mptctl_eventenable - "
1618 "Unable to read in mpt_ioctl_eventenable struct @ %p\n",
1619 __FILE__, __LINE__, uarg);
1620 return -EFAULT;
1621 }
1622
1623 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1624 (ioc == NULL)) {
1625 printk(KERN_DEBUG MYNAM "%s::mptctl_eventenable() @%d - ioc%d not found!\n",
1626 __FILE__, __LINE__, iocnum);
1627 return -ENODEV;
1628 }
1629
1630 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventenable called.\n",
1631 ioc->name));
1632 if (ioc->events == NULL) {
1633
1634
1635 int sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
1636 ioc->events = kzalloc(sz, GFP_KERNEL);
1637 if (!ioc->events) {
1638 printk(MYIOC_s_ERR_FMT
1639 ": ERROR - Insufficient memory to add adapter!\n",
1640 ioc->name);
1641 return -ENOMEM;
1642 }
1643 ioc->alloc_total += sz;
1644
1645 ioc->eventContext = 0;
1646 }
1647
1648
1649
1650 ioc->eventTypes = karg.eventTypes;
1651
1652 return 0;
1653}
1654
1655
1656static int
1657mptctl_eventreport (unsigned long arg)
1658{
1659 struct mpt_ioctl_eventreport __user *uarg = (void __user *) arg;
1660 struct mpt_ioctl_eventreport karg;
1661 MPT_ADAPTER *ioc;
1662 int iocnum;
1663 int numBytes, maxEvents, max;
1664
1665 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) {
1666 printk(KERN_ERR MYNAM "%s@%d::mptctl_eventreport - "
1667 "Unable to read in mpt_ioctl_eventreport struct @ %p\n",
1668 __FILE__, __LINE__, uarg);
1669 return -EFAULT;
1670 }
1671
1672 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1673 (ioc == NULL)) {
1674 printk(KERN_DEBUG MYNAM "%s::mptctl_eventreport() @%d - ioc%d not found!\n",
1675 __FILE__, __LINE__, iocnum);
1676 return -ENODEV;
1677 }
1678 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventreport called.\n",
1679 ioc->name));
1680
1681 numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
1682 maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS);
1683
1684
1685 max = MPTCTL_EVENT_LOG_SIZE < maxEvents ? MPTCTL_EVENT_LOG_SIZE : maxEvents;
1686
1687
1688
1689
1690 if ((max < 1) || !ioc->events)
1691 return -ENODATA;
1692
1693
1694 ioc->aen_event_read_flag=0;
1695
1696
1697
1698 numBytes = max * sizeof(MPT_IOCTL_EVENTS);
1699 if (copy_to_user(uarg->eventData, ioc->events, numBytes)) {
1700 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_eventreport - "
1701 "Unable to write out mpt_ioctl_eventreport struct @ %p\n",
1702 ioc->name, __FILE__, __LINE__, ioc->events);
1703 return -EFAULT;
1704 }
1705
1706 return 0;
1707}
1708
1709
1710static int
1711mptctl_replace_fw (unsigned long arg)
1712{
1713 struct mpt_ioctl_replace_fw __user *uarg = (void __user *) arg;
1714 struct mpt_ioctl_replace_fw karg;
1715 MPT_ADAPTER *ioc;
1716 int iocnum;
1717 int newFwSize;
1718
1719 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
1720 printk(KERN_ERR MYNAM "%s@%d::mptctl_replace_fw - "
1721 "Unable to read in mpt_ioctl_replace_fw struct @ %p\n",
1722 __FILE__, __LINE__, uarg);
1723 return -EFAULT;
1724 }
1725
1726 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1727 (ioc == NULL)) {
1728 printk(KERN_DEBUG MYNAM "%s::mptctl_replace_fw() @%d - ioc%d not found!\n",
1729 __FILE__, __LINE__, iocnum);
1730 return -ENODEV;
1731 }
1732
1733 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_replace_fw called.\n",
1734 ioc->name));
1735
1736
1737 if (ioc->cached_fw == NULL)
1738 return 0;
1739
1740 mpt_free_fw_memory(ioc);
1741
1742
1743
1744 newFwSize = ALIGN(karg.newImageSize, 4);
1745
1746 mpt_alloc_fw_memory(ioc, newFwSize);
1747 if (ioc->cached_fw == NULL)
1748 return -ENOMEM;
1749
1750
1751
1752 if (copy_from_user(ioc->cached_fw, uarg->newImage, newFwSize)) {
1753 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_replace_fw - "
1754 "Unable to read in mpt_ioctl_replace_fw image "
1755 "@ %p\n", ioc->name, __FILE__, __LINE__, uarg);
1756 mpt_free_fw_memory(ioc);
1757 return -EFAULT;
1758 }
1759
1760
1761
1762 ioc->facts.FWImageSize = newFwSize;
1763 return 0;
1764}
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778static int
1779mptctl_mpt_command (unsigned long arg)
1780{
1781 struct mpt_ioctl_command __user *uarg = (void __user *) arg;
1782 struct mpt_ioctl_command karg;
1783 MPT_ADAPTER *ioc;
1784 int iocnum;
1785 int rc;
1786
1787
1788 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_command))) {
1789 printk(KERN_ERR MYNAM "%s@%d::mptctl_mpt_command - "
1790 "Unable to read in mpt_ioctl_command struct @ %p\n",
1791 __FILE__, __LINE__, uarg);
1792 return -EFAULT;
1793 }
1794
1795 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1796 (ioc == NULL)) {
1797 printk(KERN_DEBUG MYNAM "%s::mptctl_mpt_command() @%d - ioc%d not found!\n",
1798 __FILE__, __LINE__, iocnum);
1799 return -ENODEV;
1800 }
1801
1802 rc = mptctl_do_mpt_command (karg, &uarg->MF);
1803
1804 return rc;
1805}
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819static int
1820mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
1821{
1822 MPT_ADAPTER *ioc;
1823 MPT_FRAME_HDR *mf = NULL;
1824 MPIHeader_t *hdr;
1825 char *psge;
1826 struct buflist bufIn;
1827 struct buflist bufOut;
1828 dma_addr_t dma_addr_in;
1829 dma_addr_t dma_addr_out;
1830 int sgSize = 0;
1831 int iocnum, flagsLength;
1832 int sz, rc = 0;
1833 int msgContext;
1834 u16 req_idx;
1835 ulong timeout;
1836 unsigned long timeleft;
1837 struct scsi_device *sdev;
1838 unsigned long flags;
1839 u8 function;
1840
1841
1842
1843 bufIn.kptr = bufOut.kptr = NULL;
1844 bufIn.len = bufOut.len = 0;
1845
1846 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1847 (ioc == NULL)) {
1848 printk(KERN_DEBUG MYNAM "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n",
1849 __FILE__, __LINE__, iocnum);
1850 return -ENODEV;
1851 }
1852
1853 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
1854 if (ioc->ioc_reset_in_progress) {
1855 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
1856 printk(KERN_ERR MYNAM "%s@%d::mptctl_do_mpt_command - "
1857 "Busy with diagnostic reset\n", __FILE__, __LINE__);
1858 return -EBUSY;
1859 }
1860 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
1861
1862
1863
1864 sz = karg.dataSgeOffset * 4;
1865 if (karg.dataInSize > 0)
1866 sz += ioc->SGE_size;
1867 if (karg.dataOutSize > 0)
1868 sz += ioc->SGE_size;
1869
1870 if (sz > ioc->req_sz) {
1871 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1872 "Request frame too large (%d) maximum (%d)\n",
1873 ioc->name, __FILE__, __LINE__, sz, ioc->req_sz);
1874 return -EFAULT;
1875 }
1876
1877
1878
1879 if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL)
1880 return -EAGAIN;
1881
1882 hdr = (MPIHeader_t *) mf;
1883 msgContext = le32_to_cpu(hdr->MsgContext);
1884 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1885
1886
1887
1888
1889
1890 if (copy_from_user(mf, mfPtr, karg.dataSgeOffset * 4)) {
1891 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1892 "Unable to read MF from mpt_ioctl_command struct @ %p\n",
1893 ioc->name, __FILE__, __LINE__, mfPtr);
1894 function = -1;
1895 rc = -EFAULT;
1896 goto done_free_mem;
1897 }
1898 hdr->MsgContext = cpu_to_le32(msgContext);
1899 function = hdr->Function;
1900
1901
1902
1903
1904 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sending mpi function (0x%02X), req=%p\n",
1905 ioc->name, hdr->Function, mf));
1906
1907 switch (function) {
1908 case MPI_FUNCTION_IOC_FACTS:
1909 case MPI_FUNCTION_PORT_FACTS:
1910 karg.dataOutSize = karg.dataInSize = 0;
1911 break;
1912
1913 case MPI_FUNCTION_CONFIG:
1914 {
1915 Config_t *config_frame;
1916 config_frame = (Config_t *)mf;
1917 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\ttype=0x%02x ext_type=0x%02x "
1918 "number=0x%02x action=0x%02x\n", ioc->name,
1919 config_frame->Header.PageType,
1920 config_frame->ExtPageType,
1921 config_frame->Header.PageNumber,
1922 config_frame->Action));
1923 break;
1924 }
1925
1926 case MPI_FUNCTION_FC_COMMON_TRANSPORT_SEND:
1927 case MPI_FUNCTION_FC_EX_LINK_SRVC_SEND:
1928 case MPI_FUNCTION_FW_UPLOAD:
1929 case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR:
1930 case MPI_FUNCTION_FW_DOWNLOAD:
1931 case MPI_FUNCTION_FC_PRIMITIVE_SEND:
1932 case MPI_FUNCTION_TOOLBOX:
1933 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
1934 break;
1935
1936 case MPI_FUNCTION_SCSI_IO_REQUEST:
1937 if (ioc->sh) {
1938 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
1939 int qtag = MPI_SCSIIO_CONTROL_UNTAGGED;
1940 int scsidir = 0;
1941 int dataSize;
1942 u32 id;
1943
1944 id = (ioc->devices_per_bus == 0) ? 256 : ioc->devices_per_bus;
1945 if (pScsiReq->TargetID > id) {
1946 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1947 "Target ID out of bounds. \n",
1948 ioc->name, __FILE__, __LINE__);
1949 rc = -ENODEV;
1950 goto done_free_mem;
1951 }
1952
1953 if (pScsiReq->Bus >= ioc->number_of_buses) {
1954 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1955 "Target Bus out of bounds. \n",
1956 ioc->name, __FILE__, __LINE__);
1957 rc = -ENODEV;
1958 goto done_free_mem;
1959 }
1960
1961 pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
1962 pScsiReq->MsgFlags |= mpt_msg_flags(ioc);
1963
1964
1965
1966
1967
1968
1969
1970
1971 if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
1972 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1973 else
1974 pScsiReq->SenseBufferLength = karg.maxSenseBytes;
1975
1976 pScsiReq->SenseBufferLowAddr =
1977 cpu_to_le32(ioc->sense_buf_low_dma
1978 + (req_idx * MPT_SENSE_BUFFER_ALLOC));
1979
1980 shost_for_each_device(sdev, ioc->sh) {
1981 struct scsi_target *starget = scsi_target(sdev);
1982 VirtTarget *vtarget = starget->hostdata;
1983
1984 if (vtarget == NULL)
1985 continue;
1986
1987 if ((pScsiReq->TargetID == vtarget->id) &&
1988 (pScsiReq->Bus == vtarget->channel) &&
1989 (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
1990 qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
1991 }
1992
1993
1994
1995
1996 if (karg.dataOutSize > 0) {
1997 scsidir = MPI_SCSIIO_CONTROL_WRITE;
1998 dataSize = karg.dataOutSize;
1999 } else {
2000 scsidir = MPI_SCSIIO_CONTROL_READ;
2001 dataSize = karg.dataInSize;
2002 }
2003
2004 pScsiReq->Control = cpu_to_le32(scsidir | qtag);
2005 pScsiReq->DataLength = cpu_to_le32(dataSize);
2006
2007
2008 } else {
2009 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2010 "SCSI driver is not loaded. \n",
2011 ioc->name, __FILE__, __LINE__);
2012 rc = -EFAULT;
2013 goto done_free_mem;
2014 }
2015 break;
2016
2017 case MPI_FUNCTION_SMP_PASSTHROUGH:
2018
2019
2020
2021
2022
2023
2024 break;
2025
2026 case MPI_FUNCTION_SATA_PASSTHROUGH:
2027 if (!ioc->sh) {
2028 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2029 "SCSI driver is not loaded. \n",
2030 ioc->name, __FILE__, __LINE__);
2031 rc = -EFAULT;
2032 goto done_free_mem;
2033 }
2034 break;
2035
2036 case MPI_FUNCTION_RAID_ACTION:
2037
2038
2039 break;
2040
2041 case MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
2042 if (ioc->sh) {
2043 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
2044 int qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
2045 int scsidir = MPI_SCSIIO_CONTROL_READ;
2046 int dataSize;
2047
2048 pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
2049 pScsiReq->MsgFlags |= mpt_msg_flags(ioc);
2050
2051
2052
2053
2054
2055
2056
2057
2058 if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
2059 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
2060 else
2061 pScsiReq->SenseBufferLength = karg.maxSenseBytes;
2062
2063 pScsiReq->SenseBufferLowAddr =
2064 cpu_to_le32(ioc->sense_buf_low_dma
2065 + (req_idx * MPT_SENSE_BUFFER_ALLOC));
2066
2067
2068
2069
2070
2071
2072
2073 if (karg.dataOutSize > 0) {
2074 scsidir = MPI_SCSIIO_CONTROL_WRITE;
2075 dataSize = karg.dataOutSize;
2076 } else {
2077 scsidir = MPI_SCSIIO_CONTROL_READ;
2078 dataSize = karg.dataInSize;
2079 }
2080
2081 pScsiReq->Control = cpu_to_le32(scsidir | qtag);
2082 pScsiReq->DataLength = cpu_to_le32(dataSize);
2083
2084 } else {
2085 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2086 "SCSI driver is not loaded. \n",
2087 ioc->name, __FILE__, __LINE__);
2088 rc = -EFAULT;
2089 goto done_free_mem;
2090 }
2091 break;
2092
2093 case MPI_FUNCTION_SCSI_TASK_MGMT:
2094 {
2095 SCSITaskMgmt_t *pScsiTm;
2096 pScsiTm = (SCSITaskMgmt_t *)mf;
2097 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2098 "\tTaskType=0x%x MsgFlags=0x%x "
2099 "TaskMsgContext=0x%x id=%d channel=%d\n",
2100 ioc->name, pScsiTm->TaskType, le32_to_cpu
2101 (pScsiTm->TaskMsgContext), pScsiTm->MsgFlags,
2102 pScsiTm->TargetID, pScsiTm->Bus));
2103 break;
2104 }
2105
2106 case MPI_FUNCTION_IOC_INIT:
2107 {
2108 IOCInit_t *pInit = (IOCInit_t *) mf;
2109 u32 high_addr, sense_high;
2110
2111
2112
2113
2114 if (sizeof(dma_addr_t) == sizeof(u64)) {
2115 high_addr = cpu_to_le32((u32)((u64)ioc->req_frames_dma >> 32));
2116 sense_high= cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2117 } else {
2118 high_addr = 0;
2119 sense_high= 0;
2120 }
2121
2122 if ((pInit->Flags != 0) || (pInit->MaxDevices != ioc->facts.MaxDevices) ||
2123 (pInit->MaxBuses != ioc->facts.MaxBuses) ||
2124 (pInit->ReplyFrameSize != cpu_to_le16(ioc->reply_sz)) ||
2125 (pInit->HostMfaHighAddr != high_addr) ||
2126 (pInit->SenseBufferHighAddr != sense_high)) {
2127 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2128 "IOC_INIT issued with 1 or more incorrect parameters. Rejected.\n",
2129 ioc->name, __FILE__, __LINE__);
2130 rc = -EFAULT;
2131 goto done_free_mem;
2132 }
2133 }
2134 break;
2135 default:
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2161 "Illegal request (function 0x%x) \n",
2162 ioc->name, __FILE__, __LINE__, hdr->Function);
2163 rc = -EFAULT;
2164 goto done_free_mem;
2165 }
2166
2167
2168
2169
2170
2171
2172 psge = (char *) (((int *) mf) + karg.dataSgeOffset);
2173 flagsLength = 0;
2174
2175 if (karg.dataOutSize > 0)
2176 sgSize ++;
2177
2178 if (karg.dataInSize > 0)
2179 sgSize ++;
2180
2181 if (sgSize > 0) {
2182
2183
2184 if (karg.dataOutSize > 0) {
2185 if (karg.dataInSize > 0) {
2186 flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2187 MPI_SGE_FLAGS_END_OF_BUFFER |
2188 MPI_SGE_FLAGS_DIRECTION)
2189 << MPI_SGE_FLAGS_SHIFT;
2190 } else {
2191 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
2192 }
2193 flagsLength |= karg.dataOutSize;
2194 bufOut.len = karg.dataOutSize;
2195 bufOut.kptr = pci_alloc_consistent(
2196 ioc->pcidev, bufOut.len, &dma_addr_out);
2197
2198 if (bufOut.kptr == NULL) {
2199 rc = -ENOMEM;
2200 goto done_free_mem;
2201 } else {
2202
2203
2204
2205 ioc->add_sge(psge, flagsLength, dma_addr_out);
2206 psge += ioc->SGE_size;
2207
2208
2209
2210 if (copy_from_user(bufOut.kptr,
2211 karg.dataOutBufPtr,
2212 bufOut.len)) {
2213 printk(MYIOC_s_ERR_FMT
2214 "%s@%d::mptctl_do_mpt_command - Unable "
2215 "to read user data "
2216 "struct @ %p\n",
2217 ioc->name, __FILE__, __LINE__,karg.dataOutBufPtr);
2218 rc = -EFAULT;
2219 goto done_free_mem;
2220 }
2221 }
2222 }
2223
2224 if (karg.dataInSize > 0) {
2225 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
2226 flagsLength |= karg.dataInSize;
2227
2228 bufIn.len = karg.dataInSize;
2229 bufIn.kptr = pci_alloc_consistent(ioc->pcidev,
2230 bufIn.len, &dma_addr_in);
2231
2232 if (bufIn.kptr == NULL) {
2233 rc = -ENOMEM;
2234 goto done_free_mem;
2235 } else {
2236
2237
2238
2239 ioc->add_sge(psge, flagsLength, dma_addr_in);
2240 }
2241 }
2242 } else {
2243
2244
2245 ioc->add_sge(psge, flagsLength, (dma_addr_t) -1);
2246 }
2247
2248 SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, hdr->MsgContext);
2249 INITIALIZE_MGMT_STATUS(ioc->ioctl_cmds.status)
2250 if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
2251
2252 mutex_lock(&ioc->taskmgmt_cmds.mutex);
2253 if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
2254 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2255 goto done_free_mem;
2256 }
2257
2258 DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
2259
2260 if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
2261 (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
2262 mpt_put_msg_frame_hi_pri(mptctl_id, ioc, mf);
2263 else {
2264 rc =mpt_send_handshake_request(mptctl_id, ioc,
2265 sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP);
2266 if (rc != 0) {
2267 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2268 "send_handshake FAILED! (ioc %p, mf %p)\n",
2269 ioc->name, ioc, mf));
2270 mpt_clear_taskmgmt_in_progress_flag(ioc);
2271 rc = -ENODATA;
2272 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2273 goto done_free_mem;
2274 }
2275 }
2276
2277 } else
2278 mpt_put_msg_frame(mptctl_id, ioc, mf);
2279
2280
2281 timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT;
2282retry_wait:
2283 timeleft = wait_for_completion_timeout(&ioc->ioctl_cmds.done,
2284 HZ*timeout);
2285 if (!(ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2286 rc = -ETIME;
2287 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: TIMED OUT!\n",
2288 ioc->name, __func__));
2289 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
2290 if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
2291 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2292 goto done_free_mem;
2293 }
2294 if (!timeleft) {
2295 printk(MYIOC_s_WARN_FMT
2296 "mpt cmd timeout, doorbell=0x%08x"
2297 " function=0x%x\n",
2298 ioc->name, mpt_GetIocState(ioc, 0), function);
2299 if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
2300 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2301 mptctl_timeout_expired(ioc, mf);
2302 mf = NULL;
2303 } else
2304 goto retry_wait;
2305 goto done_free_mem;
2306 }
2307
2308 if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
2309 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2310
2311
2312 mf = NULL;
2313
2314
2315
2316
2317 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_RF_VALID) {
2318 if (karg.maxReplyBytes < ioc->reply_sz) {
2319 sz = min(karg.maxReplyBytes,
2320 4*ioc->ioctl_cmds.reply[2]);
2321 } else {
2322 sz = min(ioc->reply_sz, 4*ioc->ioctl_cmds.reply[2]);
2323 }
2324 if (sz > 0) {
2325 if (copy_to_user(karg.replyFrameBufPtr,
2326 ioc->ioctl_cmds.reply, sz)){
2327 printk(MYIOC_s_ERR_FMT
2328 "%s@%d::mptctl_do_mpt_command - "
2329 "Unable to write out reply frame %p\n",
2330 ioc->name, __FILE__, __LINE__, karg.replyFrameBufPtr);
2331 rc = -ENODATA;
2332 goto done_free_mem;
2333 }
2334 }
2335 }
2336
2337
2338
2339 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_SENSE_VALID) {
2340 sz = min(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE);
2341 if (sz > 0) {
2342 if (copy_to_user(karg.senseDataPtr,
2343 ioc->ioctl_cmds.sense, sz)) {
2344 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2345 "Unable to write sense data to user %p\n",
2346 ioc->name, __FILE__, __LINE__,
2347 karg.senseDataPtr);
2348 rc = -ENODATA;
2349 goto done_free_mem;
2350 }
2351 }
2352 }
2353
2354
2355
2356
2357 if ((ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD) &&
2358 (karg.dataInSize > 0) && (bufIn.kptr)) {
2359
2360 if (copy_to_user(karg.dataInBufPtr,
2361 bufIn.kptr, karg.dataInSize)) {
2362 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2363 "Unable to write data to user %p\n",
2364 ioc->name, __FILE__, __LINE__,
2365 karg.dataInBufPtr);
2366 rc = -ENODATA;
2367 }
2368 }
2369
2370done_free_mem:
2371
2372 CLEAR_MGMT_STATUS(ioc->ioctl_cmds.status)
2373 SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, 0);
2374
2375
2376
2377 if (bufOut.kptr != NULL) {
2378 pci_free_consistent(ioc->pcidev,
2379 bufOut.len, (void *) bufOut.kptr, dma_addr_out);
2380 }
2381
2382 if (bufIn.kptr != NULL) {
2383 pci_free_consistent(ioc->pcidev,
2384 bufIn.len, (void *) bufIn.kptr, dma_addr_in);
2385 }
2386
2387
2388
2389
2390 if (mf)
2391 mpt_free_msg_frame(ioc, mf);
2392
2393 return rc;
2394}
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407static int
2408mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
2409{
2410 hp_host_info_t __user *uarg = (void __user *) arg;
2411 MPT_ADAPTER *ioc;
2412 struct pci_dev *pdev;
2413 char *pbuf=NULL;
2414 dma_addr_t buf_dma;
2415 hp_host_info_t karg;
2416 CONFIGPARMS cfg;
2417 ConfigPageHeader_t hdr;
2418 int iocnum;
2419 int rc, cim_rev;
2420 ToolboxIstwiReadWriteRequest_t *IstwiRWRequest;
2421 MPT_FRAME_HDR *mf = NULL;
2422 unsigned long timeleft;
2423 int retval;
2424 u32 msgcontext;
2425
2426
2427
2428 if (data_size == sizeof(hp_host_info_t))
2429 cim_rev = 1;
2430 else if (data_size == sizeof(hp_host_info_rev0_t))
2431 cim_rev = 0;
2432 else
2433 return -EFAULT;
2434
2435 if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) {
2436 printk(KERN_ERR MYNAM "%s@%d::mptctl_hp_host_info - "
2437 "Unable to read in hp_host_info struct @ %p\n",
2438 __FILE__, __LINE__, uarg);
2439 return -EFAULT;
2440 }
2441
2442 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
2443 (ioc == NULL)) {
2444 printk(KERN_DEBUG MYNAM "%s::mptctl_hp_hostinfo() @%d - ioc%d not found!\n",
2445 __FILE__, __LINE__, iocnum);
2446 return -ENODEV;
2447 }
2448 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": mptctl_hp_hostinfo called.\n",
2449 ioc->name));
2450
2451
2452
2453
2454 pdev = (struct pci_dev *) ioc->pcidev;
2455
2456 karg.vendor = pdev->vendor;
2457 karg.device = pdev->device;
2458 karg.subsystem_id = pdev->subsystem_device;
2459 karg.subsystem_vendor = pdev->subsystem_vendor;
2460 karg.devfn = pdev->devfn;
2461 karg.bus = pdev->bus->number;
2462
2463
2464
2465
2466 if (ioc->sh != NULL)
2467 karg.host_no = ioc->sh->host_no;
2468 else
2469 karg.host_no = -1;
2470
2471
2472
2473 karg.fw_version[0] = ioc->facts.FWVersion.Struct.Major >= 10 ?
2474 ((ioc->facts.FWVersion.Struct.Major / 10) + '0') : '0';
2475 karg.fw_version[1] = (ioc->facts.FWVersion.Struct.Major % 10 ) + '0';
2476 karg.fw_version[2] = '.';
2477 karg.fw_version[3] = ioc->facts.FWVersion.Struct.Minor >= 10 ?
2478 ((ioc->facts.FWVersion.Struct.Minor / 10) + '0') : '0';
2479 karg.fw_version[4] = (ioc->facts.FWVersion.Struct.Minor % 10 ) + '0';
2480 karg.fw_version[5] = '.';
2481 karg.fw_version[6] = ioc->facts.FWVersion.Struct.Unit >= 10 ?
2482 ((ioc->facts.FWVersion.Struct.Unit / 10) + '0') : '0';
2483 karg.fw_version[7] = (ioc->facts.FWVersion.Struct.Unit % 10 ) + '0';
2484 karg.fw_version[8] = '.';
2485 karg.fw_version[9] = ioc->facts.FWVersion.Struct.Dev >= 10 ?
2486 ((ioc->facts.FWVersion.Struct.Dev / 10) + '0') : '0';
2487 karg.fw_version[10] = (ioc->facts.FWVersion.Struct.Dev % 10 ) + '0';
2488 karg.fw_version[11] = '\0';
2489
2490
2491
2492 hdr.PageVersion = 0;
2493 hdr.PageLength = 0;
2494 hdr.PageNumber = 0;
2495 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
2496 cfg.cfghdr.hdr = &hdr;
2497 cfg.physAddr = -1;
2498 cfg.pageAddr = 0;
2499 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2500 cfg.dir = 0;
2501 cfg.timeout = 10;
2502
2503 strncpy(karg.serial_number, " ", 24);
2504 if (mpt_config(ioc, &cfg) == 0) {
2505 if (cfg.cfghdr.hdr->PageLength > 0) {
2506
2507 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2508
2509 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
2510 if (pbuf) {
2511 cfg.physAddr = buf_dma;
2512 if (mpt_config(ioc, &cfg) == 0) {
2513 ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf;
2514 if (strlen(pdata->BoardTracerNumber) > 1) {
2515 strncpy(karg.serial_number, pdata->BoardTracerNumber, 24);
2516 karg.serial_number[24-1]='\0';
2517 }
2518 }
2519 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
2520 pbuf = NULL;
2521 }
2522 }
2523 }
2524 rc = mpt_GetIocState(ioc, 1);
2525 switch (rc) {
2526 case MPI_IOC_STATE_OPERATIONAL:
2527 karg.ioc_status = HP_STATUS_OK;
2528 break;
2529
2530 case MPI_IOC_STATE_FAULT:
2531 karg.ioc_status = HP_STATUS_FAILED;
2532 break;
2533
2534 case MPI_IOC_STATE_RESET:
2535 case MPI_IOC_STATE_READY:
2536 default:
2537 karg.ioc_status = HP_STATUS_OTHER;
2538 break;
2539 }
2540
2541 karg.base_io_addr = pci_resource_start(pdev, 0);
2542
2543 if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))
2544 karg.bus_phys_width = HP_BUS_WIDTH_UNK;
2545 else
2546 karg.bus_phys_width = HP_BUS_WIDTH_16;
2547
2548 karg.hard_resets = 0;
2549 karg.soft_resets = 0;
2550 karg.timeouts = 0;
2551 if (ioc->sh != NULL) {
2552 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
2553
2554 if (hd && (cim_rev == 1)) {
2555 karg.hard_resets = ioc->hard_resets;
2556 karg.soft_resets = ioc->soft_resets;
2557 karg.timeouts = ioc->timeouts;
2558 }
2559 }
2560
2561
2562
2563
2564 if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) {
2565 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
2566 "%s, no msg frames!!\n", ioc->name, __func__));
2567 goto out;
2568 }
2569
2570 IstwiRWRequest = (ToolboxIstwiReadWriteRequest_t *)mf;
2571 msgcontext = IstwiRWRequest->MsgContext;
2572 memset(IstwiRWRequest,0,sizeof(ToolboxIstwiReadWriteRequest_t));
2573 IstwiRWRequest->MsgContext = msgcontext;
2574 IstwiRWRequest->Function = MPI_FUNCTION_TOOLBOX;
2575 IstwiRWRequest->Tool = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
2576 IstwiRWRequest->Flags = MPI_TB_ISTWI_FLAGS_READ;
2577 IstwiRWRequest->NumAddressBytes = 0x01;
2578 IstwiRWRequest->DataLength = cpu_to_le16(0x04);
2579 if (pdev->devfn & 1)
2580 IstwiRWRequest->DeviceAddr = 0xB2;
2581 else
2582 IstwiRWRequest->DeviceAddr = 0xB0;
2583
2584 pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma);
2585 if (!pbuf)
2586 goto out;
2587 ioc->add_sge((char *)&IstwiRWRequest->SGL,
2588 (MPT_SGE_FLAGS_SSIMPLE_READ|4), buf_dma);
2589
2590 retval = 0;
2591 SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context,
2592 IstwiRWRequest->MsgContext);
2593 INITIALIZE_MGMT_STATUS(ioc->ioctl_cmds.status)
2594 mpt_put_msg_frame(mptctl_id, ioc, mf);
2595
2596retry_wait:
2597 timeleft = wait_for_completion_timeout(&ioc->ioctl_cmds.done,
2598 HZ*MPT_IOCTL_DEFAULT_TIMEOUT);
2599 if (!(ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2600 retval = -ETIME;
2601 printk(MYIOC_s_WARN_FMT "%s: failed\n", ioc->name, __func__);
2602 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
2603 mpt_free_msg_frame(ioc, mf);
2604 goto out;
2605 }
2606 if (!timeleft) {
2607 printk(MYIOC_s_WARN_FMT
2608 "HOST INFO command timeout, doorbell=0x%08x\n",
2609 ioc->name, mpt_GetIocState(ioc, 0));
2610 mptctl_timeout_expired(ioc, mf);
2611 } else
2612 goto retry_wait;
2613 goto out;
2614 }
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_RF_VALID)
2626 karg.rsvd = *(u32 *)pbuf;
2627
2628 out:
2629 CLEAR_MGMT_STATUS(ioc->ioctl_cmds.status)
2630 SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, 0);
2631
2632 if (pbuf)
2633 pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma);
2634
2635
2636
2637 if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) {
2638 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_hpgethostinfo - "
2639 "Unable to write out hp_host_info @ %p\n",
2640 ioc->name, __FILE__, __LINE__, uarg);
2641 return -EFAULT;
2642 }
2643
2644 return 0;
2645
2646}
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659static int
2660mptctl_hp_targetinfo(unsigned long arg)
2661{
2662 hp_target_info_t __user *uarg = (void __user *) arg;
2663 SCSIDevicePage0_t *pg0_alloc;
2664 SCSIDevicePage3_t *pg3_alloc;
2665 MPT_ADAPTER *ioc;
2666 MPT_SCSI_HOST *hd = NULL;
2667 hp_target_info_t karg;
2668 int iocnum;
2669 int data_sz;
2670 dma_addr_t page_dma;
2671 CONFIGPARMS cfg;
2672 ConfigPageHeader_t hdr;
2673 int tmp, np, rc = 0;
2674
2675 if (copy_from_user(&karg, uarg, sizeof(hp_target_info_t))) {
2676 printk(KERN_ERR MYNAM "%s@%d::mptctl_hp_targetinfo - "
2677 "Unable to read in hp_host_targetinfo struct @ %p\n",
2678 __FILE__, __LINE__, uarg);
2679 return -EFAULT;
2680 }
2681
2682 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
2683 (ioc == NULL)) {
2684 printk(KERN_DEBUG MYNAM "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n",
2685 __FILE__, __LINE__, iocnum);
2686 return -ENODEV;
2687 }
2688 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_hp_targetinfo called.\n",
2689 ioc->name));
2690
2691
2692
2693 if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))
2694 return 0;
2695
2696 if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL))
2697 return 0;
2698
2699 if (ioc->sh->host_no != karg.hdr.host)
2700 return -ENODEV;
2701
2702
2703
2704 data_sz = ioc->spi_data.sdp0length * 4;
2705 pg0_alloc = (SCSIDevicePage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
2706 if (pg0_alloc) {
2707 hdr.PageVersion = ioc->spi_data.sdp0version;
2708 hdr.PageLength = data_sz;
2709 hdr.PageNumber = 0;
2710 hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
2711
2712 cfg.cfghdr.hdr = &hdr;
2713 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2714 cfg.dir = 0;
2715 cfg.timeout = 0;
2716 cfg.physAddr = page_dma;
2717
2718 cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
2719
2720 if ((rc = mpt_config(ioc, &cfg)) == 0) {
2721 np = le32_to_cpu(pg0_alloc->NegotiatedParameters);
2722 karg.negotiated_width = np & MPI_SCSIDEVPAGE0_NP_WIDE ?
2723 HP_BUS_WIDTH_16 : HP_BUS_WIDTH_8;
2724
2725 if (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) {
2726 tmp = (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
2727 if (tmp < 0x09)
2728 karg.negotiated_speed = HP_DEV_SPEED_ULTRA320;
2729 else if (tmp <= 0x09)
2730 karg.negotiated_speed = HP_DEV_SPEED_ULTRA160;
2731 else if (tmp <= 0x0A)
2732 karg.negotiated_speed = HP_DEV_SPEED_ULTRA2;
2733 else if (tmp <= 0x0C)
2734 karg.negotiated_speed = HP_DEV_SPEED_ULTRA;
2735 else if (tmp <= 0x25)
2736 karg.negotiated_speed = HP_DEV_SPEED_FAST;
2737 else
2738 karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
2739 } else
2740 karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
2741 }
2742
2743 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg0_alloc, page_dma);
2744 }
2745
2746
2747
2748 karg.message_rejects = -1;
2749 karg.phase_errors = -1;
2750 karg.parity_errors = -1;
2751 karg.select_timeouts = -1;
2752
2753
2754
2755 hdr.PageVersion = 0;
2756 hdr.PageLength = 0;
2757 hdr.PageNumber = 3;
2758 hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
2759
2760 cfg.cfghdr.hdr = &hdr;
2761 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2762 cfg.dir = 0;
2763 cfg.timeout = 0;
2764 cfg.physAddr = -1;
2765 if ((mpt_config(ioc, &cfg) == 0) && (cfg.cfghdr.hdr->PageLength > 0)) {
2766
2767 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2768 data_sz = (int) cfg.cfghdr.hdr->PageLength * 4;
2769 pg3_alloc = (SCSIDevicePage3_t *) pci_alloc_consistent(
2770 ioc->pcidev, data_sz, &page_dma);
2771 if (pg3_alloc) {
2772 cfg.physAddr = page_dma;
2773 cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
2774 if ((rc = mpt_config(ioc, &cfg)) == 0) {
2775 karg.message_rejects = (u32) le16_to_cpu(pg3_alloc->MsgRejectCount);
2776 karg.phase_errors = (u32) le16_to_cpu(pg3_alloc->PhaseErrorCount);
2777 karg.parity_errors = (u32) le16_to_cpu(pg3_alloc->ParityErrorCount);
2778 }
2779 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg3_alloc, page_dma);
2780 }
2781 }
2782 hd = shost_priv(ioc->sh);
2783 if (hd != NULL)
2784 karg.select_timeouts = hd->sel_timeout[karg.hdr.id];
2785
2786
2787
2788 if (copy_to_user((char __user *)arg, &karg, sizeof(hp_target_info_t))) {
2789 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_hp_target_info - "
2790 "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
2791 ioc->name, __FILE__, __LINE__, uarg);
2792 return -EFAULT;
2793 }
2794
2795 return 0;
2796}
2797
2798
2799
2800static const struct file_operations mptctl_fops = {
2801 .owner = THIS_MODULE,
2802 .llseek = no_llseek,
2803 .fasync = mptctl_fasync,
2804 .unlocked_ioctl = mptctl_ioctl,
2805#ifdef CONFIG_COMPAT
2806 .compat_ioctl = compat_mpctl_ioctl,
2807#endif
2808};
2809
2810static struct miscdevice mptctl_miscdev = {
2811 MPT_MINOR,
2812 MYNAM,
2813 &mptctl_fops
2814};
2815
2816
2817
2818#ifdef CONFIG_COMPAT
2819
2820static int
2821compat_mptfwxfer_ioctl(struct file *filp, unsigned int cmd,
2822 unsigned long arg)
2823{
2824 struct mpt_fw_xfer32 kfw32;
2825 struct mpt_fw_xfer kfw;
2826 MPT_ADAPTER *iocp = NULL;
2827 int iocnum, iocnumX;
2828 int nonblock = (filp->f_flags & O_NONBLOCK);
2829 int ret;
2830
2831
2832 if (copy_from_user(&kfw32, (char __user *)arg, sizeof(kfw32)))
2833 return -EFAULT;
2834
2835
2836 iocnumX = kfw32.iocnum & 0xFF;
2837 if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
2838 (iocp == NULL)) {
2839 printk(KERN_DEBUG MYNAM "::compat_mptfwxfer_ioctl @%d - ioc%d not found!\n",
2840 __LINE__, iocnumX);
2841 return -ENODEV;
2842 }
2843
2844 if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
2845 return ret;
2846
2847 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "compat_mptfwxfer_ioctl() called\n",
2848 iocp->name));
2849 kfw.iocnum = iocnum;
2850 kfw.fwlen = kfw32.fwlen;
2851 kfw.bufp = compat_ptr(kfw32.bufp);
2852
2853 ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);
2854
2855 mutex_unlock(&iocp->ioctl_cmds.mutex);
2856
2857 return ret;
2858}
2859
2860static int
2861compat_mpt_command(struct file *filp, unsigned int cmd,
2862 unsigned long arg)
2863{
2864 struct mpt_ioctl_command32 karg32;
2865 struct mpt_ioctl_command32 __user *uarg = (struct mpt_ioctl_command32 __user *) arg;
2866 struct mpt_ioctl_command karg;
2867 MPT_ADAPTER *iocp = NULL;
2868 int iocnum, iocnumX;
2869 int nonblock = (filp->f_flags & O_NONBLOCK);
2870 int ret;
2871
2872 if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32)))
2873 return -EFAULT;
2874
2875
2876 iocnumX = karg32.hdr.iocnum & 0xFF;
2877 if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
2878 (iocp == NULL)) {
2879 printk(KERN_DEBUG MYNAM "::compat_mpt_command @%d - ioc%d not found!\n",
2880 __LINE__, iocnumX);
2881 return -ENODEV;
2882 }
2883
2884 if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
2885 return ret;
2886
2887 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "compat_mpt_command() called\n",
2888 iocp->name));
2889
2890 karg.hdr.iocnum = karg32.hdr.iocnum;
2891 karg.hdr.port = karg32.hdr.port;
2892 karg.timeout = karg32.timeout;
2893 karg.maxReplyBytes = karg32.maxReplyBytes;
2894
2895 karg.dataInSize = karg32.dataInSize;
2896 karg.dataOutSize = karg32.dataOutSize;
2897 karg.maxSenseBytes = karg32.maxSenseBytes;
2898 karg.dataSgeOffset = karg32.dataSgeOffset;
2899
2900 karg.replyFrameBufPtr = (char __user *)(unsigned long)karg32.replyFrameBufPtr;
2901 karg.dataInBufPtr = (char __user *)(unsigned long)karg32.dataInBufPtr;
2902 karg.dataOutBufPtr = (char __user *)(unsigned long)karg32.dataOutBufPtr;
2903 karg.senseDataPtr = (char __user *)(unsigned long)karg32.senseDataPtr;
2904
2905
2906
2907 ret = mptctl_do_mpt_command (karg, &uarg->MF);
2908
2909 mutex_unlock(&iocp->ioctl_cmds.mutex);
2910
2911 return ret;
2912}
2913
2914static long compat_mpctl_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
2915{
2916 long ret;
2917 mutex_lock(&mpctl_mutex);
2918 switch (cmd) {
2919 case MPTIOCINFO:
2920 case MPTIOCINFO1:
2921 case MPTIOCINFO2:
2922 case MPTTARGETINFO:
2923 case MPTEVENTQUERY:
2924 case MPTEVENTENABLE:
2925 case MPTEVENTREPORT:
2926 case MPTHARDRESET:
2927 case HP_GETHOSTINFO:
2928 case HP_GETTARGETINFO:
2929 case MPTTEST:
2930 ret = __mptctl_ioctl(f, cmd, arg);
2931 break;
2932 case MPTCOMMAND32:
2933 ret = compat_mpt_command(f, cmd, arg);
2934 break;
2935 case MPTFWDOWNLOAD32:
2936 ret = compat_mptfwxfer_ioctl(f, cmd, arg);
2937 break;
2938 default:
2939 ret = -ENOIOCTLCMD;
2940 break;
2941 }
2942 mutex_unlock(&mpctl_mutex);
2943 return ret;
2944}
2945
2946#endif
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958static int
2959mptctl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2960{
2961 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2962
2963 mutex_init(&ioc->ioctl_cmds.mutex);
2964 init_completion(&ioc->ioctl_cmds.done);
2965 return 0;
2966}
2967
2968
2969
2970
2971
2972
2973
2974
2975static void
2976mptctl_remove(struct pci_dev *pdev)
2977{
2978}
2979
2980static struct mpt_pci_driver mptctl_driver = {
2981 .probe = mptctl_probe,
2982 .remove = mptctl_remove,
2983};
2984
2985
2986static int __init mptctl_init(void)
2987{
2988 int err;
2989 int where = 1;
2990
2991 show_mptmod_ver(my_NAME, my_VERSION);
2992
2993 mpt_device_driver_register(&mptctl_driver, MPTCTL_DRIVER);
2994
2995
2996 err = misc_register(&mptctl_miscdev);
2997 if (err < 0) {
2998 printk(KERN_ERR MYNAM ": Can't register misc device [minor=%d].\n", MPT_MINOR);
2999 goto out_fail;
3000 }
3001 printk(KERN_INFO MYNAM ": Registered with Fusion MPT base driver\n");
3002 printk(KERN_INFO MYNAM ": /dev/%s @ (major,minor=%d,%d)\n",
3003 mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
3004
3005
3006
3007
3008 ++where;
3009 mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER,
3010 "mptctl_reply");
3011 if (!mptctl_id || mptctl_id >= MPT_MAX_PROTOCOL_DRIVERS) {
3012 printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
3013 misc_deregister(&mptctl_miscdev);
3014 err = -EBUSY;
3015 goto out_fail;
3016 }
3017
3018 mptctl_taskmgmt_id = mpt_register(mptctl_taskmgmt_reply, MPTCTL_DRIVER,
3019 "mptctl_taskmgmt_reply");
3020 if (!mptctl_taskmgmt_id || mptctl_taskmgmt_id >= MPT_MAX_PROTOCOL_DRIVERS) {
3021 printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
3022 mpt_deregister(mptctl_id);
3023 misc_deregister(&mptctl_miscdev);
3024 err = -EBUSY;
3025 goto out_fail;
3026 }
3027
3028 mpt_reset_register(mptctl_id, mptctl_ioc_reset);
3029 mpt_event_register(mptctl_id, mptctl_event_process);
3030
3031 return 0;
3032
3033out_fail:
3034
3035 mpt_device_driver_deregister(MPTCTL_DRIVER);
3036
3037 return err;
3038}
3039
3040
3041static void mptctl_exit(void)
3042{
3043 misc_deregister(&mptctl_miscdev);
3044 printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n",
3045 mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
3046
3047
3048 mpt_event_deregister(mptctl_id);
3049
3050
3051 mpt_reset_deregister(mptctl_id);
3052
3053
3054 mpt_deregister(mptctl_taskmgmt_id);
3055 mpt_deregister(mptctl_id);
3056
3057 mpt_device_driver_deregister(MPTCTL_DRIVER);
3058
3059}
3060
3061
3062
3063module_init(mptctl_init);
3064module_exit(mptctl_exit);
3065