From 837f5fe89c843422452ef5e1a7e3d20e9caa3268 Mon Sep 17 00:00:00 2001 From: "Yang, Bo" Date: Mon, 11 Oct 2010 06:59:20 -0600 Subject: [SCSI] megaraid_sas: support devices update flag Driver added the Device update flag to tell LSI application driver whether to do the device Update. LSI MegaRAID SAS application will check this flag to decide if it needs to update the Device or not. Signed-off-by Bo Yang Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index d3c9cdee292..09a455d4b6e 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -103,6 +103,7 @@ static int megasas_poll_wait_aen; static DECLARE_WAIT_QUEUE_HEAD(megasas_poll_wait); static u32 support_poll_for_event; static u32 megasas_dbg_lvl; +static u32 support_device_change; /* define lock for aen poll */ spinlock_t poll_aen_lock; @@ -4658,6 +4659,15 @@ megasas_sysfs_show_support_poll_for_event(struct device_driver *dd, char *buf) static DRIVER_ATTR(support_poll_for_event, S_IRUGO, megasas_sysfs_show_support_poll_for_event, NULL); + static ssize_t +megasas_sysfs_show_support_device_change(struct device_driver *dd, char *buf) +{ + return sprintf(buf, "%u\n", support_device_change); +} + +static DRIVER_ATTR(support_device_change, S_IRUGO, + megasas_sysfs_show_support_device_change, NULL); + static ssize_t megasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf) { @@ -4978,6 +4988,7 @@ static int __init megasas_init(void) MEGASAS_EXT_VERSION); support_poll_for_event = 2; + support_device_change = 1; memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info)); @@ -5026,8 +5037,17 @@ static int __init megasas_init(void) if (rval) goto err_dcf_poll_mode_io; + rval = driver_create_file(&megasas_pci_driver.driver, + &driver_attr_support_device_change); + if (rval) + goto err_dcf_support_device_change; + return rval; +err_dcf_support_device_change: + driver_remove_file(&megasas_pci_driver.driver, + &driver_attr_poll_mode_io); + err_dcf_poll_mode_io: driver_remove_file(&megasas_pci_driver.driver, &driver_attr_dbg_lvl); @@ -5057,6 +5077,10 @@ static void __exit megasas_exit(void) &driver_attr_poll_mode_io); driver_remove_file(&megasas_pci_driver.driver, &driver_attr_dbg_lvl); + driver_remove_file(&megasas_pci_driver.driver, + &driver_attr_support_poll_for_event); + driver_remove_file(&megasas_pci_driver.driver, + &driver_attr_support_device_change); driver_remove_file(&megasas_pci_driver.driver, &driver_attr_release_date); driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version); -- cgit v1.2.3-18-g5258 From 1fd106851698e9a858d20ab0e0f0afd5e9ec9332 Mon Sep 17 00:00:00 2001 From: "Yang, Bo" Date: Tue, 12 Oct 2010 07:18:50 -0600 Subject: [SCSI] megaraid_sas: Add input parameter for max_sectors Driver add the input parameters support for max_sectors for megaraid sas gen2 chip. Customer can set the max_sectors support to 1MB for gen2 chip during the driver load. Signed-off-by Bo Yang Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas.c | 30 ++++++++++++++++++++++++++++++ drivers/scsi/megaraid/megaraid_sas.h | 1 + 2 files changed, 31 insertions(+) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 09a455d4b6e..41ffc205724 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -56,6 +56,15 @@ module_param_named(poll_mode_io, poll_mode_io, int, 0); MODULE_PARM_DESC(poll_mode_io, "Complete cmds from IO path, (default=0)"); +/* + * Number of sectors per IO command + * Will be set in megasas_init_mfi if user does not provide + */ +static unsigned int max_sectors; +module_param_named(max_sectors, max_sectors, int, 0); +MODULE_PARM_DESC(max_sectors, + "Maximum number of sectors per IO command"); + MODULE_LICENSE("GPL"); MODULE_VERSION(MEGASAS_VERSION); MODULE_AUTHOR("megaraidlinux@lsi.com"); @@ -3586,6 +3595,27 @@ static int megasas_io_attach(struct megasas_instance *instance) 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; + else { + if (max_sectors) { + if (((instance->pdev->device == + PCI_DEVICE_ID_LSI_SAS1078GEN2) || + (instance->pdev->device == + PCI_DEVICE_ID_LSI_SAS0079GEN2)) && + (max_sectors <= MEGASAS_MAX_SECTORS)) { + instance->max_sectors_per_req = max_sectors; + } else { + printk(KERN_INFO "megasas: max_sectors should be > 0" + "and <= %d (or < 1MB for GEN2 controller)\n", + instance->max_sectors_per_req); + } + } + } + host->max_sectors = instance->max_sectors_per_req; host->cmd_per_lun = 128; host->max_channel = MEGASAS_MAX_CHANNELS - 1; diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 16a4f68a34b..54d1a154b44 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -706,6 +706,7 @@ struct megasas_ctrl_info { #define MEGASAS_MAX_LD_IDS (MEGASAS_MAX_LD_CHANNELS * \ MEGASAS_MAX_DEV_PER_CHANNEL) +#define MEGASAS_MAX_SECTORS (2*1024) #define MEGASAS_DBG_LVL 1 #define MEGASAS_FW_BUSY 1 -- cgit v1.2.3-18-g5258 From 707e09bd867cee4cd0e5bff0a67513aa0232fcec Mon Sep 17 00:00:00 2001 From: "Yang, Bo" Date: Tue, 12 Oct 2010 07:20:27 -0600 Subject: [SCSI] megaraid_sas: Add three times Online controller reset If fw didn't raise the interrupt with the fw state change to driver and fw goes to failure state, driver Will check the FW state in driver's timeout routine and issue the reset if need. Driver will do the OCR upto three times until kill adapter. Also driver will issue OCR before driver kill adapter even if fw in operational state. Signed-off-by Bo Yang Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas.c | 70 +++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 41ffc205724..a8a2666831d 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -728,6 +728,10 @@ static int megasas_check_reset_gen2(struct megasas_instance *instance, struct megasas_register_set __iomem *regs) { + if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) { + return 1; + } + return 0; } @@ -940,6 +944,7 @@ megasas_make_sgl_skinny(struct megasas_instance *instance, mfi_sgl->sge_skinny[i].length = sg_dma_len(os_sgl); mfi_sgl->sge_skinny[i].phys_addr = sg_dma_address(os_sgl); + mfi_sgl->sge_skinny[i].flag = 0; } } return sge_count; @@ -1567,6 +1572,28 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr) } } +static void +megasas_internal_reset_defer_cmds(struct megasas_instance *instance); + +static void +process_fw_state_change_wq(struct work_struct *work); + +void megasas_do_ocr(struct megasas_instance *instance) +{ + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) || + (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) || + (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR)) { + *instance->consumer = MEGASAS_ADPRESET_INPROG_SIGN; + } + instance->instancet->disable_intr(instance->reg_set); + instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT; + instance->issuepend_done = 0; + + atomic_set(&instance->fw_outstanding, 0); + megasas_internal_reset_defer_cmds(instance); + process_fw_state_change_wq(&instance->work_init); +} + /** * megasas_wait_for_outstanding - Wait for all outstanding cmds * @instance: Adapter soft state @@ -1584,6 +1611,8 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance) unsigned long flags; struct list_head clist_local; struct megasas_cmd *reset_cmd; + u32 fw_state; + u8 kill_adapter_flag; spin_lock_irqsave(&instance->hba_lock, flags); adprecovery = instance->adprecovery; @@ -1669,7 +1698,45 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance) msleep(1000); } - if (atomic_read(&instance->fw_outstanding)) { + i = 0; + kill_adapter_flag = 0; + do { + fw_state = instance->instancet->read_fw_status_reg( + instance->reg_set) & MFI_STATE_MASK; + if ((fw_state == MFI_STATE_FAULT) && + (instance->disableOnlineCtrlReset == 0)) { + if (i == 3) { + kill_adapter_flag = 2; + break; + } + megasas_do_ocr(instance); + kill_adapter_flag = 1; + + /* wait for 1 secs to let FW finish the pending cmds */ + msleep(1000); + } + i++; + } while (i <= 3); + + if (atomic_read(&instance->fw_outstanding) && + !kill_adapter_flag) { + if (instance->disableOnlineCtrlReset == 0) { + + megasas_do_ocr(instance); + + /* wait for 5 secs to let FW finish the pending cmds */ + for (i = 0; i < wait_time; i++) { + int outstanding = + atomic_read(&instance->fw_outstanding); + if (!outstanding) + return SUCCESS; + msleep(1000); + } + } + } + + if (atomic_read(&instance->fw_outstanding) || + (kill_adapter_flag == 2)) { printk(KERN_NOTICE "megaraid_sas: pending cmds after reset\n"); /* * Send signal to FW to stop processing any pending cmds. @@ -2679,6 +2746,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance) return -ENOMEM; } + memset(cmd->frame, 0, total_sz); cmd->frame->io.context = cmd->index; cmd->frame->io.pad_0 = 0; } -- cgit v1.2.3-18-g5258 From e340c3537239d5b6a2b21d4245c8577d457b0476 Mon Sep 17 00:00:00 2001 From: "Yang, Bo" Date: Tue, 12 Oct 2010 07:21:59 -0600 Subject: [SCSI] megaraid_sas: Version and documentation update Signed-off-by Bo Yang Signed-off-by: James Bottomley --- drivers/scsi/megaraid/megaraid_sas.c | 2 +- drivers/scsi/megaraid/megaraid_sas.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index a8a2666831d..eb29d508513 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -10,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * FILE : megaraid_sas.c - * Version : v00.00.04.17.1-rc1 + * Version : v00.00.04.31-rc1 * * Authors: * (email-id : megaraidlinux@lsi.com) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 54d1a154b44..ad16f5e6004 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -18,9 +18,9 @@ /* * MegaRAID SAS Driver meta data */ -#define MEGASAS_VERSION "00.00.04.17.1-rc1" -#define MEGASAS_RELDATE "Oct. 29, 2009" -#define MEGASAS_EXT_VERSION "Thu. Oct. 29, 11:41:51 PST 2009" +#define MEGASAS_VERSION "00.00.04.31-rc1" +#define MEGASAS_RELDATE "May 3, 2010" +#define MEGASAS_EXT_VERSION "Mon. May 3, 11:41:51 PST 2010" /* * Device IDs -- cgit v1.2.3-18-g5258 From f281233d3eba15fb225d21ae2e228fd4553d824a Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 16 Nov 2010 02:10:29 -0500 Subject: SCSI host lock push-down Move the mid-layer's ->queuecommand() invocation from being locked with the host lock to being unlocked to facilitate speeding up the critical path for drivers who don't need this lock taken anyway. The patch below presents a simple SCSI host lock push-down as an equivalent transformation. No locking or other behavior should change with this patch. All existing bugs and locking orders are preserved. Additionally, add one parameter to queuecommand, struct Scsi_Host * and remove one parameter from queuecommand, void (*done)(struct scsi_cmnd *) Scsi_Host* is a convenient pointer that most host drivers need anyway, and 'done' is redundant to struct scsi_cmnd->scsi_done. Minimal code disturbance was attempted with this change. Most drivers needed only two one-line modifications for their host lock push-down. Signed-off-by: Jeff Garzik Acked-by: James Bottomley Signed-off-by: Linus Torvalds --- drivers/scsi/megaraid/megaraid_mbox.c | 7 ++++--- drivers/scsi/megaraid/megaraid_sas.c | 4 +++- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index a7810a106b3..5708cb27d07 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -113,8 +113,7 @@ static int megaraid_mbox_fire_sync_cmd(adapter_t *); static void megaraid_mbox_display_scb(adapter_t *, scb_t *); static void megaraid_mbox_setup_device_map(adapter_t *); -static int megaraid_queue_command(struct scsi_cmnd *, - void (*)(struct scsi_cmnd *)); +static int megaraid_queue_command(struct Scsi_Host *, struct scsi_cmnd *); static scb_t *megaraid_mbox_build_cmd(adapter_t *, struct scsi_cmnd *, int *); static void megaraid_mbox_runpendq(adapter_t *, scb_t *); static void megaraid_mbox_prepare_pthru(adapter_t *, scb_t *, @@ -1484,7 +1483,7 @@ mbox_post_cmd(adapter_t *adapter, scb_t *scb) * Queue entry point for mailbox based controllers. */ static int -megaraid_queue_command(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *)) +megaraid_queue_command_lck(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *)) { adapter_t *adapter; scb_t *scb; @@ -1513,6 +1512,8 @@ megaraid_queue_command(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *)) return if_busy; } +static DEF_SCSI_QCMD(megaraid_queue_command) + /** * megaraid_mbox_build_cmd - transform the mid-layer scsi commands * @adapter : controller's soft state diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index eb29d508513..7451bc096a0 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -1334,7 +1334,7 @@ megasas_dump_pending_frames(struct megasas_instance *instance) * @done: Callback entry point */ static int -megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) +megasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) { u32 frame_count; struct megasas_cmd *cmd; @@ -1417,6 +1417,8 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) return 0; } +static DEF_SCSI_QCMD(megasas_queue_command) + static struct megasas_instance *megasas_lookup_instance(u16 host_no) { int i; -- cgit v1.2.3-18-g5258