0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 #include <linux/kernel.h>
0049 #include <linux/module.h>
0050 #include <linux/errno.h>
0051 #include <linux/init.h>
0052 #include <linux/slab.h>
0053 #include <linux/types.h>
0054 #include <linux/pci.h>
0055 #include <linux/delay.h> /* for mdelay */
0056 #include <linux/miscdevice.h>
0057 #include <linux/mutex.h>
0058 #include <linux/compat.h>
0059
0060 #include <asm/io.h>
0061 #include <linux/uaccess.h>
0062
0063 #include <scsi/scsi.h>
0064 #include <scsi/scsi_cmnd.h>
0065 #include <scsi/scsi_device.h>
0066 #include <scsi/scsi_host.h>
0067 #include <scsi/scsi_tcq.h>
0068
0069 #define COPYRIGHT "Copyright (c) 1999-2008 LSI Corporation"
0070 #define MODULEAUTHOR "LSI Corporation"
0071 #include "mptbase.h"
0072 #include "mptctl.h"
0073
0074
0075 #define my_NAME "Fusion MPT misc device (ioctl) driver"
0076 #define my_VERSION MPT_LINUX_VERSION_COMMON
0077 #define MYNAM "mptctl"
0078
0079 MODULE_AUTHOR(MODULEAUTHOR);
0080 MODULE_DESCRIPTION(my_NAME);
0081 MODULE_LICENSE("GPL");
0082 MODULE_VERSION(my_VERSION);
0083
0084
0085
0086 static DEFINE_MUTEX(mpctl_mutex);
0087 static u8 mptctl_id = MPT_MAX_PROTOCOL_DRIVERS;
0088 static u8 mptctl_taskmgmt_id = MPT_MAX_PROTOCOL_DRIVERS;
0089
0090 static DECLARE_WAIT_QUEUE_HEAD ( mptctl_wait );
0091
0092
0093
0094 struct buflist {
0095 u8 *kptr;
0096 int len;
0097 };
0098
0099
0100
0101
0102
0103 static int mptctl_fw_download(MPT_ADAPTER *iocp, unsigned long arg);
0104 static int mptctl_getiocinfo(MPT_ADAPTER *iocp, unsigned long arg, unsigned int cmd);
0105 static int mptctl_gettargetinfo(MPT_ADAPTER *iocp, unsigned long arg);
0106 static int mptctl_readtest(MPT_ADAPTER *iocp, unsigned long arg);
0107 static int mptctl_mpt_command(MPT_ADAPTER *iocp, unsigned long arg);
0108 static int mptctl_eventquery(MPT_ADAPTER *iocp, unsigned long arg);
0109 static int mptctl_eventenable(MPT_ADAPTER *iocp, unsigned long arg);
0110 static int mptctl_eventreport(MPT_ADAPTER *iocp, unsigned long arg);
0111 static int mptctl_replace_fw(MPT_ADAPTER *iocp, unsigned long arg);
0112
0113 static int mptctl_do_reset(MPT_ADAPTER *iocp, unsigned long arg);
0114 static int mptctl_hp_hostinfo(MPT_ADAPTER *iocp, unsigned long arg, unsigned int cmd);
0115 static int mptctl_hp_targetinfo(MPT_ADAPTER *iocp, unsigned long arg);
0116
0117 static int mptctl_probe(struct pci_dev *);
0118 static void mptctl_remove(struct pci_dev *);
0119
0120 #ifdef CONFIG_COMPAT
0121 static long compat_mpctl_ioctl(struct file *f, unsigned cmd, unsigned long arg);
0122 #endif
0123
0124
0125
0126 static int mptctl_do_mpt_command(MPT_ADAPTER *iocp, struct mpt_ioctl_command karg, void __user *mfPtr);
0127 static int mptctl_do_fw_download(MPT_ADAPTER *iocp, char __user *ufwbuf, size_t fwlen);
0128 static MptSge_t *kbuf_alloc_2_sgl(int bytes, u32 dir, int sge_offset, int *frags,
0129 struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc);
0130 static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma,
0131 struct buflist *buflist, MPT_ADAPTER *ioc);
0132
0133
0134
0135
0136 static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);
0137
0138
0139
0140
0141 static int mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
0142 static struct fasync_struct *async_queue=NULL;
0143
0144
0145
0146
0147
0148
0149 #define MAX_FRAGS_SPILL1 9
0150 #define MAX_FRAGS_SPILL2 15
0151 #define FRAGS_PER_BUCKET (MAX_FRAGS_SPILL2 + 1)
0152
0153
0154
0155 #define MAX_CHAIN_FRAGS (4 * MAX_FRAGS_SPILL2 + 1)
0156
0157
0158
0159
0160 #define MAX_SGL_BYTES ((MAX_FRAGS_SPILL1 + 1 + (4 * FRAGS_PER_BUCKET)) * 8)
0161
0162
0163 #define MAX_KMALLOC_SZ (128*1024)
0164
0165 #define MPT_IOCTL_DEFAULT_TIMEOUT 10
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178 static inline int
0179 mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock)
0180 {
0181 int rc = 0;
0182
0183 if (nonblock) {
0184 if (!mutex_trylock(&ioc->ioctl_cmds.mutex))
0185 rc = -EAGAIN;
0186 } else {
0187 if (mutex_lock_interruptible(&ioc->ioctl_cmds.mutex))
0188 rc = -ERESTARTSYS;
0189 }
0190 return rc;
0191 }
0192
0193
0194
0195
0196
0197
0198
0199
0200 static int
0201 mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
0202 {
0203 char *sense_data;
0204 int req_index;
0205 int sz;
0206
0207 if (!req)
0208 return 0;
0209
0210 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "completing mpi function "
0211 "(0x%02X), req=%p, reply=%p\n", ioc->name, req->u.hdr.Function,
0212 req, reply));
0213
0214
0215
0216
0217
0218 if (ioc->ioctl_cmds.msg_context != req->u.hdr.MsgContext)
0219 goto out_continuation;
0220
0221 ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
0222
0223 if (!reply)
0224 goto out;
0225
0226 ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
0227 sz = min(ioc->reply_sz, 4*reply->u.reply.MsgLength);
0228 memcpy(ioc->ioctl_cmds.reply, reply, sz);
0229
0230 if (reply->u.reply.IOCStatus || reply->u.reply.IOCLogInfo)
0231 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0232 "iocstatus (0x%04X), loginfo (0x%08X)\n", ioc->name,
0233 le16_to_cpu(reply->u.reply.IOCStatus),
0234 le32_to_cpu(reply->u.reply.IOCLogInfo)));
0235
0236 if ((req->u.hdr.Function == MPI_FUNCTION_SCSI_IO_REQUEST) ||
0237 (req->u.hdr.Function ==
0238 MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
0239
0240 if (reply->u.sreply.SCSIStatus || reply->u.sreply.SCSIState)
0241 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0242 "scsi_status (0x%02x), scsi_state (0x%02x), "
0243 "tag = (0x%04x), transfer_count (0x%08x)\n", ioc->name,
0244 reply->u.sreply.SCSIStatus,
0245 reply->u.sreply.SCSIState,
0246 le16_to_cpu(reply->u.sreply.TaskTag),
0247 le32_to_cpu(reply->u.sreply.TransferCount)));
0248
0249 if (reply->u.sreply.SCSIState &
0250 MPI_SCSI_STATE_AUTOSENSE_VALID) {
0251 sz = req->u.scsireq.SenseBufferLength;
0252 req_index =
0253 le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
0254 sense_data = ((u8 *)ioc->sense_buf_pool +
0255 (req_index * MPT_SENSE_BUFFER_ALLOC));
0256 memcpy(ioc->ioctl_cmds.sense, sense_data, sz);
0257 ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_SENSE_VALID;
0258 }
0259 }
0260
0261 out:
0262
0263
0264 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_PENDING) {
0265 if (req->u.hdr.Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
0266 mpt_clear_taskmgmt_in_progress_flag(ioc);
0267 ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
0268 complete(&ioc->ioctl_cmds.done);
0269 if (ioc->bus_type == SAS)
0270 ioc->schedule_target_reset(ioc);
0271 } else {
0272 ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
0273 complete(&ioc->ioctl_cmds.done);
0274 }
0275 }
0276
0277 out_continuation:
0278 if (reply && (reply->u.reply.MsgFlags &
0279 MPI_MSGFLAGS_CONTINUATION_REPLY))
0280 return 0;
0281 return 1;
0282 }
0283
0284
0285 static int
0286 mptctl_taskmgmt_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
0287 {
0288 if (!mf)
0289 return 0;
0290
0291 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0292 "TaskMgmt completed (mf=%p, mr=%p)\n",
0293 ioc->name, mf, mr));
0294
0295 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
0296
0297 if (!mr)
0298 goto out;
0299
0300 ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
0301 memcpy(ioc->taskmgmt_cmds.reply, mr,
0302 min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
0303 out:
0304 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
0305 mpt_clear_taskmgmt_in_progress_flag(ioc);
0306 ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
0307 complete(&ioc->taskmgmt_cmds.done);
0308 if (ioc->bus_type == SAS)
0309 ioc->schedule_target_reset(ioc);
0310 return 1;
0311 }
0312 return 0;
0313 }
0314
0315 static int
0316 mptctl_do_taskmgmt(MPT_ADAPTER *ioc, u8 tm_type, u8 bus_id, u8 target_id)
0317 {
0318 MPT_FRAME_HDR *mf;
0319 SCSITaskMgmt_t *pScsiTm;
0320 SCSITaskMgmtReply_t *pScsiTmReply;
0321 int ii;
0322 int retval;
0323 unsigned long timeout;
0324 u16 iocstatus;
0325
0326
0327 mutex_lock(&ioc->taskmgmt_cmds.mutex);
0328 if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
0329 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
0330 return -EPERM;
0331 }
0332
0333 retval = 0;
0334
0335 mf = mpt_get_msg_frame(mptctl_taskmgmt_id, ioc);
0336 if (mf == NULL) {
0337 dtmprintk(ioc,
0338 printk(MYIOC_s_WARN_FMT "TaskMgmt, no msg frames!!\n",
0339 ioc->name));
0340 mpt_clear_taskmgmt_in_progress_flag(ioc);
0341 retval = -ENOMEM;
0342 goto tm_done;
0343 }
0344
0345 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
0346 ioc->name, mf));
0347
0348 pScsiTm = (SCSITaskMgmt_t *) mf;
0349 memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t));
0350 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
0351 pScsiTm->TaskType = tm_type;
0352 if ((tm_type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) &&
0353 (ioc->bus_type == FC))
0354 pScsiTm->MsgFlags =
0355 MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
0356 pScsiTm->TargetID = target_id;
0357 pScsiTm->Bus = bus_id;
0358 pScsiTm->ChainOffset = 0;
0359 pScsiTm->Reserved = 0;
0360 pScsiTm->Reserved1 = 0;
0361 pScsiTm->TaskMsgContext = 0;
0362 for (ii= 0; ii < 8; ii++)
0363 pScsiTm->LUN[ii] = 0;
0364 for (ii=0; ii < 7; ii++)
0365 pScsiTm->Reserved2[ii] = 0;
0366
0367 switch (ioc->bus_type) {
0368 case FC:
0369 timeout = 40;
0370 break;
0371 case SAS:
0372 timeout = 30;
0373 break;
0374 case SPI:
0375 default:
0376 timeout = 10;
0377 break;
0378 }
0379
0380 dtmprintk(ioc,
0381 printk(MYIOC_s_DEBUG_FMT "TaskMgmt type=%d timeout=%ld\n",
0382 ioc->name, tm_type, timeout));
0383
0384 INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
0385 if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
0386 (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
0387 mpt_put_msg_frame_hi_pri(mptctl_taskmgmt_id, ioc, mf);
0388 else {
0389 retval = mpt_send_handshake_request(mptctl_taskmgmt_id, ioc,
0390 sizeof(SCSITaskMgmt_t), (u32 *)pScsiTm, CAN_SLEEP);
0391 if (retval != 0) {
0392 dfailprintk(ioc,
0393 printk(MYIOC_s_ERR_FMT
0394 "TaskMgmt send_handshake FAILED!"
0395 " (ioc %p, mf %p, rc=%d) \n", ioc->name,
0396 ioc, mf, retval));
0397 mpt_free_msg_frame(ioc, mf);
0398 mpt_clear_taskmgmt_in_progress_flag(ioc);
0399 goto tm_done;
0400 }
0401 }
0402
0403
0404 ii = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done, timeout*HZ);
0405
0406 if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
0407 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0408 "TaskMgmt failed\n", ioc->name));
0409 mpt_free_msg_frame(ioc, mf);
0410 mpt_clear_taskmgmt_in_progress_flag(ioc);
0411 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
0412 retval = 0;
0413 else
0414 retval = -1;
0415 goto tm_done;
0416 }
0417
0418 if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
0419 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0420 "TaskMgmt failed\n", ioc->name));
0421 retval = -1;
0422 goto tm_done;
0423 }
0424
0425 pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply;
0426 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0427 "TaskMgmt fw_channel = %d, fw_id = %d, task_type=0x%02X, "
0428 "iocstatus=0x%04X\n\tloginfo=0x%08X, response_code=0x%02X, "
0429 "term_cmnds=%d\n", ioc->name, pScsiTmReply->Bus,
0430 pScsiTmReply->TargetID, tm_type,
0431 le16_to_cpu(pScsiTmReply->IOCStatus),
0432 le32_to_cpu(pScsiTmReply->IOCLogInfo),
0433 pScsiTmReply->ResponseCode,
0434 le32_to_cpu(pScsiTmReply->TerminationCount)));
0435
0436 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
0437
0438 if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
0439 iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED ||
0440 iocstatus == MPI_IOCSTATUS_SUCCESS)
0441 retval = 0;
0442 else {
0443 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0444 "TaskMgmt failed\n", ioc->name));
0445 retval = -1;
0446 }
0447
0448 tm_done:
0449 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
0450 CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
0451 return retval;
0452 }
0453
0454
0455
0456
0457
0458
0459
0460 static void
0461 mptctl_timeout_expired(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
0462 {
0463 unsigned long flags;
0464 int ret_val = -1;
0465 SCSIIORequest_t *scsi_req = (SCSIIORequest_t *) mf;
0466 u8 function = mf->u.hdr.Function;
0467
0468 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": %s\n",
0469 ioc->name, __func__));
0470
0471 if (mpt_fwfault_debug)
0472 mpt_halt_firmware(ioc);
0473
0474 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
0475 if (ioc->ioc_reset_in_progress) {
0476 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
0477 CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status)
0478 mpt_free_msg_frame(ioc, mf);
0479 return;
0480 }
0481 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
0482
0483
0484 CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status)
0485
0486 if (ioc->bus_type == SAS) {
0487 if (function == MPI_FUNCTION_SCSI_IO_REQUEST)
0488 ret_val = mptctl_do_taskmgmt(ioc,
0489 MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
0490 scsi_req->Bus, scsi_req->TargetID);
0491 else if (function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)
0492 ret_val = mptctl_do_taskmgmt(ioc,
0493 MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
0494 scsi_req->Bus, 0);
0495 if (!ret_val)
0496 return;
0497 } else {
0498 if ((function == MPI_FUNCTION_SCSI_IO_REQUEST) ||
0499 (function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH))
0500 ret_val = mptctl_do_taskmgmt(ioc,
0501 MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
0502 scsi_req->Bus, 0);
0503 if (!ret_val)
0504 return;
0505 }
0506
0507 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling Reset! \n",
0508 ioc->name));
0509 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
0510 mpt_free_msg_frame(ioc, mf);
0511 }
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521 static int
0522 mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
0523 {
0524 switch(reset_phase) {
0525 case MPT_IOC_SETUP_RESET:
0526 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0527 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
0528 break;
0529 case MPT_IOC_PRE_RESET:
0530 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0531 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
0532 break;
0533 case MPT_IOC_POST_RESET:
0534 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0535 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
0536 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_PENDING) {
0537 ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_DID_IOCRESET;
0538 complete(&ioc->ioctl_cmds.done);
0539 }
0540 break;
0541 default:
0542 break;
0543 }
0544
0545 return 1;
0546 }
0547
0548
0549
0550 static int
0551 mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
0552 {
0553 u8 event;
0554
0555 event = le32_to_cpu(pEvReply->Event) & 0xFF;
0556
0557 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s() called\n",
0558 ioc->name, __func__));
0559 if(async_queue == NULL)
0560 return 1;
0561
0562
0563
0564
0565
0566 if (event == 0x21) {
0567 ioc->aen_event_read_flag=1;
0568 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Raised SIGIO to application\n",
0569 ioc->name));
0570 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0571 "Raised SIGIO to application\n", ioc->name));
0572 kill_fasync(&async_queue, SIGIO, POLL_IN);
0573 return 1;
0574 }
0575
0576
0577
0578
0579
0580 if(ioc->aen_event_read_flag)
0581 return 1;
0582
0583
0584
0585
0586 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
0587 ioc->aen_event_read_flag=1;
0588 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0589 "Raised SIGIO to application\n", ioc->name));
0590 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0591 "Raised SIGIO to application\n", ioc->name));
0592 kill_fasync(&async_queue, SIGIO, POLL_IN);
0593 }
0594 return 1;
0595 }
0596
0597 static int
0598 mptctl_fasync(int fd, struct file *filep, int mode)
0599 {
0600 MPT_ADAPTER *ioc;
0601 int ret;
0602
0603 mutex_lock(&mpctl_mutex);
0604 list_for_each_entry(ioc, &ioc_list, list)
0605 ioc->aen_event_read_flag=0;
0606
0607 ret = fasync_helper(fd, filep, mode, &async_queue);
0608 mutex_unlock(&mpctl_mutex);
0609 return ret;
0610 }
0611
0612
0613
0614
0615
0616
0617
0618 static long
0619 __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
0620 {
0621 mpt_ioctl_header __user *uhdr = (void __user *) arg;
0622 mpt_ioctl_header khdr;
0623 int iocnum;
0624 unsigned iocnumX;
0625 int nonblock = (file->f_flags & O_NONBLOCK);
0626 int ret;
0627 MPT_ADAPTER *iocp = NULL;
0628
0629 if (copy_from_user(&khdr, uhdr, sizeof(khdr))) {
0630 printk(KERN_ERR MYNAM "%s::mptctl_ioctl() @%d - "
0631 "Unable to copy mpt_ioctl_header data @ %p\n",
0632 __FILE__, __LINE__, uhdr);
0633 return -EFAULT;
0634 }
0635 ret = -ENXIO;
0636
0637
0638
0639
0640 iocnumX = khdr.iocnum & 0xFF;
0641 if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
0642 (iocp == NULL))
0643 return -ENODEV;
0644
0645 if (!iocp->active) {
0646 printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - Controller disabled.\n",
0647 __FILE__, __LINE__);
0648 return -EFAULT;
0649 }
0650
0651
0652
0653
0654
0655
0656 if ((cmd & ~IOCSIZE_MASK) == (MPTIOCINFO & ~IOCSIZE_MASK)) {
0657 return mptctl_getiocinfo(iocp, arg, _IOC_SIZE(cmd));
0658 } else if (cmd == MPTTARGETINFO) {
0659 return mptctl_gettargetinfo(iocp, arg);
0660 } else if (cmd == MPTTEST) {
0661 return mptctl_readtest(iocp, arg);
0662 } else if (cmd == MPTEVENTQUERY) {
0663 return mptctl_eventquery(iocp, arg);
0664 } else if (cmd == MPTEVENTENABLE) {
0665 return mptctl_eventenable(iocp, arg);
0666 } else if (cmd == MPTEVENTREPORT) {
0667 return mptctl_eventreport(iocp, arg);
0668 } else if (cmd == MPTFWREPLACE) {
0669 return mptctl_replace_fw(iocp, arg);
0670 }
0671
0672
0673
0674
0675 if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
0676 return ret;
0677
0678 if (cmd == MPTFWDOWNLOAD)
0679 ret = mptctl_fw_download(iocp, arg);
0680 else if (cmd == MPTCOMMAND)
0681 ret = mptctl_mpt_command(iocp, arg);
0682 else if (cmd == MPTHARDRESET)
0683 ret = mptctl_do_reset(iocp, arg);
0684 else if ((cmd & ~IOCSIZE_MASK) == (HP_GETHOSTINFO & ~IOCSIZE_MASK))
0685 ret = mptctl_hp_hostinfo(iocp, arg, _IOC_SIZE(cmd));
0686 else if (cmd == HP_GETTARGETINFO)
0687 ret = mptctl_hp_targetinfo(iocp, arg);
0688 else
0689 ret = -EINVAL;
0690
0691 mutex_unlock(&iocp->ioctl_cmds.mutex);
0692
0693 return ret;
0694 }
0695
0696 static long
0697 mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
0698 {
0699 long ret;
0700 mutex_lock(&mpctl_mutex);
0701 ret = __mptctl_ioctl(file, cmd, arg);
0702 mutex_unlock(&mpctl_mutex);
0703 return ret;
0704 }
0705
0706 static int mptctl_do_reset(MPT_ADAPTER *iocp, unsigned long arg)
0707 {
0708 struct mpt_ioctl_diag_reset __user *urinfo = (void __user *) arg;
0709 struct mpt_ioctl_diag_reset krinfo;
0710
0711 if (copy_from_user(&krinfo, urinfo, sizeof(struct mpt_ioctl_diag_reset))) {
0712 printk(KERN_ERR MYNAM "%s@%d::mptctl_do_reset - "
0713 "Unable to copy mpt_ioctl_diag_reset struct @ %p\n",
0714 __FILE__, __LINE__, urinfo);
0715 return -EFAULT;
0716 }
0717
0718 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "mptctl_do_reset called.\n",
0719 iocp->name));
0720
0721 if (mpt_HardResetHandler(iocp, CAN_SLEEP) != 0) {
0722 printk (MYIOC_s_ERR_FMT "%s@%d::mptctl_do_reset - reset failed.\n",
0723 iocp->name, __FILE__, __LINE__);
0724 return -1;
0725 }
0726
0727 return 0;
0728 }
0729
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747 static int
0748 mptctl_fw_download(MPT_ADAPTER *iocp, unsigned long arg)
0749 {
0750 struct mpt_fw_xfer __user *ufwdl = (void __user *) arg;
0751 struct mpt_fw_xfer kfwdl;
0752
0753 if (copy_from_user(&kfwdl, ufwdl, sizeof(struct mpt_fw_xfer))) {
0754 printk(KERN_ERR MYNAM "%s@%d::_ioctl_fwdl - "
0755 "Unable to copy mpt_fw_xfer struct @ %p\n",
0756 __FILE__, __LINE__, ufwdl);
0757 return -EFAULT;
0758 }
0759
0760 return mptctl_do_fw_download(iocp, kfwdl.bufp, kfwdl.fwlen);
0761 }
0762
0763
0764
0765
0766
0767
0768
0769
0770
0771
0772
0773
0774
0775
0776
0777 static int
0778 mptctl_do_fw_download(MPT_ADAPTER *iocp, char __user *ufwbuf, size_t fwlen)
0779 {
0780 FWDownload_t *dlmsg;
0781 MPT_FRAME_HDR *mf;
0782 FWDownloadTCSGE_t *ptsge;
0783 MptSge_t *sgl, *sgIn;
0784 char *sgOut;
0785 struct buflist *buflist;
0786 struct buflist *bl;
0787 dma_addr_t sgl_dma;
0788 int ret;
0789 int numfrags = 0;
0790 int maxfrags;
0791 int n = 0;
0792 u32 sgdir;
0793 u32 nib;
0794 int fw_bytes_copied = 0;
0795 int i;
0796 int sge_offset = 0;
0797 u16 iocstat;
0798 pFWDownloadReply_t ReplyMsg = NULL;
0799 unsigned long timeleft;
0800
0801
0802
0803 if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
0804 return -EAGAIN;
0805
0806 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT
0807 "mptctl_do_fwdl called. mptctl_id = %xh.\n", iocp->name, mptctl_id));
0808 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.bufp = %p\n",
0809 iocp->name, ufwbuf));
0810 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.fwlen = %d\n",
0811 iocp->name, (int)fwlen));
0812
0813 dlmsg = (FWDownload_t*) mf;
0814 ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL;
0815 sgOut = (char *) (ptsge + 1);
0816
0817
0818
0819
0820 dlmsg->ImageType = MPI_FW_DOWNLOAD_ITYPE_FW;
0821 dlmsg->Reserved = 0;
0822 dlmsg->ChainOffset = 0;
0823 dlmsg->Function = MPI_FUNCTION_FW_DOWNLOAD;
0824 dlmsg->Reserved1[0] = dlmsg->Reserved1[1] = dlmsg->Reserved1[2] = 0;
0825 if (iocp->facts.MsgVersion >= MPI_VERSION_01_05)
0826 dlmsg->MsgFlags = MPI_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT;
0827 else
0828 dlmsg->MsgFlags = 0;
0829
0830
0831
0832
0833 ptsge->Reserved = 0;
0834 ptsge->ContextSize = 0;
0835 ptsge->DetailsLength = 12;
0836 ptsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
0837 ptsge->Reserved_0100_Checksum = 0;
0838 ptsge->ImageOffset = 0;
0839 ptsge->ImageSize = cpu_to_le32(fwlen);
0840
0841
0842
0843
0844
0845
0846
0847
0848
0849
0850
0851
0852
0853
0854
0855
0856
0857 sgdir = 0x04000000;
0858 sge_offset = sizeof(MPIHeader_t) + sizeof(FWDownloadTCSGE_t);
0859 if ((sgl = kbuf_alloc_2_sgl(fwlen, sgdir, sge_offset,
0860 &numfrags, &buflist, &sgl_dma, iocp)) == NULL)
0861 return -ENOMEM;
0862
0863
0864
0865
0866
0867
0868
0869
0870
0871
0872
0873
0874 maxfrags = (iocp->req_sz - sizeof(MPIHeader_t) -
0875 sizeof(FWDownloadTCSGE_t))
0876 / iocp->SGE_size;
0877 if (numfrags > maxfrags) {
0878 ret = -EMLINK;
0879 goto fwdl_out;
0880 }
0881
0882 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: sgl buffer = %p, sgfrags = %d\n",
0883 iocp->name, sgl, numfrags));
0884
0885
0886
0887
0888
0889 ret = -EFAULT;
0890 sgIn = sgl;
0891 bl = buflist;
0892 for (i=0; i < numfrags; i++) {
0893
0894
0895
0896
0897
0898
0899
0900 nib = (sgIn->FlagsLength & 0x30000000) >> 28;
0901 if (nib == 0 || nib == 3) {
0902 ;
0903 } else if (sgIn->Address) {
0904 iocp->add_sge(sgOut, sgIn->FlagsLength, sgIn->Address);
0905 n++;
0906 if (copy_from_user(bl->kptr, ufwbuf+fw_bytes_copied, bl->len)) {
0907 printk(MYIOC_s_ERR_FMT "%s@%d::_ioctl_fwdl - "
0908 "Unable to copy f/w buffer hunk#%d @ %p\n",
0909 iocp->name, __FILE__, __LINE__, n, ufwbuf);
0910 goto fwdl_out;
0911 }
0912 fw_bytes_copied += bl->len;
0913 }
0914 sgIn++;
0915 bl++;
0916 sgOut += iocp->SGE_size;
0917 }
0918
0919 DBG_DUMP_FW_DOWNLOAD(iocp, (u32 *)mf, numfrags);
0920
0921
0922
0923
0924 ReplyMsg = NULL;
0925 SET_MGMT_MSG_CONTEXT(iocp->ioctl_cmds.msg_context, dlmsg->MsgContext);
0926 INITIALIZE_MGMT_STATUS(iocp->ioctl_cmds.status)
0927 mpt_put_msg_frame(mptctl_id, iocp, mf);
0928
0929
0930 retry_wait:
0931 timeleft = wait_for_completion_timeout(&iocp->ioctl_cmds.done, HZ*60);
0932 if (!(iocp->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
0933 ret = -ETIME;
0934 printk(MYIOC_s_WARN_FMT "%s: failed\n", iocp->name, __func__);
0935 if (iocp->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
0936 mpt_free_msg_frame(iocp, mf);
0937 goto fwdl_out;
0938 }
0939 if (!timeleft) {
0940 printk(MYIOC_s_WARN_FMT
0941 "FW download timeout, doorbell=0x%08x\n",
0942 iocp->name, mpt_GetIocState(iocp, 0));
0943 mptctl_timeout_expired(iocp, mf);
0944 } else
0945 goto retry_wait;
0946 goto fwdl_out;
0947 }
0948
0949 if (!(iocp->ioctl_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
0950 printk(MYIOC_s_WARN_FMT "%s: failed\n", iocp->name, __func__);
0951 mpt_free_msg_frame(iocp, mf);
0952 ret = -ENODATA;
0953 goto fwdl_out;
0954 }
0955
0956 if (sgl)
0957 kfree_sgl(sgl, sgl_dma, buflist, iocp);
0958
0959 ReplyMsg = (pFWDownloadReply_t)iocp->ioctl_cmds.reply;
0960 iocstat = le16_to_cpu(ReplyMsg->IOCStatus) & MPI_IOCSTATUS_MASK;
0961 if (iocstat == MPI_IOCSTATUS_SUCCESS) {
0962 printk(MYIOC_s_INFO_FMT "F/W update successful!\n", iocp->name);
0963 return 0;
0964 } else if (iocstat == MPI_IOCSTATUS_INVALID_FUNCTION) {
0965 printk(MYIOC_s_WARN_FMT "Hmmm... F/W download not supported!?!\n",
0966 iocp->name);
0967 printk(MYIOC_s_WARN_FMT "(time to go bang on somebodies door)\n",
0968 iocp->name);
0969 return -EBADRQC;
0970 } else if (iocstat == MPI_IOCSTATUS_BUSY) {
0971 printk(MYIOC_s_WARN_FMT "IOC_BUSY!\n", iocp->name);
0972 printk(MYIOC_s_WARN_FMT "(try again later?)\n", iocp->name);
0973 return -EBUSY;
0974 } else {
0975 printk(MYIOC_s_WARN_FMT "ioctl_fwdl() returned [bad] status = %04xh\n",
0976 iocp->name, iocstat);
0977 printk(MYIOC_s_WARN_FMT "(bad VooDoo)\n", iocp->name);
0978 return -ENOMSG;
0979 }
0980 return 0;
0981
0982 fwdl_out:
0983
0984 CLEAR_MGMT_STATUS(iocp->ioctl_cmds.status);
0985 SET_MGMT_MSG_CONTEXT(iocp->ioctl_cmds.msg_context, 0);
0986 kfree_sgl(sgl, sgl_dma, buflist, iocp);
0987 return ret;
0988 }
0989
0990
0991
0992
0993
0994
0995
0996
0997
0998
0999
1000
1001
1002
1003
1004
1005 static MptSge_t *
1006 kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags,
1007 struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc)
1008 {
1009 MptSge_t *sglbuf = NULL;
1010
1011 struct buflist *buflist = NULL;
1012 MptSge_t *sgl;
1013 int numfrags = 0;
1014 int fragcnt = 0;
1015 int alloc_sz = min(bytes,MAX_KMALLOC_SZ);
1016 int bytes_allocd = 0;
1017 int this_alloc;
1018 dma_addr_t pa;
1019 int i, buflist_ent;
1020 int sg_spill = MAX_FRAGS_SPILL1;
1021 int dir;
1022
1023 if (bytes < 0)
1024 return NULL;
1025
1026
1027 *frags = 0;
1028 *blp = NULL;
1029
1030
1031
1032
1033 i = MAX_SGL_BYTES / 8;
1034 buflist = kzalloc(i, GFP_USER);
1035 if (!buflist)
1036 return NULL;
1037 buflist_ent = 0;
1038
1039
1040
1041
1042
1043
1044 sglbuf = dma_alloc_coherent(&ioc->pcidev->dev, MAX_SGL_BYTES,
1045 sglbuf_dma, GFP_KERNEL);
1046 if (sglbuf == NULL)
1047 goto free_and_fail;
1048
1049 if (sgdir & 0x04000000)
1050 dir = DMA_TO_DEVICE;
1051 else
1052 dir = DMA_FROM_DEVICE;
1053
1054
1055
1056
1057
1058
1059
1060
1061 sgl = sglbuf;
1062 sg_spill = ((ioc->req_sz - sge_offset)/ioc->SGE_size) - 1;
1063 while (bytes_allocd < bytes) {
1064 this_alloc = min(alloc_sz, bytes-bytes_allocd);
1065 buflist[buflist_ent].len = this_alloc;
1066 buflist[buflist_ent].kptr = dma_alloc_coherent(&ioc->pcidev->dev,
1067 this_alloc,
1068 &pa, GFP_KERNEL);
1069 if (buflist[buflist_ent].kptr == NULL) {
1070 alloc_sz = alloc_sz / 2;
1071 if (alloc_sz == 0) {
1072 printk(MYIOC_s_WARN_FMT "-SG: No can do - "
1073 "not enough memory! :-(\n", ioc->name);
1074 printk(MYIOC_s_WARN_FMT "-SG: (freeing %d frags)\n",
1075 ioc->name, numfrags);
1076 goto free_and_fail;
1077 }
1078 continue;
1079 } else {
1080 dma_addr_t dma_addr;
1081
1082 bytes_allocd += this_alloc;
1083 sgl->FlagsLength = (0x10000000|sgdir|this_alloc);
1084 dma_addr = dma_map_single(&ioc->pcidev->dev,
1085 buflist[buflist_ent].kptr,
1086 this_alloc, dir);
1087 sgl->Address = dma_addr;
1088
1089 fragcnt++;
1090 numfrags++;
1091 sgl++;
1092 buflist_ent++;
1093 }
1094
1095 if (bytes_allocd >= bytes)
1096 break;
1097
1098
1099 if (fragcnt == sg_spill) {
1100 printk(MYIOC_s_WARN_FMT
1101 "-SG: No can do - " "Chain required! :-(\n", ioc->name);
1102 printk(MYIOC_s_WARN_FMT "(freeing %d frags)\n", ioc->name, numfrags);
1103 goto free_and_fail;
1104 }
1105
1106
1107 if (numfrags*8 > MAX_SGL_BYTES){
1108
1109 printk(MYIOC_s_WARN_FMT "-SG: No can do - "
1110 "too many SG frags! :-(\n", ioc->name);
1111 printk(MYIOC_s_WARN_FMT "-SG: (freeing %d frags)\n",
1112 ioc->name, numfrags);
1113 goto free_and_fail;
1114 }
1115 }
1116
1117
1118 sgl[-1].FlagsLength |= 0xC1000000;
1119
1120 *frags = numfrags;
1121 *blp = buflist;
1122
1123 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "-SG: kbuf_alloc_2_sgl() - "
1124 "%d SG frags generated!\n", ioc->name, numfrags));
1125
1126 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "-SG: kbuf_alloc_2_sgl() - "
1127 "last (big) alloc_sz=%d\n", ioc->name, alloc_sz));
1128
1129 return sglbuf;
1130
1131 free_and_fail:
1132 if (sglbuf != NULL) {
1133 for (i = 0; i < numfrags; i++) {
1134 dma_addr_t dma_addr;
1135 u8 *kptr;
1136 int len;
1137
1138 if ((sglbuf[i].FlagsLength >> 24) == 0x30)
1139 continue;
1140
1141 dma_addr = sglbuf[i].Address;
1142 kptr = buflist[i].kptr;
1143 len = buflist[i].len;
1144
1145 dma_free_coherent(&ioc->pcidev->dev, len, kptr,
1146 dma_addr);
1147 }
1148 dma_free_coherent(&ioc->pcidev->dev, MAX_SGL_BYTES, sglbuf,
1149 *sglbuf_dma);
1150 }
1151 kfree(buflist);
1152 return NULL;
1153 }
1154
1155
1156
1157
1158
1159 static void
1160 kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma, struct buflist *buflist, MPT_ADAPTER *ioc)
1161 {
1162 MptSge_t *sg = sgl;
1163 struct buflist *bl = buflist;
1164 u32 nib;
1165 int dir;
1166 int n = 0;
1167
1168 if (sg->FlagsLength & 0x04000000)
1169 dir = DMA_TO_DEVICE;
1170 else
1171 dir = DMA_FROM_DEVICE;
1172
1173 nib = (sg->FlagsLength & 0xF0000000) >> 28;
1174 while (! (nib & 0x4)) {
1175
1176 if (nib == 0 || nib == 3) {
1177 ;
1178 } else if (sg->Address) {
1179 dma_addr_t dma_addr;
1180 void *kptr;
1181 int len;
1182
1183 dma_addr = sg->Address;
1184 kptr = bl->kptr;
1185 len = bl->len;
1186 dma_unmap_single(&ioc->pcidev->dev, dma_addr, len,
1187 dir);
1188 dma_free_coherent(&ioc->pcidev->dev, len, kptr,
1189 dma_addr);
1190 n++;
1191 }
1192 sg++;
1193 bl++;
1194 nib = (le32_to_cpu(sg->FlagsLength) & 0xF0000000) >> 28;
1195 }
1196
1197
1198 if (sg->Address) {
1199 dma_addr_t dma_addr;
1200 void *kptr;
1201 int len;
1202
1203 dma_addr = sg->Address;
1204 kptr = bl->kptr;
1205 len = bl->len;
1206 dma_unmap_single(&ioc->pcidev->dev, dma_addr, len, dir);
1207 dma_free_coherent(&ioc->pcidev->dev, len, kptr, dma_addr);
1208 n++;
1209 }
1210
1211 dma_free_coherent(&ioc->pcidev->dev, MAX_SGL_BYTES, sgl, sgl_dma);
1212 kfree(buflist);
1213 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "-SG: Free'd 1 SGL buf + %d kbufs!\n",
1214 ioc->name, n));
1215 }
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227 static int
1228 mptctl_getiocinfo (MPT_ADAPTER *ioc, unsigned long arg, unsigned int data_size)
1229 {
1230 struct mpt_ioctl_iocinfo __user *uarg = (void __user *) arg;
1231 struct mpt_ioctl_iocinfo *karg;
1232 struct pci_dev *pdev;
1233 unsigned int port;
1234 int cim_rev;
1235 struct scsi_device *sdev;
1236 VirtDevice *vdevice;
1237
1238
1239
1240
1241
1242 if (data_size == sizeof(struct mpt_ioctl_iocinfo_rev0))
1243 cim_rev = 0;
1244 else if (data_size == sizeof(struct mpt_ioctl_iocinfo_rev1))
1245 cim_rev = 1;
1246 else if (data_size == sizeof(struct mpt_ioctl_iocinfo))
1247 cim_rev = 2;
1248 else if (data_size == (sizeof(struct mpt_ioctl_iocinfo_rev0)+12))
1249 cim_rev = 0;
1250 else
1251 return -EFAULT;
1252
1253 karg = memdup_user(uarg, data_size);
1254 if (IS_ERR(karg)) {
1255 printk(KERN_ERR MYNAM "%s@%d::mpt_ioctl_iocinfo() - memdup_user returned error [%ld]\n",
1256 __FILE__, __LINE__, PTR_ERR(karg));
1257 return PTR_ERR(karg);
1258 }
1259
1260
1261 if (karg->hdr.maxDataSize != data_size) {
1262 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - "
1263 "Structure size mismatch. Command not completed.\n",
1264 ioc->name, __FILE__, __LINE__);
1265 kfree(karg);
1266 return -EFAULT;
1267 }
1268
1269 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_getiocinfo called.\n",
1270 ioc->name));
1271
1272
1273
1274
1275 if (ioc->bus_type == SAS)
1276 karg->adapterType = MPT_IOCTL_INTERFACE_SAS;
1277 else if (ioc->bus_type == FC)
1278 karg->adapterType = MPT_IOCTL_INTERFACE_FC;
1279 else
1280 karg->adapterType = MPT_IOCTL_INTERFACE_SCSI;
1281
1282 if (karg->hdr.port > 1) {
1283 kfree(karg);
1284 return -EINVAL;
1285 }
1286 port = karg->hdr.port;
1287
1288 karg->port = port;
1289 pdev = (struct pci_dev *) ioc->pcidev;
1290
1291 karg->pciId = pdev->device;
1292 karg->hwRev = pdev->revision;
1293 karg->subSystemDevice = pdev->subsystem_device;
1294 karg->subSystemVendor = pdev->subsystem_vendor;
1295
1296 if (cim_rev == 1) {
1297
1298
1299 karg->pciInfo.u.bits.busNumber = pdev->bus->number;
1300 karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
1301 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1302 } else if (cim_rev == 2) {
1303
1304
1305 karg->pciInfo.u.bits.busNumber = pdev->bus->number;
1306 karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
1307 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
1308 karg->pciInfo.segmentID = pci_domain_nr(pdev->bus);
1309 }
1310
1311
1312
1313 karg->numDevices = 0;
1314 if (ioc->sh) {
1315 shost_for_each_device(sdev, ioc->sh) {
1316 vdevice = sdev->hostdata;
1317 if (vdevice == NULL || vdevice->vtarget == NULL)
1318 continue;
1319 if (vdevice->vtarget->tflags &
1320 MPT_TARGET_FLAGS_RAID_COMPONENT)
1321 continue;
1322 karg->numDevices++;
1323 }
1324 }
1325
1326
1327
1328 karg->FWVersion = ioc->facts.FWVersion.Word;
1329 karg->BIOSVersion = ioc->biosVersion;
1330
1331
1332
1333 strncpy (karg->driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH);
1334 karg->driverVersion[MPT_IOCTL_VERSION_LENGTH-1]='\0';
1335
1336 karg->busChangeEvent = 0;
1337 karg->hostId = ioc->pfacts[port].PortSCSIID;
1338 karg->rsvd[0] = karg->rsvd[1] = 0;
1339
1340
1341
1342 if (copy_to_user((char __user *)arg, karg, data_size)) {
1343 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - "
1344 "Unable to write out mpt_ioctl_iocinfo struct @ %p\n",
1345 ioc->name, __FILE__, __LINE__, uarg);
1346 kfree(karg);
1347 return -EFAULT;
1348 }
1349
1350 kfree(karg);
1351 return 0;
1352 }
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364 static int
1365 mptctl_gettargetinfo (MPT_ADAPTER *ioc, unsigned long arg)
1366 {
1367 struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg;
1368 struct mpt_ioctl_targetinfo karg;
1369 VirtDevice *vdevice;
1370 char *pmem;
1371 int *pdata;
1372 int numDevices = 0;
1373 int lun;
1374 int maxWordsLeft;
1375 int numBytes;
1376 struct scsi_device *sdev;
1377
1378 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
1379 printk(KERN_ERR MYNAM "%s@%d::mptctl_gettargetinfo - "
1380 "Unable to read in mpt_ioctl_targetinfo struct @ %p\n",
1381 __FILE__, __LINE__, uarg);
1382 return -EFAULT;
1383 }
1384
1385 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_gettargetinfo called.\n",
1386 ioc->name));
1387 numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
1388 maxWordsLeft = numBytes/sizeof(int);
1389
1390 if (maxWordsLeft <= 0) {
1391 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n",
1392 ioc->name, __FILE__, __LINE__);
1393 return -ENOMEM;
1394 }
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410 pmem = kzalloc(numBytes, GFP_KERNEL);
1411 if (!pmem) {
1412 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n",
1413 ioc->name, __FILE__, __LINE__);
1414 return -ENOMEM;
1415 }
1416 pdata = (int *) pmem;
1417
1418
1419
1420 if (ioc->sh){
1421 shost_for_each_device(sdev, ioc->sh) {
1422 if (!maxWordsLeft)
1423 continue;
1424 vdevice = sdev->hostdata;
1425 if (vdevice == NULL || vdevice->vtarget == NULL)
1426 continue;
1427 if (vdevice->vtarget->tflags &
1428 MPT_TARGET_FLAGS_RAID_COMPONENT)
1429 continue;
1430 lun = (vdevice->vtarget->raidVolume) ? 0x80 : vdevice->lun;
1431 *pdata = (((u8)lun << 16) + (vdevice->vtarget->channel << 8) +
1432 (vdevice->vtarget->id ));
1433 pdata++;
1434 numDevices++;
1435 --maxWordsLeft;
1436 }
1437 }
1438 karg.numDevices = numDevices;
1439
1440
1441
1442 if (copy_to_user((char __user *)arg, &karg,
1443 sizeof(struct mpt_ioctl_targetinfo))) {
1444 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo - "
1445 "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
1446 ioc->name, __FILE__, __LINE__, uarg);
1447 kfree(pmem);
1448 return -EFAULT;
1449 }
1450
1451
1452
1453 if (copy_to_user(uarg->targetInfo, pmem, numBytes)) {
1454 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo - "
1455 "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
1456 ioc->name, __FILE__, __LINE__, pdata);
1457 kfree(pmem);
1458 return -EFAULT;
1459 }
1460
1461 kfree(pmem);
1462
1463 return 0;
1464 }
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474 static int
1475 mptctl_readtest (MPT_ADAPTER *ioc, unsigned long arg)
1476 {
1477 struct mpt_ioctl_test __user *uarg = (void __user *) arg;
1478 struct mpt_ioctl_test karg;
1479
1480 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) {
1481 printk(KERN_ERR MYNAM "%s@%d::mptctl_readtest - "
1482 "Unable to read in mpt_ioctl_test struct @ %p\n",
1483 __FILE__, __LINE__, uarg);
1484 return -EFAULT;
1485 }
1486
1487 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_readtest called.\n",
1488 ioc->name));
1489
1490
1491
1492
1493 #ifdef MFCNT
1494 karg.chip_type = ioc->mfcnt;
1495 #else
1496 karg.chip_type = ioc->pcidev->device;
1497 #endif
1498 strncpy (karg.name, ioc->name, MPT_MAX_NAME);
1499 karg.name[MPT_MAX_NAME-1]='\0';
1500 strncpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH);
1501 karg.product[MPT_PRODUCT_LENGTH-1]='\0';
1502
1503
1504
1505 if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_test))) {
1506 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_readtest - "
1507 "Unable to write out mpt_ioctl_test struct @ %p\n",
1508 ioc->name, __FILE__, __LINE__, uarg);
1509 return -EFAULT;
1510 }
1511
1512 return 0;
1513 }
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526 static int
1527 mptctl_eventquery (MPT_ADAPTER *ioc, unsigned long arg)
1528 {
1529 struct mpt_ioctl_eventquery __user *uarg = (void __user *) arg;
1530 struct mpt_ioctl_eventquery karg;
1531
1532 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) {
1533 printk(KERN_ERR MYNAM "%s@%d::mptctl_eventquery - "
1534 "Unable to read in mpt_ioctl_eventquery struct @ %p\n",
1535 __FILE__, __LINE__, uarg);
1536 return -EFAULT;
1537 }
1538
1539 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventquery called.\n",
1540 ioc->name));
1541 karg.eventEntries = MPTCTL_EVENT_LOG_SIZE;
1542 karg.eventTypes = ioc->eventTypes;
1543
1544
1545
1546 if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) {
1547 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_eventquery - "
1548 "Unable to write out mpt_ioctl_eventquery struct @ %p\n",
1549 ioc->name, __FILE__, __LINE__, uarg);
1550 return -EFAULT;
1551 }
1552 return 0;
1553 }
1554
1555
1556 static int
1557 mptctl_eventenable (MPT_ADAPTER *ioc, unsigned long arg)
1558 {
1559 struct mpt_ioctl_eventenable __user *uarg = (void __user *) arg;
1560 struct mpt_ioctl_eventenable karg;
1561
1562 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) {
1563 printk(KERN_ERR MYNAM "%s@%d::mptctl_eventenable - "
1564 "Unable to read in mpt_ioctl_eventenable struct @ %p\n",
1565 __FILE__, __LINE__, uarg);
1566 return -EFAULT;
1567 }
1568
1569 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventenable called.\n",
1570 ioc->name));
1571 if (ioc->events == NULL) {
1572
1573
1574 int sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
1575 ioc->events = kzalloc(sz, GFP_KERNEL);
1576 if (!ioc->events) {
1577 printk(MYIOC_s_ERR_FMT
1578 ": ERROR - Insufficient memory to add adapter!\n",
1579 ioc->name);
1580 return -ENOMEM;
1581 }
1582 ioc->alloc_total += sz;
1583
1584 ioc->eventContext = 0;
1585 }
1586
1587
1588
1589 ioc->eventTypes = karg.eventTypes;
1590
1591 return 0;
1592 }
1593
1594
1595 static int
1596 mptctl_eventreport (MPT_ADAPTER *ioc, unsigned long arg)
1597 {
1598 struct mpt_ioctl_eventreport __user *uarg = (void __user *) arg;
1599 struct mpt_ioctl_eventreport karg;
1600 int numBytes, maxEvents, max;
1601
1602 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) {
1603 printk(KERN_ERR MYNAM "%s@%d::mptctl_eventreport - "
1604 "Unable to read in mpt_ioctl_eventreport struct @ %p\n",
1605 __FILE__, __LINE__, uarg);
1606 return -EFAULT;
1607 }
1608
1609 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventreport called.\n",
1610 ioc->name));
1611
1612 numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
1613 maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS);
1614
1615
1616 max = MPTCTL_EVENT_LOG_SIZE < maxEvents ? MPTCTL_EVENT_LOG_SIZE : maxEvents;
1617
1618
1619
1620
1621 if ((max < 1) || !ioc->events)
1622 return -ENODATA;
1623
1624
1625 ioc->aen_event_read_flag=0;
1626
1627
1628
1629 numBytes = max * sizeof(MPT_IOCTL_EVENTS);
1630 if (copy_to_user(uarg->eventData, ioc->events, numBytes)) {
1631 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_eventreport - "
1632 "Unable to write out mpt_ioctl_eventreport struct @ %p\n",
1633 ioc->name, __FILE__, __LINE__, ioc->events);
1634 return -EFAULT;
1635 }
1636
1637 return 0;
1638 }
1639
1640
1641 static int
1642 mptctl_replace_fw (MPT_ADAPTER *ioc, unsigned long arg)
1643 {
1644 struct mpt_ioctl_replace_fw __user *uarg = (void __user *) arg;
1645 struct mpt_ioctl_replace_fw karg;
1646 int newFwSize;
1647
1648 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
1649 printk(KERN_ERR MYNAM "%s@%d::mptctl_replace_fw - "
1650 "Unable to read in mpt_ioctl_replace_fw struct @ %p\n",
1651 __FILE__, __LINE__, uarg);
1652 return -EFAULT;
1653 }
1654
1655 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_replace_fw called.\n",
1656 ioc->name));
1657
1658
1659 if (ioc->cached_fw == NULL)
1660 return 0;
1661
1662 mpt_free_fw_memory(ioc);
1663
1664
1665
1666 newFwSize = ALIGN(karg.newImageSize, 4);
1667
1668 mpt_alloc_fw_memory(ioc, newFwSize);
1669 if (ioc->cached_fw == NULL)
1670 return -ENOMEM;
1671
1672
1673
1674 if (copy_from_user(ioc->cached_fw, uarg->newImage, newFwSize)) {
1675 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_replace_fw - "
1676 "Unable to read in mpt_ioctl_replace_fw image "
1677 "@ %p\n", ioc->name, __FILE__, __LINE__, uarg);
1678 mpt_free_fw_memory(ioc);
1679 return -EFAULT;
1680 }
1681
1682
1683
1684 ioc->facts.FWImageSize = newFwSize;
1685 return 0;
1686 }
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700 static int
1701 mptctl_mpt_command (MPT_ADAPTER *ioc, unsigned long arg)
1702 {
1703 struct mpt_ioctl_command __user *uarg = (void __user *) arg;
1704 struct mpt_ioctl_command karg;
1705 int rc;
1706
1707
1708 if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_command))) {
1709 printk(KERN_ERR MYNAM "%s@%d::mptctl_mpt_command - "
1710 "Unable to read in mpt_ioctl_command struct @ %p\n",
1711 __FILE__, __LINE__, uarg);
1712 return -EFAULT;
1713 }
1714
1715 rc = mptctl_do_mpt_command (ioc, karg, &uarg->MF);
1716
1717 return rc;
1718 }
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732 static int
1733 mptctl_do_mpt_command (MPT_ADAPTER *ioc, struct mpt_ioctl_command karg, void __user *mfPtr)
1734 {
1735 MPT_FRAME_HDR *mf = NULL;
1736 MPIHeader_t *hdr;
1737 char *psge;
1738 struct buflist bufIn;
1739 struct buflist bufOut;
1740 dma_addr_t dma_addr_in;
1741 dma_addr_t dma_addr_out;
1742 int sgSize = 0;
1743 int flagsLength;
1744 int sz, rc = 0;
1745 int msgContext;
1746 u16 req_idx;
1747 ulong timeout;
1748 unsigned long timeleft;
1749 struct scsi_device *sdev;
1750 unsigned long flags;
1751 u8 function;
1752
1753
1754
1755 bufIn.kptr = bufOut.kptr = NULL;
1756 bufIn.len = bufOut.len = 0;
1757
1758 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
1759 if (ioc->ioc_reset_in_progress) {
1760 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
1761 printk(KERN_ERR MYNAM "%s@%d::mptctl_do_mpt_command - "
1762 "Busy with diagnostic reset\n", __FILE__, __LINE__);
1763 return -EBUSY;
1764 }
1765 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
1766
1767
1768 if (karg.maxReplyBytes < 0 ||
1769 karg.dataInSize < 0 ||
1770 karg.dataOutSize < 0 ||
1771 karg.dataSgeOffset < 0 ||
1772 karg.maxSenseBytes < 0 ||
1773 karg.dataSgeOffset > ioc->req_sz / 4)
1774 return -EINVAL;
1775
1776
1777
1778 sz = karg.dataSgeOffset * 4;
1779 if (karg.dataInSize > 0)
1780 sz += ioc->SGE_size;
1781 if (karg.dataOutSize > 0)
1782 sz += ioc->SGE_size;
1783
1784 if (sz > ioc->req_sz) {
1785 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1786 "Request frame too large (%d) maximum (%d)\n",
1787 ioc->name, __FILE__, __LINE__, sz, ioc->req_sz);
1788 return -EFAULT;
1789 }
1790
1791
1792
1793 if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL)
1794 return -EAGAIN;
1795
1796 hdr = (MPIHeader_t *) mf;
1797 msgContext = le32_to_cpu(hdr->MsgContext);
1798 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1799
1800
1801
1802
1803
1804 if (copy_from_user(mf, mfPtr, karg.dataSgeOffset * 4)) {
1805 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1806 "Unable to read MF from mpt_ioctl_command struct @ %p\n",
1807 ioc->name, __FILE__, __LINE__, mfPtr);
1808 function = -1;
1809 rc = -EFAULT;
1810 goto done_free_mem;
1811 }
1812 hdr->MsgContext = cpu_to_le32(msgContext);
1813 function = hdr->Function;
1814
1815
1816
1817
1818 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sending mpi function (0x%02X), req=%p\n",
1819 ioc->name, hdr->Function, mf));
1820
1821 switch (function) {
1822 case MPI_FUNCTION_IOC_FACTS:
1823 case MPI_FUNCTION_PORT_FACTS:
1824 karg.dataOutSize = karg.dataInSize = 0;
1825 break;
1826
1827 case MPI_FUNCTION_CONFIG:
1828 {
1829 Config_t *config_frame;
1830 config_frame = (Config_t *)mf;
1831 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\ttype=0x%02x ext_type=0x%02x "
1832 "number=0x%02x action=0x%02x\n", ioc->name,
1833 config_frame->Header.PageType,
1834 config_frame->ExtPageType,
1835 config_frame->Header.PageNumber,
1836 config_frame->Action));
1837 break;
1838 }
1839
1840 case MPI_FUNCTION_FC_COMMON_TRANSPORT_SEND:
1841 case MPI_FUNCTION_FC_EX_LINK_SRVC_SEND:
1842 case MPI_FUNCTION_FW_UPLOAD:
1843 case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR:
1844 case MPI_FUNCTION_FW_DOWNLOAD:
1845 case MPI_FUNCTION_FC_PRIMITIVE_SEND:
1846 case MPI_FUNCTION_TOOLBOX:
1847 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
1848 break;
1849
1850 case MPI_FUNCTION_SCSI_IO_REQUEST:
1851 if (ioc->sh) {
1852 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
1853 int qtag = MPI_SCSIIO_CONTROL_UNTAGGED;
1854 int scsidir = 0;
1855 int dataSize;
1856 u32 id;
1857
1858 id = (ioc->devices_per_bus == 0) ? 256 : ioc->devices_per_bus;
1859 if (pScsiReq->TargetID > id) {
1860 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1861 "Target ID out of bounds. \n",
1862 ioc->name, __FILE__, __LINE__);
1863 rc = -ENODEV;
1864 goto done_free_mem;
1865 }
1866
1867 if (pScsiReq->Bus >= ioc->number_of_buses) {
1868 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1869 "Target Bus out of bounds. \n",
1870 ioc->name, __FILE__, __LINE__);
1871 rc = -ENODEV;
1872 goto done_free_mem;
1873 }
1874
1875 pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
1876 pScsiReq->MsgFlags |= mpt_msg_flags(ioc);
1877
1878
1879
1880
1881
1882
1883
1884
1885 if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
1886 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1887 else
1888 pScsiReq->SenseBufferLength = karg.maxSenseBytes;
1889
1890 pScsiReq->SenseBufferLowAddr =
1891 cpu_to_le32(ioc->sense_buf_low_dma
1892 + (req_idx * MPT_SENSE_BUFFER_ALLOC));
1893
1894 shost_for_each_device(sdev, ioc->sh) {
1895 struct scsi_target *starget = scsi_target(sdev);
1896 VirtTarget *vtarget = starget->hostdata;
1897
1898 if (vtarget == NULL)
1899 continue;
1900
1901 if ((pScsiReq->TargetID == vtarget->id) &&
1902 (pScsiReq->Bus == vtarget->channel) &&
1903 (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
1904 qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
1905 }
1906
1907
1908
1909
1910 if (karg.dataOutSize > 0) {
1911 scsidir = MPI_SCSIIO_CONTROL_WRITE;
1912 dataSize = karg.dataOutSize;
1913 } else {
1914 scsidir = MPI_SCSIIO_CONTROL_READ;
1915 dataSize = karg.dataInSize;
1916 }
1917
1918 pScsiReq->Control = cpu_to_le32(scsidir | qtag);
1919 pScsiReq->DataLength = cpu_to_le32(dataSize);
1920
1921
1922 } else {
1923 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1924 "SCSI driver is not loaded. \n",
1925 ioc->name, __FILE__, __LINE__);
1926 rc = -EFAULT;
1927 goto done_free_mem;
1928 }
1929 break;
1930
1931 case MPI_FUNCTION_SMP_PASSTHROUGH:
1932
1933
1934
1935
1936
1937
1938 break;
1939
1940 case MPI_FUNCTION_SATA_PASSTHROUGH:
1941 if (!ioc->sh) {
1942 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
1943 "SCSI driver is not loaded. \n",
1944 ioc->name, __FILE__, __LINE__);
1945 rc = -EFAULT;
1946 goto done_free_mem;
1947 }
1948 break;
1949
1950 case MPI_FUNCTION_RAID_ACTION:
1951
1952
1953 break;
1954
1955 case MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
1956 if (ioc->sh) {
1957 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
1958 int qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
1959 int scsidir = MPI_SCSIIO_CONTROL_READ;
1960 int dataSize;
1961
1962 pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
1963 pScsiReq->MsgFlags |= mpt_msg_flags(ioc);
1964
1965
1966
1967
1968
1969
1970
1971
1972 if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
1973 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1974 else
1975 pScsiReq->SenseBufferLength = karg.maxSenseBytes;
1976
1977 pScsiReq->SenseBufferLowAddr =
1978 cpu_to_le32(ioc->sense_buf_low_dma
1979 + (req_idx * MPT_SENSE_BUFFER_ALLOC));
1980
1981
1982
1983
1984
1985
1986
1987 if (karg.dataOutSize > 0) {
1988 scsidir = MPI_SCSIIO_CONTROL_WRITE;
1989 dataSize = karg.dataOutSize;
1990 } else {
1991 scsidir = MPI_SCSIIO_CONTROL_READ;
1992 dataSize = karg.dataInSize;
1993 }
1994
1995 pScsiReq->Control = cpu_to_le32(scsidir | qtag);
1996 pScsiReq->DataLength = cpu_to_le32(dataSize);
1997
1998 } else {
1999 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2000 "SCSI driver is not loaded. \n",
2001 ioc->name, __FILE__, __LINE__);
2002 rc = -EFAULT;
2003 goto done_free_mem;
2004 }
2005 break;
2006
2007 case MPI_FUNCTION_SCSI_TASK_MGMT:
2008 {
2009 SCSITaskMgmt_t *pScsiTm;
2010 pScsiTm = (SCSITaskMgmt_t *)mf;
2011 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2012 "\tTaskType=0x%x MsgFlags=0x%x "
2013 "TaskMsgContext=0x%x id=%d channel=%d\n",
2014 ioc->name, pScsiTm->TaskType, le32_to_cpu
2015 (pScsiTm->TaskMsgContext), pScsiTm->MsgFlags,
2016 pScsiTm->TargetID, pScsiTm->Bus));
2017 break;
2018 }
2019
2020 case MPI_FUNCTION_IOC_INIT:
2021 {
2022 IOCInit_t *pInit = (IOCInit_t *) mf;
2023 u32 high_addr, sense_high;
2024
2025
2026
2027
2028 if (sizeof(dma_addr_t) == sizeof(u64)) {
2029 high_addr = cpu_to_le32((u32)((u64)ioc->req_frames_dma >> 32));
2030 sense_high= cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2031 } else {
2032 high_addr = 0;
2033 sense_high= 0;
2034 }
2035
2036 if ((pInit->Flags != 0) || (pInit->MaxDevices != ioc->facts.MaxDevices) ||
2037 (pInit->MaxBuses != ioc->facts.MaxBuses) ||
2038 (pInit->ReplyFrameSize != cpu_to_le16(ioc->reply_sz)) ||
2039 (pInit->HostMfaHighAddr != high_addr) ||
2040 (pInit->SenseBufferHighAddr != sense_high)) {
2041 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2042 "IOC_INIT issued with 1 or more incorrect parameters. Rejected.\n",
2043 ioc->name, __FILE__, __LINE__);
2044 rc = -EFAULT;
2045 goto done_free_mem;
2046 }
2047 }
2048 break;
2049 default:
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2075 "Illegal request (function 0x%x) \n",
2076 ioc->name, __FILE__, __LINE__, hdr->Function);
2077 rc = -EFAULT;
2078 goto done_free_mem;
2079 }
2080
2081
2082
2083
2084
2085
2086 psge = (char *) (((int *) mf) + karg.dataSgeOffset);
2087 flagsLength = 0;
2088
2089 if (karg.dataOutSize > 0)
2090 sgSize ++;
2091
2092 if (karg.dataInSize > 0)
2093 sgSize ++;
2094
2095 if (sgSize > 0) {
2096
2097
2098 if (karg.dataOutSize > 0) {
2099 if (karg.dataInSize > 0) {
2100 flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2101 MPI_SGE_FLAGS_END_OF_BUFFER |
2102 MPI_SGE_FLAGS_DIRECTION)
2103 << MPI_SGE_FLAGS_SHIFT;
2104 } else {
2105 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
2106 }
2107 flagsLength |= karg.dataOutSize;
2108 bufOut.len = karg.dataOutSize;
2109 bufOut.kptr = dma_alloc_coherent(&ioc->pcidev->dev,
2110 bufOut.len,
2111 &dma_addr_out, GFP_KERNEL);
2112
2113 if (bufOut.kptr == NULL) {
2114 rc = -ENOMEM;
2115 goto done_free_mem;
2116 } else {
2117
2118
2119
2120 ioc->add_sge(psge, flagsLength, dma_addr_out);
2121 psge += ioc->SGE_size;
2122
2123
2124
2125 if (copy_from_user(bufOut.kptr,
2126 karg.dataOutBufPtr,
2127 bufOut.len)) {
2128 printk(MYIOC_s_ERR_FMT
2129 "%s@%d::mptctl_do_mpt_command - Unable "
2130 "to read user data "
2131 "struct @ %p\n",
2132 ioc->name, __FILE__, __LINE__,karg.dataOutBufPtr);
2133 rc = -EFAULT;
2134 goto done_free_mem;
2135 }
2136 }
2137 }
2138
2139 if (karg.dataInSize > 0) {
2140 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
2141 flagsLength |= karg.dataInSize;
2142
2143 bufIn.len = karg.dataInSize;
2144 bufIn.kptr = dma_alloc_coherent(&ioc->pcidev->dev,
2145 bufIn.len,
2146 &dma_addr_in, GFP_KERNEL);
2147
2148 if (bufIn.kptr == NULL) {
2149 rc = -ENOMEM;
2150 goto done_free_mem;
2151 } else {
2152
2153
2154
2155 ioc->add_sge(psge, flagsLength, dma_addr_in);
2156 }
2157 }
2158 } else {
2159
2160
2161 ioc->add_sge(psge, flagsLength, (dma_addr_t) -1);
2162 }
2163
2164 SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, hdr->MsgContext);
2165 INITIALIZE_MGMT_STATUS(ioc->ioctl_cmds.status)
2166 if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
2167
2168 mutex_lock(&ioc->taskmgmt_cmds.mutex);
2169 if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
2170 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2171 goto done_free_mem;
2172 }
2173
2174 DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
2175
2176 if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
2177 (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
2178 mpt_put_msg_frame_hi_pri(mptctl_id, ioc, mf);
2179 else {
2180 rc =mpt_send_handshake_request(mptctl_id, ioc,
2181 sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP);
2182 if (rc != 0) {
2183 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2184 "send_handshake FAILED! (ioc %p, mf %p)\n",
2185 ioc->name, ioc, mf));
2186 mpt_clear_taskmgmt_in_progress_flag(ioc);
2187 rc = -ENODATA;
2188 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2189 goto done_free_mem;
2190 }
2191 }
2192
2193 } else
2194 mpt_put_msg_frame(mptctl_id, ioc, mf);
2195
2196
2197 timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT;
2198 retry_wait:
2199 timeleft = wait_for_completion_timeout(&ioc->ioctl_cmds.done,
2200 HZ*timeout);
2201 if (!(ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2202 rc = -ETIME;
2203 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: TIMED OUT!\n",
2204 ioc->name, __func__));
2205 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
2206 if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
2207 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2208 goto done_free_mem;
2209 }
2210 if (!timeleft) {
2211 printk(MYIOC_s_WARN_FMT
2212 "mpt cmd timeout, doorbell=0x%08x"
2213 " function=0x%x\n",
2214 ioc->name, mpt_GetIocState(ioc, 0), function);
2215 if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
2216 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2217 mptctl_timeout_expired(ioc, mf);
2218 mf = NULL;
2219 } else
2220 goto retry_wait;
2221 goto done_free_mem;
2222 }
2223
2224 if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
2225 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
2226
2227
2228 mf = NULL;
2229
2230
2231
2232
2233 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_RF_VALID) {
2234 if (karg.maxReplyBytes < ioc->reply_sz) {
2235 sz = min(karg.maxReplyBytes,
2236 4*ioc->ioctl_cmds.reply[2]);
2237 } else {
2238 sz = min(ioc->reply_sz, 4*ioc->ioctl_cmds.reply[2]);
2239 }
2240 if (sz > 0) {
2241 if (copy_to_user(karg.replyFrameBufPtr,
2242 ioc->ioctl_cmds.reply, sz)){
2243 printk(MYIOC_s_ERR_FMT
2244 "%s@%d::mptctl_do_mpt_command - "
2245 "Unable to write out reply frame %p\n",
2246 ioc->name, __FILE__, __LINE__, karg.replyFrameBufPtr);
2247 rc = -ENODATA;
2248 goto done_free_mem;
2249 }
2250 }
2251 }
2252
2253
2254
2255 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_SENSE_VALID) {
2256 sz = min(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE);
2257 if (sz > 0) {
2258 if (copy_to_user(karg.senseDataPtr,
2259 ioc->ioctl_cmds.sense, sz)) {
2260 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2261 "Unable to write sense data to user %p\n",
2262 ioc->name, __FILE__, __LINE__,
2263 karg.senseDataPtr);
2264 rc = -ENODATA;
2265 goto done_free_mem;
2266 }
2267 }
2268 }
2269
2270
2271
2272
2273 if ((ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD) &&
2274 (karg.dataInSize > 0) && (bufIn.kptr)) {
2275
2276 if (copy_to_user(karg.dataInBufPtr,
2277 bufIn.kptr, karg.dataInSize)) {
2278 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
2279 "Unable to write data to user %p\n",
2280 ioc->name, __FILE__, __LINE__,
2281 karg.dataInBufPtr);
2282 rc = -ENODATA;
2283 }
2284 }
2285
2286 done_free_mem:
2287
2288 CLEAR_MGMT_STATUS(ioc->ioctl_cmds.status)
2289 SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, 0);
2290
2291
2292
2293 if (bufOut.kptr != NULL) {
2294 dma_free_coherent(&ioc->pcidev->dev, bufOut.len,
2295 (void *)bufOut.kptr, dma_addr_out);
2296 }
2297
2298 if (bufIn.kptr != NULL) {
2299 dma_free_coherent(&ioc->pcidev->dev, bufIn.len,
2300 (void *)bufIn.kptr, dma_addr_in);
2301 }
2302
2303
2304
2305
2306 if (mf)
2307 mpt_free_msg_frame(ioc, mf);
2308
2309 return rc;
2310 }
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323 static int
2324 mptctl_hp_hostinfo(MPT_ADAPTER *ioc, unsigned long arg, unsigned int data_size)
2325 {
2326 hp_host_info_t __user *uarg = (void __user *) arg;
2327 struct pci_dev *pdev;
2328 char *pbuf=NULL;
2329 dma_addr_t buf_dma;
2330 hp_host_info_t karg;
2331 CONFIGPARMS cfg;
2332 ConfigPageHeader_t hdr;
2333 int rc, cim_rev;
2334 ToolboxIstwiReadWriteRequest_t *IstwiRWRequest;
2335 MPT_FRAME_HDR *mf = NULL;
2336 unsigned long timeleft;
2337 u32 msgcontext;
2338
2339
2340
2341 if (data_size == sizeof(hp_host_info_t))
2342 cim_rev = 1;
2343 else if (data_size == sizeof(hp_host_info_rev0_t))
2344 cim_rev = 0;
2345 else
2346 return -EFAULT;
2347
2348 if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) {
2349 printk(KERN_ERR MYNAM "%s@%d::mptctl_hp_host_info - "
2350 "Unable to read in hp_host_info struct @ %p\n",
2351 __FILE__, __LINE__, uarg);
2352 return -EFAULT;
2353 }
2354
2355 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": mptctl_hp_hostinfo called.\n",
2356 ioc->name));
2357
2358
2359
2360
2361 pdev = (struct pci_dev *) ioc->pcidev;
2362
2363 karg.vendor = pdev->vendor;
2364 karg.device = pdev->device;
2365 karg.subsystem_id = pdev->subsystem_device;
2366 karg.subsystem_vendor = pdev->subsystem_vendor;
2367 karg.devfn = pdev->devfn;
2368 karg.bus = pdev->bus->number;
2369
2370
2371
2372
2373 if (ioc->sh != NULL)
2374 karg.host_no = ioc->sh->host_no;
2375 else
2376 karg.host_no = -1;
2377
2378
2379 snprintf(karg.fw_version, sizeof(karg.fw_version),
2380 "%.2hhu.%.2hhu.%.2hhu.%.2hhu",
2381 ioc->facts.FWVersion.Struct.Major,
2382 ioc->facts.FWVersion.Struct.Minor,
2383 ioc->facts.FWVersion.Struct.Unit,
2384 ioc->facts.FWVersion.Struct.Dev);
2385
2386
2387
2388 hdr.PageVersion = 0;
2389 hdr.PageLength = 0;
2390 hdr.PageNumber = 0;
2391 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
2392 cfg.cfghdr.hdr = &hdr;
2393 cfg.physAddr = -1;
2394 cfg.pageAddr = 0;
2395 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2396 cfg.dir = 0;
2397 cfg.timeout = 10;
2398
2399 strncpy(karg.serial_number, " ", 24);
2400 if (mpt_config(ioc, &cfg) == 0) {
2401 if (cfg.cfghdr.hdr->PageLength > 0) {
2402
2403 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2404
2405 pbuf = dma_alloc_coherent(&ioc->pcidev->dev,
2406 hdr.PageLength * 4,
2407 &buf_dma, GFP_KERNEL);
2408 if (pbuf) {
2409 cfg.physAddr = buf_dma;
2410 if (mpt_config(ioc, &cfg) == 0) {
2411 ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf;
2412 if (strlen(pdata->BoardTracerNumber) > 1) {
2413 strlcpy(karg.serial_number,
2414 pdata->BoardTracerNumber, 24);
2415 }
2416 }
2417 dma_free_coherent(&ioc->pcidev->dev,
2418 hdr.PageLength * 4, pbuf,
2419 buf_dma);
2420 pbuf = NULL;
2421 }
2422 }
2423 }
2424 rc = mpt_GetIocState(ioc, 1);
2425 switch (rc) {
2426 case MPI_IOC_STATE_OPERATIONAL:
2427 karg.ioc_status = HP_STATUS_OK;
2428 break;
2429
2430 case MPI_IOC_STATE_FAULT:
2431 karg.ioc_status = HP_STATUS_FAILED;
2432 break;
2433
2434 case MPI_IOC_STATE_RESET:
2435 case MPI_IOC_STATE_READY:
2436 default:
2437 karg.ioc_status = HP_STATUS_OTHER;
2438 break;
2439 }
2440
2441 karg.base_io_addr = pci_resource_start(pdev, 0);
2442
2443 if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))
2444 karg.bus_phys_width = HP_BUS_WIDTH_UNK;
2445 else
2446 karg.bus_phys_width = HP_BUS_WIDTH_16;
2447
2448 karg.hard_resets = 0;
2449 karg.soft_resets = 0;
2450 karg.timeouts = 0;
2451 if (ioc->sh != NULL) {
2452 MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
2453
2454 if (hd && (cim_rev == 1)) {
2455 karg.hard_resets = ioc->hard_resets;
2456 karg.soft_resets = ioc->soft_resets;
2457 karg.timeouts = ioc->timeouts;
2458 }
2459 }
2460
2461
2462
2463
2464 if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) {
2465 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
2466 "%s, no msg frames!!\n", ioc->name, __func__));
2467 goto out;
2468 }
2469
2470 IstwiRWRequest = (ToolboxIstwiReadWriteRequest_t *)mf;
2471 msgcontext = IstwiRWRequest->MsgContext;
2472 memset(IstwiRWRequest,0,sizeof(ToolboxIstwiReadWriteRequest_t));
2473 IstwiRWRequest->MsgContext = msgcontext;
2474 IstwiRWRequest->Function = MPI_FUNCTION_TOOLBOX;
2475 IstwiRWRequest->Tool = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
2476 IstwiRWRequest->Flags = MPI_TB_ISTWI_FLAGS_READ;
2477 IstwiRWRequest->NumAddressBytes = 0x01;
2478 IstwiRWRequest->DataLength = cpu_to_le16(0x04);
2479 if (pdev->devfn & 1)
2480 IstwiRWRequest->DeviceAddr = 0xB2;
2481 else
2482 IstwiRWRequest->DeviceAddr = 0xB0;
2483
2484 pbuf = dma_alloc_coherent(&ioc->pcidev->dev, 4, &buf_dma, GFP_KERNEL);
2485 if (!pbuf)
2486 goto out;
2487 ioc->add_sge((char *)&IstwiRWRequest->SGL,
2488 (MPT_SGE_FLAGS_SSIMPLE_READ|4), buf_dma);
2489
2490 SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context,
2491 IstwiRWRequest->MsgContext);
2492 INITIALIZE_MGMT_STATUS(ioc->ioctl_cmds.status)
2493 mpt_put_msg_frame(mptctl_id, ioc, mf);
2494
2495 retry_wait:
2496 timeleft = wait_for_completion_timeout(&ioc->ioctl_cmds.done,
2497 HZ*MPT_IOCTL_DEFAULT_TIMEOUT);
2498 if (!(ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2499 printk(MYIOC_s_WARN_FMT "%s: failed\n", ioc->name, __func__);
2500 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
2501 mpt_free_msg_frame(ioc, mf);
2502 goto out;
2503 }
2504 if (!timeleft) {
2505 printk(MYIOC_s_WARN_FMT
2506 "HOST INFO command timeout, doorbell=0x%08x\n",
2507 ioc->name, mpt_GetIocState(ioc, 0));
2508 mptctl_timeout_expired(ioc, mf);
2509 } else
2510 goto retry_wait;
2511 goto out;
2512 }
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_RF_VALID)
2524 karg.rsvd = *(u32 *)pbuf;
2525
2526 out:
2527 CLEAR_MGMT_STATUS(ioc->ioctl_cmds.status)
2528 SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, 0);
2529
2530 if (pbuf)
2531 dma_free_coherent(&ioc->pcidev->dev, 4, pbuf, buf_dma);
2532
2533
2534
2535 if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) {
2536 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_hpgethostinfo - "
2537 "Unable to write out hp_host_info @ %p\n",
2538 ioc->name, __FILE__, __LINE__, uarg);
2539 return -EFAULT;
2540 }
2541
2542 return 0;
2543
2544 }
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557 static int
2558 mptctl_hp_targetinfo(MPT_ADAPTER *ioc, unsigned long arg)
2559 {
2560 hp_target_info_t __user *uarg = (void __user *) arg;
2561 SCSIDevicePage0_t *pg0_alloc;
2562 SCSIDevicePage3_t *pg3_alloc;
2563 MPT_SCSI_HOST *hd = NULL;
2564 hp_target_info_t karg;
2565 int data_sz;
2566 dma_addr_t page_dma;
2567 CONFIGPARMS cfg;
2568 ConfigPageHeader_t hdr;
2569 int tmp, np, rc = 0;
2570
2571 if (copy_from_user(&karg, uarg, sizeof(hp_target_info_t))) {
2572 printk(KERN_ERR MYNAM "%s@%d::mptctl_hp_targetinfo - "
2573 "Unable to read in hp_host_targetinfo struct @ %p\n",
2574 __FILE__, __LINE__, uarg);
2575 return -EFAULT;
2576 }
2577
2578 if (karg.hdr.id >= MPT_MAX_FC_DEVICES)
2579 return -EINVAL;
2580 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_hp_targetinfo called.\n",
2581 ioc->name));
2582
2583
2584
2585 if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))
2586 return 0;
2587
2588 if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL))
2589 return 0;
2590
2591 if (ioc->sh->host_no != karg.hdr.host)
2592 return -ENODEV;
2593
2594
2595
2596 data_sz = ioc->spi_data.sdp0length * 4;
2597 pg0_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz, &page_dma,
2598 GFP_KERNEL);
2599 if (pg0_alloc) {
2600 hdr.PageVersion = ioc->spi_data.sdp0version;
2601 hdr.PageLength = data_sz;
2602 hdr.PageNumber = 0;
2603 hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
2604
2605 cfg.cfghdr.hdr = &hdr;
2606 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2607 cfg.dir = 0;
2608 cfg.timeout = 0;
2609 cfg.physAddr = page_dma;
2610
2611 cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
2612
2613 if ((rc = mpt_config(ioc, &cfg)) == 0) {
2614 np = le32_to_cpu(pg0_alloc->NegotiatedParameters);
2615 karg.negotiated_width = np & MPI_SCSIDEVPAGE0_NP_WIDE ?
2616 HP_BUS_WIDTH_16 : HP_BUS_WIDTH_8;
2617
2618 if (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) {
2619 tmp = (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
2620 if (tmp < 0x09)
2621 karg.negotiated_speed = HP_DEV_SPEED_ULTRA320;
2622 else if (tmp <= 0x09)
2623 karg.negotiated_speed = HP_DEV_SPEED_ULTRA160;
2624 else if (tmp <= 0x0A)
2625 karg.negotiated_speed = HP_DEV_SPEED_ULTRA2;
2626 else if (tmp <= 0x0C)
2627 karg.negotiated_speed = HP_DEV_SPEED_ULTRA;
2628 else if (tmp <= 0x25)
2629 karg.negotiated_speed = HP_DEV_SPEED_FAST;
2630 else
2631 karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
2632 } else
2633 karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
2634 }
2635
2636 dma_free_coherent(&ioc->pcidev->dev, data_sz, (u8 *)pg0_alloc,
2637 page_dma);
2638 }
2639
2640
2641
2642 karg.message_rejects = -1;
2643 karg.phase_errors = -1;
2644 karg.parity_errors = -1;
2645 karg.select_timeouts = -1;
2646
2647
2648
2649 hdr.PageVersion = 0;
2650 hdr.PageLength = 0;
2651 hdr.PageNumber = 3;
2652 hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
2653
2654 cfg.cfghdr.hdr = &hdr;
2655 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2656 cfg.dir = 0;
2657 cfg.timeout = 0;
2658 cfg.physAddr = -1;
2659 if ((mpt_config(ioc, &cfg) == 0) && (cfg.cfghdr.hdr->PageLength > 0)) {
2660
2661 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2662 data_sz = (int) cfg.cfghdr.hdr->PageLength * 4;
2663 pg3_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz,
2664 &page_dma, GFP_KERNEL);
2665 if (pg3_alloc) {
2666 cfg.physAddr = page_dma;
2667 cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
2668 if ((rc = mpt_config(ioc, &cfg)) == 0) {
2669 karg.message_rejects = (u32) le16_to_cpu(pg3_alloc->MsgRejectCount);
2670 karg.phase_errors = (u32) le16_to_cpu(pg3_alloc->PhaseErrorCount);
2671 karg.parity_errors = (u32) le16_to_cpu(pg3_alloc->ParityErrorCount);
2672 }
2673 dma_free_coherent(&ioc->pcidev->dev, data_sz,
2674 (u8 *)pg3_alloc, page_dma);
2675 }
2676 }
2677 hd = shost_priv(ioc->sh);
2678 if (hd != NULL)
2679 karg.select_timeouts = hd->sel_timeout[karg.hdr.id];
2680
2681
2682
2683 if (copy_to_user((char __user *)arg, &karg, sizeof(hp_target_info_t))) {
2684 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_hp_target_info - "
2685 "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
2686 ioc->name, __FILE__, __LINE__, uarg);
2687 return -EFAULT;
2688 }
2689
2690 return 0;
2691 }
2692
2693
2694
2695 static const struct file_operations mptctl_fops = {
2696 .owner = THIS_MODULE,
2697 .llseek = no_llseek,
2698 .fasync = mptctl_fasync,
2699 .unlocked_ioctl = mptctl_ioctl,
2700 #ifdef CONFIG_COMPAT
2701 .compat_ioctl = compat_mpctl_ioctl,
2702 #endif
2703 };
2704
2705 static struct miscdevice mptctl_miscdev = {
2706 MPT_MINOR,
2707 MYNAM,
2708 &mptctl_fops
2709 };
2710
2711
2712
2713 #ifdef CONFIG_COMPAT
2714
2715 static int
2716 compat_mptfwxfer_ioctl(struct file *filp, unsigned int cmd,
2717 unsigned long arg)
2718 {
2719 struct mpt_fw_xfer32 kfw32;
2720 struct mpt_fw_xfer kfw;
2721 MPT_ADAPTER *iocp = NULL;
2722 int iocnum, iocnumX;
2723 int nonblock = (filp->f_flags & O_NONBLOCK);
2724 int ret;
2725
2726
2727 if (copy_from_user(&kfw32, (char __user *)arg, sizeof(kfw32)))
2728 return -EFAULT;
2729
2730
2731 iocnumX = kfw32.iocnum & 0xFF;
2732 if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
2733 (iocp == NULL)) {
2734 printk(KERN_DEBUG MYNAM "::compat_mptfwxfer_ioctl @%d - ioc%d not found!\n",
2735 __LINE__, iocnumX);
2736 return -ENODEV;
2737 }
2738
2739 if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
2740 return ret;
2741
2742 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "compat_mptfwxfer_ioctl() called\n",
2743 iocp->name));
2744 kfw.iocnum = iocnum;
2745 kfw.fwlen = kfw32.fwlen;
2746 kfw.bufp = compat_ptr(kfw32.bufp);
2747
2748 ret = mptctl_do_fw_download(iocp, kfw.bufp, kfw.fwlen);
2749
2750 mutex_unlock(&iocp->ioctl_cmds.mutex);
2751
2752 return ret;
2753 }
2754
2755 static int
2756 compat_mpt_command(struct file *filp, unsigned int cmd,
2757 unsigned long arg)
2758 {
2759 struct mpt_ioctl_command32 karg32;
2760 struct mpt_ioctl_command32 __user *uarg = (struct mpt_ioctl_command32 __user *) arg;
2761 struct mpt_ioctl_command karg;
2762 MPT_ADAPTER *iocp = NULL;
2763 int iocnum, iocnumX;
2764 int nonblock = (filp->f_flags & O_NONBLOCK);
2765 int ret;
2766
2767 if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32)))
2768 return -EFAULT;
2769
2770
2771 iocnumX = karg32.hdr.iocnum & 0xFF;
2772 if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
2773 (iocp == NULL)) {
2774 printk(KERN_DEBUG MYNAM "::compat_mpt_command @%d - ioc%d not found!\n",
2775 __LINE__, iocnumX);
2776 return -ENODEV;
2777 }
2778
2779 if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
2780 return ret;
2781
2782 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "compat_mpt_command() called\n",
2783 iocp->name));
2784
2785 karg.hdr.iocnum = karg32.hdr.iocnum;
2786 karg.hdr.port = karg32.hdr.port;
2787 karg.timeout = karg32.timeout;
2788 karg.maxReplyBytes = karg32.maxReplyBytes;
2789
2790 karg.dataInSize = karg32.dataInSize;
2791 karg.dataOutSize = karg32.dataOutSize;
2792 karg.maxSenseBytes = karg32.maxSenseBytes;
2793 karg.dataSgeOffset = karg32.dataSgeOffset;
2794
2795 karg.replyFrameBufPtr = (char __user *)(unsigned long)karg32.replyFrameBufPtr;
2796 karg.dataInBufPtr = (char __user *)(unsigned long)karg32.dataInBufPtr;
2797 karg.dataOutBufPtr = (char __user *)(unsigned long)karg32.dataOutBufPtr;
2798 karg.senseDataPtr = (char __user *)(unsigned long)karg32.senseDataPtr;
2799
2800
2801
2802 ret = mptctl_do_mpt_command (iocp, karg, &uarg->MF);
2803
2804 mutex_unlock(&iocp->ioctl_cmds.mutex);
2805
2806 return ret;
2807 }
2808
2809 static long compat_mpctl_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
2810 {
2811 long ret;
2812 mutex_lock(&mpctl_mutex);
2813 switch (cmd) {
2814 case MPTIOCINFO:
2815 case MPTIOCINFO1:
2816 case MPTIOCINFO2:
2817 case MPTTARGETINFO:
2818 case MPTEVENTQUERY:
2819 case MPTEVENTENABLE:
2820 case MPTEVENTREPORT:
2821 case MPTHARDRESET:
2822 case HP_GETHOSTINFO:
2823 case HP_GETTARGETINFO:
2824 case MPTTEST:
2825 ret = __mptctl_ioctl(f, cmd, arg);
2826 break;
2827 case MPTCOMMAND32:
2828 ret = compat_mpt_command(f, cmd, arg);
2829 break;
2830 case MPTFWDOWNLOAD32:
2831 ret = compat_mptfwxfer_ioctl(f, cmd, arg);
2832 break;
2833 default:
2834 ret = -ENOIOCTLCMD;
2835 break;
2836 }
2837 mutex_unlock(&mpctl_mutex);
2838 return ret;
2839 }
2840
2841 #endif
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853 static int
2854 mptctl_probe(struct pci_dev *pdev)
2855 {
2856 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2857
2858 mutex_init(&ioc->ioctl_cmds.mutex);
2859 init_completion(&ioc->ioctl_cmds.done);
2860 return 0;
2861 }
2862
2863
2864
2865
2866
2867
2868
2869
2870 static void
2871 mptctl_remove(struct pci_dev *pdev)
2872 {
2873 }
2874
2875 static struct mpt_pci_driver mptctl_driver = {
2876 .probe = mptctl_probe,
2877 .remove = mptctl_remove,
2878 };
2879
2880
2881 static int __init mptctl_init(void)
2882 {
2883 int err;
2884 int where = 1;
2885
2886 show_mptmod_ver(my_NAME, my_VERSION);
2887
2888 mpt_device_driver_register(&mptctl_driver, MPTCTL_DRIVER);
2889
2890
2891 err = misc_register(&mptctl_miscdev);
2892 if (err < 0) {
2893 printk(KERN_ERR MYNAM ": Can't register misc device [minor=%d].\n", MPT_MINOR);
2894 goto out_fail;
2895 }
2896 printk(KERN_INFO MYNAM ": Registered with Fusion MPT base driver\n");
2897 printk(KERN_INFO MYNAM ": /dev/%s @ (major,minor=%d,%d)\n",
2898 mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
2899
2900
2901
2902
2903 ++where;
2904 mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER,
2905 "mptctl_reply");
2906 if (!mptctl_id || mptctl_id >= MPT_MAX_PROTOCOL_DRIVERS) {
2907 printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
2908 misc_deregister(&mptctl_miscdev);
2909 err = -EBUSY;
2910 goto out_fail;
2911 }
2912
2913 mptctl_taskmgmt_id = mpt_register(mptctl_taskmgmt_reply, MPTCTL_DRIVER,
2914 "mptctl_taskmgmt_reply");
2915 if (!mptctl_taskmgmt_id || mptctl_taskmgmt_id >= MPT_MAX_PROTOCOL_DRIVERS) {
2916 printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
2917 mpt_deregister(mptctl_id);
2918 misc_deregister(&mptctl_miscdev);
2919 err = -EBUSY;
2920 goto out_fail;
2921 }
2922
2923 mpt_reset_register(mptctl_id, mptctl_ioc_reset);
2924 mpt_event_register(mptctl_id, mptctl_event_process);
2925
2926 return 0;
2927
2928 out_fail:
2929
2930 mpt_device_driver_deregister(MPTCTL_DRIVER);
2931
2932 return err;
2933 }
2934
2935
2936 static void mptctl_exit(void)
2937 {
2938 misc_deregister(&mptctl_miscdev);
2939 printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n",
2940 mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
2941
2942
2943 mpt_event_deregister(mptctl_id);
2944
2945
2946 mpt_reset_deregister(mptctl_id);
2947
2948
2949 mpt_deregister(mptctl_taskmgmt_id);
2950 mpt_deregister(mptctl_id);
2951
2952 mpt_device_driver_deregister(MPTCTL_DRIVER);
2953
2954 }
2955
2956
2957
2958 module_init(mptctl_init);
2959 module_exit(mptctl_exit);