📄 rhel3.patch
字号:
+ struct megasas_ioctl_mm *ioctl_mm = NULL; - init_frame = (struct megasas_init_frame *)cmd->frame;- initq_info = (struct megasas_init_queue_info *)- ((unsigned long)init_frame + 64);+ if(i >= MAX_IOCTL_MEM_POOL)+ goto out; - init_frame_h = cmd->frame_phys_addr;- initq_info_h = init_frame_h + 64;+ spin_lock_irqsave(&instance->ioctl_memory_pool_lock, flags); - context = init_frame->context;- memset(init_frame, 0, MEGAMFI_FRAME_SIZE);- memset(initq_info, 0, sizeof(struct megasas_init_queue_info));- init_frame->context = context;+ if (!list_empty(&instance->ioctl_memory_pool[i])) {+ ioctl_mm = list_entry((&instance->ioctl_memory_pool[i])->next,+ struct megasas_ioctl_mm, list);+ list_del_init(&ioctl_mm->list);+ } else + printk(KERN_ERR "megasas: ioctl memory pool empty!\n"); - initq_info->reply_queue_entries = instance->max_fw_cmds + 1;- initq_info->reply_queue_start_phys_addr_lo = instance->reply_queue_h;-- initq_info->producer_index_phys_addr_lo = instance->producer_h;- initq_info->consumer_index_phys_addr_lo = instance->consumer_h;+ spin_unlock_irqrestore(&instance->ioctl_memory_pool_lock, flags);+out:+ return ioctl_mm;+} - init_frame->cmd = MFI_CMD_INIT;- init_frame->cmd_status = 0xFF;- init_frame->queue_info_new_phys_addr_lo = initq_info_h; - init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info);+/**+ * megasas_return_ioctl_mm - Return a memory to ioctl memory pool+ * @instance: Adapter soft state+ * @megasas_ioctl_mm: ioctl mem block + * @i: mem_pool_index+ * + */+static inline void+megasas_return_ioctl_mem(struct megasas_instance *instance,+ struct megasas_ioctl_mm *ioctl_mm, u8 i)+{+ unsigned long flags;+ if(!ioctl_mm)+ {+ printk(KERN_DEBUG "megasas: Trying to return NULL to mem_pool\n");+ return;+ }+ spin_lock_irqsave(&instance->ioctl_memory_pool_lock, flags);+ list_add_tail(&ioctl_mm->list, &instance->ioctl_memory_pool[i]);+ spin_unlock_irqrestore(&instance->ioctl_memory_pool_lock, flags);+} - /*- * disable the intr before firing the init frame to FW - */ - instance->instancet->disable_intr(instance->reg_set);- - /*- * Issue the init frame in polled mode- */-- if (megasas_issue_polled(instance, cmd)) {- printk(KERN_DEBUG "megasas: Failed to init firmware\n");- megasas_return_cmd(instance, cmd);- goto fail_fw_init;+/**+ * megasas_free_ioctl_mem_pools - Free all the memory in the ioctl memory pool+ * @instance: Adapter soft state+ */+static void+megasas_free_ioctl_mem_pools(struct megasas_instance *instance)+{+ struct megasas_ioctl_mm *ioctl_mm;+ u32 i,j;+ u32 mem_size;+ if(instance->mem_pool_empty)+ return;+ for (i=0; i < MAX_IOCTL_MEM_POOL; i++) {+ mem_size = arr_size[i];+ for (j = 0; j < arr[i]; j++) {+ ioctl_mm = megasas_get_ioctl_mem(instance, i);+ + if (ioctl_mm){ + if(ioctl_mm->vaddr)+ pci_free_consistent(instance->pdev, + mem_size, + ioctl_mm->vaddr,+ ioctl_mm->buf_handle);+ kfree(ioctl_mm);+ }+ } }+} - megasas_return_cmd(instance, cmd);+/*+ * The memory pool will have 8x4K, 4*8K and 1x64K memory + * ioctl_memory_pool[0] ----> 4k memory list+ * ioctl_memory_pool[1] ----> 8K memory list + * ioctl_memory_pool[2] ----> 64K memory list + */++/**+ * megasas_setup_mem_pools - Free all the memory in the ioctl memory pool+ * @instance: Adapter soft state+ */+static int+megasas_setup_mem_pools(struct megasas_instance *instance)+{+ struct megasas_ioctl_mm *ioctl_mm;+ dma_addr_t buf_handle;+ void *vaddr;+ u32 i, j;+ u32 mem_size;+ for (i=0; i < MAX_IOCTL_MEM_POOL; i++) {+ mem_size = arr_size[i];+ + for (j = 0; j < arr[i]; j++) {+ + ioctl_mm = kmalloc(sizeof(struct megasas_ioctl_mm), GFP_KERNEL); + if(!ioctl_mm){+ printk(KERN_DEBUG "megasas:Failed to alloc init memory for ioctl \n");+ goto failed_to_alloc_mem_ioctl;+ }+ vaddr = pci_alloc_consistent(instance->pdev,mem_size,+ &buf_handle);+ if (!vaddr) {+ printk(KERN_DEBUG "megasas:Failed to alloc init memory for ioctl \n");+ goto failed_to_alloc_mem_ioctl;+ } else {+ ioctl_mm->vaddr = vaddr;+ ioctl_mm->buf_handle = (u32)buf_handle; + list_add_tail(&ioctl_mm->list, + &instance->ioctl_memory_pool[i]);+ }+ }+ } return 0;+failed_to_alloc_mem_ioctl:+ megasas_free_ioctl_mem_pools(instance);+ return 1;+} - fail_fw_init:- return -EINVAL;+int+megasas_get_buff_for_sge(struct megasas_iocpacket *ioc,+ struct megasas_instance *instance,+ struct megasas_cmd *cmd)+{+ int i,n;+ u8 mem_type;+ struct megasas_ioctl_mm* ioctl_mm;+ if(instance->mem_pool_empty)+ goto empty;+ for (i = 0; i < ioc->sge_count; i++) {+ /*+ * Check if we have buffer to use from our mem_pool+ * If we donot have enough to satisfy for all sge's then + * free that has already been attached to the ioc+ */+ mem_type=0xff;+ if (ioc->sgl[i].iov_len <= MEGASAS_INIT_IOCTL_MEM_SIZE)+ mem_type=0;+ else if ((ioc->sgl[i].iov_len > MEGASAS_INIT_IOCTL_MEM_SIZE) && + (ioc->sgl[i].iov_len <= 2*MEGASAS_INIT_IOCTL_MEM_SIZE)) + mem_type=1;+ else if ((ioc->sgl[i].iov_len > 2*MEGASAS_INIT_IOCTL_MEM_SIZE) && + (ioc->sgl[i].iov_len <= 16*MEGASAS_INIT_IOCTL_MEM_SIZE)) + mem_type=2;++ ioctl_mm = megasas_get_ioctl_mem(instance, mem_type);+ + if (ioctl_mm) {+ cmd->ioctl_mem[i]=ioctl_mm;+ cmd->ioctl_mem_pool_index[i] = mem_type;+ } else {+ /* Not enough buffer in mem pool+ * Free all allocated buffer for this ioc+ */+ goto out;+ }+ }+ return 0;+out:+ for (n = 0; n < i; n++) {+ 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[i]=NULL;+ cmd->ioctl_mem_pool_index[i] = 0xff;+ }+ }+empty:+ return 1; } /**@@ -2049,8 +2210,14 @@ static int megasas_init_mfi(struct megas u32 tmp_sectors; struct megasas_register_set __iomem *reg_set; + struct megasas_cmd *cmd; struct megasas_ctrl_info *ctrl_info; + struct megasas_init_frame *init_frame;+ struct megasas_init_queue_info *initq_info;+ dma_addr_t init_frame_h;+ dma_addr_t initq_info_h;+ /* * Map the message registers */@@ -2126,9 +2293,53 @@ static int megasas_init_mfi(struct megas printk(KERN_DEBUG "megasas: Out of DMA mem for reply queue\n"); goto fail_reply_queue; }++ /*+ * Prepare a init frame. Note the init frame points to queue info+ * structure. Each frame has SGL allocated after first 64 bytes. For+ * this frame - since we don't need any SGL - we use SGL's space as+ * queue info structure+ *+ * We will not get a NULL command below. We just created the pool.+ */+ cmd = megasas_get_cmd(instance);++ init_frame = (struct megasas_init_frame *)cmd->frame;+ initq_info = (struct megasas_init_queue_info *)+ ((unsigned long)init_frame + 64);++ init_frame_h = cmd->frame_phys_addr;+ initq_info_h = init_frame_h + 64;++ memset(init_frame, 0, MEGAMFI_FRAME_SIZE);+ memset(initq_info, 0, sizeof(struct megasas_init_queue_info));++ initq_info->reply_queue_entries = instance->max_fw_cmds + 1;+ initq_info->reply_queue_start_phys_addr_lo = instance->reply_queue_h;++ initq_info->producer_index_phys_addr_lo = instance->producer_h;+ initq_info->consumer_index_phys_addr_lo = instance->consumer_h;++ init_frame->cmd = MFI_CMD_INIT;+ init_frame->cmd_status = 0xFF;+ init_frame->queue_info_new_phys_addr_lo = initq_info_h;++ init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info);++ /*+ * disable the intr before firing the init frame to FW + */ + instance->instancet->disable_intr(instance->reg_set); - if (megasas_issue_init_mfi(instance))+ /*+ * Issue the init frame in polled mode+ */+ if (megasas_issue_polled(instance, cmd)) {+ printk(KERN_DEBUG "megasas: Failed to init firmware\n"); goto fail_fw_init;+ }++ megasas_return_cmd(instance, cmd); ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL); @@ -2159,15 +2370,10 @@ static int megasas_init_mfi(struct megas kfree(ctrl_info); - /*- * Setup tasklet for cmd completion- */-- tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc,- (unsigned long)instance); return 0; fail_fw_init:+ megasas_return_cmd(instance, cmd); pci_free_consistent(instance->pdev, reply_q_sz, instance->reply_queue, instance->reply_queue_h);@@ -2411,30 +2617,6 @@ static int megasas_start_aen(struct mega class_locale.word); } -static ssize_t-sysfs_max_sectors_read(struct kobject *kobj, char *buf,- loff_t off, size_t count)-{- struct Scsi_Host *host = class_to_shost(container_of(kobj,- struct class_device, kobj));- struct megasas_instance *instance = - (struct megasas_instance *)host->hostdata;-- count = sprintf(buf,"%u\n", instance->max_sectors_per_req);-- return count+1;-}--static struct bin_attribute sysfs_max_sectors_attr = {- .attr = {- .name = "max_sectors",- .mode = S_IRUSR|S_IRGRP|S_IROTH,- .owner = THIS_MODULE,- },- .size = 7,- .read = sysfs_max_sectors_read,-};- /** * megasas_io_attach - Attaches this driver to SCSI mid-layer * @instance: Adapter soft state@@ -2442,28 +2624,30 @@ static struct bin_attribute sysfs_max_se static int megasas_io_attach(struct megasas_instance *instance) { struct Scsi_Host *host = instance->host;- int error; /* * Export parameters required by SCSI mid-layer */+ scsi_set_pci_device(host, instance->pdev);++ host->host_lock = &instance->host_lock; host->irq = instance->pdev->irq; host->unique_id = instance->unique_id; host->can_queue = instance->max_fw_cmds - MEGASAS_INT_CMDS; host->this_id = instance->init_id; host->sg_tablesize = instance->max_num_sge;-+ /* * Check if the module parameter value for max_sectors can be used */- if (max_sectors && max_sectors < instance->max_sectors_per_req)- instance->max_sectors_per_req = max_sectors;+ if (max_sector && max_sector < instance->max_sectors_per_req)+ instance->max_sectors_per_req = max_sector; else {- if (max_sectors)+ if (max_sector) printk(KERN_INFO "megasas: max_sectors should be > 0 and" "<= %d\n",instance->max_sectors_per_req); }-+ max_sector = instance->max_sectors_per_req; host->max_sectors = instance->max_sectors_per_req; /*@@ -2475,12 +2659,12 @@ static int megasas_io_attach(struct mega else printk(KERN_INFO "megasas: cmd_per_lun should be > 0 and" "<= %d\n",MEGASAS_DEFAULT_CMD_PER_LUN);- + cmd_per_lun = instance->cmd_per_lun; host->cmd_per_lun = instance->cmd_per_lun; printk(KERN_DEBUG "megasas: max_sectors : 0x%x, cmd_per_lun : 0x%x\n", instance->max_sectors_per_req, instance->cmd_per_lun);-+ host->max_channel = MEGASAS_MAX_CHANNELS - 1; host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL; host->max_lun = MEGASAS_MAX_LUN;@@ -2495,47 +2679,10 @@ static int megasas_io_attach(struct mega } /*- * Create sysfs entries for module paramaters- */- error = sysfs_create_bin_file(&instance->host->shost_classdev.kobj,- &sysfs_max_sectors_attr);- if (error) {- printk(KERN_INFO "megasas: Error in creating the sysfs entry"- " max_sectors.\n");- goto out_remove_host;- }-- /* * Trigger SCSI to scan our drives */ scsi_scan_host(host); return 0;--out_remove_host:- scsi_remove_host(host);- return error;-}--static int-megasas_set_dma_mask(struct pci_dev *pdev)-{- /*- * All our contollers are capable of performing 64-bit DMA- */- if (IS_DMA64) {- if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) != 0) {-- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0)- goto fail_set_dma_mask;- }- } else {- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0)- goto fail_set_dma_mask;- }- return 0;--fail_set_dma_mask:- return 1; } /**@@ -2546,7 +2693,7 @@ fail_set_dma_mask: static int __devinit megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) {- int rval;+ int rval, i; struct Scsi_Host *host; struct megasas_instance *instance; @@ -2571,8 +2718,19 @@ megasas_probe_one(struct pci_dev *pdev, pci_set_master(pdev); - if (megasas_set_dma_mask(pdev))- goto fail_set_dma_mask;+ /*+ * All our contollers are capable of performing 64-bit DMA+ */+ if (IS_DMA64) {+ if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) != 0) {++ if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0)+ goto fail_set_dma_mask;+ }+ } else {+ if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0)+ goto fail_set_dma_mask;+ } host = scsi_host_alloc(&megasas_template, sizeof(struct megasas_instance));@@ -2614,18 +2772,33 @@ megasas_probe_one(struct pci_dev *pdev, * Initialize locks and queues */ INIT_LIST_HEAD(&instance->cmd_pool);-+ atomic_set(&instance->fw_outstanding,0); init_waitqueue_head(&instance->int_cmd_wait_q); init_waitqueue_head(&instance->abort_cmd_wait_q); + spin_lock_init(&instance->host_lock); spin_lock_init(&instance->cmd_pool_lock);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -