cregit-Linux how code gets into the kernel

Release 4.14 drivers/message/fusion/mptctl.c

/*
 *  linux/drivers/message/fusion/mptctl.c
 *      mpt Ioctl driver.
 *      For use with LSI PCI chip/adapters
 *      running LSI Fusion MPT (Message Passing Technology) firmware.
 *
 *  Copyright (c) 1999-2008 LSI Corporation
 *  (mailto:DL-MPTFusionLinux@lsi.com)
 *
 */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; version 2 of the License.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    NO WARRANTY
    THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
    CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
    LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
    solely responsible for determining the appropriateness of using and
    distributing the Program and assumes all risks associated with its
    exercise of rights under this Agreement, including but not limited to
    the risks and costs of program errors, damage to or loss of data,
    programs or equipment, and unavailability or interruption of operations.

    DISCLAIMER OF LIABILITY
    NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
    USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
    HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/delay.h>	/* for mdelay */
#include <linux/miscdevice.h>
#include <linux/mutex.h>
#include <linux/compat.h>

#include <asm/io.h>
#include <linux/uaccess.h>

#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>


#define COPYRIGHT	"Copyright (c) 1999-2008 LSI Corporation"

#define MODULEAUTHOR	"LSI Corporation"
#include "mptbase.h"
#include "mptctl.h"

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/

#define my_NAME		"Fusion MPT misc device (ioctl) driver"

#define my_VERSION	MPT_LINUX_VERSION_COMMON

#define MYNAM		"mptctl"


MODULE_AUTHOR(MODULEAUTHOR);

MODULE_DESCRIPTION(my_NAME);
MODULE_LICENSE("GPL");

MODULE_VERSION(my_VERSION);

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/

static DEFINE_MUTEX(mpctl_mutex);

static u8 mptctl_id = MPT_MAX_PROTOCOL_DRIVERS;

static u8 mptctl_taskmgmt_id = MPT_MAX_PROTOCOL_DRIVERS;

static DECLARE_WAIT_QUEUE_HEAD ( mptctl_wait );

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/


struct buflist {
	
u8	*kptr;
	
int	 len;
};

/*
 * Function prototypes. Called from OS entry point mptctl_ioctl.
 * arg contents specific to function.
 */
static int mptctl_fw_download(unsigned long arg);
static int mptctl_getiocinfo(unsigned long arg, unsigned int cmd);
static int mptctl_gettargetinfo(unsigned long arg);
static int mptctl_readtest(unsigned long arg);
static int mptctl_mpt_command(unsigned long arg);
static int mptctl_eventquery(unsigned long arg);
static int mptctl_eventenable(unsigned long arg);
static int mptctl_eventreport(unsigned long arg);
static int mptctl_replace_fw(unsigned long arg);

static int mptctl_do_reset(unsigned long arg);
static int mptctl_hp_hostinfo(unsigned long arg, unsigned int cmd);
static int mptctl_hp_targetinfo(unsigned long arg);

static int  mptctl_probe(struct pci_dev *, const struct pci_device_id *);
static void mptctl_remove(struct pci_dev *);

#ifdef CONFIG_COMPAT
static long compat_mpctl_ioctl(struct file *f, unsigned cmd, unsigned long arg);
#endif
/*
 * Private function calls.
 */
static int mptctl_do_mpt_command(struct mpt_ioctl_command karg, void __user *mfPtr);
static int mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen);
static MptSge_t *kbuf_alloc_2_sgl(int bytes, u32 dir, int sge_offset, int *frags,
		struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc);
static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma,
		struct buflist *buflist, MPT_ADAPTER *ioc);

/*
 * Reset Handler cleanup function
 */
static int  mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);

/*
 * Event Handler function
 */
static int mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);

static struct fasync_struct *async_queue=NULL;

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
 * Scatter gather list (SGL) sizes and limits...
 */
//#define MAX_SCSI_FRAGS        9

#define MAX_FRAGS_SPILL1	9

#define MAX_FRAGS_SPILL2	15

#define FRAGS_PER_BUCKET	(MAX_FRAGS_SPILL2 + 1)

//#define MAX_CHAIN_FRAGS       64
//#define MAX_CHAIN_FRAGS       (15+15+15+16)

#define MAX_CHAIN_FRAGS		(4 * MAX_FRAGS_SPILL2 + 1)

//  Define max sg LIST bytes ( == (#frags + #chains) * 8 bytes each)
//  Works out to: 592d bytes!     (9+1)*8 + 4*(15+1)*8
//                  ^----------------- 80 + 512

#define MAX_SGL_BYTES		((MAX_FRAGS_SPILL1 + 1 + (4 * FRAGS_PER_BUCKET)) * 8)

/* linux only seems to ever give 128kB MAX contiguous (GFP_USER) mem bytes */

#define MAX_KMALLOC_SZ		(128*1024)


#define MPT_IOCTL_DEFAULT_TIMEOUT 10	
/* Default timeout value (seconds) */

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
 *      mptctl_syscall_down - Down the MPT adapter syscall semaphore.
 *      @ioc: Pointer to MPT adapter
 *      @nonblock: boolean, non-zero if O_NONBLOCK is set
 *
 *      All of the ioctl commands can potentially sleep, which is illegal
 *      with a spinlock held, thus we perform mutual exclusion here.
 *
 *      Returns negative errno on error, or zero for success.
 */

static inline int mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock) { int rc = 0; if (nonblock) { if (!mutex_trylock(&ioc->ioctl_cmds.mutex)) rc = -EAGAIN; } else { if (mutex_lock_interruptible(&ioc->ioctl_cmds.mutex)) rc = -ERESTARTSYS; } return rc; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds3248.48%125.00%
Pam Delaney2537.88%125.00%
Kashyap Desai69.09%125.00%
Christoph Hellwig34.55%125.00%
Total66100.00%4100.00%

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * This is the callback for any message we have posted. The message itself * will be returned to the message pool when we return from the IRQ * * This runs in irq context so be short and sweet. */
static int mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply) { char *sense_data; int req_index; int sz; if (!req) return 0; dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "completing mpi function " "(0x%02X), req=%p, reply=%p\n", ioc->name, req->u.hdr.Function, req, reply)); /* * Handling continuation of the same reply. Processing the first * reply, and eating the other replys that come later. */ if (ioc->ioctl_cmds.msg_context != req->u.hdr.MsgContext) goto out_continuation; ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD; if (!reply) goto out; ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_RF_VALID; sz = min(ioc->reply_sz, 4*reply->u.reply.MsgLength); memcpy(ioc->ioctl_cmds.reply, reply, sz); if (reply->u.reply.IOCStatus || reply->u.reply.IOCLogInfo) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "iocstatus (0x%04X), loginfo (0x%08X)\n", ioc->name, le16_to_cpu(reply->u.reply.IOCStatus), le32_to_cpu(reply->u.reply.IOCLogInfo))); if ((req->u.hdr.Function == MPI_FUNCTION_SCSI_IO_REQUEST) || (req->u.hdr.Function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { if (reply->u.sreply.SCSIStatus || reply->u.sreply.SCSIState) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "scsi_status (0x%02x), scsi_state (0x%02x), " "tag = (0x%04x), transfer_count (0x%08x)\n", ioc->name, reply->u.sreply.SCSIStatus, reply->u.sreply.SCSIState, le16_to_cpu(reply->u.sreply.TaskTag), le32_to_cpu(reply->u.sreply.TransferCount))); if (reply->u.sreply.SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) { sz = req->u.scsireq.SenseBufferLength; req_index = le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx); sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC)); memcpy(ioc->ioctl_cmds.sense, sense_data, sz); ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_SENSE_VALID; } } out: /* We are done, issue wake up */ if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_PENDING) { if (req->u.hdr.Function == MPI_FUNCTION_SCSI_TASK_MGMT) { mpt_clear_taskmgmt_in_progress_flag(ioc); ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING; complete(&ioc->ioctl_cmds.done); if (ioc->bus_type == SAS) ioc->schedule_target_reset(ioc); } else { ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING; complete(&ioc->ioctl_cmds.done); } } out_continuation: if (reply && (reply->u.reply.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) return 0; return 1; }

Contributors

PersonTokensPropCommitsCommitProp
Kashyap Desai18337.27%333.33%
Sathya Prakash M R13527.49%111.11%
Pam Delaney13327.09%111.11%
Linus Torvalds357.13%111.11%
James Bottomley51.02%333.33%
Total491100.00%9100.00%


static int mptctl_taskmgmt_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) { if (!mf) return 0; dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt completed (mf=%p, mr=%p)\n", ioc->name, mf, mr)); ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD; if (!mr) goto out; ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID; memcpy(ioc->taskmgmt_cmds.reply, mr, min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength)); out: if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) { mpt_clear_taskmgmt_in_progress_flag(ioc); ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING; complete(&ioc->taskmgmt_cmds.done); if (ioc->bus_type == SAS) ioc->schedule_target_reset(ioc); return 1; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Kashyap Desai13386.36%240.00%
Pam Delaney85.19%120.00%
Linus Torvalds74.55%120.00%
Sathya Prakash M R63.90%120.00%
Total154100.00%5100.00%


static int mptctl_do_taskmgmt(MPT_ADAPTER *ioc, u8 tm_type, u8 bus_id, u8 target_id) { MPT_FRAME_HDR *mf; SCSITaskMgmt_t *pScsiTm; SCSITaskMgmtReply_t *pScsiTmReply; int ii; int retval; unsigned long timeout; unsigned long time_count; u16 iocstatus; mutex_lock(&ioc->taskmgmt_cmds.mutex); if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) { mutex_unlock(&ioc->taskmgmt_cmds.mutex); return -EPERM; } retval = 0; mf = mpt_get_msg_frame(mptctl_taskmgmt_id, ioc); if (mf == NULL) { dtmprintk(ioc, printk(MYIOC_s_WARN_FMT "TaskMgmt, no msg frames!!\n", ioc->name)); mpt_clear_taskmgmt_in_progress_flag(ioc); retval = -ENOMEM; goto tm_done; } dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n", ioc->name, mf)); pScsiTm = (SCSITaskMgmt_t *) mf; memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t)); pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; pScsiTm->TaskType = tm_type; if ((tm_type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (ioc->bus_type == FC)) pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION; pScsiTm->TargetID = target_id; pScsiTm->Bus = bus_id; pScsiTm->ChainOffset = 0; pScsiTm->Reserved = 0; pScsiTm->Reserved1 = 0; pScsiTm->TaskMsgContext = 0; for (ii= 0; ii < 8; ii++) pScsiTm->LUN[ii] = 0; for (ii=0; ii < 7; ii++) pScsiTm->Reserved2[ii] = 0; switch (ioc->bus_type) { case FC: timeout = 40; break; case SAS: timeout = 30; break; case SPI: default: timeout = 10; break; } dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt type=%d timeout=%ld\n", ioc->name, tm_type, timeout)); INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status) time_count = jiffies; if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) && (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) mpt_put_msg_frame_hi_pri(mptctl_taskmgmt_id, ioc, mf); else { retval = mpt_send_handshake_request(mptctl_taskmgmt_id, ioc, sizeof(SCSITaskMgmt_t), (u32 *)pScsiTm, CAN_SLEEP); if (retval != 0) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "TaskMgmt send_handshake FAILED!" " (ioc %p, mf %p, rc=%d) \n", ioc->name, ioc, mf, retval)); mpt_free_msg_frame(ioc, mf); mpt_clear_taskmgmt_in_progress_flag(ioc); goto tm_done; } } /* Now wait for the command to complete */ ii = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done, timeout*HZ); if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) { dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt failed\n", ioc->name)); mpt_free_msg_frame(ioc, mf); mpt_clear_taskmgmt_in_progress_flag(ioc); if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) retval = 0; else retval = -1; /* return failure */ goto tm_done; } if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) { dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt failed\n", ioc->name)); retval = -1; /* return failure */ goto tm_done; } pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply; dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt fw_channel = %d, fw_id = %d, task_type=0x%02X, " "iocstatus=0x%04X\n\tloginfo=0x%08X, response_code=0x%02X, " "term_cmnds=%d\n", ioc->name, pScsiTmReply->Bus, pScsiTmReply->TargetID, tm_type, le16_to_cpu(pScsiTmReply->IOCStatus), le32_to_cpu(pScsiTmReply->IOCLogInfo), pScsiTmReply->ResponseCode, le32_to_cpu(pScsiTmReply->TerminationCount))); iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK; if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED || iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED || iocstatus == MPI_IOCSTATUS_SUCCESS) retval = 0; else { dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt failed\n", ioc->name)); retval = -1; /* return failure */ } tm_done: mutex_unlock(&ioc->taskmgmt_cmds.mutex); CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status) return retval; }

