/* Raise SIGIO for persistent events. *TODO-thisdefineisnotinMPIspecyet, *buttheyplantosetitto0x21
*/ 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); return1;
}
/* This flag is set after SIGIO was raised, and *remainssetuntiltheapplicationhasread *theeventlogviaioctl=MPTEVENTREPORT
*/ if(ioc->aen_event_read_flag) return1;
/* Signal only for the events that are *requestedforbytheapplication
*/ 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);
} return1;
}
staticint
mptctl_fasync(int fd, struct file *filep, int mode)
{
MPT_ADAPTER *ioc; int ret;
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 iocnumX and the adapter *pointer(iocp)
*/
iocnumX = khdr.iocnum & 0xFF; if ((mpt_verify_adapter(iocnumX, &iocp) < 0) || (iocp == NULL)) return -ENODEV;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* *SGEAllocationroutine * *Inputs:bytes-numberofbytestobetransferred *sgdir-datadirection *sge_offset-offset(inbytes)fromthestartoftherequest *frametothefirstSGE *ioc-pointertothemptadapter *Outputs:frags-numberofscattergatherelements *blp-pointtothebuflistpointer *sglbuf_dma-pointertothe(dma)sgl *Returns:Nulliffailes *pointertothe(virtual)sglifsuccessful.
*/ static MptSge_t *
kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags, struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc)
{
MptSge_t *sglbuf = NULL; /* pointer to array of SGE */ /* and chain buffers */ struct buflist *buflist = NULL; /* kernel routine */
MptSge_t *sgl; int numfrags = 0; int fragcnt = 0; int alloc_sz = min(bytes,MAX_KMALLOC_SZ); // avoid kernel warning msg! int bytes_allocd = 0; int this_alloc;
dma_addr_t pa; // phys addr int i, buflist_ent; int sg_spill = MAX_FRAGS_SPILL1; int dir;
if (bytes < 0) return NULL;
/* initialization */
*frags = 0;
*blp = NULL;
/* Allocate and initialize an array of kernel *structuresfortheSGelements.
*/
i = MAX_SGL_BYTES / 8;
buflist = kzalloc(i, GFP_USER); if (!buflist) return NULL;
buflist_ent = 0;
/* Allocate a single block of memory to store the sg elements and *thechainbuffers.Thecallingroutineisresponsiblefor *copyingthedatainthisarrayintothecorrectplaceinthe *requestandchainbuffers.
*/
sglbuf = dma_alloc_coherent(&ioc->pcidev->dev, MAX_SGL_BYTES,
sglbuf_dma, GFP_KERNEL); if (sglbuf == NULL) goto free_and_fail;
if (sgdir & 0x04000000)
dir = DMA_TO_DEVICE; else
dir = DMA_FROM_DEVICE;
/* Need to chain? */ if (fragcnt == sg_spill) {
printk(MYIOC_s_WARN_FMT "-SG: No can do - ""Chain required! :-(\n", ioc->name);
printk(MYIOC_s_WARN_FMT "(freeing %d frags)\n", ioc->name, numfrags); goto free_and_fail;
}
/* overflow check... */ if (numfrags*8 > MAX_SGL_BYTES){ /* GRRRRR... */
printk(MYIOC_s_WARN_FMT "-SG: No can do - " "too many SG frags! :-(\n", ioc->name);
printk(MYIOC_s_WARN_FMT "-SG: (freeing %d frags)\n",
ioc->name, numfrags); goto free_and_fail;
}
}
/* Last sge fixup: set LE+eol+eob bits */
sgl[-1].FlagsLength |= 0xC1000000;
/* Fill in the data and return the structure to the calling *program
*/ if (ioc->bus_type == SAS)
karg->adapterType = MPT_IOCTL_INTERFACE_SAS; elseif (ioc->bus_type == FC)
karg->adapterType = MPT_IOCTL_INTERFACE_FC; else
karg->adapterType = MPT_IOCTL_INTERFACE_SCSI;
if (karg->hdr.port > 1) {
kfree(karg); return -EINVAL;
}
port = karg->hdr.port;
if (cim_rev == 1) { /* Get the PCI bus, device, and function numbers for the IOC
*/
karg->pciInfo.u.bits.busNumber = pdev->bus->number;
karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
} elseif (cim_rev == 2) { /* Get the PCI bus, device, function and segment ID numbers
for the IOC */
karg->pciInfo.u.bits.busNumber = pdev->bus->number;
karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
karg->pciInfo.segmentID = pci_domain_nr(pdev->bus);
}
/* Get number of devices
*/
karg->numDevices = 0; if (ioc->sh) {
shost_for_each_device(sdev, ioc->sh) {
vdevice = sdev->hostdata; if (vdevice == NULL || vdevice->vtarget == NULL) continue; if (vdevice->vtarget->tflags &
MPT_TARGET_FLAGS_RAID_COMPONENT) continue;
karg->numDevices++;
}
}
/* Set the BIOS and FW Version
*/
karg->FWVersion = ioc->facts.FWVersion.Word;
karg->BIOSVersion = ioc->biosVersion;
/* Set the Version Strings.
*/
strscpy_pad(karg->driverVersion, MPT_LINUX_PACKAGE_NAME, sizeof(karg->driverVersion));
/* Copy the data from kernel memory to user memory
*/ if (copy_to_user((char __user *)arg, karg, data_size)) {
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - " "Unable to write out mpt_ioctl_iocinfo struct @ %p\n",
ioc->name, __FILE__, __LINE__, uarg);
kfree(karg); return -EFAULT;
}
kfree(karg); return0;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* *mptctl_gettargetinfo-Querythehostadapterfortargetinformation. *@arg:Userspaceargument * *Outputs:None. *Return:0ifsuccessful *-EFAULTifdataunavailable *-ENODEVifnosuchdevice/adapter
*/ staticint
mptctl_gettargetinfo (MPT_ADAPTER *ioc, unsignedlong arg)
{ struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg; struct mpt_ioctl_targetinfo karg;
VirtDevice *vdevice; char *pmem; int *pdata; int numDevices = 0; int lun; int maxWordsLeft; int numBytes; struct scsi_device *sdev;
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
printk(KERN_ERR MYNAM "%s@%d::mptctl_gettargetinfo - " "Unable to read in mpt_ioctl_targetinfo struct @ %p\n",
__FILE__, __LINE__, uarg); return -EFAULT;
}
if (maxWordsLeft <= 0) {
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n",
ioc->name, __FILE__, __LINE__); return -ENOMEM;
}
/* Fill in the data and return the structure to the calling *program
*/
/* struct mpt_ioctl_targetinfo does not contain sufficient space *forthetargetstructuressowhentheIOCTLiscalled,thereis *notsufficientstackspaceforthestructure.Allocatememory, *populatethememory,copybacktotheuser,thenfreememory. *targetInfoformat: *bits31-24:reserved *23-16:LUN *15-8:BusNumber *7-0:TargetID
*/
pmem = kzalloc(numBytes, GFP_KERNEL); if (!pmem) {
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n",
ioc->name, __FILE__, __LINE__); return -ENOMEM;
}
pdata = (int *) pmem;
/* Get number of devices
*/ if (ioc->sh){
shost_for_each_device(sdev, ioc->sh) { if (!maxWordsLeft) continue;
vdevice = sdev->hostdata; if (vdevice == NULL || vdevice->vtarget == NULL) continue; if (vdevice->vtarget->tflags &
MPT_TARGET_FLAGS_RAID_COMPONENT) continue;
lun = (vdevice->vtarget->raidVolume) ? 0x80 : vdevice->lun;
*pdata = (((u8)lun << 16) + (vdevice->vtarget->channel << 8) +
(vdevice->vtarget->id ));
pdata++;
numDevices++;
--maxWordsLeft;
}
}
karg.numDevices = numDevices;
/* Copy part of the data from kernel memory to user memory
*/ if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_targetinfo))) {
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo - " "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
ioc->name, __FILE__, __LINE__, uarg);
kfree(pmem); return -EFAULT;
}
/* Copy the remaining data from kernel memory to user memory
*/ if (copy_to_user(uarg->targetInfo, pmem, numBytes)) {
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo - " "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
ioc->name, __FILE__, __LINE__, pdata);
kfree(pmem); return -EFAULT;
}
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) {
printk(KERN_ERR MYNAM "%s@%d::mptctl_readtest - " "Unable to read in mpt_ioctl_test struct @ %p\n",
__FILE__, __LINE__, uarg); return -EFAULT;
}
dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_readtest called.\n",
ioc->name)); /* Fill in the data and return the structure to the calling *program
*/
/* Copy the data from kernel memory to user memory
*/ if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_test))) {
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_readtest - " "Unable to write out mpt_ioctl_test struct @ %p\n",
ioc->name, __FILE__, __LINE__, uarg); return -EFAULT;
}
/* Copy the data from kernel memory to user memory
*/ if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) {
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_eventquery - " "Unable to write out mpt_ioctl_eventquery struct @ %p\n",
ioc->name, __FILE__, __LINE__, uarg); return -EFAULT;
} return0;
}
/* If fewer than 1 event is requested, there must have *beensometypeoferror.
*/ if ((max < 1) || !ioc->events) return -ENODATA;
/* reset this flag so SIGIO can restart */
ioc->aen_event_read_flag=0;
/* Copy the data from kernel memory to user memory
*/
numBytes = max * sizeof(MPT_IOCTL_EVENTS); if (copy_to_user(uarg->eventData, ioc->events, numBytes)) {
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_eventreport - " "Unable to write out mpt_ioctl_eventreport struct @ %p\n",
ioc->name, __FILE__, __LINE__, ioc->events); return -EFAULT;
}
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
printk(KERN_ERR MYNAM "%s@%d::mptctl_replace_fw - " "Unable to read in mpt_ioctl_replace_fw struct @ %p\n",
__FILE__, __LINE__, uarg); return -EFAULT;
}
dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_replace_fw called.\n",
ioc->name)); /* If caching FW, Free the old FW image
*/ if (ioc->cached_fw == NULL) return0;
mpt_free_fw_memory(ioc);
/* Allocate memory for the new FW image
*/
newFwSize = ALIGN(karg.newImageSize, 4);
mpt_alloc_fw_memory(ioc, newFwSize); if (ioc->cached_fw == NULL) return -ENOMEM;
/* Copy the data from user memory to kernel space
*/ if (copy_from_user(ioc->cached_fw, uarg->newImage, newFwSize)) {
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_replace_fw - " "Unable to read in mpt_ioctl_replace_fw image " "@ %p\n", ioc->name, __FILE__, __LINE__, uarg);
mpt_free_fw_memory(ioc); return -EFAULT;
}
/* Verify that the final request frame will not be too large.
*/
sz = karg.dataSgeOffset * 4; if (karg.dataInSize > 0)
sz += ioc->SGE_size; if (karg.dataOutSize > 0)
sz += ioc->SGE_size;
if (sz > ioc->req_sz) {
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "Request frame too large (%d) maximum (%d)\n",
ioc->name, __FILE__, __LINE__, sz, ioc->req_sz); return -EFAULT;
}
/* Get a free request frame and save the message context.
*/ if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) return -EAGAIN;
/* Copy the request frame *Resetthesavedmessagecontext. *Requestframeinuserspace
*/ if (copy_from_user(mf, mfPtr, karg.dataSgeOffset * 4)) {
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "Unable to read MF from mpt_ioctl_command struct @ %p\n",
ioc->name, __FILE__, __LINE__, mfPtr);
function = -1;
rc = -EFAULT; goto done_free_mem;
}
hdr->MsgContext = cpu_to_le32(msgContext);
function = hdr->Function;
/* Verify that this request is allowed.
*/
dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sending mpi function (0x%02X), req=%p\n",
ioc->name, hdr->Function, mf));
switch (function) { case MPI_FUNCTION_IOC_FACTS: case MPI_FUNCTION_PORT_FACTS:
karg.dataOutSize = karg.dataInSize = 0; break;
case MPI_FUNCTION_FC_COMMON_TRANSPORT_SEND: case MPI_FUNCTION_FC_EX_LINK_SRVC_SEND: case MPI_FUNCTION_FW_UPLOAD: case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR: case MPI_FUNCTION_FW_DOWNLOAD: case MPI_FUNCTION_FC_PRIMITIVE_SEND: case MPI_FUNCTION_TOOLBOX: case MPI_FUNCTION_SAS_IO_UNIT_CONTROL: break;
case MPI_FUNCTION_SCSI_IO_REQUEST: if (ioc->sh) {
SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf; int qtag = MPI_SCSIIO_CONTROL_UNTAGGED; int scsidir = 0; int dataSize;
u32 id;
id = (ioc->devices_per_bus == 0) ? 256 : ioc->devices_per_bus; if (pScsiReq->TargetID > id) {
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "Target ID out of bounds. \n",
ioc->name, __FILE__, __LINE__);
rc = -ENODEV; goto done_free_mem;
}
if (pScsiReq->Bus >= ioc->number_of_buses) {
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "Target Bus out of bounds. \n",
ioc->name, __FILE__, __LINE__);
rc = -ENODEV; goto done_free_mem;
}
/* Have the IOCTL driver set the direction based *onthedataOutSize(orderingissuewithSparc).
*/ if (karg.dataOutSize > 0) {
scsidir = MPI_SCSIIO_CONTROL_WRITE;
dataSize = karg.dataOutSize;
} else {
scsidir = MPI_SCSIIO_CONTROL_READ;
dataSize = karg.dataInSize;
}
case MPI_FUNCTION_SMP_PASSTHROUGH: /* Check mf->PassthruFlags to determine if *transferisImmediateModeornot. *ImmediatemodereturnsdataintheReplyFrame. *Else,wearesendingrequestandresponsedata *intwoSGLsattheendofthemf.
*/ break;
case MPI_FUNCTION_SATA_PASSTHROUGH: if (!ioc->sh) {
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "SCSI driver is not loaded. \n",
ioc->name, __FILE__, __LINE__);
rc = -EFAULT; goto done_free_mem;
} break;
case MPI_FUNCTION_RAID_ACTION: /* Just add a SGE
*/ break;
case MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH: if (ioc->sh) {
SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf; int qtag = MPI_SCSIIO_CONTROL_SIMPLEQ; int scsidir = MPI_SCSIIO_CONTROL_READ; int dataSize;
/* Have the IOCTL driver set the direction based *onthedataOutSize(orderingissuewithSparc).
*/ if (karg.dataOutSize > 0) {
scsidir = MPI_SCSIIO_CONTROL_WRITE;
dataSize = karg.dataOutSize;
} else {
scsidir = MPI_SCSIIO_CONTROL_READ;
dataSize = karg.dataInSize;
}
/* Verify that all entries in the IOC INIT match *existingsetup(andinLEformat).
*/ if (sizeof(dma_addr_t) == sizeof(u64)) {
high_addr = cpu_to_le32((u32)((u64)ioc->req_frames_dma >> 32));
sense_high= cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
} else {
high_addr = 0;
sense_high= 0;
}
/* What to do with these??? CHECK ME!!! MPI_FUNCTION_FC_LINK_SRVC_BUF_POST MPI_FUNCTION_FC_LINK_SRVC_RSP MPI_FUNCTION_FC_ABORT MPI_FUNCTION_LAN_SEND MPI_FUNCTION_LAN_RECEIVE MPI_FUNCTION_LAN_RESET
*/
/* Add the SGL ( at most one data in SGE and one data out SGE ) *InthecaseoftwoSGE's-thedataout(write)willalways *preceedethedatain(read)SGE.psgListisusedtofreethe *allocatedmemory.
*/
psge = (char *) (((int *) mf) + karg.dataSgeOffset);
flagsLength = 0;
if (karg.dataOutSize > 0)
sgSize ++;
if (karg.dataInSize > 0)
sgSize ++;
if (sgSize > 0) {
/* Set up the dataOut memory allocation */ if (karg.dataOutSize > 0) { if (karg.dataInSize > 0) {
flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT |
MPI_SGE_FLAGS_END_OF_BUFFER |
MPI_SGE_FLAGS_DIRECTION)
<< MPI_SGE_FLAGS_SHIFT;
} else {
flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
}
flagsLength |= karg.dataOutSize;
bufOut.len = karg.dataOutSize;
bufOut.kptr = dma_alloc_coherent(&ioc->pcidev->dev,
bufOut.len,
&dma_addr_out, GFP_KERNEL);
if (bufOut.kptr == NULL) {
rc = -ENOMEM; goto done_free_mem;
} else { /* Set up this SGE. *CopytoMFandtosglbuf
*/
ioc->add_sge(psge, flagsLength, dma_addr_out);
psge += ioc->SGE_size;
/* Copy user data to kernel space.
*/ if (copy_from_user(bufOut.kptr,
karg.dataOutBufPtr,
bufOut.len)) {
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - Unable " "to read user data " "struct @ %p\n",
ioc->name, __FILE__, __LINE__,karg.dataOutBufPtr);
rc = -EFAULT; goto done_free_mem;
}
}
}
/* Now wait for the command to complete */
timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT;
retry_wait:
timeleft = wait_for_completion_timeout(&ioc->ioctl_cmds.done,
HZ*timeout); if (!(ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
rc = -ETIME;
dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: TIMED OUT!\n",
ioc->name, __func__)); if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) { if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
mutex_unlock(&ioc->taskmgmt_cmds.mutex); goto done_free_mem;
} if (!timeleft) {
printk(MYIOC_s_WARN_FMT "mpt cmd timeout, doorbell=0x%08x" " function=0x%x\n",
ioc->name, mpt_GetIocState(ioc, 0), function); if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
mutex_unlock(&ioc->taskmgmt_cmds.mutex);
mptctl_timeout_expired(ioc, mf);
mf = NULL;
} else goto retry_wait; goto done_free_mem;
}
if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
mutex_unlock(&ioc->taskmgmt_cmds.mutex);
mf = NULL;
/* If a valid reply frame, copy to the user. *Offset2:replylengthinU32's
*/ if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_RF_VALID) { if (karg.maxReplyBytes < ioc->reply_sz) {
sz = min(karg.maxReplyBytes, 4*ioc->ioctl_cmds.reply[2]);
} else {
sz = min(ioc->reply_sz, 4*ioc->ioctl_cmds.reply[2]);
} if (sz > 0) { if (copy_to_user(karg.replyFrameBufPtr,
ioc->ioctl_cmds.reply, sz)){
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "Unable to write out reply frame %p\n",
ioc->name, __FILE__, __LINE__, karg.replyFrameBufPtr);
rc = -ENODATA; goto done_free_mem;
}
}
}
/* If valid sense data, copy to user.
*/ if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_SENSE_VALID) {
sz = min(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE); if (sz > 0) { if (copy_to_user(karg.senseDataPtr,
ioc->ioctl_cmds.sense, sz)) {
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "Unable to write sense data to user %p\n",
ioc->name, __FILE__, __LINE__,
karg.senseDataPtr);
rc = -ENODATA; goto done_free_mem;
}
}
}
/* If the overall status is _GOOD and data in, copy data *touser.
*/ if ((ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD) &&
(karg.dataInSize > 0) && (bufIn.kptr)) {
if (copy_to_user(karg.dataInBufPtr,
bufIn.kptr, karg.dataInSize)) {
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - " "Unable to write data to user %p\n",
ioc->name, __FILE__, __LINE__,
karg.dataInBufPtr);
rc = -ENODATA;
}
}
/* Save the SCSI host no. if *SCSIdriverloaded
*/ if (ioc->sh != NULL)
karg.host_no = ioc->sh->host_no; else
karg.host_no = -1;
/* Reformat the fw_version into a string */
snprintf(karg.fw_version, sizeof(karg.fw_version), "%.2hhu.%.2hhu.%.2hhu.%.2hhu",
ioc->facts.FWVersion.Struct.Major,
ioc->facts.FWVersion.Struct.Minor,
ioc->facts.FWVersion.Struct.Unit,
ioc->facts.FWVersion.Struct.Dev);
/* Issue a config request to get the device serial number
*/
hdr.PageVersion = 0;
hdr.PageLength = 0;
hdr.PageNumber = 0;
hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
cfg.cfghdr.hdr = &hdr;
cfg.physAddr = -1;
cfg.pageAddr = 0;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
cfg.dir = 0; /* read */
cfg.timeout = 10;
strscpy_pad(karg.serial_number, " ", sizeof(karg.serial_number)); if (mpt_config(ioc, &cfg) == 0) { if (cfg.cfghdr.hdr->PageLength > 0) { /* Issue the second config page request */
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
if (pbuf)
dma_free_coherent(&ioc->pcidev->dev, 4, pbuf, buf_dma);
/* Copy the data from kernel memory to user memory
*/ if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) {
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_hpgethostinfo - " "Unable to write out hp_host_info @ %p\n",
ioc->name, __FILE__, __LINE__, uarg); return -EFAULT;
}
/* Copy the data from kernel memory to user memory
*/ if (copy_to_user((char __user *)arg, &karg, sizeof(hp_target_info_t))) {
printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_hp_target_info - " "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
ioc->name, __FILE__, __LINE__, uarg); return -EFAULT;
}
/* Pass new structure to do_mpt_command
*/
ret = mptctl_do_mpt_command (iocp, karg, &uarg->MF);
mutex_unlock(&iocp->ioctl_cmds.mutex);
return ret;
}
staticlong compat_mpctl_ioctl(struct file *f, unsignedint cmd, unsignedlong arg)
{ long ret;
mutex_lock(&mpctl_mutex); switch (cmd) { case MPTIOCINFO: case MPTIOCINFO1: case MPTIOCINFO2: case MPTTARGETINFO: case MPTEVENTQUERY: case MPTEVENTENABLE: case MPTEVENTREPORT: case MPTHARDRESET: case HP_GETHOSTINFO: case HP_GETTARGETINFO: case MPTTEST:
ret = __mptctl_ioctl(f, cmd, arg); break; case MPTCOMMAND32:
ret = compat_mpt_command(f, cmd, arg); break; case MPTFWDOWNLOAD32:
ret = compat_mptfwxfer_ioctl(f, cmd, arg); break; default:
ret = -ENOIOCTLCMD; break;
}
mutex_unlock(&mpctl_mutex); return ret;
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.112Bemerkung:
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-09-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.