From: t_jeang Date: Tue, 6 Jan 2009 12:06:00 +0000 (+0000) Subject: megaraid_sas 00.00.03.21 X-Git-Tag: mptlinux-4.00.38.02 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=9c97437a65b8607843208598e9bf30252afce872;p=xenclient%2Fkernel.git megaraid_sas 00.00.03.21 Taken from CA-23199 --- diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 87383574..5d962779 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -2,7 +2,7 @@ * * Linux MegaRAID driver for SAS based RAID controllers * - * Copyright (c) 2003-2005 LSI Corporation. + * Copyright (c) 2003-2005 LSI Logic Corporation. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -10,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * FILE : megaraid_sas.c - * Version : v00.00.03.15-RH1 + * Version : v00.00.03.21 * * Authors: * (email-id : megaraidlinux@lsi.com) @@ -47,11 +47,39 @@ #include "megaraid_sas.h" /* - * Module parameters + * Modules parameters */ /* - * poll_mode_io:1- schedule command completion from q cmd + * Fast driver load option, skip scanning for physical devices during load. + * This would result in physical devices being skipped during driver load + * time. These can be later added though, using /proc/scsi/scsi + */ +static unsigned int fast_load = 0; +module_param_named(fast_load, fast_load, int, 0); +MODULE_PARM_DESC(fast_load, + "megasas: Faster loading of the driver, skips physical devices! \ + (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 = 0; +module_param_named(max_sectors, max_sectors, int, 0); +MODULE_PARM_DESC(max_sectors, + "Maximum number of sectors per IO command"); + +/* + * Number of cmds per logical unit + */ +static unsigned int cmd_per_lun = MEGASAS_DEFAULT_CMD_PER_LUN; +module_param_named(cmd_per_lun, cmd_per_lun, int, 0); +MODULE_PARM_DESC(cmd_per_lun, + "Maximum number of commands per logical unit (default=128)"); + +/* + * poll_mode_io:1- schedule complete completion from q cmd */ static unsigned int poll_mode_io; module_param_named(poll_mode_io, poll_mode_io, int, 0); @@ -61,7 +89,7 @@ MODULE_PARM_DESC(poll_mode_io, MODULE_LICENSE("GPL"); MODULE_VERSION(MEGASAS_VERSION); MODULE_AUTHOR("megaraidlinux@lsi.com"); -MODULE_DESCRIPTION("LSI MegaRAID SAS Driver"); +MODULE_DESCRIPTION("LSI Logic MegaRAID SAS Driver"); /* * PCI ID table for all supported controllers @@ -71,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)}, + {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)}, /* xscale IOP, vega */ @@ -198,6 +227,9 @@ megasas_clear_intr_xscale(struct megasas_register_set __iomem * regs) */ writel(status, ®s->outbound_intr_status); + /* Dummy readl to force pci flush */ + readl(®s->outbound_intr_status); + return 0; } @@ -249,7 +281,7 @@ megasas_enable_intr_ppc(struct megasas_register_set __iomem * regs) } /** - * megasas_disable_intr_ppc - Disable interrupt + * megasas_disable_intr_ppc - Disables interrupt * @regs: MFI register set */ static inline void @@ -293,6 +325,9 @@ megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs) */ writel(status, ®s->outbound_doorbell_clear); + /* Dummy readl to force pci flush */ + readl(®s->outbound_doorbell_clear); + return 0; } /** @@ -531,11 +566,12 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp, /** * megasas_get_frame_count - Computes the number of frames * @sge_count : number of sg elements + * @frame_type : type of frame- io or pthru frame * * Returns the number of frames required for numnber of sge's (sge_count) */ -static u32 megasas_get_frame_count(u8 sge_count) +static u32 megasas_get_frame_count(u8 sge_count, u8 frame_type) { int num_cnt; int sge_bytes; @@ -546,13 +582,22 @@ static u32 megasas_get_frame_count(u8 sge_count) sizeof(struct megasas_sge32); /* - * Main frame can contain 2 SGEs for 64-bit SGLs and - * 3 SGEs for 32-bit SGLs - */ - if (IS_DMA64) - num_cnt = sge_count - 2; - else - num_cnt = sge_count - 3; + * Main frame can contain 2 SGEs for 64-bit SGLs and + * 3 SGEs for 32-bit SGLs for ldio & + * 1 SGEs for 64-bit SGLs and + * 2 SGEs for 32-bit SGLs for pthru frame + */ + if (unlikely(frame_type == PTHRU_FRAME)) { + if (IS_DMA64) + num_cnt = sge_count - 1; + else + num_cnt = sge_count - 2; + } else { + if (IS_DMA64) + num_cnt = sge_count - 2; + else + num_cnt = sge_count - 3; + } if(num_cnt>0){ sge_bytes = sge_sz * num_cnt; @@ -634,7 +679,8 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, * Compute the total number of frames this command consumes. FW uses * this number to pull sufficient number of frames from host memory. */ - cmd->frame_count = megasas_get_frame_count(pthru->sge_count); + cmd->frame_count = megasas_get_frame_count(pthru->sge_count, + PTHRU_FRAME); return cmd->frame_count; } @@ -751,7 +797,7 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp, * Compute the total number of frames this command consumes. FW uses * this number to pull sufficient number of frames from host memory. */ - cmd->frame_count = megasas_get_frame_count(ldio->sge_count); + cmd->frame_count = megasas_get_frame_count(ldio->sge_count, IO_FRAME); return cmd->frame_count; } @@ -881,8 +927,6 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *)) */ scmd->result = DID_OK << 16; goto out_done; - default: - break; } cmd = megasas_get_cmd(instance); @@ -957,8 +1001,7 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr) u32 consumer; u32 context; struct megasas_cmd *cmd; - struct megasas_instance *instance = - (struct megasas_instance *)instance_addr; + struct megasas_instance *instance = (struct megasas_instance *)instance_addr; unsigned long flags; /* If we have already declared adapter dead, donot complete cmds */ @@ -986,22 +1029,6 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr) *instance->consumer = producer; spin_unlock_irqrestore(&instance->completion_lock, flags); - - /* - * 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); - } - } /** @@ -1028,7 +1055,7 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance) printk(KERN_NOTICE "megasas: [%2d]waiting for %d " "commands to complete\n",i,outstanding); /* - * Call cmd completion routine. Cmd to be + * Call cmd completion routine. Cmd to be * be completed directly without depending on isr. */ megasas_complete_cmd_dpc((unsigned long)instance); @@ -1085,7 +1112,7 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd) return ret_val; } -/** + /** * megasas_reset_timer - quiesce the adapter if required * @scmd: scsi cmnd * @@ -1218,20 +1245,54 @@ megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd) 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 = { .module = THIS_MODULE, - .name = "LSI SAS based MegaRAID driver", + .name = "LSI Logic SAS based MegaRAID driver", .proc_name = "megaraid_sas", .slave_configure = megasas_slave_configure, + .slave_alloc = megasas_slave_alloc, .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, - .proc_info = (void *) RH_EXTENDED_MAGIC, .eh_timed_out = megasas_reset_timer, .bios_param = megasas_bios_param, .use_clustering = ENABLE_CLUSTERING, @@ -1335,6 +1396,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; @@ -1447,6 +1509,22 @@ 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); + } + } /** @@ -1479,7 +1557,7 @@ out_done: /** * megasas_isr - isr entry point */ -static irqreturn_t megasas_isr(int irq, void *devp, struct pt_regs *regs) +static irqreturn_t megasas_isr(int irq, void *devp) { return megasas_deplete_reply_queue((struct megasas_instance *)devp, DID_OK); @@ -1952,7 +2030,7 @@ megasas_issue_init_mfi(struct megasas_instance *instance) memset(init_frame, 0, MEGAMFI_FRAME_SIZE); memset(initq_info, 0, sizeof(struct megasas_init_queue_info)); init_frame->context = context; - + initq_info->reply_queue_entries = instance->max_fw_cmds + 1; initq_info->reply_queue_start_phys_addr_lo = instance->reply_queue_h; @@ -1966,16 +2044,16 @@ megasas_issue_init_mfi(struct megasas_instance *instance) init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info); /* - * disable the intr before firing the init frame to FW - */ + * disable the intr before firing the init frame to FW + */ instance->instancet->disable_intr(instance->reg_set); - + /* * Issue the init frame in polled mode */ if (megasas_issue_polled(instance, cmd)) { - printk(KERN_ERR "megasas: Failed to init firmware\n"); + printk(KERN_DEBUG "megasas: Failed to init firmware\n"); megasas_return_cmd(instance, cmd); goto fail_fw_init; } @@ -1984,8 +2062,8 @@ megasas_issue_init_mfi(struct megasas_instance *instance) return 0; -fail_fw_init: - return -EINVAL; + fail_fw_init: + return -EINVAL; } /** @@ -2006,19 +2084,19 @@ megasas_start_timer(struct megasas_instance *instance, timer->data = (unsigned long)instance; timer->function = fn; add_timer(timer); -} + } /** * megasas_io_completion_timer - Timer fn * @instance_addr: Address of adapter soft state * - * Schedules tasklet for cmd completion + * Schedules tasklet for cmd completion * if poll_mode_io is set */ static void megasas_io_completion_timer(unsigned long instance_addr) { - struct megasas_instance *instance = + struct megasas_instance *instance = (struct megasas_instance *)instance_addr; if (atomic_read(&instance->fw_outstanding)) @@ -2052,7 +2130,7 @@ static int megasas_init_mfi(struct megasas_instance *instance) */ instance->base_addr = pci_resource_start(instance->pdev, 0); - if (pci_request_regions(instance->pdev, "megasas: LSI")) { + if (pci_request_regions(instance->pdev, "megasas: LSI Logic")) { printk(KERN_DEBUG "megasas: IO memory region busy!\n"); return -EBUSY; } @@ -2069,6 +2147,7 @@ static int megasas_init_mfi(struct megasas_instance *instance) switch(instance->pdev->device) { case PCI_DEVICE_ID_LSI_SAS1078R: + case PCI_DEVICE_ID_LSI_SAS1078DE: instance->instancet = &megasas_instance_template_ppc; break; case PCI_DEVICE_ID_LSI_SAS1064R: @@ -2122,7 +2201,7 @@ static int megasas_init_mfi(struct megasas_instance *instance) printk(KERN_DEBUG "megasas: Out of DMA mem for reply queue\n"); goto fail_reply_queue; } - + if (megasas_issue_init_mfi(instance)) goto fail_fw_init; @@ -2147,17 +2226,17 @@ static int megasas_init_mfi(struct megasas_instance *instance) tmp_sectors = (max_sectors_1 < max_sectors_2) ? max_sectors_1 : max_sectors_2; } - + 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; kfree(ctrl_info); /* - * Setup tasklet for cmd completion - */ + * Setup tasklet for cmd completion + */ tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc, (unsigned long)instance); @@ -2413,6 +2492,30 @@ static int megasas_start_aen(struct megasas_instance *instance) class_locale.word); } +static ssize_t +sysfs_max_sectors_read(struct kobject *kobj, char *buf, + loff_t off, size_t count) +{ + struct Scsi_Host *host = class_to_shost(container_of(kobj, + struct class_device, kobj)); + struct megasas_instance *instance = + (struct megasas_instance *)host->hostdata; + + count = sprintf(buf,"%u\n", instance->max_sectors_per_req); + + return count+1; +} + +static struct bin_attribute sysfs_max_sectors_attr = { + .attr = { + .name = "max_sectors", + .mode = S_IRUSR|S_IRGRP|S_IROTH, + .owner = THIS_MODULE, + }, + .size = 7, + .read = sysfs_max_sectors_read, +}; + /** * megasas_io_attach - Attaches this driver to SCSI mid-layer * @instance: Adapter soft state @@ -2420,6 +2523,7 @@ static int megasas_start_aen(struct megasas_instance *instance) static int megasas_io_attach(struct megasas_instance *instance) { struct Scsi_Host *host = instance->host; + int error; /* * Export parameters required by SCSI mid-layer @@ -2429,8 +2533,35 @@ static int megasas_io_attach(struct megasas_instance *instance) host->can_queue = 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) + printk(KERN_INFO "megasas: max_sectors should be > 0 and" + "<= %d\n",instance->max_sectors_per_req); + } + host->max_sectors = instance->max_sectors_per_req; - host->cmd_per_lun = MEGASAS_DEFAULT_CMD_PER_LUN; + + /* + * Check if the module parameter value for cmd_per_lun can be used + */ + instance->cmd_per_lun = MEGASAS_DEFAULT_CMD_PER_LUN; + if (cmd_per_lun && cmd_per_lun <= MEGASAS_DEFAULT_CMD_PER_LUN) + instance->cmd_per_lun = cmd_per_lun; + else + printk(KERN_INFO "megasas: cmd_per_lun should be > 0 and" + "<= %d\n",MEGASAS_DEFAULT_CMD_PER_LUN); + + host->cmd_per_lun = instance->cmd_per_lun; + + printk(KERN_DEBUG "megasas: max_sectors : 0x%x, cmd_per_lun : 0x%x\n", + instance->max_sectors_per_req, instance->cmd_per_lun); + host->max_channel = MEGASAS_MAX_CHANNELS - 1; host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL; host->max_lun = MEGASAS_MAX_LUN; @@ -2444,11 +2575,26 @@ static int megasas_io_attach(struct megasas_instance *instance) return -ENODEV; } + /* + * Create sysfs entries for module paramaters + */ + error = sysfs_create_bin_file(&instance->host->shost_classdev.kobj, + &sysfs_max_sectors_attr); + if (error) { + printk(KERN_INFO "megasas: Error in creating the sysfs entry" + " max_sectors.\n"); + goto out_remove_host; + } + /* * Trigger SCSI to scan our drives */ scsi_scan_host(host); return 0; + +out_remove_host: + scsi_remove_host(host); + return error; } static int @@ -2728,7 +2874,7 @@ static void megasas_shutdown_controller(struct megasas_instance *instance, /** * megasas_suspend - driver suspend entry point * @pdev: PCI device structure - * @state: state + * @state: */ static int __devinit megasas_suspend(struct pci_dev *pdev, pm_message_t state) @@ -2746,10 +2892,12 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state) megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN); tasklet_kill(&instance->isr_tasklet); - pci_set_drvdata(instance->pdev, instance); + pci_set_drvdata(instance->pdev, instance); instance->instancet->disable_intr(instance->reg_set); free_irq(instance->pdev->irq, instance); + scsi_host_put(host); + pci_save_state(pdev); pci_disable_device(pdev); @@ -2768,7 +2916,7 @@ megasas_resume(struct pci_dev *pdev) int rval; struct Scsi_Host *host; struct megasas_instance *instance; - + instance = pci_get_drvdata(pdev); host = instance->host; pci_set_power_state(pdev, PCI_D0); @@ -2797,7 +2945,7 @@ megasas_resume(struct pci_dev *pdev) *instance->producer = 0; *instance->consumer = 0; - atomic_set(&instance->fw_outstanding, 0); + atomic_set(&instance->fw_outstanding,0); /* * We expect the FW state to be READY @@ -2809,18 +2957,23 @@ megasas_resume(struct pci_dev *pdev) goto fail_init_mfi; tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc, - (unsigned long)instance); + (unsigned long)instance); /* * Register IRQ */ if (request_irq(pdev->irq, megasas_isr, IRQF_SHARED, - "megasas", instance)) { + "megasas",instance)) { printk(KERN_DEBUG "megasas: Failed to register IRQ\n"); goto fail_irq; } instance->instancet->enable_intr(instance->reg_set); + /* + * Store instance in PCI softstate + */ + pci_set_drvdata(pdev, instance); + /* * Initiate AEN (Asynchronous Event Notification) */ @@ -2832,11 +2985,11 @@ megasas_resume(struct pci_dev *pdev) megasas_start_timer(instance, &instance->io_completion_timer, megasas_io_completion_timer, MEGASAS_COMPLETION_TIMER_INTERVAL); - - return 0; - -fail_irq: -fail_init_mfi: + + return 0; + + fail_irq: + fail_init_mfi: if (instance->evt_detail) pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), @@ -2850,8 +3003,8 @@ fail_init_mfi: pci_free_consistent(pdev, sizeof(u32), instance->consumer, instance->consumer_h); scsi_host_put(host); -fail_set_dma_mask: -fail_ready_state: + fail_set_dma_mask: + fail_ready_state: pci_disable_device(pdev); return -ENODEV; @@ -2873,6 +3026,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); megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN); @@ -2925,6 +3079,7 @@ static void megasas_shutdown(struct pci_dev *pdev) { struct megasas_instance *instance = pci_get_drvdata(pdev); megasas_flush_cache(instance); + megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN); } /** @@ -2997,6 +3152,7 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, void *sense = NULL; dma_addr_t sense_handle; u32 *sense_ptr; + unsigned long *sense_buff; memset(kbuff_arr, 0, sizeof(kbuff_arr)); @@ -3101,17 +3257,24 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, */ if (ioc->sense_len) { /* - * sense_ptr points to the location that has the user + * 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 + - ioc->sense_off); - + ioc->sense_off); +#if defined(__ia64__) + if (copy_to_user((void __user *)((unsigned long)(*sense_buff)), +#else if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)), - sense, ioc->sense_len)) { - error = -EFAULT; - goto out; - } +#endif + sense, ioc->sense_len)) { + printk(KERN_ERR "megasas: Failed to copy out to user" + "sense data\n"); + error = -EFAULT; + goto out; + } } /* @@ -3139,20 +3302,6 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, return error; } -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_mgmt_ioctl_fw(struct file *file, unsigned long arg) { struct megasas_iocpacket __user *user_ioc = @@ -3343,7 +3492,7 @@ static DRIVER_ATTR(release_date, S_IRUGO, megasas_sysfs_show_release_date, static ssize_t megasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf) { - return sprintf(buf, "%u\n", megasas_dbg_lvl); + return sprintf(buf,"%u\n",megasas_dbg_lvl); } static ssize_t @@ -3363,19 +3512,18 @@ static DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUGO, megasas_sysfs_show_dbg_lvl, static ssize_t megasas_sysfs_show_poll_mode_io(struct device_driver *dd, char *buf) { - return sprintf(buf, "%u\n", poll_mode_io); + return sprintf(buf,"%u\n",poll_mode_io); } static ssize_t -megasas_sysfs_set_poll_mode_io(struct device_driver *dd, const char *buf, - size_t count) +megasas_sysfs_set_poll_mode_io(struct device_driver *dd, const char *buf, size_t count) { int retval = count; int tmp = poll_mode_io; int i; struct megasas_instance *instance; - if (sscanf(buf, "%u", &poll_mode_io) < 1) { + if(sscanf(buf,"%u",&poll_mode_io) < 1){ printk(KERN_ERR "megasas: could not set poll_mode_io\n"); retval = -EINVAL; } @@ -3393,13 +3541,13 @@ megasas_sysfs_set_poll_mode_io(struct device_driver *dd, const char *buf, for (i = 0; i < megasas_mgmt_info.max_index; i++) { instance = megasas_mgmt_info.instance[i]; if (instance) { - megasas_start_timer(instance, - &instance->io_completion_timer, + megasas_start_timer(instance, &instance->io_completion_timer, megasas_io_completion_timer, MEGASAS_COMPLETION_TIMER_INTERVAL); } } - } else { + } + else { /* * Delete timers for all adapters */ @@ -3414,9 +3562,8 @@ out: return retval; } -static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUGO, - megasas_sysfs_show_poll_mode_io, - megasas_sysfs_set_poll_mode_io); +static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUGO, megasas_sysfs_show_poll_mode_io, + megasas_sysfs_set_poll_mode_io); /** * megasas_init - Driver load entry point @@ -3474,6 +3621,7 @@ 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); @@ -3495,13 +3643,12 @@ err_pcidrv: static void __exit megasas_exit(void) { driver_remove_file(&megasas_pci_driver.driver, - &driver_attr_poll_mode_io); - driver_remove_file(&megasas_pci_driver.driver, - &driver_attr_dbg_lvl); + &driver_attr_poll_mode_io); driver_remove_file(&megasas_pci_driver.driver, - &driver_attr_release_date); + &driver_attr_dbg_lvl); driver_remove_file(&megasas_pci_driver.driver, - &driver_attr_version); + &driver_attr_release_date); + driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version); pci_unregister_driver(&megasas_pci_driver); unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl"); diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index b26f430e..1a89505f 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2,7 +2,7 @@ * * Linux MegaRAID driver for SAS based RAID controllers * - * Copyright (c) 2003-2005 LSI Corporation. + * Copyright (c) 2003-2005 LSI Logic Corporation. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -18,14 +18,15 @@ /* * MegaRAID SAS Driver meta data */ -#define MEGASAS_VERSION "00.00.03.15-RH1" -#define MEGASAS_RELDATE "Nov 21, 2007" -#define MEGASAS_EXT_VERSION "Wed Nov. 21 10:29:45 PST 2007" +#define MEGASAS_VERSION "00.00.03.21" +#define MEGASAS_RELDATE "June 12, 2008" +#define MEGASAS_EXT_VERSION "Thu June 12 09:41:51 PST 2008" /* * Device IDs */ #define PCI_DEVICE_ID_LSI_SAS1078R 0x0060 +#define PCI_DEVICE_ID_LSI_SAS1078DE 0x007C #define PCI_DEVICE_ID_LSI_VERDE_ZCR 0x0413 /* @@ -543,6 +544,10 @@ struct megasas_ctrl_info { #define MEGASAS_DBG_LVL 1 #define MEGASAS_FW_BUSY 1 +/* Frame Type */ +#define IO_FRAME 0 +#define PTHRU_FRAME 1 + /* * When SCSI mid-layer calls driver's reset routine, driver waits for * MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note @@ -553,7 +558,9 @@ struct megasas_ctrl_info { #define MEGASAS_RESET_WAIT_TIME 180 #define MEGASAS_INTERNAL_CMD_WAIT_TIME 180 #define MEGASAS_RESET_NOTICE_INTERVAL 5 + #define MEGASAS_IOCTL_CMD 0 + #define MEGASAS_DEFAULT_CMD_TIMEOUT 90 /* @@ -573,7 +580,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 @@ -1082,11 +1089,11 @@ struct megasas_instance { u16 max_num_sge; u16 max_fw_cmds; u32 max_sectors_per_req; + u32 cmd_per_lun; struct megasas_cmd **cmd_list; struct list_head cmd_pool; spinlock_t cmd_pool_lock; - /* used to synch producer, consumer ptrs */ spinlock_t completion_lock; struct dma_pool *frame_dma_pool; struct dma_pool *sense_dma_pool; @@ -1107,13 +1114,13 @@ struct megasas_instance { atomic_t fw_outstanding; u32 hw_crit_error; - + struct megasas_instance_template *instancet; struct tasklet_struct isr_tasklet; u8 flag; unsigned long last_time; - + struct timer_list io_completion_timer; };