Contributors

PersonTokensPropCommitsCommitProp
Kashyap Desai40757.98%222.22%
Pam Delaney16423.36%111.11%
Sathya Prakash M R588.26%222.22%
Linus Torvalds334.70%111.11%
James Bottomley314.42%111.11%
Eric Moore91.28%222.22%
Total702100.00%9100.00%

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* mptctl_timeout_expired * * Expecting an interrupt, however timed out. * */
static void mptctl_timeout_expired(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) { unsigned long flags; int ret_val = -1; SCSIIORequest_t *scsi_req = (SCSIIORequest_t *) mf; u8 function = mf->u.hdr.Function; dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": %s\n", ioc->name, __func__)); if (mpt_fwfault_debug) mpt_halt_firmware(ioc); spin_lock_irqsave(&ioc->taskmgmt_lock, flags); if (ioc->ioc_reset_in_progress) { spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status) mpt_free_msg_frame(ioc, mf); return; } spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status) if (ioc->bus_type == SAS) { if (function == MPI_FUNCTION_SCSI_IO_REQUEST) ret_val = mptctl_do_taskmgmt(ioc, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, scsi_req->Bus, scsi_req->TargetID); else if (function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) ret_val = mptctl_do_taskmgmt(ioc, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, scsi_req->Bus, 0); if (!ret_val) return; } else { if ((function == MPI_FUNCTION_SCSI_IO_REQUEST) || (function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) ret_val = mptctl_do_taskmgmt(ioc, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, scsi_req->Bus, 0); if (!ret_val) return; } dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling Reset! \n", ioc->name)); mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); mpt_free_msg_frame(ioc, mf); }

Contributors

PersonTokensPropCommitsCommitProp
Kashyap Desai253100.00%1100.00%
Total253100.00%1100.00%

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* mptctl_ioc_reset * * Clean-up functionality. Used only if there has been a * reload of the FW due. * */
static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) { switch(reset_phase) { case MPT_IOC_SETUP_RESET: dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__)); break; case MPT_IOC_PRE_RESET: dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__)); break; case MPT_IOC_POST_RESET: dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__)); if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_PENDING) { ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_DID_IOCRESET; complete(&ioc->ioctl_cmds.done); } break; default: break; } return 1; }

Contributors

PersonTokensPropCommitsCommitProp
Kashyap Desai7664.96%228.57%
Pam Delaney1512.82%114.29%
Sathya Prakash M R119.40%114.29%
Linus Torvalds108.55%114.29%
James Bottomley54.27%228.57%
Total117100.00%7100.00%

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* ASYNC Event Notification Support */
static int mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) { u8 event; event = le32_to_cpu(pEvReply->Event) & 0xFF; dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s() called\n", ioc->name, __func__)); if(async_queue == NULL) return 1; /* Raise SIGIO for persistent events. * TODO - this define is not in MPI spec yet, * but they plan to set it to 0x21 */ if (event == 0x21 ) { ioc->aen_event_read_flag=1; dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Raised SIGIO to application\n", ioc->name)); devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Raised SIGIO to application\n", ioc->name)); kill_fasync(&async_queue, SIGIO, POLL_IN); return 1; } /* This flag is set after SIGIO was raised, and * remains set until the application has read * the event log via ioctl=MPTEVENTREPORT */ if(ioc->aen_event_read_flag) return 1; /* Signal only for the events that are * requested for by the application */ if (ioc->events && (ioc->eventTypes & ( 1 << event))) { ioc->aen_event_read_flag=1; dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Raised SIGIO to application\n", ioc->name)); devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Raised SIGIO to application\n", ioc->name)); kill_fasync(&async_queue, SIGIO, POLL_IN); } return 1; }

Contributors

