📄 rhel3-ga.patch
字号:
+ instance->last_time=jiffies; } cmd = megasas_get_cmd(instance);@@ -920,6 +1108,14 @@ megasas_queue_command(struct scsi_cmnd * cmd->scmd = scmd; scmd->SCp.ptr = (char *)cmd;+ scmd->SCp.sent_command = jiffies;++ /*+ * Add this command to the pending list+ */+ spin_lock_irqsave(&instance->pending_lock, flags);+ list_add_tail(&cmd->list, &instance->pending_list);+ spin_unlock_irqrestore(&instance->pending_lock, flags); /* * Issue the command to the FW@@ -937,45 +1133,15 @@ megasas_queue_command(struct scsi_cmnd * return 0; } -static int megasas_slave_configure(struct scsi_device *sdev)-{- /*- * Don't export physical disk devices to the disk driver.- *- * FIXME: Currently we don't export them to the midlayer at all.- * That will be fixed once LSI engineers have audited the- * firmware for possible issues.- */- if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && sdev->type == TYPE_DISK)- return -ENXIO;-- /*- * The RAID firmware may require extended timeouts.- */- if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS)- sdev->timeout = MEGASAS_DEFAULT_CMD_TIMEOUT * HZ;- return 0;-}--/**- * megasas_complete_cmd_dpc - Returns FW's controller structure- * @instance_addr: Address of adapter soft state- *- * Tasklet to complete cmds- */-static void megasas_complete_cmd_dpc(unsigned long instance_addr)+static void+megasas_complete_cmd_q(struct megasas_instance *instance, u8 alt_status) { u32 producer; u32 consumer; u32 context; struct megasas_cmd *cmd;- struct megasas_instance *instance = (struct megasas_instance *)instance_addr; unsigned long flags; - /* If we have already declared adapter dead, donot complete cmds */- if (instance->hw_crit_error)- return;- spin_lock_irqsave(&instance->completion_lock, flags); producer = *instance->producer;@@ -986,7 +1152,7 @@ static void megasas_complete_cmd_dpc(uns cmd = instance->cmd_list[context]; - megasas_complete_cmd(instance, cmd, DID_OK);+ megasas_complete_cmd(instance, cmd, alt_status); consumer++; if (consumer == (instance->max_fw_cmds + 1)) {@@ -1026,10 +1192,10 @@ static int megasas_wait_for_outstanding( * Call cmd completion routine. Cmd to be * be completed directly without depending on isr. */- megasas_complete_cmd_dpc((unsigned long)instance);+ megasas_complete_cmd_q(instance, DID_OK); } - msleep(1000);+ mdelay(1000); } if (atomic_read(&instance->fw_outstanding)) {@@ -1060,10 +1226,11 @@ static int megasas_generic_reset(struct int ret_val; struct megasas_instance *instance; - instance = (struct megasas_instance *)scmd->device->host->hostdata;+ instance = (struct megasas_instance *)scmd->host->hostdata; - scmd_printk(KERN_NOTICE, scmd, "megasas: RESET -%ld cmd=%x retries=%x\n",- scmd->serial_number, scmd->cmnd[0], scmd->retries);+ printk(KERN_NOTICE "megasas: RESET -%ld cmd=%x <c=%d t=%d l=%d> retries=%x\n",+ scmd->serial_number, scmd->cmnd[0], scmd->channel,+ scmd->target, scmd->lun, scmd->retries); if (instance->hw_crit_error) { printk(KERN_ERR "megasas: cannot recover from previous reset "@@ -1071,48 +1238,17 @@ static int megasas_generic_reset(struct return FAILED; } + spin_unlock(scmd->host->host_lock); ret_val = megasas_wait_for_outstanding(instance); if (ret_val == SUCCESS) printk(KERN_NOTICE "megasas: reset successful \n"); else printk(KERN_ERR "megasas: failed to do reset\n");+ spin_lock(scmd->host->host_lock); return ret_val; } - /**- * megasas_reset_timer - quiesce the adapter if required- * @scmd: scsi cmnd- *- * Sets the FW busy flag and reduces the host->can_queue if the- * cmd has not been completed within the timeout period.- */-static enum-scsi_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)-{- struct megasas_cmd *cmd = (struct megasas_cmd *)scmd->SCp.ptr;- struct megasas_instance *instance;- unsigned long flags;-- if (time_after(jiffies, scmd->jiffies_at_alloc +- (MEGASAS_DEFAULT_CMD_TIMEOUT * 2) * HZ)) {- return EH_NOT_HANDLED;- }-- instance = cmd->instance;- if (!(instance->flag & MEGASAS_FW_BUSY)) {- /* FW is busy, throttle IO */- spin_lock_irqsave(instance->host->host_lock, flags);-- instance->host->can_queue = 16;- instance->last_time = jiffies;- instance->flag |= MEGASAS_FW_BUSY;-- spin_unlock_irqrestore(instance->host->host_lock, flags);- }- return EH_RESET_TIMER;-}- /** * megasas_reset_device - Device reset handler entry point */@@ -1144,49 +1280,6 @@ static int megasas_reset_bus_host(struct } /**- * megasas_bios_param - Returns disk geometry for a disk- * @sdev: device handle- * @bdev: block device- * @capacity: drive capacity- * @geom: geometry parameters- */-static int-megasas_bios_param(struct scsi_device *sdev, struct block_device *bdev,- sector_t capacity, int geom[])-{- int heads;- int sectors;- sector_t cylinders;- unsigned long tmp;- /* Default heads (64) & sectors (32) */- heads = 64;- sectors = 32;-- tmp = heads * sectors;- cylinders = capacity;-- sector_div(cylinders, tmp);-- /*- * Handle extended translation size for logical drives > 1Gb- */-- if (capacity >= 0x200000) {- heads = 255;- sectors = 63;- tmp = heads*sectors;- cylinders = capacity;- sector_div(cylinders, tmp);- }-- geom[0] = heads;- geom[1] = sectors;- geom[2] = cylinders;-- return 0;-}--/** * megasas_service_aen - Processes an event notification * @instance: Adapter soft state * @cmd: AEN command completed by the ISR@@ -1213,57 +1306,27 @@ megasas_service_aen(struct megasas_insta megasas_return_cmd(instance, cmd); } -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_slave_alloc(struct scsi_device *sdev) {- struct megasas_instance *instance ;- int tmp_fastload = fast_load;- instance = megasas_lookup_instance(sdev->host->host_no);-- if (tmp_fastload && sdev->channel < MEGASAS_MAX_PD_CHANNELS) {- if ((sdev->id == MEGASAS_MAX_DEV_PER_CHANNEL -1) &&- (sdev->channel == MEGASAS_MAX_PD_CHANNELS - 1)) {- /* If fast load option was set and scan for last device is- * over, reset the fast_load flag so that during a possible- * next scan, devices can be made available- */- fast_load = 0;- }- return -ENXIO;- }-- return 0;-}-+static int megasas_detect(Scsi_Host_Template * sht);+static int megasas_release(struct Scsi_Host *host); /* * Scsi host template for megaraid_sas driver */-static struct scsi_host_template megasas_template = {-+static Scsi_Host_Template megasas_template = {+ .name = "MegaRAID SAS",+ .proc_name = "lsi_megaraid_sas", .module = THIS_MODULE,- .name = "LSI Logic SAS based MegaRAID driver",- .proc_name = "megaraid_sas",- .slave_configure = megasas_slave_configure,- .slave_alloc = megasas_slave_alloc,+ .info = megasas_info,+ .detect = megasas_detect,+ .release = megasas_release, .queuecommand = megasas_queue_command,+ .eh_abort_handler = megasas_abort_command, .eh_device_reset_handler = megasas_reset_device, .eh_bus_reset_handler = megasas_reset_bus_host, .eh_host_reset_handler = megasas_reset_bus_host,- .eh_timed_out = megasas_reset_timer,- .bios_param = megasas_bios_param, .use_clustering = ENABLE_CLUSTERING,+ .use_new_eh_code = 1,+ .highmem_io = 1,+ .vary_io = 1, }; /**@@ -1314,7 +1377,7 @@ megasas_complete_abort(struct megasas_in * @instance: Adapter soft state * @cmd: Completed command */-static void+static inline void megasas_unmap_sgbuf(struct megasas_instance *instance, struct megasas_cmd *cmd) { dma_addr_t buf_h;@@ -1358,16 +1421,18 @@ megasas_unmap_sgbuf(struct megasas_insta * an alternate status (as in the case of aborted * commands) */-static void+static inline void megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, u8 alt_status) { int exception = 0; struct megasas_header *hdr = &cmd->frame->hdr;- unsigned long flags;+ unsigned long flags ;+ int outstanding; - if (cmd->scmd)- cmd->scmd->SCp.ptr = NULL;+ if (cmd->scmd) {+ cmd->scmd->SCp.ptr = (char *)0;+ } switch (hdr->cmd) { @@ -1384,6 +1449,19 @@ megasas_complete_cmd(struct megasas_inst megasas_complete_int_cmd(instance, cmd); break; }+ /*+ * Don't export physical disk devices to mid-layer.+ */+ if (!MEGASAS_IS_LOGICAL(cmd->scmd) &&+ (hdr->cmd_status == MFI_STAT_OK) &&+ (cmd->scmd->cmnd[0] == INQUIRY)) {++ if (((*(u8 *) cmd->scmd->request_buffer) & 0x1F) ==+ TYPE_DISK) {+ cmd->scmd->result = DID_BAD_TARGET << 16;+ exception = 1;+ }+ } case MFI_CMD_LD_READ: case MFI_CMD_LD_WRITE:@@ -1397,6 +1475,10 @@ megasas_complete_cmd(struct megasas_inst atomic_dec(&instance->fw_outstanding); + spin_lock_irqsave(&instance->pending_lock, flags);+ list_del_init(&cmd->list);+ spin_unlock_irqrestore(&instance->pending_lock, flags);+ megasas_unmap_sgbuf(instance, cmd); cmd->scmd->scsi_done(cmd->scmd); megasas_return_cmd(instance, cmd);@@ -1444,6 +1526,9 @@ megasas_complete_cmd(struct megasas_inst } atomic_dec(&instance->fw_outstanding);+ spin_lock_irqsave(&instance->pending_lock, flags);+ list_del_init(&cmd->list);+ spin_unlock_irqrestore(&instance->pending_lock, flags); megasas_unmap_sgbuf(instance, cmd); cmd->scmd->scsi_done(cmd->scmd);@@ -1477,22 +1562,11 @@ megasas_complete_cmd(struct megasas_inst hdr->cmd); break; }- - /*- * Check if we can restore can_queue- */- if (instance->flag & MEGASAS_FW_BUSY- && time_after(jiffies, instance->last_time + 5 * HZ)- && atomic_read(&instance->fw_outstanding) < 17) {-- spin_lock_irqsave(instance->host->host_lock, flags);- instance->flag &= ~MEGASAS_FW_BUSY;- instance->host->can_queue =- instance->max_fw_cmds - MEGASAS_INT_CMDS;-- spin_unlock_irqrestore(instance->host->host_lock, flags);+ if(instance->is_busy){+ outstanding = atomic_read(&instance->fw_outstanding);+ if(outstanding<17)+ instance->is_busy=0; }- } /**@@ -1502,7 +1576,7 @@ megasas_complete_cmd(struct megasas_inst * SCSI mid-layer instead of the status * returned by the FW */-static int+static inline int megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status) { /*@@ -1512,20 +1586,19 @@ megasas_deplete_reply_queue(struct megas if(instance->instancet->clear_intr(instance->reg_set)) return IRQ_NONE; - if (instance->hw_crit_error)+ if(instance->hw_crit_error) goto out_done;- /*- * Schedule the tasklet for cmd completion- */- tasklet_schedule(&instance->isr_tasklet);++ megasas_complete_cmd_q(instance, alt_status); out_done: return IRQ_HANDLED;+ } /** * megasas_isr - isr entry point */-static irqreturn_t megasas_isr(int irq, void *devp)+static irqreturn_t megasas_isr(int irq, void *devp, struct pt_regs *regs) { return megasas_deplete_reply_queue((struct megasas_instance *)devp, DID_OK);@@ -1640,7 +1713,7 @@ megasas_transition_to_ready(struct megas MFI_STATE_MASK ; if (fw_state == cur_state) {- msleep(1);+ mdelay(1); } else break; }@@ -1743,7 +1816,7 @@ static int megasas_create_frame_pool(str */ instance->frame_dma_pool = pci_pool_create("megasas frame pool", instance->pdev, total_sz, 64,- 0);+ 0, GFP_DMA); if (!instance->frame_dma_pool) { printk(KERN_DEBUG "megasas: failed to setup frame pool\n");@@ -1751,7 +1824,8 @@ static int megasas_create_frame_pool(str } instance->sense_dma_pool = pci_pool_create("megasas sense pool",- instance->pdev, 128, 4, 0);+ instance->pdev, 128, 4, 0,+ GFP_DMA); if (!instance->sense_dma_pool) { printk(KERN_DEBUG "megasas: failed to setup sense pool\n");@@ -1960,78 +2034,187 @@ megasas_get_ctrl_info(struct megasas_ins } /**- * megasas_issue_init_mfi - Initializes the FW- * @instance: Adapter soft state+ * megasas_get_ioctl_mem - Get a buff from the free ioctl memory pool+ * @instance: Adapter soft state+ * @i: mem_pool_index *- * Issues the INIT MFI cmd+ * Returns a free buff from the pool */-static int-megasas_issue_init_mfi(struct megasas_instance *instance)+static inline struct megasas_ioctl_mm *+megasas_get_ioctl_mem(struct megasas_instance* instance, u8 i) {- u32 context;-- struct megasas_cmd *cmd;-- 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;-- /*- * 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);+ unsigned long flags;+ 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -