📄 rhel3.patch
字号:
+ spin_lock_init(&instance->ioctl_memory_pool_lock); spin_lock_init(&instance->completion_lock); sema_init(&instance->aen_mutex, 1); sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS); + /** + for-ioctl: initialize ioctl memory list and memory lock + **/++ for (i=0; i<MAX_IOCTL_MEM_POOL; i++) {+ INIT_LIST_HEAD(&instance->ioctl_memory_pool[i]);+ }++ if(megasas_setup_mem_pools(instance))+ instance->mem_pool_empty=1;+ + /* end for-ioctl */+ /* * Initialize PCI related and misc parameters */@@ -2635,8 +2808,8 @@ megasas_probe_one(struct pci_dev *pdev, instance->init_id = MEGASAS_DEFAULT_INIT_ID; megasas_dbg_lvl = 0;- instance->flag = 0;- instance->last_time = 0;+ instance->is_busy=0;+ instance->last_time=0; /* * Initialize MFI Firmware@@ -2647,7 +2820,7 @@ megasas_probe_one(struct pci_dev *pdev, /* * Register IRQ */- if (request_irq(pdev->irq, megasas_isr, IRQF_SHARED, "megasas", instance)) {+ if (request_irq(pdev->irq, megasas_isr, SA_SHIRQ, "megasas", instance)) { printk(KERN_DEBUG "megasas: Failed to register IRQ\n"); goto fail_irq; }@@ -2680,6 +2853,10 @@ megasas_probe_one(struct pci_dev *pdev, */ if (megasas_io_attach(instance)) goto fail_io_attach;+#if CONFIG_PROC_FS+ if (megasas_proc_hba_map)+ megasas_create_proc_entry(instance);+#endif return 0; @@ -2698,6 +2875,8 @@ megasas_probe_one(struct pci_dev *pdev, fail_irq: fail_init_mfi: fail_alloc_dma_buf:+ /* Free the ioctl mem pool */+ megasas_free_ioctl_mem_pools(instance); if (instance->evt_detail) pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), instance->evt_detail,@@ -2753,12 +2932,40 @@ static void megasas_flush_cache(struct m } /**+ * megasas_reboot_notify- Flush adapter cache+ * @this: Our notifier block+ * @code: The event notified+ * @unused: Unused+ */+static int+megasas_reboot_notify (struct notifier_block *this, unsigned long code,+ void *unused)+{+ struct megasas_instance *instance;+ int i;++ for (i = 0; i < megasas_mgmt_info.max_index; i++) {+ instance = megasas_mgmt_info.instance[i];+ if (instance) {+ megasas_flush_cache(instance);+ }+ }++ return NOTIFY_DONE;+}++/**+ * notifier block to get notification on system halt/reboot/shutdown/power off+ */+static struct notifier_block megasas_notifier = {+ .notifier_call = megasas_reboot_notify+};++/** * megasas_shutdown_controller - Instructs FW to shutdown the controller * @instance: Adapter soft state- * @opcode: Shutdown/Hibernate */-static void megasas_shutdown_controller(struct megasas_instance *instance,- u32 opcode)+static void megasas_shutdown_controller(struct megasas_instance *instance) { struct megasas_cmd *cmd; struct megasas_dcmd_frame *dcmd;@@ -2781,7 +2988,7 @@ static void megasas_shutdown_controller( dcmd->flags = MFI_FRAME_DIR_NONE; dcmd->timeout = 0; dcmd->data_xfer_len = 0;- dcmd->opcode = opcode;+ dcmd->opcode = MR_DCMD_CTRL_SHUTDOWN; megasas_issue_blocked_cmd(instance, cmd); @@ -2791,136 +2998,6 @@ static void megasas_shutdown_controller( } /**- * megasas_suspend - driver suspend entry point- * @pdev: PCI device structure- * @state: - */-static int __devinit-megasas_suspend(struct pci_dev *pdev, pm_message_t state)-{- struct Scsi_Host *host;- struct megasas_instance *instance;-- instance = pci_get_drvdata(pdev);- host = instance->host;-- megasas_flush_cache(instance);- megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN);- tasklet_kill(&instance->isr_tasklet);-- pci_set_drvdata(instance->pdev, instance); - instance->instancet->disable_intr(instance->reg_set);- free_irq(instance->pdev->irq, instance);-- scsi_host_put(host);-- pci_save_state(pdev);- pci_disable_device(pdev);-- pci_set_power_state(pdev, pci_choose_state(pdev, state));-- return 0;-}--/**- * megasas_resume- driver resume entry point- * @pdev: PCI device structure- */-static int __devinit-megasas_resume(struct pci_dev *pdev)-{- int rval;- struct Scsi_Host *host;- struct megasas_instance *instance;- - instance = pci_get_drvdata(pdev);- host = instance->host;- pci_set_power_state(pdev, PCI_D0);- pci_enable_wake(pdev, PCI_D0, 0);- pci_restore_state(pdev);-- /*- * PCI prepping: enable device set bus mastering and dma mask- */- rval = pci_enable_device(pdev);-- if (rval) {- printk(KERN_INFO "megasas: Enable device failed\n");- return rval;- }-- pci_set_master(pdev);-- if (megasas_set_dma_mask(pdev))- goto fail_set_dma_mask;-- /*- * Initialize MFI Firmware- */-- *instance->producer = 0;- *instance->consumer = 0;-- atomic_set(&instance->fw_outstanding,0);-- /*- * We expect the FW state to be READY- */- if (megasas_transition_to_ready(instance))- goto fail_ready_state;-- if (megasas_issue_init_mfi(instance))- goto fail_init_mfi;-- tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc,- (unsigned long)instance); - /*- * Register IRQ- */- if (request_irq(pdev->irq, megasas_isr, IRQF_SHARED,- "megasas",instance)) {- printk(KERN_DEBUG "megasas: Failed to register IRQ\n");- goto fail_irq;- }-- instance->instancet->enable_intr(instance->reg_set);-- /*- * Store instance in PCI softstate- */- pci_set_drvdata(pdev, instance);-- /*- * Initiate AEN (Asynchronous Event Notification)- */- if (megasas_start_aen(instance))- printk(KERN_ERR "megasas: Start AEN failed\n");- - return 0; - - fail_irq:- fail_init_mfi:-- if (instance->evt_detail)- pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),- instance->evt_detail,- instance->evt_detail_h);-- if (instance->producer)- pci_free_consistent(pdev, sizeof(u32), instance->producer,- instance->producer_h);- if (instance->consumer)- pci_free_consistent(pdev, sizeof(u32), instance->consumer,- instance->consumer_h);- scsi_host_put(host);- fail_set_dma_mask:- fail_ready_state:- pci_disable_device(pdev);-- return -ENODEV;-}--/** * megasas_detach_one - PCI hot"un"plug entry point * @pdev: PCI device structure */@@ -2932,12 +3009,14 @@ static void megasas_detach_one(struct pc instance = pci_get_drvdata(pdev); host = instance->host;+#if CONFIG_PROC_FS+ if (megasas_proc_root && instance->hba_proc_dir)+ megasas_remove_proc_entry(instance);+#endif - sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_max_sectors_attr); scsi_remove_host(instance->host); megasas_flush_cache(instance);- megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);- tasklet_kill(&instance->isr_tasklet);+ megasas_shutdown_controller(instance); /* * Take the instance off the instance array. Note that we will not@@ -2960,6 +3039,9 @@ static void megasas_detach_one(struct pc megasas_release_mfi(instance); + /* Free IOCTL mem pool */+ megasas_free_ioctl_mem_pools(instance); + pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), instance->evt_detail, instance->evt_detail_h); @@ -2979,16 +3061,6 @@ static void megasas_detach_one(struct pc } /**- * megasas_shutdown - Shutdown entry point- * @device: Generic device structure- */-static void megasas_shutdown(struct pci_dev *pdev)-{- struct megasas_instance *instance = pci_get_drvdata(pdev);- megasas_flush_cache(instance);-}--/** * megasas_mgmt_open - char node "open" entry point */ static int megasas_mgmt_open(struct inode *inode, struct file *filep)@@ -3023,11 +3095,11 @@ static int megasas_mgmt_fasync(int fd, s { int rc; - mutex_lock(&megasas_async_queue_mutex);+ down(&megasas_async_queue_mutex); rc = fasync_helper(fd, filep, mode, &megasas_async_queue); - mutex_unlock(&megasas_async_queue_mutex);+ up(&megasas_async_queue_mutex); if (rc >= 0) { /* For sanity check when we get ioctl */@@ -3043,14 +3115,14 @@ static int megasas_mgmt_fasync(int fd, s /** * megasas_mgmt_fw_ioctl - Issues management ioctls to FW * @instance: Adapter soft state- * @argp: User's ioctl packet+ * @ioc: Kernel virtual address ioctl packet */ static int megasas_mgmt_fw_ioctl(struct megasas_instance *instance,- struct megasas_iocpacket __user * user_ioc, struct megasas_iocpacket *ioc) { struct megasas_sge32 *kern_sge32;+ struct megasas_ioctl_mm *ioctl_mem = NULL; struct megasas_cmd *cmd; void *kbuff_arr[MAX_IOCTL_SGE]; dma_addr_t buf_handle = 0;@@ -3059,6 +3131,7 @@ megasas_mgmt_fw_ioctl(struct megasas_ins dma_addr_t sense_handle; u32 *sense_ptr; unsigned long *sense_buff;+ u8 from_pool=0; memset(kbuff_arr, 0, sizeof(kbuff_arr)); @@ -3095,17 +3168,29 @@ megasas_mgmt_fw_ioctl(struct megasas_ins ((unsigned long)cmd->frame + ioc->sgl_off); /*+ * Check if we have buffer to use from our mem_pool+ * If we donot have then try to allocate new buffer+ */+ if(!megasas_get_buff_for_sge(ioc,instance,cmd))+ from_pool=1;++ /* * For each user buffer, create a mirror buffer and copy in */ for (i = 0; i < ioc->sge_count; i++) {- kbuff_arr[i] = dma_alloc_coherent(&instance->pdev->dev,+ if (from_pool) {+ kbuff_arr[i] = cmd->ioctl_mem[i]->vaddr;+ buf_handle = cmd->ioctl_mem[i]->buf_handle;+ } else {+ kbuff_arr[i] = pci_alloc_consistent(instance->pdev, ioc->sgl[i].iov_len,- &buf_handle, GFP_KERNEL);- if (!kbuff_arr[i]) {- printk(KERN_DEBUG "megasas: Failed to alloc "- "kernel SGL buffer for IOCTL \n");- error = -ENOMEM;- goto out;+ &buf_handle);+ if (!kbuff_arr[i]) {+ printk(KERN_DEBUG "megasas: Failed to alloc "+ "kernel SGL buffer for IOCTL \n");+ error = -ENOMEM;+ goto out;+ } } /*@@ -3127,8 +3212,8 @@ megasas_mgmt_fw_ioctl(struct megasas_ins } if (ioc->sense_len) {- sense = dma_alloc_coherent(&instance->pdev->dev, ioc->sense_len,- &sense_handle, GFP_KERNEL);+ sense = pci_alloc_consistent(instance->pdev, ioc->sense_len,+ &sense_handle); if (!sense) { error = -ENOMEM; goto out;@@ -3166,16 +3251,17 @@ megasas_mgmt_fw_ioctl(struct megasas_ins * sense_buff points to the location that has the user * sense buffer address */- sense_buff = (unsigned long *) ((unsigned long)ioc->frame.raw ++ sense_buff = (unsigned long *) ((unsigned long)ioc->frame.raw + ioc->sense_off); sense_ptr = (u32 *) ((unsigned long)ioc->frame.raw + ioc->sense_off); #if defined(__ia64__) if (copy_to_user((void __user *)((unsigned long)(*sense_buff)),+ sense, ioc->sense_len)) { #else if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)),-#endif sense, ioc->sense_len)) {+#endif printk(KERN_ERR "megasas: Failed to copy out to user" "sense data\n"); error = -EFAULT;@@ -3186,28 +3272,50 @@ megasas_mgmt_fw_ioctl(struct megasas_ins /* * copy the status codes returned by the fw */- if (copy_to_user(&user_ioc->frame.hdr.cmd_status,- &cmd->frame->hdr.cmd_status, sizeof(u8))) {- printk(KERN_DEBUG "megasas: Error copying out cmd_status\n");- error = -EFAULT;- }+ ioc->frame.hdr.cmd_status = cmd->frame->hdr.cmd_status; out: if (sense) {- dma_free_coherent(&instance->pdev->dev, ioc->sense_len,+ pci_free_consistent(instance->pdev, ioc->sense_len, sense, sense_handle); }-+ for (i = 0; i < ioc->sge_count && kbuff_arr[i]; i++) {- dma_free_coherent(&instance->pdev->dev,- kern_sge32[i].length,- kbuff_arr[i], kern_sge32[i].phys_addr);++ if (from_pool) {+ /* Return to the mem pool */+ if ((struct megasas_ioctl_mm *)cmd->ioctl_mem[i]) {+ megasas_return_ioctl_mem(instance, + (struct megasas_ioctl_mm *)cmd->ioctl_mem[i], + cmd->ioctl_mem_pool_index[i]);+ cmd->ioctl_mem_pool_index[i]=0xff;+ cmd->ioctl_mem[i]=NULL;+ }+ } else {+ pci_free_consistent(instance->pdev,+ kern_sge32[i].length,+ kbuff_arr[i], kern_sge32[i].phys_addr);+ } } megasas_return_cmd(instance, cmd); return error; } +static struct megasas_instance *megasas_lookup_instance(u16 host_no)+{+ int i;++ for (i = 0; i < megasas_mgmt_info.max_index; i++) {++ if ((megasas_mgmt_info.instance[i]) &&+ (megasas_mgmt_info.instance[i]->host->host_no == host_no))+ return megasas_mgmt_info.instance[i];+ }++ return NULL;+}+ static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg) { struct megasas_iocpacket __user *user_ioc =@@ -3238,7 +3346,16 @@ static int megasas_mgmt_ioctl_fw(struct error = -ERESTARTSYS; goto out_kfree_ioc; }- error = megasas_mgmt_fw_ioctl(instance, user_ioc, ioc);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -