📄 mptctl.c
字号:
// 02000000 qtag = MPI_SCSIIO_CONTROL_SIMPLEQ; // 00000000 if (xferbytes == 0) { // Do 0-byte READ!!! // IMPORTANT! Need to set no SCSI DIR for this! scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER; } scsictl = scsidir | qtag; /* * Set sgdir for DMA transfer. */// sgdir = 0x04000000; // SCSI WRITE sgdir = 0x00000000; // SCSI READ if ((sgl = kbuf_alloc_2_sgl(MAX(512,xferbytes), sgdir, &numfrags, &buflist, &sgl_dma, iocp)) == NULL) return -ENOMEM; sgfragcpycnt = MIN(10,numfrags); nextchainoffset = 0; if (numfrags > 10) nextchainoffset = 0x1E; sbphys = SenseBufDMA; rwperf_reset = 0;// do { // target-loop blkno = SACRED_BLOCKS; // Treat first N blocks as sacred! // FIXME! Skip option blklo = blkno; blkhi = blkno; do { // inner-loop while ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) { mb(); schedule(); barrier(); } msg = (u32*)mf; /* Start piecing the SCSIIORequest together */ msg[0] = 0x00000000 | nextchainoffset<<16 | target; msg[1] = 0x0000FF0A; // 255 sense bytes, 10-byte CDB! msg[3] = lun << 8; msg[4] = 0; msg[5] = scsictl; // 16 bytes of CDB @ msg[6,7,8,9] are below... msg[6] = ( ((blkno & 0xFF000000) >> 8) | ((blkno & 0x00FF0000) << 8) | scsiop ); msg[7] = ( (((u32)kPerfInfo.nblks & 0x0000FF00) << 16) | ((blkno & 0x000000FF) << 8) | ((blkno & 0x0000FF00) >> 8) ); msg[8] = (kPerfInfo.nblks & 0x00FF); msg[9] = 0; msg[10] = xferbytes;// msg[11] = 0xD0000100;// msg[12] = sbphys;// msg[13] = 0; msg[11] = sbphys; // Copy the SGL... if (xferbytes) { sgOut = (SGESimple32_t*)&msg[12]; sgIn = sgl; for (i=0; i < sgfragcpycnt; i++) *sgOut++ = *sgIn++; } // fubar! QueueDepth issue!!! while ( !rwperf_reset && (DevIosCount[targetM][lunM] >= MIN(qdepth,64)) ) { mb(); schedule(); barrier(); }// blkno += kPerfInfo.nblks;// EXP Stuff!// Try optimizing to certain cache size for the target!// by keeping blkno within cache range if at all possible#if 0 if ( cache_sz && ((2 * kPerfInfo.nblks) <= (cache_sz>>9)) && ((blkno + kPerfInfo.nblks) > ((cache_sz>>9) + SACRED_BLOCKS)) ) blkno = SACRED_BLOCKS; else blkno += kPerfInfo.nblks;#endif// Ok, cheat! if (cache_sz && ((blkno + kPerfInfo.nblks) > ((cache_sz>>9) + SACRED_BLOCKS)) ) blkno = SACRED_BLOCKS; else blkno += kPerfInfo.nblks; if (blkno > blkhi) blkhi = blkno; DevIosCount[targetM][lunM]++; /* * Finally, post the request */ mpt_put_msg_frame(mptctl_id, ioc, mf); /* let linux breath! */ mb(); schedule(); barrier(); //dprintk((KERN_DEBUG MYNAM "-perf: inner-loop, cnt=%d\n", iters)); } while ((--iters > 0) && !rwperf_reset); dprintk((KERN_INFO MYNAM "-perf: DbG: blklo=%d, blkhi=%d\n", blklo, blkhi)); dprintk((KERN_INFO MYNAM "-perf: target-loop, thisTarget=%d\n", target));// // TEMPORARY!// target = 0;// } while (target); if (DevIosCount[targetM][lunM]) { dprintk((KERN_INFO " DbG: DevIosCount[%d][%d]=%d\n", targetM, lunM, DevIosCount[targetM][lunM])); } while (DevIosCount[targetM][lunM]) { //dprintk((KERN_DEBUG " DbG: Waiting... DevIosCount[%d][%d]=%d\n", // targetM, lunM, DevIosCount[targetM][lunM])); mb(); schedule(); barrier(); } DevInUse[targetM][lunM] = 0; pci_free_consistent(iocp->pcidev, 256, SenseBuf, SenseBufDMA); if (sgl) kfree_sgl(sgl, sgl_dma, buflist, iocp); dprintk((KERN_INFO " *** done ***\n")); return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/static intmpt_ioctl_rwperf_status(unsigned long arg){ struct mpt_raw_r_w kPerfInfo; /* NOTE: local copy, on stack==KERNEL_SPACE! */ MPT_ADAPTER *iocp; int ioc;// u8 targ;// u8 lun; int T, L; char *myname = "_rwperf_status()"; dprintk((KERN_INFO "%s - starting...\n", myname)); /* Get a pointer to the MPT adapter. */ if ((ioc = mpt_ioctl_rwperf_init(&kPerfInfo, arg, myname, &iocp)) < 0) return ioc; /* set perf parameters from input */// targ = kPerfInfo.target & 0xFF;// lun = kPerfInfo.lun & 0x1F; for (T=0; T < myMAX_TARGETS; T++) for (L=0; L < myMAX_LUNS; L++) if (DevIosCount[T][L]) { printk(KERN_INFO "%s: ioc%d->00:%02x:%02x" ", IosCnt=%d\n", myname, ioc, T, L, DevIosCount[T][L] ); } return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/static intmpt_ioctl_rwperf_reset(unsigned long arg){ struct mpt_raw_r_w kPerfInfo; /* NOTE: local copy, on stack==KERNEL_SPACE! */ MPT_ADAPTER *iocp; int ioc;// u8 targ;// u8 lun; int T, L; int i; char *myname = "_rwperf_reset()"; dprintk((KERN_INFO "%s - starting...\n", myname)); /* Get MPT adapter id. */ if ((ioc = mpt_ioctl_rwperf_init(&kPerfInfo, arg, myname, &iocp)) < 0) return ioc; /* set perf parameters from input */// targ = kPerfInfo.target & 0xFF;// lun = kPerfInfo.lun & 0x1F; rwperf_reset = 1; for (i=0; i < 1000000; i++) { mb(); schedule(); barrier(); } rwperf_reset = 0; for (T=0; T < myMAX_TARGETS; T++) for (L=0; L < myMAX_LUNS; L++) if (DevIosCount[T][L]) { printk(KERN_INFO "%s: ioc%d->00:%02x:%02x, " "IosCnt RESET! (from %d to 0)\n", myname, ioc, T, L, DevIosCount[T][L] ); DevIosCount[T][L] = 0; DevInUse[T][L] = 0; } return 0;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/static intmpt_ioctl_scsi_cmd(unsigned long arg){ return -ENOSYS;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,51)#define owner_THIS_MODULE owner: THIS_MODULE,#else#define owner_THIS_MODULE#endifstatic struct file_operations mptctl_fops = { owner_THIS_MODULE llseek: no_llseek, read: mptctl_read, write: mptctl_write, ioctl: mpt_ioctl, open: mptctl_open, release: mptctl_release,};static struct miscdevice mptctl_miscdev = { MPT_MINOR, MYNAM, &mptctl_fops};/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/#if defined(__sparc__) && defined(__sparc_v9__) /*{*//* The dynamic ioctl32 compat. registry only exists in >2.3.x sparc64 kernels */#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) /*{*/extern int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *));int unregister_ioctl32_conversion(unsigned int cmd);struct mpt_fw_xfer32 { unsigned int iocnum; unsigned int fwlen; u32 bufp;};#define MPTFWDOWNLOAD32 _IOWR(MPT_MAGIC_NUMBER,15,struct mpt_fw_xfer32)extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/static intsparc32_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *filp){ struct mpt_fw_xfer32 kfw32; struct mpt_fw_xfer kfw; MPT_ADAPTER *iocp = NULL; int iocnum, iocnumX; int nonblock = (filp->f_flags & O_NONBLOCK); int ret; dprintk((KERN_INFO MYNAM "::sparc32_mptfwxfer_ioctl() called\n")); if (copy_from_user(&kfw32, (char *)arg, sizeof(kfw32))) return -EFAULT; /* Verify intended MPT adapter */ iocnumX = kfw32.iocnum & 0xFF; if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) || (iocp == NULL)) { printk(KERN_ERR MYNAM "::sparc32_mptfwxfer_ioctl @%d - ioc%d not found!\n", __LINE__, iocnumX); return -ENODEV; } if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0) return ret; kfw.iocnum = iocnum; kfw.fwlen = kfw32.fwlen; kfw.bufp = (void *)(unsigned long)kfw32.bufp; ret = mpt_ioctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen); up(&mptctl_syscall_sem_ioc[iocp->id]); return ret;}#endif /*} linux >= 2.3.x */#endif /*} sparc *//*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/int __init mptctl_init(void){ int err; int i; int where = 1; show_mptmod_ver(my_NAME, my_VERSION); for (i=0; i<MPT_MAX_ADAPTERS; i++) { sema_init(&mptctl_syscall_sem_ioc[i], 1); }#if defined(__sparc__) && defined(__sparc_v9__) /*{*/#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) /*{*/ err = register_ioctl32_conversion(MPTRWPERF, NULL); if (++where && err) goto out_fail; err = register_ioctl32_conversion(MPTRWPERF_CHK, NULL); if (++where && err) goto out_fail; err = register_ioctl32_conversion(MPTRWPERF_RESET, NULL); if (++where && err) goto out_fail; err = register_ioctl32_conversion(MPTFWDOWNLOAD32, sparc32_mptfwxfer_ioctl); if (++where && err) goto out_fail;#endif /*} linux >= 2.3.x */#endif /*} sparc */ if (misc_register(&mptctl_miscdev) == -1) { printk(KERN_ERR MYNAM ": Can't register misc device [minor=%d].\n", MPT_MINOR); err = -EBUSY; goto out_fail; } printk(KERN_INFO MYNAM ": Registered with Fusion MPT base driver\n"); printk(KERN_INFO MYNAM ": /dev/%s @ (major,minor=%d,%d)\n", mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor); /* * Install our handler */ ++where; if ((mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER)) <= 0) { printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n"); misc_deregister(&mptctl_miscdev); err = -EBUSY; goto out_fail; } return 0;out_fail:#if defined(__sparc__) && defined(__sparc_v9__) /*{*/#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) /*{*/ printk(KERN_ERR MYNAM ": ERROR: Failed to register ioctl32_conversion!" " (%d:err=%d)\n", where, err); unregister_ioctl32_conversion(MPTRWPERF); unregister_ioctl32_conversion(MPTRWPERF_CHK); unregister_ioctl32_conversion(MPTRWPERF_RESET); unregister_ioctl32_conversion(MPTFWDOWNLOAD32);#endif /*} linux >= 2.3.x */#endif /*} sparc */ return err;}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/void mptctl_exit(void){#if defined(__sparc__) && defined(__sparc_v9__) /*{*/#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) /*{*/ unregister_ioctl32_conversion(MPTRWPERF); unregister_ioctl32_conversion(MPTRWPERF_CHK); unregister_ioctl32_conversion(MPTRWPERF_RESET); unregister_ioctl32_conversion(MPTFWDOWNLOAD32);#endif /*} linux >= 2.3.x */#endif /*} sparc */ misc_deregister(&mptctl_miscdev); printk(KERN_INFO MYNAM ": /dev/%s @ (major,minor=%d,%d)\n", mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor); printk(KERN_INFO MYNAM ": Deregistered from Fusion MPT base driver\n"); mpt_deregister(mptctl_id);}/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/module_init(mptctl_init);module_exit(mptctl_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -