📄 rhel3.patch
字号:
+#endif+ {+ scmd->result = DID_OK << 16;+ goto out_done;+ }+ }++ /* If FW is busy donot accept any more cmds */+ if(instance->is_busy){+ sec = (jiffies - instance->last_time) / HZ;+ if(sec<10) + return SCSI_MLQUEUE_HOST_BUSY;+ else{+ instance->is_busy=0;+ instance->last_time=0;+ }+ }++ if(scmd->retries>1){+ instance->is_busy=1;+ instance->last_time=jiffies; } cmd = megasas_get_cmd(instance);@@ -912,7 +1097,7 @@ megasas_queue_command(struct scsi_cmnd * */ if (megasas_is_ldio(scmd)) frame_count = megasas_build_ldio(instance, scmd, cmd);- else+ else frame_count = megasas_build_dcdb(instance, scmd, cmd); if (!frame_count)@@ -920,6 +1105,7 @@ megasas_queue_command(struct scsi_cmnd * cmd->scmd = scmd; scmd->SCp.ptr = (char *)cmd;+ scmd->SCp.sent_command = jiffies; /* * Issue the command to the FW@@ -937,45 +1123,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 +1142,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,7 +1182,7 @@ 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);@@ -1060,10 +1216,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 +1228,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 +1270,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 +1296,22 @@ 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;-}- /* * Scsi host template for megaraid_sas driver */-static struct scsi_host_template megasas_template = {+static Scsi_Host_Template megasas_template = { - .module = THIS_MODULE,- .name = "LSI Logic SAS based MegaRAID driver",+ .name = "MegaRAID SAS", .proc_name = "megaraid_sas",- .slave_configure = megasas_slave_configure,- .slave_alloc = megasas_slave_alloc,+ .info = megasas_info, .queuecommand = megasas_queue_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 +1362,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;@@ -1364,10 +1412,11 @@ megasas_complete_cmd(struct megasas_inst { int exception = 0; struct megasas_header *hdr = &cmd->frame->hdr;- unsigned long flags;+ int outstanding;+ if (cmd->scmd) {+ cmd->scmd->SCp.ptr = (char *)0;+ } - if (cmd->scmd)- cmd->scmd->SCp.ptr = NULL; switch (hdr->cmd) { @@ -1385,6 +1434,20 @@ megasas_complete_cmd(struct megasas_inst 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: @@ -1477,22 +1540,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,22 +1554,21 @@ megasas_complete_cmd(struct megasas_inst * SCSI mid-layer instead of the status * returned by the FW */-static int+static inline void megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status) { /* * Check if it is our interrupt * Clear the interrupt */- if(instance->instancet->clear_intr(instance->reg_set))+ if (instance->instancet->clear_intr(instance->reg_set)) return IRQ_NONE; 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; }@@ -1525,7 +1576,7 @@ out_done: /** * 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);@@ -1550,7 +1601,7 @@ megasas_transition_to_ready(struct megas fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK; - if (fw_state != MFI_STATE_READY)+ if (fw_state != MFI_STATE_READY) printk(KERN_INFO "megasas: Waiting for FW to come to ready" " state\n"); @@ -1574,7 +1625,7 @@ megasas_transition_to_ready(struct megas cur_state = MFI_STATE_WAIT_HANDSHAKE; break; - case MFI_STATE_BOOT_MESSAGE_PENDING:+ case MFI_STATE_BOOT_MESSAGE_PENDING: writel(MFI_INIT_HOTPLUG, &instance->reg_set->inbound_doorbell); @@ -1743,7 +1794,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 +1802,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 +2012,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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -