📄 sles9-sp1.patch
字号:
diff -uprN base/megaraid_sas.c sles9-sp1/megaraid_sas.c--- base/megaraid_sas.c 2007-10-13 20:49:29.000000000 -0700+++ sles9-sp1/megaraid_sas.c 2007-10-13 20:45:56.000000000 -0700@@ -28,6 +28,7 @@ #include <linux/types.h> #include <linux/pci.h> #include <linux/list.h>+#include <linux/version.h> #include <linux/moduleparam.h> #include <linux/module.h> #include <linux/spinlock.h>@@ -36,9 +37,9 @@ #include <linux/uio.h> #include <asm/uaccess.h> #include <linux/fs.h>-#include <linux/compat.h>+#include <linux/ioctl32.h> #include <linux/blkdev.h>-#include <linux/mutex.h>+#include <linux/compat.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h>@@ -78,6 +79,7 @@ module_param_named(cmd_per_lun, cmd_per_ MODULE_PARM_DESC(cmd_per_lun, "Maximum number of commands per logical unit (default=128)"); + MODULE_LICENSE("GPL"); MODULE_VERSION(MEGASAS_VERSION); MODULE_AUTHOR("megaraidlinux@lsi.com");@@ -104,20 +106,40 @@ MODULE_DEVICE_TABLE(pci, megasas_pci_tab static int megasas_mgmt_majorno; static struct megasas_mgmt_info megasas_mgmt_info; static struct fasync_struct *megasas_async_queue;-static DEFINE_MUTEX(megasas_async_queue_mutex);- static u32 megasas_dbg_lvl;- static void megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, u8 alt_status);++static DECLARE_MUTEX(megasas_async_queue_mutex);++/**+ * msleep - sleep for a number of milliseconds+ * @msecs: number of milliseconds to sleep+ *+ * Issues schedule_timeout call for the specified number+ * of milliseconds.+ */++static inline unsigned long msecs_to_jiffies(unsigned long msecs)+{+ return ((HZ * msecs + 999) / 1000);+}++static void msleep(unsigned long msecs)+{+ set_current_state(TASK_UNINTERRUPTIBLE);+ schedule_timeout(msecs_to_jiffies(msecs) + 1);+}+ + /** * megasas_get_cmd - Get a command from the free pool * @instance: Adapter soft state * * Returns a free command from the pool */-static struct megasas_cmd *megasas_get_cmd(struct megasas_instance+static inline struct megasas_cmd *megasas_get_cmd(struct megasas_instance *instance) { unsigned long flags;@@ -181,7 +203,7 @@ megasas_enable_intr_xscale(struct megasa static inline void megasas_disable_intr_xscale(struct megasas_register_set __iomem * regs) {- u32 mask = 0x1f;+ u32 mask = 0x1f; writel(mask, ®s->outbound_intr_mask); /* Dummy readl to force pci flush */ readl(®s->outbound_intr_mask);@@ -196,6 +218,7 @@ megasas_read_fw_status_reg_xscale(struct { return readl(&(regs)->outbound_msg_0); }+ /** * megasas_clear_interrupt_xscale - Check & clear interrupt * @regs: MFI register set@@ -275,7 +298,7 @@ megasas_enable_intr_ppc(struct megasas_r static inline void megasas_disable_intr_ppc(struct megasas_register_set __iomem * regs) {- u32 mask = 0xFFFFFFFF;+ u32 mask = 0xFFFFFFFF; writel(mask, ®s->outbound_intr_mask); /* Dummy readl to force pci flush */ readl(®s->outbound_intr_mask);@@ -396,8 +419,7 @@ megasas_issue_blocked_cmd(struct megasas instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set); - wait_event_timeout(instance->int_cmd_wait_q, (cmd->cmd_status != ENODATA),- MEGASAS_INTERNAL_CMD_WAIT_TIME*HZ);+ wait_event(instance->int_cmd_wait_q, (cmd->cmd_status != ENODATA)); return 0; }@@ -444,8 +466,7 @@ megasas_issue_blocked_abort_cmd(struct m /* * Wait for this cmd to complete */- wait_event_timeout(instance->abort_cmd_wait_q, (cmd->cmd_status != 0xFF),- MEGASAS_INTERNAL_CMD_WAIT_TIME*HZ);+ wait_event(instance->abort_cmd_wait_q, (cmd->cmd_status != 0xFF)); megasas_return_cmd(instance, cmd); return 0;@@ -460,7 +481,7 @@ megasas_issue_blocked_abort_cmd(struct m * If successful, this function returns the number of SG elements. Otherwise, * it returnes -1. */-static int+static inline int megasas_make_sgl32(struct megasas_instance *instance, struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl) {@@ -508,7 +529,7 @@ megasas_make_sgl32(struct megasas_instan * If successful, this function returns the number of SG elements. Otherwise, * it returnes -1. */-static int+static inline int megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl) {@@ -549,7 +570,7 @@ megasas_make_sgl64(struct megasas_instan } /**- * megasas_get_frame_count - Computes the number of frames+ * megasas_get_frame_count - Computes the number of frames * @sge_count : number of sg elements * * Returns the number of frames required for numnber of sge's (sge_count)@@ -587,7 +608,7 @@ static u32 megasas_get_frame_count(u8 sg frame_count = 8; return frame_count; }-+ /** * megasas_build_dcdb - Prepares a direct cdb (DCDB) command * @instance: Adapter soft state@@ -597,7 +618,7 @@ static u32 megasas_get_frame_count(u8 sg * This function prepares CDB commands. These are typcially pass-through * commands to the devices. */-static int+static inline int megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, struct megasas_cmd *cmd) {@@ -667,7 +688,7 @@ megasas_build_dcdb(struct megasas_instan * * Frames (and accompanying SGLs) for regular SCSI IOs use this function. */-static int+static inline int megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp, struct megasas_cmd *cmd) {@@ -803,7 +824,7 @@ static inline int megasas_is_ldio(struct } /**- * megasas_dump_pending_frames - Dumps the frame address of all pending cmds+ * megasas_dump_pending_frames - Dumps the frame address of all pending cmds * in FW * @instance: Adapter soft state */@@ -824,13 +845,15 @@ megasas_dump_pending_frames(struct megas printk(KERN_ERR "\nmegasas[%d]: 64 bit SGLs were sent to FW\n",instance->host->host_no); else printk(KERN_ERR "\nmegasas[%d]: 32 bit SGLs were sent to FW\n",instance->host->host_no);-+ printk(KERN_ERR "megasas[%d]: Pending OS cmds in FW : \n",instance->host->host_no); for (i = 0; i < max_cmd; i++) { cmd = instance->cmd_list[i]; if(!cmd->scmd) continue;+ printk(KERN_ERR "megasas[%d]: Frame addr :0x%08lx : ",instance->host->host_no,(unsigned long)cmd->frame_phys_addr);+ if (megasas_is_ldio(cmd->scmd)){ ldio = (struct megasas_io_frame *)cmd->frame; mfi_sgl = &ldio->sgl;@@ -876,17 +899,17 @@ megasas_queue_command(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;+ scmd->scsi_done = done;+ scmd->result = 0; /* Don't process if we have already declared adapter dead */ if (instance->hw_crit_error) return SCSI_MLQUEUE_HOST_BUSY; - scmd->scsi_done = done;- scmd->result = 0;- if (MEGASAS_IS_LOGICAL(scmd) && (scmd->device->id >= MEGASAS_MAX_LD || scmd->device->lun)) { scmd->result = DID_BAD_TARGET << 16;@@ -894,13 +917,24 @@ megasas_queue_command(struct scsi_cmnd * } switch (scmd->cmnd[0]) {- case SYNCHRONIZE_CACHE:- /*- * FW takes care of flush cache on its own- * No need to send it down- */- scmd->result = DID_OK << 16;- goto out_done;+ case SYNCHRONIZE_CACHE:+ 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);@@ -920,6 +954,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,40 +972,20 @@ 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)+void megasas_complete_cmd_dpc(unsigned long instance_addr) { u32 producer; u32 consumer; u32 context;+ unsigned long flags; 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)@@ -978,9 +993,9 @@ static void megasas_complete_cmd_dpc(uns spin_lock_irqsave(&instance->completion_lock, flags); - producer = *instance->producer;- consumer = *instance->consumer;-+ producer = *instance->producer;+ consumer = *instance->consumer;+ while (consumer != producer) { context = instance->reply_queue[consumer]; @@ -1026,7 +1041,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_dpc(instance); } msleep(1000);@@ -1062,8 +1077,9 @@ static int megasas_generic_reset(struct instance = (struct megasas_instance *)scmd->device->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->device->channel,+ scmd->device->id, scmd->device->lun, scmd->retries); if (instance->hw_crit_error) { printk(KERN_ERR "megasas: cannot recover from previous reset "@@ -1071,46 +1087,17 @@ static int megasas_generic_reset(struct return FAILED; } + spin_unlock(scmd->device->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"); - return ret_val;-}+ spin_lock(scmd->device->host->host_lock); - /**- * 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;+ return ret_val; } /**@@ -1213,6 +1200,16 @@ megasas_service_aen(struct megasas_insta megasas_return_cmd(instance, cmd); } +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 = 90 * HZ ;+ return 0;+}+ static struct megasas_instance *megasas_lookup_instance(u16 host_no) { int i;@@ -1255,13 +1252,12 @@ static struct scsi_host_template megasas .module = THIS_MODULE, .name = "LSI Logic SAS based MegaRAID driver", .proc_name = "megaraid_sas",- .slave_configure = megasas_slave_configure, .slave_alloc = megasas_slave_alloc,+ .slave_configure = megasas_slave_configure, .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, };@@ -1314,7 +1310,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 +1354,15 @@ 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;-+ int outstanding; if (cmd->scmd)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -