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 = kmalloc(data_size, GFP_KERNEL);
1265 if (karg == NULL) {
1266 printk(KERN_ERR MYNAM "%s::mpt_ioctl_iocinfo() @%d - no memory available!\n",
1267 __FILE__, __LINE__);
1268 return -ENOMEM;
1269 }
1270
1271 if (copy_from_user(karg, uarg, data_size)) {
1272 printk(KERN_ERR MYNAM "%s@%d::mptctl_getiocinfo - "
1273 "Unable to read in mpt_ioctl_iocinfo struct @ %p\n",
1274 __FILE__, __LINE__, uarg);
1275 kfree(karg);
1276 return -EFAULT;
1277 }
1278
1279 if (((iocnum = mpt_verify_adapter(karg->hdr.iocnum, &ioc)) < 0) ||
1280 (ioc == NULL)) {
1281 printk(KERN_DEBUG MYNAM "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n",
1282 __FILE__, __LINE__, iocnum);
1283 kfree(karg);
1284 return -ENODEV;
1285 }
1286
1287
1288 if (karg->hdr.maxDataSize != data_size) {
1289 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - "
1290 "Structure size mismatch. Command not completed.\n",
1291 ioc->name, __FILE__, __LINE__);
1292 kfree(karg);
1293 return -EFAULT;
1294 }
1295
1296 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_getiocinfo called.\n",
1297 ioc->name));
1298
1299
1300
1301
1302 if (ioc->bus_type == SAS)
1303 karg->adapterType = MPT_IOCTL_INTERFACE_SAS;
1304 else if (ioc->bus_type == FC)
1305 karg->adapterType = MPT_IOCTL_INTERFACE_FC;
1306 else
1307 karg->adapterType = MPT_IOCTL_INTERFACE_SCSI;
1308
1309 if (karg->hdr.port > 1) {
1310 kfree(karg);
1311 return -EINVAL;
1312 }
1313 port = karg->hdr.port;
1314
1315 karg->port = port;
1316 pdev = (struct pci_dev *) ioc->pcidev;
1317
1318 karg->pciId = pdev->device;
1319 karg->hwRev = pdev->revision;
1320 karg->subSystemDevice = pdev->subsystem_device;
1321 karg->subSystemVendor = pdev->subsystem_vendor;
1322
1323 if (cim_rev == 1) {
1324
1325
1326 karg->pciInfo.u.bits.busNumber = pdev->bus->number;
1327 karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
1328 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1329 } else if (cim_rev == 2) {
1330
1331
1332 karg->pciInfo.u.bits.busNumber = pdev->bus->number;
1333 karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
1334 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1335 karg->pciInfo.segmentID = pci_domain_nr(pdev->bus);
1336 }
1337
1338
1339
1340 karg->numDevices = 0;
1341 if (ioc->sh) {
1342 shost_for_each_device(sdev, ioc->sh) {
1343 vdevice = sdev->hostdata;
1344 if (vdevice == NULL || vdevice->vtarget == NULL)
1345 continue;
1346 if (vdevice->vtarget->tflags &
1347 MPT_TARGET_FLAGS_RAID_COMPONENT)
1348 continue;
1349 karg->numDevices++;
1350 }
1351 }
1352
1353
1354
1355 karg->FWVersion = ioc->facts.FWVersion.Word;
1356 karg->BIOSVersion = ioc->biosVersion;
1357
1358
1359
1360 strncpy (karg->driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH);
1361 karg->driverVersion[MPT_IOCTL_VERSION_LENGTH-1]='\0';
1362
1363 karg->busChangeEvent = 0;
1364 karg->hostId = ioc->pfacts[port].PortSCSIID;
1365 karg->rsvd[0] = karg->rsvd[1] = 0;
1366
1367
1368
1369 if (copy_to_user((char __user *)arg, karg, data_size)) {
1370 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - "
1371 "Unable to write out mpt_ioctl_iocinfo struct @ %p\n",
1372 ioc->name, __FILE__, __LINE__, uarg);
1373 kfree(karg);
1374 return -EFAULT;
1375 }
1376
1377 kfree(karg);
1378 return 0;
1379}
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391static int
1392mptctl_gettargetinfo (unsigned long arg)
1393{
1394 struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg;
1395 struct mpt_ioctl_targetinfo karg;
1396 MPT_ADAPTER *ioc;
1397 VirtDevice *vdevice;
1398 char *pmem;
1399 int *pdata;
1400 int iocnum;
1401 int numDevices = 0;
1402 int lun;
1403 int maxWordsLeft;
1404 int numBytes;
1405 u8 port;
1406 struct scsi_device *sdev;
1407
1408 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
1409 printk(KERN_ERR MYNAM "%s@%d::mptctl_gettargetinfo - "
1410 "Unable to read in mpt_ioctl_targetinfo struct @ %p\n",
1411 __FILE__, __LINE__, uarg);
1412 return -EFAULT;
1413 }
1414
1415 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1416 (ioc == NULL)) {
1417 printk(KERN_DEBUG MYNAM "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n",
1418 __FILE__, __LINE__, iocnum);
1419 return -ENODEV;
1420 }
1421
1422 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_gettargetinfo called.\n",
1423 ioc->name));
1424
1425
1426
1427
1428 numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
1429 maxWordsLeft = numBytes/sizeof(int);
1430 port = karg.hdr.port;
1431
1432 if (maxWordsLeft <= 0) {
1433 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n",
1434 ioc->name, __FILE__, __LINE__);
1435 return -ENOMEM;
1436 }
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452 pmem = kzalloc(numBytes, GFP_KERNEL);
1453 if (!pmem) {
1454 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n",
1455 ioc->name, __FILE__, __LINE__);
1456 return -ENOMEM;
1457 }
1458 pdata = (int *) pmem;
1459
1460
1461
1462 if (ioc->sh){
1463 shost_for_each_device(sdev, ioc->sh) {
1464 if (!maxWordsLeft)
1465 continue;
1466 vdevice = sdev->hostdata;
1467 if (vdevice == NULL || vdevice->vtarget == NULL)
1468 continue;
1469 if (vdevice->vtarget->tflags &
1470 MPT_TARGET_FLAGS_RAID_COMPONENT)
1471 continue;
1472 lun = (vdevice->vtarget->raidVolume) ? 0x80 : vdevice->lun;
1473 *pdata = (((u8)lun << 16) + (vdevice->vtarget->channel << 8) +
1474 (vdevice->vtarget->id ));
1475 pdata++;
1476 numDevices++;
1477 --maxWordsLeft;
1478 }
1479 }
1480 karg.numDevices = numDevices;
1481
1482
1483
1484 if (copy_to_user((char __user *)arg, &karg,
1485 sizeof(struct mpt_ioctl_targetinfo))) {
1486 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo - "
1487 "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
1488 ioc->name, __FILE__, __LINE__, uarg);
1489 kfree(pmem);
1490 return -EFAULT;
1491 }
1492
1493
1494
1495 if (copy_to_user(uarg->targetInfo, pmem, numBytes)) {
1496 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo - "
1497 "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
1498 ioc->name, __FILE__, __LINE__, pdata);
1499 kfree(pmem);
1500 return -EFAULT;
1501 }
1502
1503 kfree(pmem);
1504
1505 return 0;
1506}
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516static int
1517mptctl_readtest (unsigned long arg)
1518{
1519 struct mpt_ioctl_test __user *uarg = (void __user *) arg;
1520 struct mpt_ioctl_test karg;
1521 MPT_ADAPTER *ioc;
1522 int iocnum;
1523
1524 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) {
1525 printk(KERN_ERR MYNAM "%s@%d::mptctl_readtest - "
1526 "Unable to read in mpt_ioctl_test struct @ %p\n",
1527 __FILE__, __LINE__, uarg);
1528 return -EFAULT;
1529 }
1530
1531 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1532 (ioc == NULL)) {
1533 printk(KERN_DEBUG MYNAM "%s::mptctl_readtest() @%d - ioc%d not found!\n",
1534 __FILE__, __LINE__, iocnum);
1535 return -ENODEV;
1536 }
1537
1538 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_readtest called.\n",
1539 ioc->name));
1540
1541
1542
1543
1544#ifdef MFCNT
1545 karg.chip_type = ioc->mfcnt;
1546#else
1547 karg.chip_type = ioc->pcidev->device;
1548#endif
1549 strncpy (karg.name, ioc->name, MPT_MAX_NAME);
1550 karg.name[MPT_MAX_NAME-1]='\0';
1551 strncpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH);
1552 karg.product[MPT_PRODUCT_LENGTH-1]='\0';
1553
1554
1555
1556 if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_test))) {
1557 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_readtest - "
1558 "Unable to write out mpt_ioctl_test struct @ %p\n",
1559 ioc->name, __FILE__, __LINE__, uarg);
1560 return -EFAULT;
1561 }
1562
1563 return 0;
1564}
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577static int
1578mptctl_eventquery (unsigned long arg)
1579{
1580 struct mpt_ioctl_eventquery __user *uarg = (void __user *) arg;
1581 struct mpt_ioctl_eventquery karg;
1582 MPT_ADAPTER *ioc;
1583 int iocnum;
1584
1585 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) {
1586 printk(KERN_ERR MYNAM "%s@%d::mptctl_eventquery - "
1587 "Unable to read in mpt_ioctl_eventquery struct @ %p\n",
1588 __FILE__, __LINE__, uarg);
1589 return -EFAULT;
1590 }
1591
1592 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1593 (ioc == NULL)) {
1594 printk(KERN_DEBUG MYNAM "%s::mptctl_eventquery() @%d - ioc%d not found!\n",
1595 __FILE__, __LINE__, iocnum);
1596 return -ENODEV;
1597 }
1598
1599 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventquery called.\n",
1600 ioc->name));
1601 karg.eventEntries = MPTCTL_EVENT_LOG_SIZE;
1602 karg.eventTypes = ioc->eventTypes;
1603
1604
1605
1606 if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) {
1607 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_eventquery - "
1608 "Unable to write out mpt_ioctl_eventquery struct @ %p\n",
1609 ioc->name, __FILE__, __LINE__, uarg);
1610 return -EFAULT;
1611 }
1612 return 0;
1613}
1614
1615
1616static int
1617mptctl_eventenable (unsigned long arg)
1618{
1619 struct mpt_ioctl_eventenable __user *uarg = (void __user *) arg;
1620 struct mpt_ioctl_eventenable karg;
1621 MPT_ADAPTER *ioc;
1622 int iocnum;
1623
1624 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) {
1625 printk(KERN_ERR MYNAM "%s@%d::mptctl_eventenable - "
1626 "Unable to read in mpt_ioctl_eventenable struct @ %p\n",
1627 __FILE__, __LINE__, uarg);
1628 return -EFAULT;
1629 }
1630
1631 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1632 (ioc == NULL)) {
1633 printk(KERN_DEBUG MYNAM "%s::mptctl_eventenable() @%d - ioc%d not found!\n",
1634 __FILE__, __LINE__, iocnum);
1635 return -ENODEV;
1636 }
1637
1638 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventenable called.\n",
1639 ioc->name));
1640 if (ioc->events == NULL) {
1641
1642
1643 int sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
1644 ioc->events = kzalloc(sz, GFP_KERNEL);
1645 if (!ioc->events) {
1646 printk(MYIOC_s_ERR_FMT
1647 ": ERROR - Insufficient memory to add adapter!\n",
1648 ioc->name);
1649 return -ENOMEM;
1650 }
1651 ioc->alloc_total += sz;
1652
1653 ioc->eventContext = 0;
1654 }
1655
1656
1657
1658 ioc->eventTypes = karg.eventTypes;
1659
1660 return 0;
1661}
1662
1663
1664static int
1665mptctl_eventreport (unsigned long arg)
1666{
1667 struct mpt_ioctl_eventreport __user *uarg = (void __user *) arg;
1668 struct mpt_ioctl_eventreport karg;
1669 MPT_ADAPTER *ioc;
1670 int iocnum;
1671 int numBytes, maxEvents, max;
1672
1673 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) {
1674 printk(KERN_ERR MYNAM "%s@%d::mptctl_eventreport - "
1675 "Unable to read in mpt_ioctl_eventreport struct @ %p\n",
1676 __FILE__, __LINE__, uarg);
1677 return -EFAULT;
1678 }
1679
1680 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1681 (ioc == NULL)) {
1682 printk(KERN_DEBUG MYNAM "%s::mptctl_eventreport() @%d - ioc%d not found!\n",
1683 __FILE__, __LINE__, iocnum);
1684 return -ENODEV;
1685 }
1686 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventreport called.\n",
1687 ioc->name));
1688
1689 numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
1690 maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS);
1691
1692
1693 max = MPTCTL_EVENT_LOG_SIZE < maxEvents ? MPTCTL_EVENT_LOG_SIZE : maxEvents;
1694
1695
1696
1697
1698 if ((max < 1) || !ioc->events)
1699 return -ENODATA;
1700
1701
1702 ioc->aen_event_read_flag=0;
1703
1704
1705
1706 numBytes = max * sizeof(MPT_IOCTL_EVENTS);
1707 if (copy_to_user(uarg->eventData, ioc->events, numBytes)) {
1708 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_eventreport - "
1709 "Unable to write out mpt_ioctl_eventreport struct @ %p\n",
1710 ioc->name, __FILE__, __LINE__, ioc->events);
1711 return -EFAULT;
1712 }
1713
1714 return 0;
1715}
1716
1717
1718static int
1719mptctl_replace_fw (unsigned long arg)
1720{
1721 struct mpt_ioctl_replace_fw __user *uarg = (void __user *) arg;
1722 struct mpt_ioctl_replace_fw karg;
1723 MPT_ADAPTER *ioc;
1724 int iocnum;
1725 int newFwSize;
1726
1727 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
1728 printk(KERN_ERR MYNAM "%s@%d::mptctl_replace_fw - "
1729 "Unable to read in mpt_ioctl_replace_fw struct @ %p\n",
1730 __FILE__, __LINE__, uarg);
1731 return -EFAULT;
1732 }
1733
1734 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1735 (ioc == NULL)) {
1736 printk(KERN_DEBUG MYNAM "%s::mptctl_replace_fw() @%d - ioc%d not found!\n",
1737 __FILE__, __LINE__, iocnum);
1738 return -ENODEV;
1739 }
1740
1741 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_replace_fw called.\n",
1742 ioc->name));
1743
1744
1745 if (ioc->cached_fw == NULL)
1746 return 0;
1747
1748 mpt_free_fw_memory(ioc);
1749
1750
1751
1752 newFwSize = karg.newImageSize;
1753
1754 if (newFwSize & 0x01)
1755 newFwSize += 1;
1756 if (newFwSize & 0x02)
1757 newFwSize += 2;
1758
1759 mpt_alloc_fw_memory(ioc, newFwSize);
1760 if (ioc->cached_fw == NULL)
1761 return -ENOMEM;
1762
1763
1764
1765 if (copy_from_user(ioc->cached_fw, uarg->newImage, newFwSize)) {
1766 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_replace_fw - "
1767 "Unable to read in mpt_ioctl_replace_fw image "
1768 "@ %p\n", ioc->name, __FILE__, __LINE__, uarg);
1769 mpt_free_fw_memory(ioc);
1770 return -EFAULT;
1771 }
1772
1773
1774
1775 ioc->facts.FWImageSize = newFwSize;
1776 return 0;
1777}
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791static int
1792mptctl_mpt_command (unsigned long arg)
1793{
1794 struct mpt_ioctl_command __user *uarg = (void __user *) arg;
1795 struct mpt_ioctl_command karg;
1796 MPT_ADAPTER *ioc;
1797 int iocnum;
1798 int rc;
1799
1800
1801 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_command))) {
1802 printk(KERN_ERR MYNAM "%s@%d::mptctl_mpt_command - "
1803 "Unable to read in mpt_ioctl_command struct @ %p\n",
1804 __FILE__, __LINE__, uarg);
1805 return -EFAULT;
1806 }
1807
1808 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1809 (ioc == NULL)) {
1810 printk(KERN_DEBUG MYNAM "%s::mptctl_mpt_command() @%d - ioc%d not found!\n",
1811 __FILE__, __LINE__, iocnum);
1812 return -ENODEV;
1813 }
1814
1815 rc = mptctl_do_mpt_command (karg, &uarg->MF);
1816
1817 return rc;
1818}
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832static int
1833mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
1834{
1835 MPT_ADAPTER *ioc;
1836 MPT_FRAME_HDR *mf = NULL;
1837 MPIHeader_t *hdr;
1838 char *psge;
1839 struct buflist bufIn;
1840 struct buflist bufOut;
1841 dma_addr_t dma_addr_in;
1842 dma_addr_t dma_addr_out;
1843 int sgSize = 0;
1844 int iocnum, flagsLength;
1845 int sz, rc = 0;
1846 int msgContext;
1847 u16 req_idx;
1848 ulong timeout;
1849 unsigned long timeleft;
1850 struct scsi_device *sdev;
1851 unsigned long flags;
1852 u8 function;
1853
1854
1855
1856 bufIn.kptr = bufOut.kptr = NULL;
1857 bufIn.len = bufOut.len = 0;
1858
1859 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
1860 (ioc == NULL)) {
1861 printk(KERN_DEBUG MYNAM "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n",
1862 __FILE__, __LINE__, iocnum);
1863 return -ENODEV;
1864 }
1865
1866 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
1867 if (ioc->ioc_reset_in_progress) {
1868 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
1869 printk(KERN_ERR MYNAM "%s@%d::mptctl_do_mpt_command - "
1870 "Busy with diagnostic reset\n", __FILE__, __LINE__);
1871 return -EBUSY;
1872 }
1873 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
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 MPIHeader_t *mpi_hdr;
2436 unsigned long timeleft;
2437 int retval;
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
2486 karg.fw_version[0] = ioc->facts.FWVersion.Struct.Major >= 10 ?
2487 ((ioc->facts.FWVersion.Struct.Major / 10) + '0') : '0';
2488 karg.fw_version[1] = (ioc->facts.FWVersion.Struct.Major % 10 ) + '0';
2489 karg.fw_version[2] = '.';
2490 karg.fw_version[3] = ioc->facts.FWVersion.Struct.Minor >= 10 ?
2491 ((ioc->facts.FWVersion.Struct.Minor / 10) + '0') : '0';
2492 karg.fw_version[4] = (ioc->facts.FWVersion.Struct.Minor % 10 ) + '0';
2493 karg.fw_version[5] = '.';
2494 karg.fw_version[6] = ioc->facts.FWVersion.Struct.Unit >= 10 ?
2495 ((ioc->facts.FWVersion.Struct.Unit / 10) + '0') : '0';
2496 karg.fw_version[7] = (ioc->facts.FWVersion.Struct.Unit % 10 ) + '0';
2497 karg.fw_version[8] = '.';
2498 karg.fw_version[9] = ioc->facts.FWVersion.Struct.Dev >= 10 ?
2499 ((ioc->facts.FWVersion.Struct.Dev / 10) + '0') : '0';
2500 karg.fw_version[10] = (ioc->facts.FWVersion.Struct.Dev % 10 ) + '0';
2501 karg.fw_version[11] = '\0';
2502
2503
2504
2505 hdr.PageVersion = 0;
2506 hdr.PageLength = 0;
2507 hdr.PageNumber = 0;
2508 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
2509 cfg.cfghdr.hdr = &hdr;
2510 cfg.physAddr = -1;
2511 cfg.pageAddr = 0;
2512 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2513 cfg.dir = 0;
2514 cfg.timeout = 10;
2515
2516 strncpy(karg.serial_number, " ", 24);
2517 if (mpt_config(ioc, &cfg) == 0) {
2518 if (cfg.cfghdr.hdr->PageLength > 0) {
2519
2520 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2521
2522 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
2523 if (pbuf) {
2524 cfg.physAddr = buf_dma;
2525 if (mpt_config(ioc, &cfg) == 0) {
2526 ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf;
2527 if (strlen(pdata->BoardTracerNumber) > 1) {
2528 strncpy(karg.serial_number, pdata->BoardTracerNumber, 24);
2529 karg.serial_number[24-1]='\0';
2530 }
2531 }
2532 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
2533 pbuf = NULL;
2534 }
2535 }
2536 }
2537 rc = mpt_GetIocState(ioc, 1);
2538 switch (rc) {
2539 case MPI_IOC_STATE_OPERATIONAL:
2540 karg.ioc_status = HP_STATUS_OK;
2541 break;
2542
2543 case MPI_IOC_STATE_FAULT:
2544 karg.ioc_status = HP_STATUS_FAILED;
2545 break;
2546
2547 case MPI_IOC_STATE_RESET:
2548 case MPI_IOC_STATE_READY:
2549 default:
2550 karg.ioc_status = HP_STATUS_OTHER;
2551 break;
2552 }
2553
2554 karg.base_io_addr = pci_resource_start(pdev, 0);
2555
2556 if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))
2557 karg.bus_phys_width = HP_BUS_WIDTH_UNK;
2558 else
2559 karg.bus_phys_width = HP_BUS_WIDTH_16;
2560
2561 karg.hard_resets = 0;
2562 karg.soft_resets = 0;
2563 karg.timeouts = 0;
2564 if (ioc->sh != NULL) {
2565 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
2566
2567 if (hd && (cim_rev == 1)) {
2568 karg.hard_resets = ioc->hard_resets;
2569 karg.soft_resets = ioc->soft_resets;
2570 karg.timeouts = ioc->timeouts;
2571 }
2572 }
2573
2574
2575
2576
2577 if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) {
2578 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
2579 "%s, no msg frames!!\n", ioc->name, __func__));
2580 goto out;
2581 }
2582
2583 IstwiRWRequest = (ToolboxIstwiReadWriteRequest_t *)mf;
2584 mpi_hdr = (MPIHeader_t *) mf;
2585 memset(IstwiRWRequest,0,sizeof(ToolboxIstwiReadWriteRequest_t));
2586 IstwiRWRequest->Function = MPI_FUNCTION_TOOLBOX;
2587 IstwiRWRequest->Tool = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
2588 IstwiRWRequest->MsgContext = mpi_hdr->MsgContext;
2589 IstwiRWRequest->Flags = MPI_TB_ISTWI_FLAGS_READ;
2590 IstwiRWRequest->NumAddressBytes = 0x01;
2591 IstwiRWRequest->DataLength = cpu_to_le16(0x04);
2592 if (pdev->devfn & 1)
2593 IstwiRWRequest->DeviceAddr = 0xB2;
2594 else
2595 IstwiRWRequest->DeviceAddr = 0xB0;
2596
2597 pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma);
2598 if (!pbuf)
2599 goto out;
2600 ioc->add_sge((char *)&IstwiRWRequest->SGL,
2601 (MPT_SGE_FLAGS_SSIMPLE_READ|4), buf_dma);
2602
2603 retval = 0;
2604 SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context,
2605 IstwiRWRequest->MsgContext);
2606 INITIALIZE_MGMT_STATUS(ioc->ioctl_cmds.status)
2607 mpt_put_msg_frame(mptctl_id, ioc, mf);
2608
2609retry_wait:
2610 timeleft = wait_for_completion_timeout(&ioc->ioctl_cmds.done,
2611 HZ*MPT_IOCTL_DEFAULT_TIMEOUT);
2612 if (!(ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2613 retval = -ETIME;
2614 printk(MYIOC_s_WARN_FMT "%s: failed\n", ioc->name, __func__);
2615 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
2616 mpt_free_msg_frame(ioc, mf);
2617 goto out;
2618 }
2619 if (!timeleft) {
2620 printk(MYIOC_s_WARN_FMT
2621 "HOST INFO command timeout, doorbell=0x%08x\n",
2622 ioc->name, mpt_GetIocState(ioc, 0));
2623 mptctl_timeout_expired(ioc, mf);
2624 } else
2625 goto retry_wait;
2626 goto out;
2627 }
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_RF_VALID)
2639 karg.rsvd = *(u32 *)pbuf;
2640
2641 out:
2642 CLEAR_MGMT_STATUS(ioc->ioctl_cmds.status)
2643 SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, 0);
2644
2645 if (pbuf)
2646 pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma);
2647
2648
2649
2650 if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) {
2651 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_hpgethostinfo - "
2652 "Unable to write out hp_host_info @ %p\n",
2653 ioc->name, __FILE__, __LINE__, uarg);
2654 return -EFAULT;
2655 }
2656
2657 return 0;
2658
2659}
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672static int
2673mptctl_hp_targetinfo(unsigned long arg)
2674{
2675 hp_target_info_t __user *uarg = (void __user *) arg;
2676 SCSIDevicePage0_t *pg0_alloc;
2677 SCSIDevicePage3_t *pg3_alloc;
2678 MPT_ADAPTER *ioc;
2679 MPT_SCSI_HOST *hd = NULL;
2680 hp_target_info_t karg;
2681 int iocnum;
2682 int data_sz;
2683 dma_addr_t page_dma;
2684 CONFIGPARMS cfg;
2685 ConfigPageHeader_t hdr;
2686 int tmp, np, rc = 0;
2687
2688 if (copy_from_user(&karg, uarg, sizeof(hp_target_info_t))) {
2689 printk(KERN_ERR MYNAM "%s@%d::mptctl_hp_targetinfo - "
2690 "Unable to read in hp_host_targetinfo struct @ %p\n",
2691 __FILE__, __LINE__, uarg);
2692 return -EFAULT;
2693 }
2694
2695 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
2696 (ioc == NULL)) {
2697 printk(KERN_DEBUG MYNAM "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n",
2698 __FILE__, __LINE__, iocnum);
2699 return -ENODEV;
2700 }
2701 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_hp_targetinfo called.\n",
2702 ioc->name));
2703
2704
2705
2706 if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))
2707 return 0;
2708
2709 if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL))
2710 return 0;
2711
2712 if (ioc->sh->host_no != karg.hdr.host)
2713 return -ENODEV;
2714
2715
2716
2717 data_sz = ioc->spi_data.sdp0length * 4;
2718 pg0_alloc = (SCSIDevicePage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
2719 if (pg0_alloc) {
2720 hdr.PageVersion = ioc->spi_data.sdp0version;
2721 hdr.PageLength = data_sz;
2722 hdr.PageNumber = 0;
2723 hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
2724
2725 cfg.cfghdr.hdr = &hdr;
2726 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2727 cfg.dir = 0;
2728 cfg.timeout = 0;
2729 cfg.physAddr = page_dma;
2730
2731 cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
2732
2733 if ((rc = mpt_config(ioc, &cfg)) == 0) {
2734 np = le32_to_cpu(pg0_alloc->NegotiatedParameters);
2735 karg.negotiated_width = np & MPI_SCSIDEVPAGE0_NP_WIDE ?
2736 HP_BUS_WIDTH_16 : HP_BUS_WIDTH_8;
2737
2738 if (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) {
2739 tmp = (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
2740 if (tmp < 0x09)
2741 karg.negotiated_speed = HP_DEV_SPEED_ULTRA320;
2742 else if (tmp <= 0x09)
2743 karg.negotiated_speed = HP_DEV_SPEED_ULTRA160;
2744 else if (tmp <= 0x0A)
2745 karg.negotiated_speed = HP_DEV_SPEED_ULTRA2;
2746 else if (tmp <= 0x0C)
2747 karg.negotiated_speed = HP_DEV_SPEED_ULTRA;
2748 else if (tmp <= 0x25)
2749 karg.negotiated_speed = HP_DEV_SPEED_FAST;
2750 else
2751 karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
2752 } else
2753 karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
2754 }
2755
2756 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg0_alloc, page_dma);
2757 }
2758
2759
2760
2761 karg.message_rejects = -1;
2762 karg.phase_errors = -1;
2763 karg.parity_errors = -1;
2764 karg.select_timeouts = -1;
2765
2766
2767
2768 hdr.PageVersion = 0;
2769 hdr.PageLength = 0;
2770 hdr.PageNumber = 3;
2771 hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
2772
2773 cfg.cfghdr.hdr = &hdr;
2774 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2775 cfg.dir = 0;
2776 cfg.timeout = 0;
2777 cfg.physAddr = -1;
2778 if ((mpt_config(ioc, &cfg) == 0) && (cfg.cfghdr.hdr->PageLength > 0)) {
2779
2780 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2781 data_sz = (int) cfg.cfghdr.hdr->PageLength * 4;
2782 pg3_alloc = (SCSIDevicePage3_t *) pci_alloc_consistent(
2783 ioc->pcidev, data_sz, &page_dma);
2784 if (pg3_alloc) {
2785 cfg.physAddr = page_dma;
2786 cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
2787 if ((rc = mpt_config(ioc, &cfg)) == 0) {
2788 karg.message_rejects = (u32) le16_to_cpu(pg3_alloc->MsgRejectCount);
2789 karg.phase_errors = (u32) le16_to_cpu(pg3_alloc->PhaseErrorCount);
2790 karg.parity_errors = (u32) le16_to_cpu(pg3_alloc->ParityErrorCount);
2791 }
2792 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg3_alloc, page_dma);
2793 }
2794 }
2795 hd = shost_priv(ioc->sh);
2796 if (hd != NULL)
2797 karg.select_timeouts = hd->sel_timeout[karg.hdr.id];
2798
2799
2800
2801 if (copy_to_user((char __user *)arg, &karg, sizeof(hp_target_info_t))) {
2802 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_hp_target_info - "
2803 "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
2804 ioc->name, __FILE__, __LINE__, uarg);
2805 return -EFAULT;
2806 }
2807
2808 return 0;
2809}
2810
2811
2812
2813static const struct file_operations mptctl_fops = {
2814 .owner = THIS_MODULE,
2815 .llseek = no_llseek,
2816 .fasync = mptctl_fasync,
2817 .unlocked_ioctl = mptctl_ioctl,
2818#ifdef CONFIG_COMPAT
2819 .compat_ioctl = compat_mpctl_ioctl,
2820#endif
2821};
2822
2823static struct miscdevice mptctl_miscdev = {
2824 MPT_MINOR,
2825 MYNAM,
2826 &mptctl_fops
2827};
2828
2829
2830
2831#ifdef CONFIG_COMPAT
2832
2833static int
2834compat_mptfwxfer_ioctl(struct file *filp, unsigned int cmd,
2835 unsigned long arg)
2836{
2837 struct mpt_fw_xfer32 kfw32;
2838 struct mpt_fw_xfer kfw;
2839 MPT_ADAPTER *iocp = NULL;
2840 int iocnum, iocnumX;
2841 int nonblock = (filp->f_flags & O_NONBLOCK);
2842 int ret;
2843
2844
2845 if (copy_from_user(&kfw32, (char __user *)arg, sizeof(kfw32)))
2846 return -EFAULT;
2847
2848
2849 iocnumX = kfw32.iocnum & 0xFF;
2850 if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
2851 (iocp == NULL)) {
2852 printk(KERN_DEBUG MYNAM "::compat_mptfwxfer_ioctl @%d - ioc%d not found!\n",
2853 __LINE__, iocnumX);
2854 return -ENODEV;
2855 }
2856
2857 if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
2858 return ret;
2859
2860 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "compat_mptfwxfer_ioctl() called\n",
2861 iocp->name));
2862 kfw.iocnum = iocnum;
2863 kfw.fwlen = kfw32.fwlen;
2864 kfw.bufp = compat_ptr(kfw32.bufp);
2865
2866 ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);
2867
2868 mutex_unlock(&iocp->ioctl_cmds.mutex);
2869
2870 return ret;
2871}
2872
2873static int
2874compat_mpt_command(struct file *filp, unsigned int cmd,
2875 unsigned long arg)
2876{
2877 struct mpt_ioctl_command32 karg32;
2878 struct mpt_ioctl_command32 __user *uarg = (struct mpt_ioctl_command32 __user *) arg;
2879 struct mpt_ioctl_command karg;
2880 MPT_ADAPTER *iocp = NULL;
2881 int iocnum, iocnumX;
2882 int nonblock = (filp->f_flags & O_NONBLOCK);
2883 int ret;
2884
2885 if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32)))
2886 return -EFAULT;
2887
2888
2889 iocnumX = karg32.hdr.iocnum & 0xFF;
2890 if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
2891 (iocp == NULL)) {
2892 printk(KERN_DEBUG MYNAM "::compat_mpt_command @%d - ioc%d not found!\n",
2893 __LINE__, iocnumX);
2894 return -ENODEV;
2895 }
2896
2897 if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
2898 return ret;
2899
2900 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "compat_mpt_command() called\n",
2901 iocp->name));
2902
2903 karg.hdr.iocnum = karg32.hdr.iocnum;
2904 karg.hdr.port = karg32.hdr.port;
2905 karg.timeout = karg32.timeout;
2906 karg.maxReplyBytes = karg32.maxReplyBytes;
2907
2908 karg.dataInSize = karg32.dataInSize;
2909 karg.dataOutSize = karg32.dataOutSize;
2910 karg.maxSenseBytes = karg32.maxSenseBytes;
2911 karg.dataSgeOffset = karg32.dataSgeOffset;
2912
2913 karg.replyFrameBufPtr = (char __user *)(unsigned long)karg32.replyFrameBufPtr;
2914 karg.dataInBufPtr = (char __user *)(unsigned long)karg32.dataInBufPtr;
2915 karg.dataOutBufPtr = (char __user *)(unsigned long)karg32.dataOutBufPtr;
2916 karg.senseDataPtr = (char __user *)(unsigned long)karg32.senseDataPtr;
2917
2918
2919
2920 ret = mptctl_do_mpt_command (karg, &uarg->MF);
2921
2922 mutex_unlock(&iocp->ioctl_cmds.mutex);
2923
2924 return ret;
2925}
2926
2927static long compat_mpctl_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
2928{
2929 long ret;
2930 mutex_lock(&mpctl_mutex);
2931 switch (cmd) {
2932 case MPTIOCINFO:
2933 case MPTIOCINFO1:
2934 case MPTIOCINFO2:
2935 case MPTTARGETINFO:
2936 case MPTEVENTQUERY:
2937 case MPTEVENTENABLE:
2938 case MPTEVENTREPORT:
2939 case MPTHARDRESET:
2940 case HP_GETHOSTINFO:
2941 case HP_GETTARGETINFO:
2942 case MPTTEST:
2943 ret = __mptctl_ioctl(f, cmd, arg);
2944 break;
2945 case MPTCOMMAND32:
2946 ret = compat_mpt_command(f, cmd, arg);
2947 break;
2948 case MPTFWDOWNLOAD32:
2949 ret = compat_mptfwxfer_ioctl(f, cmd, arg);
2950 break;
2951 default:
2952 ret = -ENOIOCTLCMD;
2953 break;
2954 }
2955 mutex_unlock(&mpctl_mutex);
2956 return ret;
2957}
2958
2959#endif
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971static int
2972mptctl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2973{
2974 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2975
2976 mutex_init(&ioc->ioctl_cmds.mutex);
2977 init_completion(&ioc->ioctl_cmds.done);
2978 return 0;
2979}
2980
2981
2982
2983
2984
2985
2986
2987
2988static void
2989mptctl_remove(struct pci_dev *pdev)
2990{
2991}
2992
2993static struct mpt_pci_driver mptctl_driver = {
2994 .probe = mptctl_probe,
2995 .remove = mptctl_remove,
2996};
2997
2998
2999static int __init mptctl_init(void)
3000{
3001 int err;
3002 int where = 1;
3003
3004 show_mptmod_ver(my_NAME, my_VERSION);
3005
3006 mpt_device_driver_register(&mptctl_driver, MPTCTL_DRIVER);
3007
3008
3009 err = misc_register(&mptctl_miscdev);
3010 if (err < 0) {
3011 printk(KERN_ERR MYNAM ": Can't register misc device [minor=%d].\n", MPT_MINOR);
3012 goto out_fail;
3013 }
3014 printk(KERN_INFO MYNAM ": Registered with Fusion MPT base driver\n");
3015 printk(KERN_INFO MYNAM ": /dev/%s @ (major,minor=%d,%d)\n",
3016 mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
3017
3018
3019
3020
3021 ++where;
3022 mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER,
3023 "mptctl_reply");
3024 if (!mptctl_id || mptctl_id >= MPT_MAX_PROTOCOL_DRIVERS) {
3025 printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
3026 misc_deregister(&mptctl_miscdev);
3027 err = -EBUSY;
3028 goto out_fail;
3029 }
3030
3031 mptctl_taskmgmt_id = mpt_register(mptctl_taskmgmt_reply, MPTCTL_DRIVER,
3032 "mptctl_taskmgmt_reply");
3033 if (!mptctl_taskmgmt_id || mptctl_taskmgmt_id >= MPT_MAX_PROTOCOL_DRIVERS) {
3034 printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
3035 mpt_deregister(mptctl_id);
3036 misc_deregister(&mptctl_miscdev);
3037 err = -EBUSY;
3038 goto out_fail;
3039 }
3040
3041 mpt_reset_register(mptctl_id, mptctl_ioc_reset);
3042 mpt_event_register(mptctl_id, mptctl_event_process);
3043
3044 return 0;
3045
3046out_fail:
3047
3048 mpt_device_driver_deregister(MPTCTL_DRIVER);
3049
3050 return err;
3051}
3052
3053
3054static void mptctl_exit(void)
3055{
3056 misc_deregister(&mptctl_miscdev);
3057 printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n",
3058 mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
3059
3060
3061 mpt_event_deregister(mptctl_id);
3062
3063
3064 mpt_reset_deregister(mptctl_id);
3065
3066
3067 mpt_deregister(mptctl_taskmgmt_id);
3068 mpt_deregister(mptctl_id);
3069
3070 mpt_device_driver_deregister(MPTCTL_DRIVER);
3071
3072}
3073
3074
3075
3076module_init(mptctl_init);
3077module_exit(mptctl_exit);
3078