PersonTokensPropCommitsCommitProp
Eric Moore14072.92%250.00%
Sathya Prakash M R5126.56%125.00%
Harvey Harrison10.52%125.00%
Total192100.00%4100.00%


static int mptctl_fasync(int fd, struct file *filep, int mode) { MPT_ADAPTER *ioc; int ret; mutex_lock(&mpctl_mutex); list_for_each_entry(ioc, &ioc_list, list) ioc->aen_event_read_flag=0; ret = fasync_helper(fd, filep, mode, &async_queue); mutex_unlock(&mpctl_mutex); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Eric Moore4770.15%133.33%
Arnd Bergmann1014.93%133.33%
Jonathan Corbet1014.93%133.33%
Total67100.00%3100.00%

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * MPT ioctl handler * cmd - specify the particular IOCTL command to be issued * arg - data specific to the command. Must not be null. */
static long __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { mpt_ioctl_header __user *uhdr = (void __user *) arg; mpt_ioctl_header khdr; int iocnum; unsigned iocnumX; int nonblock = (file->f_flags & O_NONBLOCK); int ret; MPT_ADAPTER *iocp = NULL; if (copy_from_user(&khdr, uhdr, sizeof(khdr))) { printk(KERN_ERR MYNAM "%s::mptctl_ioctl() @%d - " "Unable to copy mpt_ioctl_header data @ %p\n", __FILE__, __LINE__, uhdr); return -EFAULT; } ret = -ENXIO; /* (-6) No such device or address */ /* Verify intended MPT adapter - set iocnum and the adapter * pointer (iocp) */ iocnumX = khdr.iocnum & 0xFF; if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) || (iocp == NULL)) return -ENODEV; if (!iocp->active) { printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - Controller disabled.\n", __FILE__, __LINE__); return -EFAULT; } /* Handle those commands that are just returning * information stored in the driver. * These commands should never time out and are unaffected * by TM and FW reloads. */ if ((cmd & ~IOCSIZE_MASK) == (MPTIOCINFO & ~IOCSIZE_MASK)) { return mptctl_getiocinfo(arg, _IOC_SIZE(cmd)); } else if (cmd == MPTTARGETINFO) { return mptctl_gettargetinfo(arg); } else if (cmd == MPTTEST) { return mptctl_readtest(arg); } else if (cmd == MPTEVENTQUERY) { return mptctl_eventquery(arg); } else if (cmd == MPTEVENTENABLE) { return mptctl_eventenable(arg); } else if (cmd == MPTEVENTREPORT) { return mptctl_eventreport(arg); } else if (cmd == MPTFWREPLACE) { return mptctl_replace_fw(arg); } /* All of these commands require an interrupt or * are unknown/illegal. */ if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0) return ret; if (cmd == MPTFWDOWNLOAD) ret = mptctl_fw_download(arg); else if (cmd == MPTCOMMAND) ret = mptctl_mpt_command(arg); else if (cmd == MPTHARDRESET) ret = mptctl_do_reset(arg); else if ((cmd & ~IOCSIZE_MASK) == (HP_GETHOSTINFO & ~IOCSIZE_MASK)) ret = mptctl_hp_hostinfo(arg, _IOC_SIZE(cmd)); else if (cmd == HP_GETTARGETINFO) ret = mptctl_hp_targetinfo(arg); else ret = -EINVAL; mutex_unlock(&iocp->ioctl_cmds.mutex); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Pam Delaney30676.12%111.11%
Pamela Delaney4310.70%111.11%
James Bottomley194.73%111.11%
Alan Cox163.98%111.11%
Eric Moore92.24%111.11%
Kashyap Desai30.75%111.11%
Al Viro30.75%111.11%
Andi Kleen20.50%111.11%
Christoph Hellwig10.25%111.11%
Total402100.00%9100.00%


static long mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { long ret; mutex_lock(&mpctl_mutex); ret = __mptctl_ioctl(file, cmd, arg); mutex_unlock(&mpctl_mutex); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Andi Kleen3879.17%150.00%
Arnd Bergmann1020.83%150.00%
Total48100.00%2100.00%


static int mptctl_do_reset(unsigned long arg) { struct mpt_ioctl_diag_reset __user *urinfo = (void __user *) arg; struct mpt_ioctl_diag_reset krinfo;