linux_iface.c
来自「6440linuxDriver的源代码」· C语言 代码 · 共 641 行 · 第 1/2 页
C
641 行
if (inout == 1) { /* User write is not supported. */ return (-ENOSYS); } len = sprintf(pBuffer,"Marvell %s Driver , Version %s\n", mv_product_name, mv_version_linux); #ifdef RAID_DRIVER if (mv_proc_ld_info(pSHost) == -1) { len = sprintf(pBuffer, "Driver is busy, please try later.\n"); goto out; } else { for (i = 0; i < MAX_LD_SUPPORTED_PERFORMANCE; i++) { if (ldinfo[i].Status != LD_STATUS_INVALID) { if (ldinfo[i].Status == LD_STATUS_OFFLINE && ldinfo[i].BGAStatus == LD_BGA_STATE_RUNNING) { ldinfo[i].BGAStatus = LD_BGA_STATE_AUTOPAUSED; } if (ldinfo[i].Status == LD_STATUS_MISSING) { ldinfo[i].Status = LD_STATUS_OFFLINE; } } else { break; } } } len += sprintf(pBuffer+len,"Index RAID\tStatus \t\tBGA Status\n"); for (i = 0 ; i < LDINFO_NUM ; i++) { if (ldinfo[i].Size.value == 0) { if (i == 0) { len += sprintf(pBuffer+len,"NO Logical Disk\n"); } break; } len += sprintf(pBuffer+len, "%-5d %s\t%s", ldinfo[i].ID, mv_ld_raid_mode(ldinfo[i].RaidMode), mv_ld_status(ldinfo[i].Status) ); tmplen = 24 -strlen(mv_ld_status(ldinfo[i].Status)); while (j < tmplen) { len += sprintf(pBuffer+len, "%s", " "); j++; } j = 0; len += sprintf(pBuffer+len, "%s", mv_ld_bga_status(ldinfo[i].BGAStatus)); if (ldinfo[i].BGAStatus != LD_BGA_STATE_NONE) { ret = mv_ld_get_status(pSHost,ldinfo[i].ID,&ld_status); if (ret == 0) { if (ld_status.Status != LD_STATUS_INVALID) { if (ld_status.Status == LD_STATUS_MISSING) ld_status.Status = LD_STATUS_OFFLINE; ld_status.BgaState = ldinfo[i].BGAStatus; } len += mv_ld_show_status(pBuffer+len,&ld_status); ret = -1; } } tmp = NULL; tmplen = 0; len += sprintf(pBuffer+len,"\n"); }out:#endif datalen = len - offset; if (datalen < 0) { datalen = 0; *ppStart = pBuffer + len; } else { *ppStart = pBuffer + offset; } return datalen;} /* *Character Device Interface. */#ifdef RAID_DRIVERstatic int mv_open(struct inode *inode, struct file *file){ unsigned int minor_number; int retval = -ENODEV; unsigned long flags = 0; spin_lock_irqsave(&inode->i_lock, flags); minor_number = MINOR(inode->i_rdev); if (minor_number >= __mv_get_adapter_count()) { printk("MV : No such device.\n"); goto out; } retval = 0;out: spin_unlock_irqrestore(&inode->i_lock, flags); return retval;}static dev_t _mv_major;int mv_register_chdev(struct hba_extension *hba){ int ret = 0; dev_t num; /* * look for already-allocated major number first, if not found or * fail to register, try allocate one . * */ if (_mv_major) ret = register_chrdev_region(MKDEV(_mv_major, hba->desc->hba_desc->id), 1, MV_DEVFS_NAME); if (ret || !_mv_major) { ret = alloc_chrdev_region(&num, hba->desc->hba_desc->id, 1, MV_DEVFS_NAME); if (ret) return ret; else _mv_major = MAJOR(num); } memset(&hba->cdev, 0, sizeof(struct cdev)); cdev_init(&hba->cdev, &mv_fops); hba->cdev.owner = THIS_MODULE; hba->desc->hba_desc->dev_no = num; MV_DBG(DMSG_KERN, "registered chrdev (%d, %d).\n", MAJOR(num), MINOR(num)); ret = cdev_add(&hba->cdev, num, 1); return ret;}void mv_unregister_chdev(struct hba_extension *hba){ cdev_del(&hba->cdev); unregister_chrdev_region(hba->desc->hba_desc->dev_no, 1);}#ifdef HAVE_UNLOCKED_IOCTLstatic long mv_ioctl(struct file *file, unsigned int cmd, unsigned long arg)#elsestatic int mv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)#endif /* HAVE_UNLOCKED_IOCTL */ { struct hba_extension *hba; PMV_Request req = NULL; int error = 0; int ret = 0; int sptdwb_size = sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER); int console_id = VIRTUAL_DEVICE_ID; unsigned long flags; PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER psptdwb = NULL; int mv_device_count;#ifdef HAVE_UNLOCKED_IOCTL hba = container_of(file->f_dentry->d_inode->i_cdev, struct hba_extension, cdev);#else hba = container_of(inode->i_cdev, struct hba_extension, cdev);#endif /* HAVE_UNLOCKED_IOCTL */ mv_device_count = __mv_get_adapter_count(); if (cmd == 1) { if (copy_to_user((void *)arg, (void *)&console_id, sizeof(int)) != 0 ) { MV_DBG(DMSG_IOCTL, "Marvell : Get VIRTUAL_DEVICE_ID Error.\n"); return -EIO; } return 0; } if (cmd == 2) { if (copy_to_user((void *)arg, (void *)&mv_device_count, sizeof(unsigned int)) != 0) { MV_DBG(DMSG_IOCTL, "Marvell : Get Device Number Error.\n"); return -EIO; } return 0; } psptdwb = kmalloc(sptdwb_size, GFP_ATOMIC); if ( NULL == psptdwb ) return -ENOMEM; error = copy_from_user(psptdwb, (void *)arg, sptdwb_size); if (error) { ret = -EIO; goto clean_psp; } if (psptdwb->sptd.DataTransferLength) { if (psptdwb->sptd.DataTransferLength > IOCTL_BUF_LEN) { MV_DBG(DMSG_IOCTL, "__MV__ not enough buf space.\n"); ret = -ENOMEM; goto clean_psp; } psptdwb->sptd.DataBuffer = ioctl_buf; memset(ioctl_buf, 0, psptdwb->sptd.DataTransferLength); error = copy_from_user( psptdwb->sptd.DataBuffer, ((PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER)arg)->sptd.DataBuffer, psptdwb->sptd.DataTransferLength); if (error) { ret = -EIO; goto clean_pspbuf; } } else { psptdwb->sptd.DataBuffer = NULL; } /*Translate request to MV_REQUEST*/ req = res_get_req_from_pool(hba->req_pool); if (NULL == req) { ret = -ENOMEM; goto clean_pspbuf; } req->Cmd_Initiator = hba; req->Org_Req = req; req->Scsi_Status = psptdwb->sptd.ScsiStatus; req->Device_Id = psptdwb->sptd.TargetId; req->Cmd_Flag = 0; req->Req_Type = REQ_TYPE_INTERNAL; if (psptdwb->sptd.DataTransferLength == 0) { req->Cmd_Flag |= CMD_FLAG_NON_DATA; } else { if (SCSI_IS_READ(psptdwb->sptd.Cdb[0])) req->Cmd_Flag |= CMD_FLAG_DATA_IN; if (SCSI_IS_READ(psptdwb->sptd.Cdb[0]) || SCSI_IS_WRITE(psptdwb->sptd.Cdb[0])) req->Cmd_Flag |= CMD_FLAG_DMA; } req->Data_Transfer_Length = psptdwb->sptd.DataTransferLength; req->Data_Buffer = psptdwb->sptd.DataBuffer; req->Sense_Info_Buffer = psptdwb->Sense_Buffer; SGTable_Init(&req->SG_Table, 0); memcpy(req->Cdb, psptdwb->sptd.Cdb, MAX_CDB_SIZE); memset(req->Context, 0, sizeof(MV_PVOID)*MAX_POSSIBLE_MODULE_NUMBER); req->LBA.value = 0; req->Sector_Count = 0; req->Completion = ioctlcallback; spin_lock_irqsave(&hba->irq_lock, flags); hba->Io_Count++;#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) atomic_set(&hba->hba_sync, 1);#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) */ hba->desc->ops->module_sendrequest(hba->desc->extension, req); spin_unlock_irqrestore(&hba->irq_lock, flags);#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) if (!__hba_wait_for_atomic_timeout(&hba->hba_sync, HBA_REQ_TIMER_IOCTL*HZ)) {#else if (!wait_for_completion_timeout(&hba->cmpl, HBA_REQ_TIMER_IOCTL*HZ)) {#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) */ MV_DBG(DMSG_HBA, "__MV__ ioctl req timed out.\n"); ret = -EIO; goto clean_pspbuf; } if (psptdwb->sptd.DataTransferLength) { error = copy_to_user(((PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER)arg)->sptd.DataBuffer, psptdwb->sptd.DataBuffer, psptdwb->sptd.DataTransferLength); if (error) { ret = -EIO; goto clean_pspbuf; } } error = copy_to_user((void*)arg, psptdwb, sptdwb_size); if (error) { ret = -EIO; goto clean_pspbuf; } if (req->Scsi_Status) ret = req->Scsi_Status;clean_pspbuf:/* use static buf instead.*/clean_psp: kfree(psptdwb); return ret;}#else /* RAID_DRIVER */inline int mv_register_chdev(struct hba_extension *hba) {return 0;}inline void mv_unregister_chdev(struct hba_extension *hba) {}#endif /* RAID_DRIVER */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?