From: t_jeang Date: Tue, 6 Jan 2009 12:06:00 +0000 (+0000) Subject: megaraid_sas 00.00.03.21 rhel5 patches X-Git-Tag: megaraid_sas-v00.00.03.21 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=6471b65522d09b6ec668cdb2bed878165b7bfb94;p=xenclient%2Fkernel.git megaraid_sas 00.00.03.21 rhel5 patches Taken from CA-23199 --- diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 5d962779..7ea3a611 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -99,6 +99,7 @@ static struct pci_device_id megasas_pci_table[] = { {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064R)}, /* xscale IOP */ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078R)}, + /* ppc IOP */ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078DE)}, /* ppc IOP */ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)}, @@ -570,7 +571,6 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp, * * Returns the number of frames required for numnber of sge's (sge_count) */ - static u32 megasas_get_frame_count(u8 sge_count, u8 frame_type) { int num_cnt; @@ -902,6 +902,7 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) u32 frame_count; struct megasas_cmd *cmd; struct megasas_instance *instance; + unsigned long sec; instance = (struct megasas_instance *) scmd->device->host->hostdata; @@ -929,6 +930,22 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) 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); if (!cmd) return SCSI_MLQUEUE_HOST_BUSY; @@ -945,7 +962,6 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) goto out_return_cmd; cmd->scmd = scmd; - scmd->SCp.ptr = (char *)cmd; /* * Issue the command to the FW @@ -985,7 +1001,7 @@ static int megasas_slave_configure(struct scsi_device *sdev) * The RAID firmware may require extended timeouts. */ if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS) - sdev->timeout = MEGASAS_DEFAULT_CMD_TIMEOUT * HZ; + sdev->timeout = 90 * HZ; return 0; } @@ -1112,39 +1128,6 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd) 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 */ @@ -1293,7 +1276,6 @@ static struct scsi_host_template megasas_template = { .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, }; @@ -1396,10 +1378,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, { int exception = 0; struct megasas_header *hdr = &cmd->frame->hdr; - unsigned long flags; - - if (cmd->scmd) - cmd->scmd->SCp.ptr = NULL; + int outstanding; switch (hdr->cmd) { @@ -1509,22 +1488,12 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, 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; } - } /** @@ -1557,7 +1526,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); @@ -2084,7 +2053,7 @@ megasas_start_timer(struct megasas_instance *instance, timer->data = (unsigned long)instance; timer->function = fn; add_timer(timer); - } +} /** * megasas_io_completion_timer - Timer fn @@ -2228,7 +2197,7 @@ static int megasas_init_mfi(struct megasas_instance *instance) } instance->max_sectors_per_req = instance->max_num_sge * - PAGE_SIZE / 512; + PAGE_SIZE / 512; if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors)) instance->max_sectors_per_req = tmp_sectors; @@ -2716,8 +2685,8 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) 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 @@ -3026,6 +2995,7 @@ static void megasas_detach_one(struct pci_dev *pdev) if (poll_mode_io) del_timer_sync(&instance->io_completion_timer); + sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_max_sectors_attr); scsi_remove_host(instance->host); megasas_flush_cache(instance); @@ -3260,6 +3230,7 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, * sense_buff points to the location that has the user * sense buffer address */ + sense_buff = (unsigned long *) ((unsigned long)ioc->frame.raw + ioc->sense_off); sense_ptr = (u32 *) ((unsigned long)ioc->frame.raw + @@ -3621,7 +3592,6 @@ static int __init megasas_init(void) goto err_dcf_poll_mode_io; return rval; - err_dcf_poll_mode_io: driver_remove_file(&megasas_pci_driver.driver, &driver_attr_dbg_lvl); @@ -3642,7 +3612,7 @@ err_pcidrv: */ static void __exit megasas_exit(void) { - driver_remove_file(&megasas_pci_driver.driver, + driver_remove_file(&megasas_pci_driver.driver, &driver_attr_poll_mode_io); driver_remove_file(&megasas_pci_driver.driver, &driver_attr_dbg_lvl); diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 1a89505f..9d549546 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -543,7 +543,6 @@ struct megasas_ctrl_info { #define MEGASAS_DBG_LVL 1 #define MEGASAS_FW_BUSY 1 - /* Frame Type */ #define IO_FRAME 0 #define PTHRU_FRAME 1 @@ -561,8 +560,6 @@ struct megasas_ctrl_info { #define MEGASAS_IOCTL_CMD 0 -#define MEGASAS_DEFAULT_CMD_TIMEOUT 90 - /* * FW reports the maximum of number of commands that it can accept (maximum * commands that can be outstanding) at any time. The driver must report a @@ -580,7 +577,7 @@ struct megasas_ctrl_info { #define MFI_OB_INTR_STATUS_MASK 0x00000002 #define MFI_POLL_TIMEOUT_SECS 60 -#define MEGASAS_COMPLETION_TIMER_INTERVAL (HZ)/10 +#define MEGASAS_COMPLETION_TIMER_INTERVAL (HZ/10) #define MFI_REPLY_1078_MESSAGE_INTERRUPT 0x80000000 @@ -1118,7 +1115,7 @@ struct megasas_instance { struct megasas_instance_template *instancet; struct tasklet_struct isr_tasklet; - u8 flag; + u8 is_busy; unsigned long last_time; struct timer_list io_completion_timer;