1 diff -Nurp linux-2.6.22-950/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.22-960/drivers/scsi/megaraid/megaraid_sas.c
2 --- linux-2.6.22-950/drivers/scsi/megaraid/megaraid_sas.c 2007-07-08 19:32:17.000000000 -0400
3 +++ linux-2.6.22-960/drivers/scsi/megaraid/megaraid_sas.c 2010-07-20 16:47:48.000000000 -0400
6 * Linux MegaRAID driver for SAS based RAID controllers
8 - * Copyright (c) 2003-2005 LSI Logic Corporation.
9 + * Copyright (c) 2009 LSI Corporation.
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 - * as published by the Free Software Foundation; either version
14 - * 2 of the License, or (at your option) any later version.
15 + *as published by the Free Software Foundation; either version 2
16 + *of the License, or (at your option) any later version.
18 - * FILE : megaraid_sas.c
19 - * Version : v00.00.03.10-rc5
20 + *This program is distributed in the hope that it will be useful,
21 + *but WITHOUT ANY WARRANTY; without even the implied warranty of
22 + *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 + *GNU General Public License for more details.
26 - * (email-id : megaraidlinux@lsi.com)
27 - * Sreenivas Bagalkote
30 + *You should have received a copy of the GNU General Public License
31 + *along with this program; if not, write to the Free Software
32 + *Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
34 - * List of supported controllers
36 - * OEM Product Name VID DID SSVID SSID
37 - * --- ------------ --- --- ---- ----
38 + * Send feedback to <Bo.Yang@lsi.com>
41 #include <linux/kernel.h>
43 #include <linux/spinlock.h>
44 #include <linux/interrupt.h>
45 #include <linux/delay.h>
46 +#include <linux/smp_lock.h>
47 #include <linux/uio.h>
48 #include <asm/uaccess.h>
50 #include <linux/compat.h>
51 #include <linux/blkdev.h>
52 #include <linux/mutex.h>
53 +#include <linux/poll.h>
55 #include <scsi/scsi.h>
56 #include <scsi/scsi_cmnd.h>
58 #include <scsi/scsi_host.h>
59 #include "megaraid_sas.h"
62 + * poll_mode_io:1- schedule complete completion from q cmd
64 +static unsigned int poll_mode_io;
65 +module_param_named(poll_mode_io, poll_mode_io, int, 0);
66 +MODULE_PARM_DESC(poll_mode_io,
67 + "Complete cmds from IO path, (default=0)");
70 + * Number of sectors per IO command
71 + * Will be set in megasas_init_mfi if user does not provide
73 +static unsigned int max_sectors;
74 +module_param_named(max_sectors, max_sectors, int, 0);
75 +MODULE_PARM_DESC(max_sectors,
76 + "Maximum number of sectors per IO command");
78 MODULE_LICENSE("GPL");
79 MODULE_VERSION(MEGASAS_VERSION);
80 MODULE_AUTHOR("megaraidlinux@lsi.com");
81 -MODULE_DESCRIPTION("LSI Logic MegaRAID SAS Driver");
82 +MODULE_DESCRIPTION("LSI MegaRAID SAS Driver");
85 * PCI ID table for all supported controllers
86 @@ -60,6 +76,16 @@ static struct pci_device_id megasas_pci_
88 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078R)},
90 + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078DE)},
92 + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078GEN2)},
94 + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0079GEN2)},
96 + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0073SKINNY)},
98 + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0071SKINNY)},
100 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)},
101 /* xscale IOP, vega */
102 {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
103 @@ -73,9 +99,35 @@ static int megasas_mgmt_majorno;
104 static struct megasas_mgmt_info megasas_mgmt_info;
105 static struct fasync_struct *megasas_async_queue;
106 static DEFINE_MUTEX(megasas_async_queue_mutex);
107 +static DEFINE_MUTEX(megasas_poll_wait_mutex);
110 +static int megasas_poll_wait_aen;
111 +static DECLARE_WAIT_QUEUE_HEAD(megasas_poll_wait);
112 +static u32 support_poll_for_event;
113 +static u32 support_device_change;
115 +/* define lock for aen poll */
116 +spinlock_t poll_aen_lock;
118 static u32 megasas_dbg_lvl;
121 +megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
124 +static int megasas_transition_to_ready(struct megasas_instance* instance);
125 +static int megasas_get_pd_list(struct megasas_instance *instance);
126 +static int megasas_issue_init_mfi(struct megasas_instance *instance);
127 +static int megasas_register_aen(struct megasas_instance *instance, u32 seq_num, u32 class_locale_word);
128 +static int megasas_check_cpx_support( struct megasas_instance *instance);
129 +static u32 megasas_remove_cpx( struct megasas_instance *instance);
130 +static int megasas_send_cpx_queue_data( struct megasas_instance *instance );
131 +static int megasas_handle_cpx_requests( struct megasas_instance *instance);
132 +static u32 megasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem * regs);
133 +static int megasas_adp_reset_gen2(struct megasas_instance *instance, struct megasas_register_set __iomem * reg_set);
137 * megasas_get_cmd - Get a command from the free pool
138 * @instance: Adapter soft state
139 @@ -133,7 +185,7 @@ megasas_return_cmd(struct megasas_instan
141 megasas_enable_intr_xscale(struct megasas_register_set __iomem * regs)
143 - writel(1, &(regs)->outbound_intr_mask);
144 + writel(0, &(regs)->outbound_intr_mask);
146 /* Dummy readl to force pci flush */
147 readl(®s->outbound_intr_mask);
148 @@ -169,21 +221,27 @@ static int
149 megasas_clear_intr_xscale(struct megasas_register_set __iomem * regs)
154 * Check if it is our interrupt
156 status = readl(®s->outbound_intr_status);
158 - if (!(status & MFI_OB_INTR_STATUS_MASK)) {
161 + if (status & MFI_OB_INTR_STATUS_MASK)
162 + mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
163 + if (status & MFI_XSCALE_OMR0_CHANGE_INTERRUPT)
164 + mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
167 * Clear the interrupt by writing back the same value
170 writel(status, ®s->outbound_intr_status);
173 + /* Dummy readl to force pci flush */
174 + readl(®s->outbound_intr_status);
180 @@ -193,10 +251,69 @@ megasas_clear_intr_xscale(struct megasas
181 * @regs : MFI register set
184 -megasas_fire_cmd_xscale(dma_addr_t frame_phys_addr,u32 frame_count, struct megasas_register_set __iomem *regs)
185 +megasas_fire_cmd_xscale(struct megasas_instance *instance,
186 + dma_addr_t frame_phys_addr,
188 + struct megasas_register_set __iomem *regs)
190 + unsigned long flags;
191 + spin_lock_irqsave(&instance->hba_lock, flags);
192 writel((frame_phys_addr >> 3)|(frame_count),
193 &(regs)->inbound_queue_port);
194 + spin_unlock_irqrestore(&instance->hba_lock, flags);
198 + * megasas_adp_reset_xscale - For controller reset
199 + * @regs: MFI register set
202 +megasas_adp_reset_xscale(struct megasas_instance *instance, struct megasas_register_set __iomem * regs)
206 + writel(MFI_ADP_RESET, ®s->inbound_doorbell);
208 + for (i=0; i < 3; i++)
209 + msleep(1000); /* sleep for 3 secs */
211 + pci_read_config_dword(instance->pdev, MFI_1068_PCSR_OFFSET, &pcidata);
212 + printk("pcidata = %x\n", pcidata);
213 + if (pcidata & 0x2) {
214 + printk("mfi 1068 offset read=%x\n", pcidata);
216 + pci_write_config_dword(instance->pdev, MFI_1068_PCSR_OFFSET, pcidata);
218 + for (i=0; i<2; i++)
219 + msleep(1000); /* need to wait 2 secs again */
222 + pci_read_config_dword(instance->pdev, MFI_1068_FW_HANDSHAKE_OFFSET, &pcidata);
223 + printk("mfi 1068 offset handshake read=%x\n", pcidata);
224 + if ((pcidata & 0xffff0000) == MFI_1068_FW_READY) {
225 + printk("mfi 1068 offset handshake=%x\n", pcidata);
227 + pci_write_config_dword(instance->pdev, MFI_1068_FW_HANDSHAKE_OFFSET, pcidata);
234 + * megasas_check_reset_xscale - For controller reset check
235 + * @regs: MFI register set
238 +megasas_check_reset_xscale(struct megasas_instance *instance, struct megasas_register_set __iomem * regs)
241 + consumer = *instance->consumer;
243 + if ((instance->adprecovery != MEGASAS_HBA_OPERATIONAL) && (*instance->consumer == MEGASAS_ADPRESET_INPROG_SIGN)) {
250 static struct megasas_instance_template megasas_instance_template_xscale = {
251 @@ -206,6 +323,8 @@ static struct megasas_instance_template
252 .disable_intr = megasas_disable_intr_xscale,
253 .clear_intr = megasas_clear_intr_xscale,
254 .read_fw_status_reg = megasas_read_fw_status_reg_xscale,
255 + .adp_reset = megasas_adp_reset_xscale,
256 + .check_reset = megasas_check_reset_xscale,
260 @@ -227,7 +346,7 @@ megasas_enable_intr_ppc(struct megasas_r
262 writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
264 - writel(~0x80000004, &(regs)->outbound_intr_mask);
265 + writel(~0x80000000, &(regs)->outbound_intr_mask);
267 /* Dummy readl to force pci flush */
268 readl(®s->outbound_intr_mask);
269 @@ -270,7 +389,7 @@ megasas_clear_intr_ppc(struct megasas_re
270 status = readl(®s->outbound_intr_status);
272 if (!(status & MFI_REPLY_1078_MESSAGE_INTERRUPT)) {
278 @@ -278,7 +397,10 @@ megasas_clear_intr_ppc(struct megasas_re
280 writel(status, ®s->outbound_doorbell_clear);
283 + /* Dummy readl to force pci flush */
284 + readl(®s->outbound_doorbell_clear);
289 * megasas_fire_cmd_ppc - Sends command to the FW
290 @@ -287,10 +409,36 @@ megasas_clear_intr_ppc(struct megasas_re
291 * @regs : MFI register set
294 -megasas_fire_cmd_ppc(dma_addr_t frame_phys_addr, u32 frame_count, struct megasas_register_set __iomem *regs)
295 +megasas_fire_cmd_ppc(struct megasas_instance *instance,
296 + dma_addr_t frame_phys_addr,
298 + struct megasas_register_set __iomem *regs)
300 + unsigned long flags;
301 + spin_lock_irqsave(&instance->hba_lock, flags);
302 writel((frame_phys_addr | (frame_count<<1))|1,
303 &(regs)->inbound_queue_port);
304 + spin_unlock_irqrestore(&instance->hba_lock, flags);
308 + * megasas_adp_reset_ppc - For controller reset
309 + * @regs: MFI register set
312 +megasas_adp_reset_ppc(struct megasas_instance *instance, struct megasas_register_set __iomem * regs)
318 + * megasas_check_reset_ppc - For controller reset check
319 + * @regs: MFI register set
322 +megasas_check_reset_ppc(struct megasas_instance *instance, struct megasas_register_set __iomem * regs)
327 static struct megasas_instance_template megasas_instance_template_ppc = {
328 @@ -300,11 +448,321 @@ static struct megasas_instance_template
329 .disable_intr = megasas_disable_intr_ppc,
330 .clear_intr = megasas_clear_intr_ppc,
331 .read_fw_status_reg = megasas_read_fw_status_reg_ppc,
332 + .adp_reset = megasas_adp_reset_ppc,
333 + .check_reset = megasas_check_reset_ppc,
337 + * megasas_enable_intr_skinny - Enables interrupts
338 + * @regs: MFI register set
341 +megasas_enable_intr_skinny(struct megasas_register_set __iomem *regs)
343 + writel(0xFFFFFFFF, &(regs)->outbound_intr_mask);
345 + /* write ~0x00000005 (4 & 1) to the intr mask*/
346 + writel(~MFI_SKINNY_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
348 + /* Dummy readl to force pci flush */
349 + readl(®s->outbound_intr_mask);
353 + * megasas_disable_intr_skinny - Disables interrupt
354 + * @regs: MFI register set
357 +megasas_disable_intr_skinny(struct megasas_register_set __iomem *regs)
359 + u32 mask = 0xFFFFFFFF;
360 + writel(mask, ®s->outbound_intr_mask);
361 + /* Dummy readl to force pci flush */
362 + readl(®s->outbound_intr_mask);
366 + * megasas_read_fw_status_reg_skinny - returns the current FW status value
367 + * @regs: MFI register set
370 +megasas_read_fw_status_reg_skinny(struct megasas_register_set __iomem *regs)
372 + return readl(&(regs)->outbound_scratch_pad);
376 + * megasas_clear_interrupt_skinny - Check & clear interrupt
377 + * @regs: MFI register set
380 +megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs)
386 + * Check if it is our interrupt
388 + status = readl(®s->outbound_intr_status);
390 + if (!(status & MFI_SKINNY_ENABLE_INTERRUPT_MASK)) {
396 + * Check if it is our interrupt
398 + if ((megasas_read_fw_status_reg_gen2( regs) & MFI_STATE_MASK ) == MFI_STATE_FAULT ){
399 + mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
401 + mfiStatus |= MFI_INTR_FLAG_REPLY_MESSAGE;
404 + * Clear the interrupt by writing back the same value
406 + writel(status, ®s->outbound_intr_status);
409 + * dummy read to flush PCI
411 + readl(®s->outbound_intr_status);
417 + * megasas_fire_cmd_skinny - Sends command to the FW
418 + * @frame_phys_addr : Physical address of cmd
419 + * @frame_count : Number of frames for the command
420 + * @regs : MFI register set
423 +megasas_fire_cmd_skinny(struct megasas_instance *instance,
424 + dma_addr_t frame_phys_addr,
426 + struct megasas_register_set __iomem *regs)
428 + unsigned long flags;
429 + spin_lock_irqsave(&instance->hba_lock, flags);
430 + writel(0, &(regs)->inbound_high_queue_port);
431 + writel((frame_phys_addr | (frame_count<<1))|1,
432 + &(regs)->inbound_low_queue_port);
433 + spin_unlock_irqrestore(&instance->hba_lock, flags);
438 + * megasas_check_reset_skinny - For controller reset check
439 + * @regs: MFI register set
442 +megasas_check_reset_skinny(struct megasas_instance *instance, struct megasas_register_set __iomem * regs)
447 +static struct megasas_instance_template megasas_instance_template_skinny = {
449 + .fire_cmd = megasas_fire_cmd_skinny,
450 + .enable_intr = megasas_enable_intr_skinny,
451 + .disable_intr = megasas_disable_intr_skinny,
452 + .clear_intr = megasas_clear_intr_skinny,
453 + .read_fw_status_reg = megasas_read_fw_status_reg_skinny,
454 + .adp_reset = megasas_adp_reset_gen2,
455 + .check_reset = megasas_check_reset_skinny,
460 +* The following functions are defined for gen2 (deviceid : 0x78 0x79)
465 + * megasas_enable_intr_gen2 - Enables interrupts
466 + * @regs: MFI register set
469 +megasas_enable_intr_gen2(struct megasas_register_set __iomem *regs)
471 + writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
473 + /* write ~0x00000005 (4 & 1) to the intr mask*/
474 + writel(~MFI_GEN2_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
476 + /* Dummy readl to force pci flush */
477 + readl(®s->outbound_intr_mask);
481 + * megasas_disable_intr_gen2 - Disables interrupt
482 + * @regs: MFI register set
485 +megasas_disable_intr_gen2(struct megasas_register_set __iomem *regs)
487 + u32 mask = 0xFFFFFFFF;
488 + writel(mask, ®s->outbound_intr_mask);
489 + /* Dummy readl to force pci flush */
490 + readl(®s->outbound_intr_mask);
494 + * megasas_read_fw_status_reg_gen2 - returns the current FW status value
495 + * @regs: MFI register set
498 +megasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs)
500 + return readl(&(regs)->outbound_scratch_pad);
504 + * megasas_clear_interrupt_gen2 - Check & clear interrupt
505 + * @regs: MFI register set
508 +megasas_clear_intr_gen2(struct megasas_register_set __iomem *regs)
513 + * Check if it is our interrupt
515 + status = readl(®s->outbound_intr_status);
517 + if (status & MFI_GEN2_ENABLE_INTERRUPT_MASK)
519 + mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
521 + if (status & MFI_G2_OUTBOUND_DOORBELL_CHANGE_INTERRUPT)
523 + mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
527 + * Clear the interrupt by writing back the same value
530 + writel(status, ®s->outbound_doorbell_clear);
532 + /* Dummy readl to force pci flush */
533 + readl(®s->outbound_intr_status);
539 + * megasas_fire_cmd_gen2 - Sends command to the FW
540 + * @frame_phys_addr : Physical address of cmd
541 + * @frame_count : Number of frames for the command
542 + * @regs : MFI register set
545 +megasas_fire_cmd_gen2(struct megasas_instance *instance,
546 + dma_addr_t frame_phys_addr,
548 + struct megasas_register_set __iomem *regs)
550 + unsigned long flags;
551 + spin_lock_irqsave(&instance->hba_lock, flags);
552 + writel((frame_phys_addr | (frame_count<<1))|1,
553 + &(regs)->inbound_queue_port);
554 + spin_unlock_irqrestore(&instance->hba_lock, flags);
558 + * megasas_adp_reset_gen2 - For controller reset
559 + * @regs: MFI register set
562 +megasas_adp_reset_gen2(struct megasas_instance *instance, struct megasas_register_set __iomem * reg_set)
564 + u32 retry = 0, delay = 0;
566 + u32 *seq_offset = ®_set->seq_offset;
567 + u32 *hostdiag_offset = ®_set->host_diag;
569 + if ( instance->instancet == &megasas_instance_template_skinny ){
570 + seq_offset = ®_set->fusion_seq_offset;
571 + hostdiag_offset = ®_set->fusion_host_diag;
574 + writel(0, seq_offset);
575 + writel(4, seq_offset);
576 + writel(0xb, seq_offset);
577 + writel(2, seq_offset);
578 + writel(7, seq_offset);
579 + writel(0xd, seq_offset);
583 + HostDiag = (u32)readl(hostdiag_offset);
585 + while ( !( HostDiag & DIAG_WRITE_ENABLE) )
588 + HostDiag = (u32)readl(hostdiag_offset);
589 + printk("ADP_RESET_GEN2: retry time=%x, hostdiag=%x\n", retry, HostDiag);
591 + if (retry++ >= 100)
596 + printk("ADP_RESET_GEN2: HostDiag=%x\n", HostDiag);
598 + writel((HostDiag | DIAG_RESET_ADAPTER), hostdiag_offset);
600 + for (delay=0; delay<10; delay++)
605 + HostDiag = (u32)readl(hostdiag_offset);
606 + while ( ( HostDiag & DIAG_RESET_ADAPTER) )
609 + HostDiag = (u32)readl(hostdiag_offset);
610 + printk("ADP_RESET_GEN2: retry time=%x, hostdiag=%x\n", retry, HostDiag);
612 + if (retry++ >= 1000)
620 + * megasas_check_reset_gen2 - For controller reset check
621 + * @regs: MFI register set
624 +megasas_check_reset_gen2(struct megasas_instance *instance, struct megasas_register_set __iomem * regs)
626 + if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
633 +static struct megasas_instance_template megasas_instance_template_gen2 = {
635 + .fire_cmd = megasas_fire_cmd_gen2,
636 + .enable_intr = megasas_enable_intr_gen2,
637 + .disable_intr = megasas_disable_intr_gen2,
638 + .clear_intr = megasas_clear_intr_gen2,
639 + .read_fw_status_reg = megasas_read_fw_status_reg_gen2,
640 + .adp_reset = megasas_adp_reset_gen2,
641 + .check_reset = megasas_check_reset_gen2,
645 * This is the end of set of functions & definitions
646 -* specific to ppc (deviceid : 0x60) controllers
647 + * specific to gen2 (deviceid : 0x78, 0x79) controllers
651 @@ -328,13 +786,17 @@ megasas_issue_polled(struct megasas_inst
653 * Issue the frame using inbound queue port
655 - instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
656 + instance->instancet->fire_cmd(instance,
657 + cmd->frame_phys_addr, 0, instance->reg_set);
660 * Wait for cmd_status to change
662 for (i = 0; (i < msecs) && (frame_hdr->cmd_status == 0xff); i++) {
664 + //FW using xor/copy as soon as we enable cpx
665 + if ( instance->cpx_supported )
666 + megasas_handle_cpx_requests( instance);
670 @@ -359,10 +821,10 @@ megasas_issue_blocked_cmd(struct megasas
672 cmd->cmd_status = ENODATA;
674 - instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
675 + instance->instancet->fire_cmd(instance,
676 + cmd->frame_phys_addr, 0, instance->reg_set);
678 - wait_event_timeout(instance->int_cmd_wait_q, (cmd->cmd_status != ENODATA),
679 - MEGASAS_INTERNAL_CMD_WAIT_TIME*HZ);
680 + wait_event(instance->int_cmd_wait_q, cmd->cmd_status != ENODATA);
684 @@ -404,13 +866,15 @@ megasas_issue_blocked_abort_cmd(struct m
686 cmd->cmd_status = 0xFF;
688 - instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
689 + instance->instancet->fire_cmd(instance,
690 + cmd->frame_phys_addr, 0, instance->reg_set);
693 * Wait for this cmd to complete
695 - wait_event_timeout(instance->abort_cmd_wait_q, (cmd->cmd_status != 0xFF),
696 - MEGASAS_INTERNAL_CMD_WAIT_TIME*HZ);
697 + wait_event(instance->abort_cmd_wait_q, cmd->cmd_status != 0xFF);
701 megasas_return_cmd(instance, cmd);
703 @@ -433,34 +897,15 @@ megasas_make_sgl32(struct megasas_instan
705 struct scatterlist *os_sgl;
708 - * Return 0 if there is no data transfer
710 - if (!scp->request_buffer || !scp->request_bufflen)
713 - if (!scp->use_sg) {
714 - mfi_sgl->sge32[0].phys_addr = pci_map_single(instance->pdev,
720 - sc_data_direction);
721 - mfi_sgl->sge32[0].length = scp->request_bufflen;
722 + sge_count = scsi_dma_map(scp);
723 + BUG_ON(sge_count < 0);
728 - os_sgl = (struct scatterlist *)scp->request_buffer;
729 - sge_count = pci_map_sg(instance->pdev, os_sgl, scp->use_sg,
730 - scp->sc_data_direction);
732 - for (i = 0; i < sge_count; i++, os_sgl++) {
733 - mfi_sgl->sge32[i].length = sg_dma_len(os_sgl);
734 - mfi_sgl->sge32[i].phys_addr = sg_dma_address(os_sgl);
736 + scsi_for_each_sg(scp, os_sgl, sge_count, i) {
737 + mfi_sgl->sge32[i].length = sg_dma_len(os_sgl);
738 + mfi_sgl->sge32[i].phys_addr = sg_dma_address(os_sgl);
745 @@ -481,46 +926,58 @@ megasas_make_sgl64(struct megasas_instan
747 struct scatterlist *os_sgl;
750 - * Return 0 if there is no data transfer
752 - if (!scp->request_buffer || !scp->request_bufflen)
754 + sge_count = scsi_dma_map(scp);
755 + BUG_ON(sge_count < 0);
757 - if (!scp->use_sg) {
758 - mfi_sgl->sge64[0].phys_addr = pci_map_single(instance->pdev,
764 - sc_data_direction);
766 + scsi_for_each_sg(scp, os_sgl, sge_count, i) {
767 + mfi_sgl->sge64[i].length = sg_dma_len(os_sgl);
768 + mfi_sgl->sge64[i].phys_addr = sg_dma_address(os_sgl);
774 - mfi_sgl->sge64[0].length = scp->request_bufflen;
776 + * megasas_make_sgl_skinny - Prepares IEEE SGL
777 + * @instance: Adapter soft state
778 + * @scp: SCSI command from the mid-layer
779 + * @mfi_sgl: SGL to be filled in
781 + * If successful, this function returns the number of SG elements. Otherwise,
785 +megasas_make_sgl_skinny(struct megasas_instance *instance,
786 + struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl)
790 + struct scatterlist *os_sgl;
794 + sge_count = scsi_dma_map(scp);
796 - os_sgl = (struct scatterlist *)scp->request_buffer;
797 - sge_count = pci_map_sg(instance->pdev, os_sgl, scp->use_sg,
798 - scp->sc_data_direction);
800 - for (i = 0; i < sge_count; i++, os_sgl++) {
801 - mfi_sgl->sge64[i].length = sg_dma_len(os_sgl);
802 - mfi_sgl->sge64[i].phys_addr = sg_dma_address(os_sgl);
804 + scsi_for_each_sg(scp, os_sgl, sge_count, i) {
805 + mfi_sgl->sge_skinny[i].length = sg_dma_len(os_sgl);
806 + mfi_sgl->sge_skinny[i].phys_addr =
807 + sg_dma_address(os_sgl);
808 + mfi_sgl->sge_skinny[i].flag = 0;
816 * megasas_get_frame_count - Computes the number of frames
817 + * @frame_type : type of frame- io or pthru frame
818 * @sge_count : number of sg elements
820 * Returns the number of frames required for numnber of sge's (sge_count)
823 -static u32 megasas_get_frame_count(u8 sge_count)
824 +static u32 megasas_get_frame_count(struct megasas_instance *instance,
825 + u8 sge_count, u8 frame_type)
829 @@ -530,14 +987,31 @@ static u32 megasas_get_frame_count(u8 sg
830 sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
831 sizeof(struct megasas_sge32);
833 + if (instance->flag_ieee) {
834 + sge_sz = sizeof(struct megasas_sge_skinny);
838 - * Main frame can contain 2 SGEs for 64-bit SGLs and
839 - * 3 SGEs for 32-bit SGLs
842 - num_cnt = sge_count - 2;
844 - num_cnt = sge_count - 3;
845 + * Main frame can contain 2 SGEs for 64-bit SGLs and
846 + * 3 SGEs for 32-bit SGLs for ldio &
847 + * 1 SGEs for 64-bit SGLs and
848 + * 2 SGEs for 32-bit SGLs for pthru frame
850 + if (unlikely(frame_type == PTHRU_FRAME)) {
851 + if (instance->flag_ieee == 1) {
852 + num_cnt = sge_count - 1;
853 + } else if (IS_DMA64)
854 + num_cnt = sge_count - 1;
856 + num_cnt = sge_count - 2;
858 + if (instance->flag_ieee == 1) {
859 + num_cnt = sge_count - 1;
860 + } else if (IS_DMA64)
861 + num_cnt = sge_count - 2;
863 + num_cnt = sge_count - 3;
867 sge_bytes = sge_sz * num_cnt;
868 @@ -582,6 +1056,10 @@ megasas_build_dcdb(struct megasas_instan
869 else if (scp->sc_data_direction == PCI_DMA_NONE)
870 flags = MFI_FRAME_DIR_NONE;
872 + if (instance->flag_ieee == 1) {
873 + flags |= MFI_FRAME_IEEE;
877 * Prepare the DCDB frame
879 @@ -592,15 +1070,31 @@ megasas_build_dcdb(struct megasas_instan
880 pthru->lun = scp->device->lun;
881 pthru->cdb_len = scp->cmd_len;
884 pthru->flags = flags;
885 - pthru->data_xfer_len = scp->request_bufflen;
886 + pthru->data_xfer_len = scsi_bufflen(scp);
888 memcpy(pthru->cdb, scp->cmnd, scp->cmd_len);
891 + * If the command is for the tape device, set the
892 + * pthru timeout to the os layer timeout value.
894 + if (scp->device->type == TYPE_TAPE) {
895 + if ((scp->request->timeout / HZ) > 0xFFFF)
896 + pthru->timeout = 0xFFFF;
898 + pthru->timeout = scp->request->timeout / HZ;
905 + if (instance->flag_ieee == 1) {
906 + pthru->flags |= MFI_FRAME_SGL64;
907 + pthru->sge_count = megasas_make_sgl_skinny(instance, scp,
909 + } else if (IS_DMA64) {
910 pthru->flags |= MFI_FRAME_SGL64;
911 pthru->sge_count = megasas_make_sgl64(instance, scp,
913 @@ -608,6 +1102,10 @@ megasas_build_dcdb(struct megasas_instan
914 pthru->sge_count = megasas_make_sgl32(instance, scp,
917 + if (pthru->sge_count > instance->max_num_sge) {
918 + printk("megasas: build_dcdb error, two many SGE\n");
922 * Sense info specific
924 @@ -619,7 +1117,8 @@ megasas_build_dcdb(struct megasas_instan
925 * Compute the total number of frames this command consumes. FW uses
926 * this number to pull sufficient number of frames from host memory.
928 - cmd->frame_count = megasas_get_frame_count(pthru->sge_count);
929 + cmd->frame_count = megasas_get_frame_count(instance, pthru->sge_count,
932 return cmd->frame_count;
934 @@ -628,7 +1127,7 @@ megasas_build_dcdb(struct megasas_instan
935 * megasas_build_ldio - Prepares IOs to logical devices
936 * @instance: Adapter soft state
938 - * @cmd: Command to to be prepared
939 + * @cmd: Command to be prepared
941 * Frames (and accompanying SGLs) for regular SCSI IOs use this function.
943 @@ -649,6 +1148,10 @@ megasas_build_ldio(struct megasas_instan
944 else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
945 flags = MFI_FRAME_DIR_READ;
947 + if (instance->flag_ieee == 1) {
948 + flags |= MFI_FRAME_IEEE;
952 * Prepare the Logical IO frame: 2nd bit is zero for all read cmds
954 @@ -719,12 +1222,20 @@ megasas_build_ldio(struct megasas_instan
959 + if (instance->flag_ieee) {
960 + ldio->flags |= MFI_FRAME_SGL64;
961 + ldio->sge_count = megasas_make_sgl_skinny(instance, scp,
963 + } else if (IS_DMA64) {
964 ldio->flags |= MFI_FRAME_SGL64;
965 ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl);
967 ldio->sge_count = megasas_make_sgl32(instance, scp, &ldio->sgl);
969 + if (ldio->sge_count > instance->max_num_sge) {
970 + printk("megasas: build_ld_io error, sge_count = %x\n", ldio->sge_count);
974 * Sense info specific
976 @@ -736,7 +1247,8 @@ megasas_build_ldio(struct megasas_instan
977 * Compute the total number of frames this command consumes. FW uses
978 * this number to pull sufficient number of frames from host memory.
980 - cmd->frame_count = megasas_get_frame_count(ldio->sge_count);
981 + cmd->frame_count = megasas_get_frame_count(instance,
982 + ldio->sge_count, IO_FRAME);
984 return cmd->frame_count;
986 @@ -821,109 +1333,1311 @@ megasas_dump_pending_frames(struct megas
987 printk(KERN_ERR "\nmegasas[%d]: Pending Internal cmds in FW : \n",instance->host->host_no);
988 for (i = 0; i < max_cmd; i++) {
990 - cmd = instance->cmd_list[i];
991 + cmd = instance->cmd_list[i];
993 + if(cmd->sync_cmd == 1){
994 + printk(KERN_ERR "0x%08lx : ", (unsigned long)cmd->frame_phys_addr);
997 + printk(KERN_ERR "megasas[%d]: Dumping Done.\n\n",instance->host->host_no);
1001 + * megasas_queue_command - Queue entry point
1002 + * @scmd: SCSI command to be queued
1003 + * @done: Callback entry point
1006 +megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
1009 + struct megasas_cmd *cmd;
1010 + struct megasas_instance *instance;
1011 + unsigned long flags;
1013 + instance = (struct megasas_instance *)
1014 + scmd->device->host->hostdata;
1016 + if (instance->issuepend_done == 0)
1017 + return SCSI_MLQUEUE_HOST_BUSY;
1019 + spin_lock_irqsave(&instance->hba_lock, flags);
1020 + //Don't process if we have already declared adapter dead
1021 + // If we are in middle of bringing up the HBA, send the busy status to mid-layer
1022 + // till the process is complete
1023 + if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
1024 + spin_unlock_irqrestore(&instance->hba_lock, flags);
1025 + return SCSI_MLQUEUE_HOST_BUSY;
1028 + spin_unlock_irqrestore(&instance->hba_lock, flags);
1030 + scmd->scsi_done = done;
1033 + if (MEGASAS_IS_LOGICAL(scmd) &&
1034 + (scmd->device->id >= MEGASAS_MAX_LD || scmd->device->lun)) {
1035 + scmd->result = DID_BAD_TARGET << 16;
1039 + switch (scmd->cmnd[0]) {
1040 + case SYNCHRONIZE_CACHE:
1042 + * FW takes care of flush cache on its own
1043 + * No need to send it down
1045 + scmd->result = DID_OK << 16;
1051 + cmd = megasas_get_cmd(instance);
1053 + return SCSI_MLQUEUE_HOST_BUSY;
1056 + * Logical drive command
1058 + if (megasas_is_ldio(scmd))
1059 + frame_count = megasas_build_ldio(instance, scmd, cmd);
1061 + frame_count = megasas_build_dcdb(instance, scmd, cmd);
1064 + goto out_return_cmd;
1067 + scmd->SCp.ptr = (char *)cmd;
1070 + * Issue the command to the FW
1072 + atomic_inc(&instance->fw_outstanding);
1074 + instance->instancet->fire_cmd(instance, cmd->frame_phys_addr,
1075 + cmd->frame_count-1, instance->reg_set);
1077 + * Check if we have pend cmds to be completed
1079 + if (poll_mode_io && atomic_read(&instance->fw_outstanding))
1080 + tasklet_schedule(&instance->isr_tasklet);
1086 + megasas_return_cmd(instance, cmd);
1092 +static struct megasas_instance *megasas_lookup_instance(u16 host_no)
1096 + for (i = 0; i < megasas_mgmt_info.max_index; i++) {
1098 + if ((megasas_mgmt_info.instance[i]) &&
1099 + (megasas_mgmt_info.instance[i]->host->host_no == host_no))
1100 + return megasas_mgmt_info.instance[i];
1106 +static int megasas_slave_configure(struct scsi_device *sdev)
1109 + struct megasas_instance *instance ;
1111 + instance = megasas_lookup_instance(sdev->host->host_no);
1114 + * Don't export physical disk devices to the disk driver.
1116 + * FIXME: Currently we don't export them to the midlayer at all.
1117 + * That will be fixed once LSI engineers have audited the
1118 + * firmware for possible issues.
1120 + if (sdev->channel < MEGASAS_MAX_PD_CHANNELS) {
1121 + if (sdev->type == TYPE_TAPE) {
1122 + blk_queue_rq_timeout(sdev->request_queue,
1123 + MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
1125 + } else if (sdev->type == TYPE_DISK) {
1127 + pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id;
1129 + if ((instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) &&
1130 + (instance->pd_list[pd_index].driveType == TYPE_DISK)) {
1131 + blk_queue_rq_timeout(sdev->request_queue,
1132 + MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
1140 + * The RAID firmware may require extended timeouts.
1142 + blk_queue_rq_timeout(sdev->request_queue,
1143 + MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
1147 +static void megaraid_sas_kill_hba(struct megasas_instance *instance)
1149 + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
1150 + (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY))
1152 + writel(MFI_STOP_ADP,
1153 + &instance->reg_set->reserved_0);
1155 + writel(MFI_STOP_ADP,
1156 + &instance->reg_set->inbound_doorbell);
1163 +void xor_gen_15x1(u32 *buff_ptrs[16], u32 bytes)
1166 + u32 *d, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9, *s10, *s11, *s12, *s13, *s14, *s15;
1169 + s1 = buff_ptrs[1];
1170 + s2 = buff_ptrs[2];
1171 + s3 = buff_ptrs[3];
1172 + s4 = buff_ptrs[4];
1173 + s5 = buff_ptrs[5];
1174 + s6 = buff_ptrs[6];
1175 + s7 = buff_ptrs[7];
1176 + s8 = buff_ptrs[8];
1177 + s9 = buff_ptrs[9];
1178 + s10 = buff_ptrs[10];
1179 + s11 = buff_ptrs[11];
1180 + s12 = buff_ptrs[12];
1181 + s13 = buff_ptrs[13];
1182 + s14 = buff_ptrs[14];
1183 + s15 = buff_ptrs[15];
1185 + for (words = bytes/4, off=0; words>0; words--, off++)
1186 + d[off] = s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off] ^ s6[off] ^ s7[off] ^\
1187 + s8[off] ^ s9[off] ^ s10[off] ^ s11[off] ^ s12[off] ^ s13[off] ^ s14[off] ^ s15[off];
1192 +void xor_gen_14x1(u32 *buff_ptrs[15], u32 bytes)
1195 + u32 *d, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9, *s10, *s11, *s12, *s13, *s14;
1198 + s1 = buff_ptrs[1];
1199 + s2 = buff_ptrs[2];
1200 + s3 = buff_ptrs[3];
1201 + s4 = buff_ptrs[4];
1202 + s5 = buff_ptrs[5];
1203 + s6 = buff_ptrs[6];
1204 + s7 = buff_ptrs[7];
1205 + s8 = buff_ptrs[8];
1206 + s9 = buff_ptrs[9];
1207 + s10 = buff_ptrs[10];
1208 + s11 = buff_ptrs[11];
1209 + s12 = buff_ptrs[12];
1210 + s13 = buff_ptrs[13];
1211 + s14 = buff_ptrs[14];
1213 + for (words = bytes/4, off=0; words>0; words--, off++)
1214 + d[off] = s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off] ^ s6[off] ^ s7[off] ^\
1215 + s8[off] ^ s9[off] ^ s10[off] ^ s11[off] ^ s12[off] ^ s13[off] ^ s14[off];
1220 +void xor_gen_13x1(u32 *buff_ptrs[14], u32 bytes)
1223 + u32 *d, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9, *s10, *s11, *s12, *s13;
1226 + s1 = buff_ptrs[1];
1227 + s2 = buff_ptrs[2];
1228 + s3 = buff_ptrs[3];
1229 + s4 = buff_ptrs[4];
1230 + s5 = buff_ptrs[5];
1231 + s6 = buff_ptrs[6];
1232 + s7 = buff_ptrs[7];
1233 + s8 = buff_ptrs[8];
1234 + s9 = buff_ptrs[9];
1235 + s10 = buff_ptrs[10];
1236 + s11 = buff_ptrs[11];
1237 + s12 = buff_ptrs[12];
1238 + s13 = buff_ptrs[13];
1240 + for (words = bytes/4, off=0; words>0; words--, off++)
1241 + d[off] = s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off] ^ s6[off] ^ s7[off] ^\
1242 + s8[off] ^ s9[off] ^ s10[off] ^ s11[off] ^ s12[off] ^ s13[off];
1247 +void xor_gen_12x1(u32 *buff_ptrs[13], u32 bytes)
1250 + u32 *d, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9, *s10, *s11, *s12;
1253 + s1 = buff_ptrs[1];
1254 + s2 = buff_ptrs[2];
1255 + s3 = buff_ptrs[3];
1256 + s4 = buff_ptrs[4];
1257 + s5 = buff_ptrs[5];
1258 + s6 = buff_ptrs[6];
1259 + s7 = buff_ptrs[7];
1260 + s8 = buff_ptrs[8];
1261 + s9 = buff_ptrs[9];
1262 + s10 = buff_ptrs[10];
1263 + s11 = buff_ptrs[11];
1264 + s12 = buff_ptrs[12];
1266 + for (words = bytes/4, off=0; words>0; words--, off++)
1267 + d[off] = s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off] ^ s6[off] ^ s7[off] ^\
1268 + s8[off] ^ s9[off] ^ s10[off] ^ s11[off] ^ s12[off];
1273 +void xor_gen_11x1(u32 *buff_ptrs[12], u32 bytes)
1276 + u32 *d, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9, *s10, *s11;
1279 + s1 = buff_ptrs[1];
1280 + s2 = buff_ptrs[2];
1281 + s3 = buff_ptrs[3];
1282 + s4 = buff_ptrs[4];
1283 + s5 = buff_ptrs[5];
1284 + s6 = buff_ptrs[6];
1285 + s7 = buff_ptrs[7];
1286 + s8 = buff_ptrs[8];
1287 + s9 = buff_ptrs[9];
1288 + s10 = buff_ptrs[10];
1289 + s11 = buff_ptrs[11];
1291 + for (words = bytes/4, off=0; words>0; words--, off++)
1292 + d[off] = s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off] ^ s6[off] ^ s7[off] ^\
1293 + s8[off] ^ s9[off] ^ s10[off] ^ s11[off];
1298 +void xor_gen_10x1(u32 *buff_ptrs[11], u32 bytes)
1301 + u32 *d, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9, *s10;
1304 + s1 = buff_ptrs[1];
1305 + s2 = buff_ptrs[2];
1306 + s3 = buff_ptrs[3];
1307 + s4 = buff_ptrs[4];
1308 + s5 = buff_ptrs[5];
1309 + s6 = buff_ptrs[6];
1310 + s7 = buff_ptrs[7];
1311 + s8 = buff_ptrs[8];
1312 + s9 = buff_ptrs[9];
1313 + s10 = buff_ptrs[10];
1315 + for (words = bytes/4, off=0; words>0; words--, off++)
1316 + d[off] = s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off] ^ s6[off] ^ s7[off] ^\
1317 + s8[off] ^ s9[off] ^ s10[off];
1322 +void xor_gen_9x1(u32 *buff_ptrs[10], u32 bytes)
1325 + u32 *d, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9;
1328 + s1 = buff_ptrs[1];
1329 + s2 = buff_ptrs[2];
1330 + s3 = buff_ptrs[3];
1331 + s4 = buff_ptrs[4];
1332 + s5 = buff_ptrs[5];
1333 + s6 = buff_ptrs[6];
1334 + s7 = buff_ptrs[7];
1335 + s8 = buff_ptrs[8];
1336 + s9 = buff_ptrs[9];
1338 + for (words = bytes/4, off=0; words>0; words--, off++)
1339 + d[off] = s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off] ^ s6[off] ^ s7[off] ^\
1340 + s8[off] ^ s9[off];
1345 +void xor_gen_8x1(u32 *buff_ptrs[9], u32 bytes)
1348 + u32 *d, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8;
1351 + s1 = buff_ptrs[1];
1352 + s2 = buff_ptrs[2];
1353 + s3 = buff_ptrs[3];
1354 + s4 = buff_ptrs[4];
1355 + s5 = buff_ptrs[5];
1356 + s6 = buff_ptrs[6];
1357 + s7 = buff_ptrs[7];
1358 + s8 = buff_ptrs[8];
1360 + for (words = bytes/4, off=0; words>0; words--, off++)
1361 + d[off] = s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off] ^ s6[off] ^ s7[off] ^ s8[off];
1366 +void xor_gen_7x1(u32 *buff_ptrs[8], u32 bytes)
1369 + u32 *d, *s1, *s2, *s3, *s4, *s5, *s6, *s7;
1372 + s1 = buff_ptrs[1];
1373 + s2 = buff_ptrs[2];
1374 + s3 = buff_ptrs[3];
1375 + s4 = buff_ptrs[4];
1376 + s5 = buff_ptrs[5];
1377 + s6 = buff_ptrs[6];
1378 + s7 = buff_ptrs[7];
1380 + for (words = bytes/4, off=0; words>0; words--, off++)
1381 + d[off] = s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off] ^ s6[off] ^ s7[off];
1386 +void xor_gen_6x1(u32 *buff_ptrs[7], u32 bytes)
1389 + u32 *d, *s1, *s2, *s3, *s4, *s5, *s6;
1392 + s1 = buff_ptrs[1];
1393 + s2 = buff_ptrs[2];
1394 + s3 = buff_ptrs[3];
1395 + s4 = buff_ptrs[4];
1396 + s5 = buff_ptrs[5];
1397 + s6 = buff_ptrs[6];
1399 + for (words = bytes/4, off=0; words>0; words--, off++)
1400 + d[off] = s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off] ^ s6[off];
1405 +void xor_gen_5x1(u32 *buff_ptrs[6], u32 bytes)
1408 + u32 *d, *s1, *s2, *s3, *s4, *s5;
1411 + s1 = buff_ptrs[1];
1412 + s2 = buff_ptrs[2];
1413 + s3 = buff_ptrs[3];
1414 + s4 = buff_ptrs[4];
1415 + s5 = buff_ptrs[5];
1417 + for (words = bytes/4, off=0; words>0; words--, off++)
1418 + d[off] = s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off];
1423 +void xor_gen_4x1(u32 *buff_ptrs[5], u32 bytes)
1426 + u32 *d, *s1, *s2, *s3, *s4;
1429 + s1 = buff_ptrs[1];
1430 + s2 = buff_ptrs[2];
1431 + s3 = buff_ptrs[3];
1432 + s4 = buff_ptrs[4];
1434 + for (words = bytes/4, off=0; words>0; words--, off++)
1435 + d[off] = s1[off] ^ s2[off] ^ s3[off] ^ s4[off];
1440 +void xor_gen_3x1(u32 *buff_ptrs[4], u32 bytes)
1443 + u32 *d, *s1, *s2, *s3;
1446 + s1 = buff_ptrs[1];
1447 + s2 = buff_ptrs[2];
1448 + s3 = buff_ptrs[3];
1450 + for (words = bytes/4, off=0; words>0; words--, off++)
1451 + d[off] = s1[off] ^ s2[off] ^ s3[off];
1456 +void xor_gen_2x1(u32 *buff_ptrs[3], u32 bytes)
1462 + s1 = buff_ptrs[1];
1463 + s2 = buff_ptrs[2];
1465 + for (words = bytes/4, off=0; words>0; words--, off++)
1466 + d[off] = s1[off] ^ s2[off];
1471 +void xor_gen_1x1(u32 *buff_ptrs[2], u32 bytes)
1477 + s1 = buff_ptrs[1];
1479 + for (words = bytes/4, off=0; words>0; words--, off++)
1485 +u8 xor_chk_15x1(u32 *buff_ptrs[16], u32 bytes)
1488 + u32 r, *d, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9, *s10, *s11, *s12, *s13, *s14, *s15;
1489 + u8 xor_result = MR_CPX_STATUS_SUCCESS;
1492 + s1 = buff_ptrs[1];
1493 + s2 = buff_ptrs[2];
1494 + s3 = buff_ptrs[3];
1495 + s4 = buff_ptrs[4];
1496 + s5 = buff_ptrs[5];
1497 + s6 = buff_ptrs[6];
1498 + s7 = buff_ptrs[7];
1499 + s8 = buff_ptrs[8];
1500 + s9 = buff_ptrs[9];
1501 + s10 = buff_ptrs[10];
1502 + s11 = buff_ptrs[11];
1503 + s12 = buff_ptrs[12];
1504 + s13 = buff_ptrs[13];
1505 + s14 = buff_ptrs[14];
1506 + s15 = buff_ptrs[15];
1509 + for (words = bytes/4, off=0; words>0; words--, off++) {
1510 + r = d[off] ^ s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off] ^ s6[off] ^ s7[off] ^\
1511 + s8[off] ^ s9[off] ^ s10[off] ^ s11[off] ^ s12[off] ^ s13[off] ^ s14[off] ^ s15[off];
1513 + xor_result = MR_CPX_STATUS_INCONSISTENT;
1517 + return xor_result;
1521 +u8 xor_chk_14x1(u32 *buff_ptrs[15], u32 bytes)
1524 + u32 r, *d, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9, *s10, *s11, *s12, *s13, *s14;
1525 + u8 xor_result = MR_CPX_STATUS_SUCCESS;
1528 + s1 = buff_ptrs[1];
1529 + s2 = buff_ptrs[2];
1530 + s3 = buff_ptrs[3];
1531 + s4 = buff_ptrs[4];
1532 + s5 = buff_ptrs[5];
1533 + s6 = buff_ptrs[6];
1534 + s7 = buff_ptrs[7];
1535 + s8 = buff_ptrs[8];
1536 + s9 = buff_ptrs[9];
1537 + s10 = buff_ptrs[10];
1538 + s11 = buff_ptrs[11];
1539 + s12 = buff_ptrs[12];
1540 + s13 = buff_ptrs[13];
1541 + s14 = buff_ptrs[14];
1543 + for (words = bytes/4, off=0; words>0; words--, off++) {
1544 + r = d[off] ^ s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off] ^ s6[off] ^ s7[off] ^\
1545 + s8[off] ^ s9[off] ^ s10[off] ^ s11[off] ^ s12[off] ^ s13[off] ^ s14[off];
1547 + xor_result = MR_CPX_STATUS_INCONSISTENT;
1551 + return xor_result;
1556 +u8 xor_chk_13x1(u32 *buff_ptrs[14], u32 bytes)
1559 + u32 r, *d, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9, *s10, *s11, *s12, *s13;
1560 + u8 xor_result = MR_CPX_STATUS_SUCCESS;
1563 + s1 = buff_ptrs[1];
1564 + s2 = buff_ptrs[2];
1565 + s3 = buff_ptrs[3];
1566 + s4 = buff_ptrs[4];
1567 + s5 = buff_ptrs[5];
1568 + s6 = buff_ptrs[6];
1569 + s7 = buff_ptrs[7];
1570 + s8 = buff_ptrs[8];
1571 + s9 = buff_ptrs[9];
1572 + s10 = buff_ptrs[10];
1573 + s11 = buff_ptrs[11];
1574 + s12 = buff_ptrs[12];
1575 + s13 = buff_ptrs[13];
1577 + for (words = bytes/4, off=0; words>0; words--, off++) {
1578 + r = d[off] ^ s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off] ^ s6[off] ^ s7[off] ^\
1579 + s8[off] ^ s9[off] ^ s10[off] ^ s11[off] ^ s12[off] ^ s13[off];
1581 + xor_result = MR_CPX_STATUS_INCONSISTENT;
1585 + return xor_result;
1590 +u8 xor_chk_12x1(u32 *buff_ptrs[13], u32 bytes)
1593 + u32 r, *d, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9, *s10, *s11, *s12;
1594 + u8 xor_result = MR_CPX_STATUS_SUCCESS;
1597 + s1 = buff_ptrs[1];
1598 + s2 = buff_ptrs[2];
1599 + s3 = buff_ptrs[3];
1600 + s4 = buff_ptrs[4];
1601 + s5 = buff_ptrs[5];
1602 + s6 = buff_ptrs[6];
1603 + s7 = buff_ptrs[7];
1604 + s8 = buff_ptrs[8];
1605 + s9 = buff_ptrs[9];
1606 + s10 = buff_ptrs[10];
1607 + s11 = buff_ptrs[11];
1608 + s12 = buff_ptrs[12];
1610 + for (words = bytes/4, off=0; words>0; words--, off++) {
1611 + r = d[off] ^ s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off] ^ s6[off] ^ s7[off] ^\
1612 + s8[off] ^ s9[off] ^ s10[off] ^ s11[off] ^ s12[off];
1614 + xor_result = MR_CPX_STATUS_INCONSISTENT;
1618 + return xor_result;
1623 +u8 xor_chk_11x1(u32 *buff_ptrs[12], u32 bytes)
1626 + u32 r, *d, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9, *s10, *s11;
1627 + u8 xor_result = MR_CPX_STATUS_SUCCESS;
1630 + s1 = buff_ptrs[1];
1631 + s2 = buff_ptrs[2];
1632 + s3 = buff_ptrs[3];
1633 + s4 = buff_ptrs[4];
1634 + s5 = buff_ptrs[5];
1635 + s6 = buff_ptrs[6];
1636 + s7 = buff_ptrs[7];
1637 + s8 = buff_ptrs[8];
1638 + s9 = buff_ptrs[9];
1639 + s10 = buff_ptrs[10];
1640 + s11 = buff_ptrs[11];
1642 + for (words = bytes/4, off=0; words>0; words--, off++) {
1643 + r = d[off] ^ s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off] ^ s6[off] ^ s7[off] ^\
1644 + s8[off] ^ s9[off] ^ s10[off] ^ s11[off];
1646 + xor_result = MR_CPX_STATUS_INCONSISTENT;
1650 + return xor_result;
1655 +u8 xor_chk_10x1(u32 *buff_ptrs[11], u32 bytes)
1658 + u32 r, *d, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9, *s10;
1659 + u8 xor_result = MR_CPX_STATUS_SUCCESS;
1662 + s1 = buff_ptrs[1];
1663 + s2 = buff_ptrs[2];
1664 + s3 = buff_ptrs[3];
1665 + s4 = buff_ptrs[4];
1666 + s5 = buff_ptrs[5];
1667 + s6 = buff_ptrs[6];
1668 + s7 = buff_ptrs[7];
1669 + s8 = buff_ptrs[8];
1670 + s9 = buff_ptrs[9];
1671 + s10 = buff_ptrs[10];
1673 + for (words = bytes/4, off=0; words>0; words--, off++) {
1674 + r = d[off] ^ s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off] ^ s6[off] ^ s7[off] ^\
1675 + s8[off] ^ s9[off] ^ s10[off];
1677 + xor_result = MR_CPX_STATUS_INCONSISTENT;
1681 + return xor_result;
1685 +u8 xor_chk_9x1(u32 *buff_ptrs[10], u32 bytes)
1688 + u32 r, *d, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9;
1689 + u8 xor_result = MR_CPX_STATUS_SUCCESS;
1692 + s1 = buff_ptrs[1];
1693 + s2 = buff_ptrs[2];
1694 + s3 = buff_ptrs[3];
1695 + s4 = buff_ptrs[4];
1696 + s5 = buff_ptrs[5];
1697 + s6 = buff_ptrs[6];
1698 + s7 = buff_ptrs[7];
1699 + s8 = buff_ptrs[8];
1700 + s9 = buff_ptrs[9];
1702 + for (words = bytes/4, off=0; words>0; words--, off++) {
1703 + r = d[off] ^ s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off] ^ s6[off] ^ s7[off] ^\
1704 + s8[off] ^ s9[off];
1706 + xor_result = MR_CPX_STATUS_INCONSISTENT;
1710 + return xor_result;
1714 +u8 xor_chk_8x1(u32 *buff_ptrs[9], u32 bytes)
1717 + u32 r, *d, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8;
1718 + u8 xor_result = MR_CPX_STATUS_SUCCESS;
1721 + s1 = buff_ptrs[1];
1722 + s2 = buff_ptrs[2];
1723 + s3 = buff_ptrs[3];
1724 + s4 = buff_ptrs[4];
1725 + s5 = buff_ptrs[5];
1726 + s6 = buff_ptrs[6];
1727 + s7 = buff_ptrs[7];
1728 + s8 = buff_ptrs[8];
1730 + for (words = bytes/4, off=0; words>0; words--, off++) {
1731 + r = d[off] ^ s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off] ^ s6[off] ^ s7[off] ^ s8[off];
1733 + xor_result = MR_CPX_STATUS_INCONSISTENT;
1737 + return xor_result;
1741 +u8 xor_chk_7x1(u32 *buff_ptrs[8], u32 bytes)
1744 + u32 r, *d, *s1, *s2, *s3, *s4, *s5, *s6, *s7;
1745 + u8 xor_result = MR_CPX_STATUS_SUCCESS;
1748 + s1 = buff_ptrs[1];
1749 + s2 = buff_ptrs[2];
1750 + s3 = buff_ptrs[3];
1751 + s4 = buff_ptrs[4];
1752 + s5 = buff_ptrs[5];
1753 + s6 = buff_ptrs[6];
1754 + s7 = buff_ptrs[7];
1756 + for (words = bytes/4, off=0; words>0; words--, off++) {
1757 + r = d[off] ^ s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off] ^ s6[off] ^ s7[off];
1759 + xor_result = MR_CPX_STATUS_INCONSISTENT;
1763 + return xor_result;
1768 +u8 xor_chk_6x1(u32 *buff_ptrs[7], u32 bytes)
1771 + u32 r, *d, *s1, *s2, *s3, *s4, *s5, *s6;
1772 + u8 xor_result = MR_CPX_STATUS_SUCCESS;
1775 + s1 = buff_ptrs[1];
1776 + s2 = buff_ptrs[2];
1777 + s3 = buff_ptrs[3];
1778 + s4 = buff_ptrs[4];
1779 + s5 = buff_ptrs[5];
1780 + s6 = buff_ptrs[6];
1782 + for (words = bytes/4, off=0; words>0; words--, off++) {
1783 + r = d[off] ^ s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off] ^ s6[off];
1785 + xor_result = MR_CPX_STATUS_INCONSISTENT;
1789 + return xor_result;
1793 +u8 xor_chk_5x1(u32 *buff_ptrs[6], u32 bytes)
1796 + u32 r, *d, *s1, *s2, *s3, *s4, *s5;
1797 + u8 xor_result = MR_CPX_STATUS_SUCCESS;
1800 + s1 = buff_ptrs[1];
1801 + s2 = buff_ptrs[2];
1802 + s3 = buff_ptrs[3];
1803 + s4 = buff_ptrs[4];
1804 + s5 = buff_ptrs[5];
1806 + for (words = bytes/4, off=0; words>0; words--, off++) {
1807 + r = d[off] ^ s1[off] ^ s2[off] ^ s3[off] ^ s4[off] ^ s5[off];
1809 + xor_result = MR_CPX_STATUS_INCONSISTENT;
1813 + return xor_result;
1817 +u8 xor_chk_4x1(u32 *buff_ptrs[5], u32 bytes)
1820 + u32 r, *d, *s1, *s2, *s3, *s4;
1821 + u8 xor_result = MR_CPX_STATUS_SUCCESS;
1824 + s1 = buff_ptrs[1];
1825 + s2 = buff_ptrs[2];
1826 + s3 = buff_ptrs[3];
1827 + s4 = buff_ptrs[4];
1829 + for (words = bytes/4, off=0; words>0; words--, off++) {
1830 + r = d[off] ^ s1[off] ^ s2[off] ^ s3[off] ^ s4[off];
1832 + xor_result = MR_CPX_STATUS_INCONSISTENT;
1836 + return xor_result;
1840 +u8 xor_chk_3x1(u32 *buff_ptrs[4], u32 bytes)
1843 + u32 r, *d, *s1, *s2, *s3;
1844 + u8 xor_result = MR_CPX_STATUS_SUCCESS;
1847 + s1 = buff_ptrs[1];
1848 + s2 = buff_ptrs[2];
1849 + s3 = buff_ptrs[3];
1851 + for (words = bytes/4, off=0; words>0; words--, off++) {
1852 + r = d[off] ^ s1[off] ^ s2[off] ^ s3[off];
1854 + xor_result = MR_CPX_STATUS_INCONSISTENT;
1858 + return xor_result;
1862 +u8 xor_chk_2x1(u32 *buff_ptrs[3], u32 bytes)
1865 + u32 r, *d, *s1, *s2;
1866 + u8 xor_result = MR_CPX_STATUS_SUCCESS;
1869 + s1 = buff_ptrs[1];
1870 + s2 = buff_ptrs[2];
1872 + for (words = bytes/4, off=0; words>0; words--, off++) {
1873 + r = d[off] ^ s1[off] ^ s2[off];
1875 + xor_result = MR_CPX_STATUS_INCONSISTENT;
1879 + return xor_result;
1883 +u8 xor_chk_1x1(u32 *buff_ptrs[2], u32 bytes)
1887 + u8 xor_result = MR_CPX_STATUS_SUCCESS;
1890 + s1 = buff_ptrs[1];
1892 + for (words = bytes/4, off=0; words>0; words--, off++) {
1893 + if (d[off] != s1[off]) {
1894 + xor_result = MR_CPX_STATUS_INCONSISTENT;
1898 + return xor_result;
1902 +XOR_LOW_LEVEL_GEN_FUNC xor_gen_funcs[MAX_MR_ROW_SIZE] = {
1920 +XOR_LOW_LEVEL_CHECK_FUNC xor_check_funcs[MAX_MR_ROW_SIZE] = {
1938 +inline static u8 megasas_scan_set_bit(u32 bitmap)
1954 + * megasas_do_cpx_xor - completes the xor operation
1955 + * @xor_des : soruce and dest buffers details.
1956 + * @host_mem : previously mapped memory for fw
1957 + * @host_mem_len : mapped memory length in bytes.
1959 + * @return 0 on success != 0 on failure
1962 +static u8 megasas_do_cpx_xor( struct mr_cpx_xor_descriptor *xor_des, const u8 *host_mem, const u32 host_mem_len)
1965 + u32 buff_valid_bit_map = xor_des->buff_valid_bitmap;
1966 + u32 *buf_ptr_list[MAX_MR_ROW_SIZE];
1967 + u32 tx_count = xor_des->size;
1968 + u8 dest_idx, buf_idx, bit;
1969 + u8 is_op_gen; // means is XOR generation (TRUE) or check (FALSE)
1970 + u8 status = MR_CPX_STATUS_SUCCESS;
1973 + //make the first buffer ptr as the destination.
1974 + if( xor_des->op == MR_CPX_XOR_OP_GEN_P || xor_des->op == MR_CPX_XOR_OP_CHECK_P )
1975 + dest_idx = xor_des->p_idx;
1977 + dest_idx = xor_des->q_idx;
1979 + buf_ptr_list[0] = (u32 *)(host_mem + xor_des->buff_list[dest_idx]);
1981 + is_op_gen = MR_CPX_XOR_OP_IS_GEN(xor_des->op);
1983 + if ( xor_des->buff_list[dest_idx]+tx_count > host_mem_len){
1984 + printk("Error: 1st host memory over flow detected.\n");
1985 + return MR_CPX_STATUS_FAILURE;
1989 + * For XOR_OP_CHECK_P, our check routine expects bufPtrs[0] to be both parity
1990 + * source and parity destination; clear out the P-index from our working bitmap
1991 + * so that the source-buffer scan loop below doesn't include P as one of the
1992 + * explicit source buffers in bufPtrs[].
1995 + buff_valid_bit_map &= ~(1<<xor_des->p_idx);
1997 + //populate buf_ptr_list with valid buffer pointers.
1998 + for ( buf_idx =1 ; buff_valid_bit_map != 0 ; buf_idx++ ){
1999 + bit = megasas_scan_set_bit( buff_valid_bit_map);
2000 + buf_ptr_list[buf_idx] = (u32 *)(host_mem + (u32)xor_des->buff_list[bit]);
2001 + if ( xor_des->buff_list[bit]+tx_count > host_mem_len) {
2002 + printk("Error: host memory over flow detected.\n");
2003 + return MR_CPX_STATUS_FAILURE;;
2005 + buff_valid_bit_map &= ~(1 <<bit);
2007 + //call the xor gen fuctions.
2009 + (*xor_gen_funcs[buf_idx-2])(buf_ptr_list, tx_count);
2011 + status = (*xor_check_funcs[buf_idx-2])(buf_ptr_list, tx_count);
2016 +static u8 megasas_copy( struct page *page, u32 page_offset, u32 sge_offset, u8 *host_ptr, u32 len, u8 dir)
2024 + off = page_offset+sge_offset;
2026 + //kmap_atomic maps single page size but os sg element can have size
2027 + //more than page size, handle it.
2028 + while( remaining > 0 ){
2030 + bytes_copied = min((size_t)remaining, (size_t)(PAGE_SIZE - (off & ~PAGE_MASK)));
2032 + page_addr = kmap_atomic(page+ (off >> PAGE_SHIFT), KM_SOFTIRQ0);
2033 + if ( page_addr == NULL ){
2034 + printk("kmap_atomic is failed.\n");
2035 + return MR_CPX_STATUS_FAILURE;;
2037 + if ( dir == MR_CPX_DIR_WRITE )
2038 + memcpy( host_ptr, page_addr+(off & ~PAGE_MASK), bytes_copied );
2040 + memcpy( page_addr+(off & ~PAGE_MASK), host_ptr, bytes_copied );
2042 + kunmap_atomic ( page_addr, KM_SOFTIRQ0 );
2044 + host_ptr += bytes_copied;
2045 + remaining -= bytes_copied;
2046 + off += bytes_copied;
2049 + return MR_CPX_STATUS_SUCCESS;
2052 + * megasas_do_cpx_copy - Completes the copy opreation
2053 + * @instance : Driver soft state.
2054 + * @cpy_des : input for copying the data.
2056 + * @return 0 on success != 0 on failure
2059 +static u8 megasas_do_cpx_copy( struct megasas_instance *instance, struct mr_cpx_copy_descriptor *cpy_des)
2061 + u8 status = MR_CPX_STATUS_SUCCESS ;
2062 + u32 total_remaining_len = cpy_des->total_byte_count;
2063 + u32 row_remaining_length;
2064 + u32 os_sge_sz = 0, os_sge_offset = 0, os_sge_idx =0, os_sge_len;
2065 + u8 sge_cnt, row_idx, *fw_ptr,host_skip_count_handled;
2066 + struct scsi_cmnd *os_cmd;
2067 + struct scatterlist *os_sgl;
2068 + struct megasas_cmd *mega_cmd;
2069 + struct megasas_io_frame *ldio;
2071 + if ( cpy_des->mfi_cmd_cxt >= instance->max_fw_cmds ){
2072 + printk("megasas: invalid context - 0x%x shoul be < 0x%x \n", cpy_des->mfi_cmd_cxt ,instance->max_fw_cmds );
2073 + return MR_CPX_STATUS_FAILURE;
2076 + mega_cmd = ( struct megasas_cmd *) instance->cmd_list[cpy_des->mfi_cmd_cxt];
2077 + os_cmd = mega_cmd->scmd;
2078 + ldio = (struct megasas_io_frame *)mega_cmd->frame;
2079 + sge_cnt = ldio->sge_count;
2081 + host_skip_count_handled = 0;
2083 + row_remaining_length =0;
2085 + scsi_for_each_sg(os_cmd, os_sgl, sge_cnt, os_sge_idx){
2087 + os_sge_len = sg_dma_len(os_sgl);
2089 + if ( !host_skip_count_handled && cpy_des->host_skip_count < ( os_sge_sz += os_sge_len ) ){
2090 + os_sge_offset = cpy_des->host_skip_count - ( os_sge_sz -os_sge_len );
2091 + os_sge_len -= os_sge_offset;
2092 + host_skip_count_handled = 1;
2093 + } else if ( !host_skip_count_handled && cpy_des->host_skip_count == os_sge_sz ){
2094 + os_sge_offset = 0;
2095 + host_skip_count_handled = 1;
2099 + if ( !host_skip_count_handled )
2102 + for( ;total_remaining_len && row_idx < MAX_MR_ROW_SIZE ; row_idx++ ){
2104 + if ( ! row_remaining_length ){
2105 + fw_ptr = (u8 *)(instance->host_mem_virt+cpy_des->copy_buf[row_idx].buf);
2106 + row_remaining_length = cpy_des->copy_buf[row_idx].size;
2109 + if ( (status = megasas_copy( sg_page(os_sgl), os_sgl->offset, os_sge_offset, fw_ptr,
2110 + MIN(os_sge_len, row_remaining_length), cpy_des->dir) ) )
2113 + total_remaining_len -= MIN(os_sge_len, row_remaining_length);
2115 + if ( os_sge_len <= row_remaining_length ){
2116 + fw_ptr += os_sge_len;
2117 + if ( !(row_remaining_length -= os_sge_len) ) row_idx++;
2118 + os_sge_offset = 0;
2121 + os_sge_len -= row_remaining_length;
2122 + os_sge_offset += row_remaining_length;
2123 + row_remaining_length =0;
2127 + if ( row_idx >= MAX_MR_ROW_SIZE && total_remaining_len )
2128 + printk("megasas: Reached end of fw sglist while pending data transfer,row_idx = 0x%x, total_remaining_len = 0x%x \n",
2129 + row_idx, total_remaining_len);
2131 + if( total_remaining_len == 0 || status == MR_CPX_STATUS_FAILURE )
2135 + if ( os_sge_idx >= sge_cnt && total_remaining_len )
2136 + printk("megasas: Reached end of os sglist while pending data transfer, os_sge_idx = 0x%x, total_remaining_len = 0x%x \n",
2137 + os_sge_idx, total_remaining_len);
2143 + * megasas_handle_cpx_requests - Manages the fw queues
2144 + * @instance : Driver soft state.
2146 + * @return 0 on success != 0 on failure
2149 +static int megasas_handle_cpx_requests( struct megasas_instance *instance)
2151 + struct mr_cpx_request_queue *req_q = instance->cpx_request_queue;
2152 + u32 producer_idx, consumer_idx;
2154 + unsigned long flags;
2156 - if(cmd->sync_cmd == 1){
2157 - printk(KERN_ERR "0x%08lx : ", (unsigned long)cmd->frame_phys_addr);
2158 + producer_idx = req_q->producer_idx;
2159 + consumer_idx = req_q->consumer_idx;
2161 + while (producer_idx != consumer_idx ){
2162 + union mr_cpx_descriptor *cpx_des = &instance->cpx_dscrptr[consumer_idx];
2163 + union mr_cpx_response_data rsp_data;
2165 + if ( cpx_des->cpx_copy_desc.hdr.type == MR_CPX_DESCRIPTOR_TYPE_COPY )
2166 + retval = megasas_do_cpx_copy( instance, ( struct mr_cpx_copy_descriptor *)cpx_des );
2168 + else if (cpx_des->cpx_copy_desc.hdr.type == MR_CPX_DESCRIPTOR_TYPE_XOR )
2169 + retval = megasas_do_cpx_xor( ( struct mr_cpx_xor_descriptor *)cpx_des,
2170 + (u8 *)instance->host_mem_virt, instance->host_mem_len );
2172 + printk("Fatal Error : Got invalid descriptor type...\n");
2173 + retval = MR_CPX_STATUS_FAILURE;
2177 + rsp_data.r.status = retval;
2178 + rsp_data.r.context = cpx_des->cpx_copy_desc.hdr.context;
2179 + rsp_data.r.type = cpx_des->cpx_copy_desc.hdr.type;
2182 + spin_lock_irqsave(&instance->hba_lock, flags);
2183 + writel( ~0, &instance->reg_set->inbound_high_queue_port);
2184 + writel( rsp_data.w, &instance->reg_set->inbound_low_queue_port);
2185 + spin_unlock_irqrestore(&instance->hba_lock, flags);
2187 + //take care of wrap around case.
2189 + if ( consumer_idx == instance->cpx_dscrptr_cnt )
2193 - printk(KERN_ERR "megasas[%d]: Dumping Done.\n\n",instance->host->host_no);
2194 + req_q->consumer_idx = producer_idx;
2200 - * megasas_queue_command - Queue entry point
2201 - * @scmd: SCSI command to be queued
2202 - * @done: Callback entry point
2203 + * megasas_complete_cmd_dpc - Returns FW's controller structure
2204 + * @instance_addr: Address of adapter soft state
2206 + * Tasklet to complete cmds
2209 -megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
2210 +static void megasas_complete_cmd_dpc(unsigned long instance_addr)
2216 struct megasas_cmd *cmd;
2217 - struct megasas_instance *instance;
2218 + struct megasas_instance *instance =
2219 + (struct megasas_instance *)instance_addr;
2220 + unsigned long flags;
2222 - instance = (struct megasas_instance *)
2223 - scmd->device->host->hostdata;
2224 + /* If we have already declared adapter dead, donot complete cmds */
2225 + spin_lock_irqsave(&instance->hba_lock, flags);
2226 + if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR ) {
2227 + spin_unlock_irqrestore(&instance->hba_lock, flags);
2230 + spin_unlock_irqrestore(&instance->hba_lock, flags);
2232 - /* Don't process if we have already declared adapter dead */
2233 - if (instance->hw_crit_error)
2234 - return SCSI_MLQUEUE_HOST_BUSY;
2235 + spin_lock_irqsave(&instance->completion_lock, flags);
2237 - scmd->scsi_done = done;
2239 + producer = *instance->producer;
2240 + consumer = *instance->consumer;
2242 - if (MEGASAS_IS_LOGICAL(scmd) &&
2243 - (scmd->device->id >= MEGASAS_MAX_LD || scmd->device->lun)) {
2244 - scmd->result = DID_BAD_TARGET << 16;
2247 + while (consumer != producer) {
2248 + context = instance->reply_queue[consumer];
2249 + if (context >= instance->max_fw_cmds) {
2250 + printk("ERROR ERROR: unexpected context value %x\n", context);
2254 - switch (scmd->cmnd[0]) {
2255 - case SYNCHRONIZE_CACHE:
2257 - * FW takes care of flush cache on its own
2258 - * No need to send it down
2260 - scmd->result = DID_OK << 16;
2264 + cmd = instance->cmd_list[context];
2266 + megasas_complete_cmd(instance, cmd, DID_OK);
2269 + if (consumer == (instance->max_fw_cmds + 1)) {
2274 - cmd = megasas_get_cmd(instance);
2276 - return SCSI_MLQUEUE_HOST_BUSY;
2277 + *instance->consumer = producer;
2280 - * Logical drive command
2282 - if (megasas_is_ldio(scmd))
2283 - frame_count = megasas_build_ldio(instance, scmd, cmd);
2285 - frame_count = megasas_build_dcdb(instance, scmd, cmd);
2286 + spin_unlock_irqrestore(&instance->completion_lock, flags);
2290 - goto out_return_cmd;
2293 - scmd->SCp.ptr = (char *)cmd;
2294 + if ( instance->cpx_supported )
2295 + megasas_handle_cpx_requests( instance);
2298 - * Issue the command to the FW
2299 + * Check if we can restore can_queue
2301 - atomic_inc(&instance->fw_outstanding);
2303 - instance->instancet->fire_cmd(cmd->frame_phys_addr ,cmd->frame_count-1,instance->reg_set);
2304 + if (instance->flag & MEGASAS_FW_BUSY
2305 + && time_after(jiffies, instance->last_time + 5 * HZ)
2306 + && atomic_read(&instance->fw_outstanding) < 17) {
2309 + spin_lock_irqsave(instance->host->host_lock, flags);
2310 + instance->flag &= ~MEGASAS_FW_BUSY;
2311 + if ((instance->pdev->device ==
2312 + PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
2313 + (instance->pdev->device ==
2314 + PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
2315 + instance->host->can_queue =
2316 + instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
2318 + instance->host->can_queue =
2319 + instance->max_fw_cmds - MEGASAS_INT_CMDS;
2322 - megasas_return_cmd(instance, cmd);
2326 + spin_unlock_irqrestore(instance->host->host_lock, flags);
2330 -static int megasas_slave_configure(struct scsi_device *sdev)
2333 - * Don't export physical disk devices to the disk driver.
2335 - * FIXME: Currently we don't export them to the midlayer at all.
2336 - * That will be fixed once LSI engineers have audited the
2337 - * firmware for possible issues.
2339 - if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && sdev->type == TYPE_DISK)
2341 +static void megasas_internal_reset_defer_cmds(struct megasas_instance *instance);
2342 +static void process_fw_state_change_wq(struct work_struct *work);
2345 - * The RAID firmware may require extended timeouts.
2347 - if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS)
2348 - sdev->timeout = MEGASAS_DEFAULT_CMD_TIMEOUT * HZ;
2350 +void megasas_do_ocr(struct megasas_instance *instance)
2352 + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) ||
2353 + (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) ||
2354 + (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR))
2356 + *instance->consumer = MEGASAS_ADPRESET_INPROG_SIGN;
2359 + instance->instancet->disable_intr(instance->reg_set);
2360 + instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
2361 + instance->issuepend_done = 0;
2363 + atomic_set(&instance->fw_outstanding, 0);
2364 + megasas_internal_reset_defer_cmds(instance);
2365 + process_fw_state_change_wq(&instance->work_init);
2370 * megasas_wait_for_outstanding - Wait for all outstanding cmds
2371 * @instance: Adapter soft state
2372 @@ -934,11 +2648,86 @@ static int megasas_slave_configure(struc
2374 static int megasas_wait_for_outstanding(struct megasas_instance *instance)
2379 u32 wait_time = MEGASAS_RESET_WAIT_TIME;
2381 + unsigned long flags;
2382 + struct list_head clist_local;
2383 + struct megasas_cmd *reset_cmd;
2385 + u8 kill_adapter_flag;
2387 - for (i = 0; i < wait_time; i++) {
2389 + // If we are in-process if internal reset, we should wait for that process to
2391 + spin_lock_irqsave(&instance->hba_lock, flags);
2392 + adprecovery = instance->adprecovery;
2393 + spin_unlock_irqrestore(&instance->hba_lock, flags);
2395 + if (adprecovery != MEGASAS_HBA_OPERATIONAL) {
2397 + // We take the ownership of all the pending commands. These would be failed to the OS
2398 + // after a successful recovery from adapter internal reset condition.
2399 + INIT_LIST_HEAD(&clist_local);
2400 + spin_lock_irqsave(&instance->hba_lock, flags);
2401 + list_splice_init(&instance->internal_reset_pending_q, &clist_local);
2402 + spin_unlock_irqrestore(&instance->hba_lock, flags);
2404 + printk("megasas: HBA reset handler invoked while adapter internal reset in progress, wait till that's over...\n");
2405 + for (i = 0; i < wait_time; i++) {
2407 + // Are we there yet?
2408 + spin_lock_irqsave(&instance->hba_lock, flags);
2409 + adprecovery = instance->adprecovery;
2410 + spin_unlock_irqrestore(&instance->hba_lock, flags);
2411 + if (adprecovery == MEGASAS_HBA_OPERATIONAL)
2415 + // Are we out of reset yet? If not, HBA is toasted :-(
2416 + if (adprecovery != MEGASAS_HBA_OPERATIONAL) {
2417 + printk("megasas: HBA reset handler timedout for internal reset. Stopping the HBA.\n");
2418 + spin_lock_irqsave(&instance->hba_lock, flags);
2419 + instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
2420 + spin_unlock_irqrestore(&instance->hba_lock, flags);
2424 + printk("megasas: HBA internal reset condition discovered to be cleared.\n");
2426 + // Send the pending commands back to the OS with reset condition
2428 + while (!list_empty(&clist_local)) {
2429 + reset_cmd = list_entry((&clist_local)->next, struct megasas_cmd, list);
2430 + list_del_init(&reset_cmd->list);
2431 + if (reset_cmd->scmd) {
2432 + reset_cmd->scmd->result = DID_RESET << 16;
2433 + printk("megasas: %d:%p reset scsi command [%02x], %#lx\n",
2434 + reset_index, reset_cmd, reset_cmd->scmd->cmnd[0], reset_cmd->scmd->serial_number);
2435 + reset_cmd->scmd->scsi_done(reset_cmd->scmd);
2436 + megasas_return_cmd(instance, reset_cmd);
2438 + else if (reset_cmd->sync_cmd) {
2439 + // Such commands have no timeout, we re-issue this guy again.
2440 + printk("megasas: %p synchronous command detected on the internal reset queue, re-issuing it.\n", reset_cmd);
2441 + reset_cmd->cmd_status = ENODATA;
2442 + instance->instancet->fire_cmd(instance, reset_cmd->frame_phys_addr ,0,instance->reg_set);
2445 + printk("megasas: %p unexpected command on the internal reset defer list.\n", reset_cmd);
2450 + printk("megaraid_sas: All pending commands have been cleared for reset condition.\n");
2455 + // Kernel reset without internal reset in progress.
2456 + printk("megaraid_sas: HBA reset handler invoked without an internal reset condition.\n");
2457 + for (i = 0; i < wait_time; i++) {
2458 int outstanding = atomic_read(&instance->fw_outstanding);
2461 @@ -947,23 +2736,79 @@ static int megasas_wait_for_outstanding(
2462 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
2463 printk(KERN_NOTICE "megasas: [%2d]waiting for %d "
2464 "commands to complete\n",i,outstanding);
2466 + * Call cmd completion routine. Cmd to be
2467 + * be completed directly without depending on isr.
2469 + megasas_complete_cmd_dpc((unsigned long)instance);
2475 - if (atomic_read(&instance->fw_outstanding)) {
2477 + kill_adapter_flag = 0;
2479 + fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
2480 + if ((fw_state == MFI_STATE_FAULT) && (instance->disableOnlineCtrlReset == 0)) {
2481 + printk("megasas: waiting_for_outstanding: before issue OCR. FW state = %x\n", fw_state);
2483 + kill_adapter_flag = 2;
2486 + megasas_do_ocr(instance);
2487 + kill_adapter_flag = 1;
2488 + printk("megasas: waiting_for_outstanding: after issue OCR. \n");
2490 + /* wait for 5 secs to let the FW finish all the pending cmds*/
2491 + for (sl=0; sl<10; sl++)
2497 + if (atomic_read(&instance->fw_outstanding) && !kill_adapter_flag) {
2498 + if (instance->disableOnlineCtrlReset == 0) {
2499 + printk("megasas: waiting_for_outstanding: before issue OCR. FW state = %x\n", fw_state);
2500 + megasas_do_ocr(instance);
2501 + printk("megasas: waiting_for_outstanding: after issue OCR. \n");
2503 + /* wait for 5 secs to let the FW finish all the pending cmds*/
2504 + for (i = 0; i < wait_time; i++) {
2505 + int outstanding = atomic_read(&instance->fw_outstanding);
2514 + if (atomic_read(&instance->fw_outstanding) || (kill_adapter_flag == 2)) {
2515 + printk("megaraid_sas: pending commands remain even after reset handling.\n");
2517 * Send signal to FW to stop processing any pending cmds.
2518 * The controller will be taken offline by the OS now.
2520 - writel(MFI_STOP_ADP,
2521 + if ((instance->pdev->device ==
2522 + PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
2523 + (instance->pdev->device ==
2524 + PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
2525 + writel(MFI_STOP_ADP,
2526 + &instance->reg_set->reserved_0);
2528 + writel(MFI_STOP_ADP,
2529 &instance->reg_set->inbound_doorbell);
2531 megasas_dump_pending_frames(instance);
2532 - instance->hw_crit_error = 1;
2533 + spin_lock_irqsave(&instance->hba_lock, flags);
2534 + instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
2535 + spin_unlock_irqrestore(&instance->hba_lock, flags);
2539 + printk("megaraid_sas: no more pending commands remain after reset handling.\n");
2544 @@ -985,7 +2830,7 @@ static int megasas_generic_reset(struct
2545 scmd_printk(KERN_NOTICE, scmd, "megasas: RESET -%ld cmd=%x retries=%x\n",
2546 scmd->serial_number, scmd->cmnd[0], scmd->retries);
2548 - if (instance->hw_crit_error) {
2549 + if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
2550 printk(KERN_ERR "megasas: cannot recover from previous reset "
2553 @@ -1008,7 +2853,7 @@ static int megasas_generic_reset(struct
2554 * cmd has not been completed within the timeout period.
2557 -scsi_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
2558 +blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
2560 struct megasas_cmd *cmd = (struct megasas_cmd *)scmd->SCp.ptr;
2561 struct megasas_instance *instance;
2562 @@ -1016,7 +2861,7 @@ scsi_eh_timer_return megasas_reset_timer
2564 if (time_after(jiffies, scmd->jiffies_at_alloc +
2565 (MEGASAS_DEFAULT_CMD_TIMEOUT * 2) * HZ)) {
2566 - return EH_NOT_HANDLED;
2567 + return BLK_EH_NOT_HANDLED;
2570 instance = cmd->instance;
2571 @@ -1030,7 +2875,7 @@ scsi_eh_timer_return megasas_reset_timer
2573 spin_unlock_irqrestore(instance->host->host_lock, flags);
2575 - return EH_RESET_TIMER;
2576 + return BLK_EH_RESET_TIMER;
2580 @@ -1106,6 +2951,8 @@ megasas_bios_param(struct scsi_device *s
2584 +static void megasas_aen_polling(struct work_struct *work);
2587 * megasas_service_aen - Processes an event notification
2588 * @instance: Adapter soft state
2589 @@ -1121,27 +2968,74 @@ megasas_bios_param(struct scsi_device *s
2591 megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
2593 + unsigned long flags;
2595 * Don't signal app if it is just an aborted previously registered aen
2597 - if (!cmd->abort_aen)
2598 + if ((!cmd->abort_aen) && (instance->unload == 0)) {
2599 + spin_lock_irqsave(&poll_aen_lock, flags);
2600 + megasas_poll_wait_aen = 1;
2601 + spin_unlock_irqrestore(&poll_aen_lock, flags);
2602 + wake_up(&megasas_poll_wait);
2603 kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
2608 instance->aen_cmd = NULL;
2609 megasas_return_cmd(instance, cmd);
2611 + if ((instance->unload == 0) && ((instance->issuepend_done == 1))) {
2612 + struct megasas_aen_event *ev;
2613 + ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2615 + printk(KERN_ERR "megasas_service_aen: out of memory\n");
2617 + ev->instance = instance;
2618 + instance->ev = ev;
2619 + INIT_WORK(&ev->hotplug_work, megasas_aen_polling);
2620 + schedule_delayed_work(
2621 + (struct delayed_work *)&ev->hotplug_work, 0);
2626 +static int megasas_slave_alloc(struct scsi_device *sdev)
2629 + struct megasas_instance *instance ;
2630 + instance = megasas_lookup_instance(sdev->host->host_no);
2632 + if ((sdev->channel < MEGASAS_MAX_PD_CHANNELS) &&
2633 + (sdev->type == TYPE_DISK)) {
2635 + * Open the OS scan to the SYSTEM PD
2638 + (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id;
2639 + if ((instance->pd_list[pd_index].driveState ==
2640 + MR_PD_STATE_SYSTEM) &&
2641 + (instance->pd_list[pd_index].driveType ==
2653 * Scsi host template for megaraid_sas driver
2655 static struct scsi_host_template megasas_template = {
2657 .module = THIS_MODULE,
2658 - .name = "LSI Logic SAS based MegaRAID driver",
2659 + .name = "LSI SAS based MegaRAID driver",
2660 .proc_name = "megaraid_sas",
2661 .slave_configure = megasas_slave_configure,
2662 + .slave_alloc = megasas_slave_alloc,
2663 .queuecommand = megasas_queue_command,
2664 .eh_device_reset_handler = megasas_reset_device,
2665 .eh_bus_reset_handler = megasas_reset_bus_host,
2666 @@ -1195,45 +3089,6 @@ megasas_complete_abort(struct megasas_in
2670 - * megasas_unmap_sgbuf - Unmap SG buffers
2671 - * @instance: Adapter soft state
2672 - * @cmd: Completed command
2675 -megasas_unmap_sgbuf(struct megasas_instance *instance, struct megasas_cmd *cmd)
2680 - if (cmd->scmd->use_sg) {
2681 - pci_unmap_sg(instance->pdev, cmd->scmd->request_buffer,
2682 - cmd->scmd->use_sg, cmd->scmd->sc_data_direction);
2686 - if (!cmd->scmd->request_bufflen)
2689 - opcode = cmd->frame->hdr.cmd;
2691 - if ((opcode == MFI_CMD_LD_READ) || (opcode == MFI_CMD_LD_WRITE)) {
2693 - buf_h = cmd->frame->io.sgl.sge64[0].phys_addr;
2695 - buf_h = cmd->frame->io.sgl.sge32[0].phys_addr;
2698 - buf_h = cmd->frame->pthru.sgl.sge64[0].phys_addr;
2700 - buf_h = cmd->frame->pthru.sgl.sge32[0].phys_addr;
2703 - pci_unmap_single(instance->pdev, buf_h, cmd->scmd->request_bufflen,
2704 - cmd->scmd->sc_data_direction);
2709 * megasas_complete_cmd - Completes a command
2710 * @instance: Adapter soft state
2711 * @cmd: Command to be completed
2712 @@ -1247,9 +3102,14 @@ static void
2713 megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
2716 + unsigned long flags;
2718 struct megasas_header *hdr = &cmd->frame->hdr;
2720 + // If the commands complete successfully, the retry counter should also be reset
2721 + // for future re-tries.
2722 + cmd->retry_for_fw_reset = 0;
2725 cmd->scmd->SCp.ptr = NULL;
2727 @@ -1281,7 +3141,7 @@ megasas_complete_cmd(struct megasas_inst
2729 atomic_dec(&instance->fw_outstanding);
2731 - megasas_unmap_sgbuf(instance, cmd);
2732 + scsi_dma_unmap(cmd->scmd);
2733 cmd->scmd->scsi_done(cmd->scmd);
2734 megasas_return_cmd(instance, cmd);
2736 @@ -1329,7 +3189,7 @@ megasas_complete_cmd(struct megasas_inst
2738 atomic_dec(&instance->fw_outstanding);
2740 - megasas_unmap_sgbuf(instance, cmd);
2741 + scsi_dma_unmap(cmd->scmd);
2742 cmd->scmd->scsi_done(cmd->scmd);
2743 megasas_return_cmd(instance, cmd);
2745 @@ -1338,6 +3198,12 @@ megasas_complete_cmd(struct megasas_inst
2749 + if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET_INFO ||
2750 + cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET) {
2751 + spin_lock_irqsave(&poll_aen_lock, flags);
2752 + megasas_poll_wait_aen = 0;
2753 + spin_unlock_irqrestore(&poll_aen_lock, flags);
2757 * See if got an event notification
2758 @@ -1364,39 +3230,286 @@ megasas_complete_cmd(struct megasas_inst
2762 + * megasas_issue_pending_cmds_again - issue all pending cmds
2763 + * in FW again because of the fw reset
2764 + * @instance: Adapter soft state
2767 +megasas_issue_pending_cmds_again(struct megasas_instance *instance)
2769 + struct megasas_cmd *cmd;
2770 + struct list_head clist_local;
2771 + union megasas_evt_class_locale class_locale;
2772 + unsigned long flags;
2775 + INIT_LIST_HEAD(&clist_local);
2776 + spin_lock_irqsave(&instance->hba_lock, flags);
2777 + list_splice_init(&instance->internal_reset_pending_q, &clist_local);
2778 + spin_unlock_irqrestore(&instance->hba_lock, flags);
2780 + while (!list_empty(&clist_local)) {
2781 + cmd = list_entry((&clist_local)->next, struct megasas_cmd, list);
2782 + list_del_init(&cmd->list);
2784 + if (cmd->sync_cmd || cmd->scmd) {
2785 + printk("megaraid_sas: command %p, %p:%d detected to be pending while HBA reset.\n", cmd, cmd->scmd, cmd->sync_cmd);
2787 + cmd->retry_for_fw_reset++;
2789 + // If a command has continuously been tried multiple times and causing
2790 + // a FW reset condition, no further recoveries should be performed on
2792 + if (cmd->retry_for_fw_reset == 3) {
2793 + printk("megaraid_sas: command %p, %p:%d was tried multiple times during adapter reset. Shutting down the HBA\n", cmd, cmd->scmd, cmd->sync_cmd);
2794 + megaraid_sas_kill_hba(instance);
2796 + instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
2801 + if (cmd->sync_cmd == 1) {
2803 + printk("megaraid_sas: unexpected SCSI command attached to internal command!\n");
2805 + printk("megasas: %p synchronous command detected on the internal reset queue, issue it again.\n", cmd);
2806 + cmd->cmd_status = ENODATA;
2807 + instance->instancet->fire_cmd(instance,cmd->frame_phys_addr ,0,instance->reg_set);
2808 + } else if (cmd->scmd) {
2809 + printk("megasas: %p scsi command [%02x], %#lx detected on the internal reset queue, issue it again.\n", cmd, cmd->scmd->cmnd[0], cmd->scmd->serial_number);
2810 + atomic_inc(&instance->fw_outstanding);
2811 + instance->instancet->fire_cmd(instance, cmd->frame_phys_addr ,cmd->frame_count-1,instance->reg_set);
2814 + printk("megasas: %p unexpected command on the internal reset defer list while re-issue!!\n", cmd);
2818 + // Re-register AEN
2819 + if (instance->aen_cmd) {
2820 + printk("megaraid_sas: existing aen_cmd discovered in deferred processing, freeing...\n");
2821 + megasas_return_cmd(instance, instance->aen_cmd);
2822 + instance->aen_cmd = NULL;
2826 + * Initiate AEN (Asynchronous Event Notification)
2828 + seq_num = instance->last_seq_num;
2829 + class_locale.members.reserved = 0;
2830 + class_locale.members.locale = MR_EVT_LOCALE_ALL;
2831 + class_locale.members.class = MR_EVT_CLASS_DEBUG;
2833 + megasas_register_aen(instance, seq_num, class_locale.word);
2839 + * Move the internal reset pending commands to a deferred queue.
2841 + * We move the commands pending at internal reset time to a pending queue. This queue would
2842 + * be flushed after successful completion of the internal reset sequence.
2843 + * if the internal reset did not complete in time, the kernel reset handler would flush these
2846 +static void megasas_internal_reset_defer_cmds(struct megasas_instance *instance)
2848 + struct megasas_cmd *cmd;
2850 + u32 max_cmd = instance->max_fw_cmds;
2852 + unsigned long flags;
2855 + spin_lock_irqsave(&instance->cmd_pool_lock, flags);
2856 + for (i = 0; i < max_cmd; i++) {
2857 + cmd = instance->cmd_list[i];
2858 + if (cmd->sync_cmd == 1 || cmd->scmd) {
2859 + printk("megasas: moving cmd[%d]:%p:%d:%p on the defer queue as internal reset in progress.\n",
2860 + defer_index, cmd, cmd->sync_cmd, cmd->scmd);
2861 + if (!list_empty(&cmd->list)) {
2862 + printk("megaraid_sas: ERROR while moving this cmd:%p, %d %p, it was discovered on some list?\n", cmd, cmd->sync_cmd, cmd->scmd);
2863 + list_del_init(&cmd->list);
2866 + list_add_tail(&cmd->list, &instance->internal_reset_pending_q);
2869 + spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
2874 +process_fw_state_change_wq(struct work_struct *work)
2876 + struct megasas_instance *instance =
2877 + container_of(work, struct megasas_instance, work_init);
2879 + unsigned long flags;
2881 + if (instance->adprecovery != MEGASAS_ADPRESET_SM_INFAULT) {
2882 + printk("megaraid_sas: error, unexpected adapter recovery state %x in %s\n", instance->adprecovery, __FUNCTION__);
2886 + if (instance->adprecovery == MEGASAS_ADPRESET_SM_INFAULT) {
2887 + printk("megaraid_sas: FW detected to be in fault state, restarting it...\n");
2889 + instance->instancet->disable_intr(instance->reg_set);
2890 + atomic_set(&instance->fw_outstanding, 0);
2892 + atomic_set(&instance->fw_reset_no_pci_access, 1);
2893 + instance->instancet->adp_reset(instance, instance->reg_set);
2894 + atomic_set(&instance->fw_reset_no_pci_access, 0 );
2896 + printk("megaraid_sas: FW was restarted successfully, initiating next stage...\n");
2898 + printk("megaraid_sas: HBA recovery state machine, state 2 starting...\n");
2900 + /*waitting for about 20 second before start the second init*/
2901 + for(wait = 0; wait < 30; wait++)
2904 + if (megasas_transition_to_ready(instance))
2906 + printk("megaraid_sas: out: controller is not in ready state\n");
2908 + megaraid_sas_kill_hba(instance);
2909 + instance->adprecovery = MEGASAS_HW_CRITICAL_ERROR;
2913 + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) ||
2914 + (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) ||
2915 + (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR))
2917 + *instance->consumer = *instance->producer;
2919 + *instance->consumer = 0;
2920 + *instance->producer = 0;
2923 + if ( megasas_check_cpx_support( instance ) == 0 ){
2924 + if ( megasas_send_cpx_queue_data( instance ) ){
2925 + printk("megasas: Sending cpx queue data to FW failed.\n");
2926 + megasas_remove_cpx(instance);
2930 + // Transition the FW to operational state
2931 + megasas_issue_init_mfi(instance);
2933 + // Setting the adapter to OPERATIONAL at this point is very important. This would
2934 + // prevent other subsystems (reset, aen, and ioctls) to block till the recovery
2935 + // logic has run it's course.
2936 + spin_lock_irqsave(&instance->hba_lock, flags);
2937 + instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
2938 + spin_unlock_irqrestore(&instance->hba_lock, flags);
2939 + instance->instancet->enable_intr(instance->reg_set);
2941 + printk("megaraid_sas: second stage of reset complete, FW is ready now.\n");
2943 + megasas_issue_pending_cmds_again(instance);
2944 + instance->issuepend_done = 1;
2952 * megasas_deplete_reply_queue - Processes all completed commands
2953 * @instance: Adapter soft state
2954 * @alt_status: Alternate status to be returned to
2955 * SCSI mid-layer instead of the status
2956 * returned by the FW
2957 + * Note: this must be called with hba lock held
2960 megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status)
2963 - * Check if it is our interrupt
2964 - * Clear the interrupt
2966 - if(instance->instancet->clear_intr(instance->reg_set))
2970 + // If the adapter is under a reset recovery, all interrupts coming from it must be acknowledged
2971 + // if the consumer pointer value indicates so.
2972 + if((mfiStatus = instance->instancet->check_reset(instance, instance->reg_set)) == 1) {
2973 + return IRQ_HANDLED;
2976 + // Clear the interrupt on the HBA
2977 + if((mfiStatus = instance->instancet->clear_intr(instance->reg_set)) == 0) {
2981 - if (instance->hw_crit_error)
2984 - * Schedule the tasklet for cmd completion
2986 + instance->mfiStatus = mfiStatus;
2988 + // If the current soft state indicates an OPERATIONAL state _and_ now we have
2989 + // detected state change, this should be FW FAULT case.
2990 + if ((mfiStatus & MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE)) {
2991 + fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
2993 + if (fw_state != MFI_STATE_FAULT) {
2994 + printk("megaraid_sas: fw state while internal state change operational, state:%x\n", fw_state);
2997 + if ((fw_state == MFI_STATE_FAULT) && (instance->disableOnlineCtrlReset == 0)){
2998 + printk("megaraid_sas: adapter reset condition is detected, waiting for it to restart...\n");
3000 + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1064R) ||
3001 + (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5) ||
3002 + (instance->pdev->device == PCI_DEVICE_ID_LSI_VERDE_ZCR))
3004 + *instance->consumer = MEGASAS_ADPRESET_INPROG_SIGN;
3008 + instance->instancet->disable_intr(instance->reg_set);
3009 + instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT; // indicates adapter restart stage 1 is in progress
3010 + instance->issuepend_done = 0;
3012 + // The pending commands are moved to a deferred list. We would pick commands up and
3013 + // re-issue once the reset processing is over.
3014 + atomic_set(&instance->fw_outstanding, 0);
3015 + megasas_internal_reset_defer_cmds(instance);
3017 + // Schedule a low-priorty thread to perform the function for current stage of
3018 + // adapter reset state machine.
3019 + printk("megaraid_sas: FW state detected, current:%x, reset stage:%d\n", fw_state, instance->adprecovery);
3020 + schedule_work(&instance->work_init);
3021 + return IRQ_HANDLED;
3024 + printk("megaraid_sas: fw state while internal state changes, state:%x, disableOCR=%x\n",
3025 + fw_state, instance->disableOnlineCtrlReset);
3029 + // Schedule the tasklet for cmd completion
3030 tasklet_schedule(&instance->isr_tasklet);
3036 * megasas_isr - isr entry point
3038 static irqreturn_t megasas_isr(int irq, void *devp)
3040 - return megasas_deplete_reply_queue((struct megasas_instance *)devp,
3042 + struct megasas_instance *instance;
3043 + unsigned long flags;
3046 + if ( atomic_read( &(( (struct megasas_instance *)devp)->fw_reset_no_pci_access )) )
3047 + return IRQ_HANDLED;
3049 + instance = (struct megasas_instance *)devp;
3051 + spin_lock_irqsave(&instance->hba_lock, flags);
3052 + rc = megasas_deplete_reply_queue(instance, DID_OK);
3053 + spin_unlock_irqrestore(&instance->hba_lock, flags);
3059 @@ -1415,6 +3528,7 @@ megasas_transition_to_ready(struct megas
3063 + u32 abs_state, curr_abs_state;
3065 fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
3067 @@ -1424,6 +3538,8 @@ megasas_transition_to_ready(struct megas
3069 while (fw_state != MFI_STATE_READY) {
3071 + abs_state = instance->instancet->read_fw_status_reg(instance->reg_set);
3075 case MFI_STATE_FAULT:
3076 @@ -1435,18 +3551,36 @@ megasas_transition_to_ready(struct megas
3078 * Set the CLR bit in inbound doorbell
3080 - writel(MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
3081 - &instance->reg_set->inbound_doorbell);
3082 + if ((instance->pdev->device ==
3083 + PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
3084 + (instance->pdev->device ==
3085 + PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
3088 + MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
3089 + &instance->reg_set->reserved_0);
3092 + MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
3093 + &instance->reg_set->inbound_doorbell);
3097 + max_wait = MEGASAS_RESET_WAIT_TIME;
3098 cur_state = MFI_STATE_WAIT_HANDSHAKE;
3101 case MFI_STATE_BOOT_MESSAGE_PENDING:
3102 - writel(MFI_INIT_HOTPLUG,
3103 - &instance->reg_set->inbound_doorbell);
3104 + if ((instance->pdev->device ==
3105 + PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
3106 + (instance->pdev->device ==
3107 + PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
3108 + writel(MFI_INIT_HOTPLUG,
3109 + &instance->reg_set->reserved_0);
3111 + writel(MFI_INIT_HOTPLUG,
3112 + &instance->reg_set->inbound_doorbell);
3115 + max_wait = MEGASAS_RESET_WAIT_TIME;
3116 cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
3119 @@ -1455,9 +3589,17 @@ megasas_transition_to_ready(struct megas
3120 * Bring it to READY state; assuming max wait 10 secs
3122 instance->instancet->disable_intr(instance->reg_set);
3123 - writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell);
3124 + if ((instance->pdev->device ==
3125 + PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
3126 + (instance->pdev->device ==
3127 + PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
3128 + writel(MFI_RESET_FLAGS,
3129 + &instance->reg_set->reserved_0);
3131 + writel(MFI_RESET_FLAGS,
3132 + &instance->reg_set->inbound_doorbell);
3135 + max_wait = MEGASAS_RESET_WAIT_TIME;
3136 cur_state = MFI_STATE_OPERATIONAL;
3139 @@ -1465,32 +3607,32 @@ megasas_transition_to_ready(struct megas
3141 * This state should not last for more than 2 seconds
3144 + max_wait = MEGASAS_RESET_WAIT_TIME;
3145 cur_state = MFI_STATE_UNDEFINED;
3148 case MFI_STATE_BB_INIT:
3150 + max_wait = MEGASAS_RESET_WAIT_TIME;
3151 cur_state = MFI_STATE_BB_INIT;
3154 case MFI_STATE_FW_INIT:
3156 + max_wait = MEGASAS_RESET_WAIT_TIME;
3157 cur_state = MFI_STATE_FW_INIT;
3160 case MFI_STATE_FW_INIT_2:
3162 + max_wait = MEGASAS_RESET_WAIT_TIME;
3163 cur_state = MFI_STATE_FW_INIT_2;
3166 case MFI_STATE_DEVICE_SCAN:
3168 + max_wait = MEGASAS_RESET_WAIT_TIME;
3169 cur_state = MFI_STATE_DEVICE_SCAN;
3172 case MFI_STATE_FLUSH_CACHE:
3174 + max_wait = MEGASAS_RESET_WAIT_TIME;
3175 cur_state = MFI_STATE_FLUSH_CACHE;
3178 @@ -1506,8 +3648,10 @@ megasas_transition_to_ready(struct megas
3179 for (i = 0; i < (max_wait * 1000); i++) {
3180 fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) &
3183 + instance->instancet->read_fw_status_reg(instance->reg_set);
3185 - if (fw_state == cur_state) {
3186 + if (abs_state == curr_abs_state) {
3190 @@ -1516,12 +3660,12 @@ megasas_transition_to_ready(struct megas
3192 * Return error if fw_state hasn't changed after max_wait
3194 - if (fw_state == cur_state) {
3195 + if (curr_abs_state == abs_state) {
3196 printk(KERN_DEBUG "FW state [%d] hasn't changed "
3197 "in %d secs\n", fw_state, max_wait);
3202 printk(KERN_INFO "megasas: FW now in Ready state\n");
3205 @@ -1594,11 +3738,16 @@ static int megasas_create_frame_pool(str
3206 sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
3207 sizeof(struct megasas_sge32);
3209 + if (instance->flag_ieee) {
3210 + sge_sz = sizeof(struct megasas_sge_skinny);
3214 * Calculated the number of 64byte frames required for SGL
3216 sgl_sz = sge_sz * instance->max_num_sge;
3217 frame_count = (sgl_sz + MEGAMFI_FRAME_SIZE - 1) / MEGAMFI_FRAME_SIZE;
3221 * We need one extra frame for the MFI command
3222 @@ -1655,7 +3804,15 @@ static int megasas_create_frame_pool(str
3226 + memset(cmd->frame, 0, total_sz);
3228 cmd->frame->io.context = cmd->index;
3231 + * Initialize pad_0 to 0, otherwise it could corrupt
3232 + * the value of context and cause FW crash
3234 + cmd->frame->io.pad_0 = 0;
3238 @@ -1714,8 +3871,7 @@ static int megasas_alloc_cmds(struct meg
3239 * Allocate the dynamic array first and then allocate individual
3242 - instance->cmd_list = kmalloc(sizeof(struct megasas_cmd *) * max_cmd,
3244 + instance->cmd_list = kcalloc(max_cmd, sizeof(struct megasas_cmd*), GFP_KERNEL);
3246 if (!instance->cmd_list) {
3247 printk(KERN_DEBUG "megasas: out of memory\n");
3248 @@ -1747,6 +3903,7 @@ static int megasas_alloc_cmds(struct meg
3249 cmd = instance->cmd_list[i];
3250 memset(cmd, 0, sizeof(struct megasas_cmd));
3253 cmd->instance = instance;
3255 list_add_tail(&cmd->list, &instance->cmd_pool);
3256 @@ -1763,6 +3920,181 @@ static int megasas_alloc_cmds(struct meg
3261 + * megasas_get_pd_list_info - Returns FW's pd_list structure
3262 + * @instance: Adapter soft state
3263 + * @pd_list: pd_list structure
3265 + * Issues an internal command (DCMD) to get the FW's controller PD
3266 + * list structure. This information is mainly used to find out SYSTEM
3267 + * supported by the FW.
3270 +megasas_get_pd_list(struct megasas_instance *instance)
3272 + int ret = 0, pd_index = 0;
3273 + struct megasas_cmd *cmd;
3274 + struct megasas_dcmd_frame *dcmd;
3275 + struct MR_PD_LIST *ci;
3276 + struct MR_PD_ADDRESS *pd_addr;
3277 + dma_addr_t ci_h = 0;
3279 + cmd = megasas_get_cmd(instance);
3282 + printk(KERN_DEBUG "megasas (get_pd_list): Failed to get cmd\n");
3286 + dcmd = &cmd->frame->dcmd;
3288 + ci = pci_alloc_consistent(instance->pdev,
3289 + MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), &ci_h);
3292 + printk(KERN_DEBUG "Failed to alloc mem for pd_list\n");
3293 + megasas_return_cmd(instance, cmd);
3297 + memset(ci, 0, sizeof(*ci));
3298 + memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3300 + dcmd->mbox.b[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
3301 + dcmd->mbox.b[1] = 0;
3302 + dcmd->cmd = MFI_CMD_DCMD;
3303 + dcmd->cmd_status = 0xFF;
3304 + dcmd->sge_count = 1;
3305 + dcmd->flags = MFI_FRAME_DIR_READ;
3306 + dcmd->timeout = 0;
3308 + dcmd->data_xfer_len = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
3309 + dcmd->opcode = MR_DCMD_PD_LIST_QUERY;
3310 + dcmd->sgl.sge32[0].phys_addr = ci_h;
3311 + dcmd->sgl.sge32[0].length = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
3313 + if (!megasas_issue_polled(instance, cmd)) {
3320 + * the following function will get the instance PD LIST.
3323 + pd_addr = ci->addr;
3327 + (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) {
3329 + memset(instance->pd_list, 0,
3330 + MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
3332 + for (pd_index = 0; pd_index < ci->count; pd_index++) {
3334 + instance->pd_list[pd_addr->deviceId].tid =
3335 + pd_addr->deviceId;
3336 + instance->pd_list[pd_addr->deviceId].driveType =
3337 + pd_addr->scsiDevType;
3338 + instance->pd_list[pd_addr->deviceId].driveState =
3339 + MR_PD_STATE_SYSTEM;
3344 + pci_free_consistent(instance->pdev,
3345 + MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST),
3349 + megasas_return_cmd(instance, cmd);
3354 + * megasas_get_ld_list_info - Returns FW's ld_list structure
3355 + * @instance: Adapter soft state
3356 + * @ld_list: ld_list structure
3358 + * Issues an internal command (DCMD) to get the FW's controller PD
3359 + * list structure. This information is mainly used to find out SYSTEM
3360 + * supported by the FW.
3363 +megasas_get_ld_list(struct megasas_instance *instance)
3365 + int ret = 0, ld_index = 0, ids = 0;
3366 + struct megasas_cmd *cmd;
3367 + struct megasas_dcmd_frame *dcmd;
3368 + struct MR_LD_LIST *ci;
3369 + dma_addr_t ci_h = 0;
3371 + cmd = megasas_get_cmd(instance);
3374 + printk(KERN_DEBUG "megasas (megasas_get_ld_list): Failed to get cmd\n");
3378 + dcmd = &cmd->frame->dcmd;
3380 + ci = pci_alloc_consistent(instance->pdev, sizeof(struct MR_LD_LIST), &ci_h);
3383 + printk(KERN_DEBUG "Failed to alloc mem for megasas_get_ld_list\n");
3384 + megasas_return_cmd(instance, cmd);
3388 + memset(ci, 0, sizeof(*ci));
3389 + memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
3391 + dcmd->cmd = MFI_CMD_DCMD;
3392 + dcmd->cmd_status = 0xFF;
3393 + dcmd->sge_count = 1;
3394 + dcmd->flags = MFI_FRAME_DIR_READ;
3395 + dcmd->timeout = 0;
3396 + dcmd->data_xfer_len = sizeof(struct MR_LD_LIST);
3397 + dcmd->opcode = MR_DCMD_LD_GET_LIST;
3398 + dcmd->sgl.sge32[0].phys_addr = ci_h;
3399 + dcmd->sgl.sge32[0].length = sizeof(struct MR_LD_LIST);
3402 + if (!megasas_issue_polled(instance, cmd)) {
3410 + * the following function will get the instance PD LIST.
3413 + if ( (ret == 0) && (ci->ldCount <= (MAX_LOGICAL_DRIVES))){
3415 + memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
3417 + for (ld_index = 0; ld_index < ci->ldCount; ld_index++) {
3418 + if (ci->ldList[ld_index].state != 0) {
3419 + ids = ci->ldList[ld_index].ref.targetId;
3420 + instance->ld_ids[ids] = ci->ldList[ld_index].ref.targetId;
3427 + pci_free_consistent(instance->pdev, sizeof(struct MR_LD_LIST), ci, ci_h);
3430 + megasas_return_cmd(instance, cmd);
3436 * megasas_get_controller_info - Returns FW's controller structure
3437 * @instance: Adapter soft state
3438 @@ -1808,6 +4140,7 @@ megasas_get_ctrl_info(struct megasas_ins
3439 dcmd->sge_count = 1;
3440 dcmd->flags = MFI_FRAME_DIR_READ;
3443 dcmd->data_xfer_len = sizeof(struct megasas_ctrl_info);
3444 dcmd->opcode = MR_DCMD_CTRL_GET_INFO;
3445 dcmd->sgl.sge32[0].phys_addr = ci_h;
3446 @@ -1827,58 +4160,276 @@ megasas_get_ctrl_info(struct megasas_ins
3452 - * megasas_complete_cmd_dpc - Returns FW's controller structure
3453 - * @instance_addr: Address of adapter soft state
3454 + * megasas_check_cpx_support : Tries to get the host memory address if fails then cpx
3455 + not supported else cpx supported.
3456 + * @instance: Adapter soft state
3458 - * Tasklet to complete cmds
3459 + * @return 0 on success non-zero on failure.
3461 -static void megasas_complete_cmd_dpc(unsigned long instance_addr)
3462 +static int megasas_check_cpx_support( struct megasas_instance *instance)
3464 + struct megasas_cmd *cmd;
3465 + struct megasas_dcmd_frame *dcmd;
3466 + struct mr_cpx_init_data *cpx_init_data;
3467 + dma_addr_t cpx_init_data_h;
3470 + cmd = megasas_get_cmd(instance);
3472 + printk(KERN_DEBUG "megasas (get_host_mem_addr): Failed to get cmd\n");
3476 + cpx_init_data = pci_alloc_consistent(instance->pdev, sizeof( struct mr_cpx_init_data), &cpx_init_data_h);
3477 + if (cpx_init_data == NULL) {
3478 + printk(KERN_DEBUG "Failed to alloc mem for cpx_init_data. \n");
3479 + megasas_return_cmd(instance, cmd);
3483 + dcmd = &cmd->frame->dcmd;
3485 + dcmd->opcode = MR_DCMD_CTRL_MISC_CPX_INIT_DATA_GET;
3486 + dcmd->data_xfer_len = sizeof(struct mr_cpx_init_data );
3487 + dcmd->cmd = MFI_CMD_DCMD;
3488 + dcmd->cmd_status = 0xff;
3489 + dcmd->sge_count = 1;
3490 + dcmd->sgl.sge32[0].phys_addr = cpx_init_data_h;
3491 + dcmd->sgl.sge32[0].length = sizeof(struct mr_cpx_init_data);
3493 + retval = megasas_issue_polled ( instance, cmd );
3495 + if ( retval == 0 && cmd->frame->hdr.cmd_status == 0 ){
3496 + instance->host_mem_phys = cpx_init_data->phys_addr_cache_buf;
3497 + instance->host_mem_len = cpx_init_data->size;
3498 + instance->cpx_dscrptr_cnt = cpx_init_data->cpx_desc_count;
3499 + if ( instance->host_mem_len == 0 || instance->host_mem_phys == 0 || ! instance->cpx_dscrptr_cnt ){
3500 + printk("Got host_mem_len = 0 OR host_mem_phys as NULL OR cpx_descriptor count = 0 \n");
3504 + printk("megasas: cpx is not supported.\n");
3509 + pci_free_consistent(instance->pdev, sizeof(struct mr_cpx_init_data), cpx_init_data, cpx_init_data_h);
3510 + megasas_return_cmd(instance, cmd);
3516 + * megasas_send_cpx_queue_data : Sends the queue setup info to fw.
3517 + * @instance: Adapter soft state
3519 + * @return 0 on success non-zero on failure.
3522 +static int megasas_send_cpx_queue_data( struct megasas_instance *instance )
3525 + struct megasas_cmd *cmd;
3526 + struct megasas_dcmd_frame *dcmd;
3529 + cmd = megasas_get_cmd(instance);
3531 + printk(KERN_DEBUG "megasas (get_host_mem_addr): Failed to get cmd\n");
3535 + //initialize dcmd data
3536 + dcmd = &cmd->frame->dcmd;
3538 + dcmd->opcode = MR_DCMD_CTRL_MISC_CPX_QUEUE_DATA;
3539 + dcmd->data_xfer_len = sizeof( struct mr_cpx_queue_data );
3540 + dcmd->cmd = MFI_CMD_DCMD;
3541 + dcmd->cmd_status = 0xff;
3542 + dcmd->sge_count = 1;
3543 + dcmd->mbox.w[0] = instance->cpx_request_queue_h;
3544 + dcmd->mbox.w[1] = 0;
3545 + dcmd->mbox.w[2] = instance->cpx_dscrptr_cnt;
3547 + retval = megasas_issue_polled ( instance, cmd );
3549 + megasas_return_cmd( instance, cmd);
3551 + if ( retval == 0 ){
3552 + instance->cpx_request_queue->consumer_idx = instance->cpx_request_queue->producer_idx = 0;
3553 + instance->cpx_supported = 1;
3559 +static u32 megasas_get_cpx_mem_len( u16 max_fw_cmds )
3561 + return (sizeof( struct mr_cpx_request_queue ) + sizeof( union mr_cpx_descriptor ) * ( max_fw_cmds) );
3564 +static u32 megasas_remove_cpx( struct megasas_instance *instance)
3566 + if ( instance->host_mem_virt )
3567 + iounmap(instance->host_mem_virt);
3568 + if ( instance->cpx_request_queue )
3569 + pci_free_consistent(instance->pdev, megasas_get_cpx_mem_len( instance->cpx_dscrptr_cnt),
3570 + instance->cpx_request_queue,instance->cpx_request_queue_h );
3571 + instance->cpx_supported = 0;
3576 +/* should have host_mem_phys intialized before calling this function.*/
3577 +static int megasas_init_cpx( struct megasas_instance *instance)
3581 + instance->host_mem_virt = ioremap(instance->host_mem_phys, instance->host_mem_len);
3582 + if ( instance->host_mem_virt == NULL ){
3583 + printk("megasas: Failed to ioremap host memory.\n");
3584 + goto error_unload;
3587 + //allocate memory for indices and descriptors for reply and response array's
3588 + instance->cpx_request_queue = pci_alloc_consistent( instance->pdev, megasas_get_cpx_mem_len (instance->cpx_dscrptr_cnt), &instance->cpx_request_queue_h );
3589 + if ( instance->cpx_request_queue == NULL ){
3590 + printk(KERN_ERR "megasas: Out of DMA memory for cpx operations.\n");
3591 + goto error_unload;
3594 + //initialize queues
3595 + instance->cpx_dscrptr = (union mr_cpx_descriptor *)((u8*)instance->cpx_request_queue + ( sizeof(instance->cpx_request_queue->consumer_idx)*2 ));
3597 + //send data to fw.
3598 + if ( megasas_send_cpx_queue_data( instance ) ){
3599 + printk("megasas: Sending cpx queue data to FW failed.\n");
3600 + goto error_unload;
3606 + megasas_remove_cpx( instance );
3611 + * megasas_issue_init_mfi - Initializes the FW
3612 + * @instance: Adapter soft state
3614 + * Issues the INIT MFI cmd
3617 +megasas_issue_init_mfi(struct megasas_instance *instance)
3623 struct megasas_cmd *cmd;
3624 - struct megasas_instance *instance = (struct megasas_instance *)instance_addr;
3625 - unsigned long flags;
3627 - /* If we have already declared adapter dead, donot complete cmds */
3628 - if (instance->hw_crit_error)
3630 + struct megasas_init_frame *init_frame;
3631 + struct megasas_init_queue_info *initq_info;
3632 + dma_addr_t init_frame_h;
3633 + dma_addr_t initq_info_h;
3635 - producer = *instance->producer;
3636 - consumer = *instance->consumer;
3638 + * Prepare a init frame. Note the init frame points to queue info
3639 + * structure. Each frame has SGL allocated after first 64 bytes. For
3640 + * this frame - since we don't need any SGL - we use SGL's space as
3641 + * queue info structure
3643 + * We will not get a NULL command below. We just created the pool.
3645 + cmd = megasas_get_cmd(instance);
3647 - while (consumer != producer) {
3648 - context = instance->reply_queue[consumer];
3649 + init_frame = (struct megasas_init_frame *)cmd->frame;
3650 + initq_info = (struct megasas_init_queue_info *)
3651 + ((unsigned long)init_frame + 64);
3653 - cmd = instance->cmd_list[context];
3654 + init_frame_h = cmd->frame_phys_addr;
3655 + initq_info_h = init_frame_h + 64;
3657 + context = init_frame->context;
3658 + memset(init_frame, 0, MEGAMFI_FRAME_SIZE);
3659 + memset(initq_info, 0, sizeof(struct megasas_init_queue_info));
3660 + init_frame->context = context;
3662 + initq_info->reply_queue_entries = instance->max_fw_cmds + 1;
3663 + initq_info->reply_queue_start_phys_addr_lo = instance->reply_queue_h;
3665 + initq_info->producer_index_phys_addr_lo = instance->producer_h;
3666 + initq_info->consumer_index_phys_addr_lo = instance->consumer_h;
3668 + init_frame->cmd = MFI_CMD_INIT;
3669 + init_frame->cmd_status = 0xFF;
3670 + init_frame->queue_info_new_phys_addr_lo = initq_info_h;
3672 + init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info);
3675 + * disable the intr before firing the init frame to FW
3677 + instance->instancet->disable_intr(instance->reg_set);
3680 + * Issue the init frame in polled mode
3683 + if (megasas_issue_polled(instance, cmd)) {
3684 + printk(KERN_ERR "megasas: Failed to init firmware\n");
3685 + megasas_return_cmd(instance, cmd);
3686 + goto fail_fw_init;
3689 - megasas_complete_cmd(instance, cmd, DID_OK);
3690 + megasas_return_cmd(instance, cmd);
3693 - if (consumer == (instance->max_fw_cmds + 1)) {
3699 - *instance->consumer = producer;
3705 - * Check if we can restore can_queue
3707 - if (instance->flag & MEGASAS_FW_BUSY
3708 - && time_after(jiffies, instance->last_time + 5 * HZ)
3709 - && atomic_read(&instance->fw_outstanding) < 17) {
3711 + * megasas_start_timer - Initializes a timer object
3712 + * @instance: Adapter soft state
3713 + * @timer: timer object to be initialized
3714 + * @fn: timer function
3715 + * @interval: time interval between timer function call
3718 +megasas_start_timer(struct megasas_instance *instance,
3719 + struct timer_list *timer,
3720 + void *fn, unsigned long interval)
3722 + init_timer(timer);
3723 + timer->expires = jiffies + interval;
3724 + timer->data = (unsigned long)instance;
3725 + timer->function = fn;
3729 - spin_lock_irqsave(instance->host->host_lock, flags);
3730 - instance->flag &= ~MEGASAS_FW_BUSY;
3731 - instance->host->can_queue =
3732 - instance->max_fw_cmds - MEGASAS_INT_CMDS;
3734 + * megasas_io_completion_timer - Timer fn
3735 + * @instance_addr: Address of adapter soft state
3737 + * Schedules tasklet for cmd completion
3738 + * if poll_mode_io is set
3741 +megasas_io_completion_timer(unsigned long instance_addr)
3743 + struct megasas_instance *instance =
3744 + (struct megasas_instance *)instance_addr;
3746 - spin_unlock_irqrestore(instance->host->host_lock, flags);
3748 + if (atomic_read(&instance->fw_outstanding))
3749 + tasklet_schedule(&instance->isr_tasklet);
3751 + /* Restart timer */
3753 + mod_timer(&instance->io_completion_timer,
3754 + jiffies + MEGASAS_COMPLETION_TIMER_INTERVAL);
3758 @@ -1893,22 +4444,24 @@ static int megasas_init_mfi(struct megas
3763 struct megasas_register_set __iomem *reg_set;
3765 - struct megasas_cmd *cmd;
3766 struct megasas_ctrl_info *ctrl_info;
3768 - struct megasas_init_frame *init_frame;
3769 - struct megasas_init_queue_info *initq_info;
3770 - dma_addr_t init_frame_h;
3771 - dma_addr_t initq_info_h;
3774 * Map the message registers
3776 - instance->base_addr = pci_resource_start(instance->pdev, 0);
3777 + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
3778 + (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
3779 + (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
3780 + (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0079GEN2)) {
3781 + instance->base_addr = pci_resource_start(instance->pdev, 1);
3783 + instance->base_addr = pci_resource_start(instance->pdev, 0);
3786 - if (pci_request_regions(instance->pdev, "megasas: LSI Logic")) {
3787 + if (pci_request_selected_regions(instance->pdev,
3788 + pci_select_bars(instance->pdev, IORESOURCE_MEM),
3789 + "megasas: LSI")) {
3790 printk(KERN_DEBUG "megasas: IO memory region busy!\n");
3793 @@ -1924,9 +4477,18 @@ static int megasas_init_mfi(struct megas
3795 switch(instance->pdev->device)
3797 - case PCI_DEVICE_ID_LSI_SAS1078R:
3798 + case PCI_DEVICE_ID_LSI_SAS1078R:
3799 + case PCI_DEVICE_ID_LSI_SAS1078DE:
3800 instance->instancet = &megasas_instance_template_ppc;
3802 + case PCI_DEVICE_ID_LSI_SAS1078GEN2:
3803 + case PCI_DEVICE_ID_LSI_SAS0079GEN2:
3804 + instance->instancet = &megasas_instance_template_gen2;
3806 + case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
3807 + case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
3808 + instance->instancet = &megasas_instance_template_skinny;
3810 case PCI_DEVICE_ID_LSI_SAS1064R:
3811 case PCI_DEVICE_ID_DELL_PERC5:
3813 @@ -1979,52 +4541,29 @@ static int megasas_init_mfi(struct megas
3814 goto fail_reply_queue;
3818 - * Prepare a init frame. Note the init frame points to queue info
3819 - * structure. Each frame has SGL allocated after first 64 bytes. For
3820 - * this frame - since we don't need any SGL - we use SGL's space as
3821 - * queue info structure
3823 - * We will not get a NULL command below. We just created the pool.
3825 - cmd = megasas_get_cmd(instance);
3827 - init_frame = (struct megasas_init_frame *)cmd->frame;
3828 - initq_info = (struct megasas_init_queue_info *)
3829 - ((unsigned long)init_frame + 64);
3831 - init_frame_h = cmd->frame_phys_addr;
3832 - initq_info_h = init_frame_h + 64;
3834 - memset(init_frame, 0, MEGAMFI_FRAME_SIZE);
3835 - memset(initq_info, 0, sizeof(struct megasas_init_queue_info));
3837 - initq_info->reply_queue_entries = instance->max_fw_cmds + 1;
3838 - initq_info->reply_queue_start_phys_addr_lo = instance->reply_queue_h;
3840 - initq_info->producer_index_phys_addr_lo = instance->producer_h;
3841 - initq_info->consumer_index_phys_addr_lo = instance->consumer_h;
3842 + if ( megasas_check_cpx_support( instance ) == 0 )
3843 + if ( megasas_init_cpx( instance ) )
3844 + printk("Error in initilizing cpx.\n");
3846 - init_frame->cmd = MFI_CMD_INIT;
3847 - init_frame->cmd_status = 0xFF;
3848 - init_frame->queue_info_new_phys_addr_lo = initq_info_h;
3849 + if (megasas_issue_init_mfi(instance))
3850 + goto fail_fw_init;
3852 - init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info);
3853 + instance->fw_support_ieee = 0;
3854 + instance->fw_support_ieee = (instance->instancet->read_fw_status_reg(reg_set) & 0x04000000);
3857 - * disable the intr before firing the init frame to FW
3859 - instance->instancet->disable_intr(instance->reg_set);
3860 + printk("megasas_init_mfi: fw_support_ieee=%d", instance->fw_support_ieee);
3861 + if (instance->fw_support_ieee)
3862 + instance->flag_ieee = 1;
3864 + /** for passthrough
3865 + * the following function will get the PD LIST.
3869 - * Issue the init frame in polled mode
3871 - if (megasas_issue_polled(instance, cmd)) {
3872 - printk(KERN_DEBUG "megasas: Failed to init firmware\n");
3873 - goto fail_fw_init;
3875 + memset(instance->pd_list, 0, MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
3876 + megasas_get_pd_list(instance);
3878 - megasas_return_cmd(instance, cmd);
3879 + memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
3880 + megasas_get_ld_list(instance);
3882 ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL);
3884 @@ -2037,17 +4576,21 @@ static int megasas_init_mfi(struct megas
3885 * Note that older firmwares ( < FW ver 30) didn't report information
3886 * to calculate max_sectors_1. So the number ended up as zero always.
3889 if (ctrl_info && !megasas_get_ctrl_info(instance, ctrl_info)) {
3891 max_sectors_1 = (1 << ctrl_info->stripe_sz_ops.min) *
3892 ctrl_info->max_strips_per_io;
3893 max_sectors_2 = ctrl_info->max_request_size;
3895 - instance->max_sectors_per_req = (max_sectors_1 < max_sectors_2)
3896 - ? max_sectors_1 : max_sectors_2;
3898 - instance->max_sectors_per_req = instance->max_num_sge *
3900 + tmp_sectors = min_t(u32, max_sectors_1 , max_sectors_2);
3901 + instance->disableOnlineCtrlReset = ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
3904 + instance->max_sectors_per_req = instance->max_num_sge *
3906 + if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors))
3907 + instance->max_sectors_per_req = tmp_sectors;
3911 @@ -2055,12 +4598,17 @@ static int megasas_init_mfi(struct megas
3912 * Setup tasklet for cmd completion
3915 - tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc,
3916 - (unsigned long)instance);
3917 + tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc,
3918 + (unsigned long)instance);
3920 + /* Initialize the cmd completion timer */
3922 + megasas_start_timer(instance, &instance->io_completion_timer,
3923 + megasas_io_completion_timer,
3924 + MEGASAS_COMPLETION_TIMER_INTERVAL);
3928 - megasas_return_cmd(instance, cmd);
3930 pci_free_consistent(instance->pdev, reply_q_sz,
3931 instance->reply_queue, instance->reply_queue_h);
3932 @@ -2072,7 +4620,8 @@ static int megasas_init_mfi(struct megas
3933 iounmap(instance->reg_set);
3936 - pci_release_regions(instance->pdev);
3937 + pci_release_selected_regions(instance->pdev,
3938 + pci_select_bars(instance->pdev, IORESOURCE_MEM));
3942 @@ -2092,7 +4641,10 @@ static void megasas_release_mfi(struct m
3944 iounmap(instance->reg_set);
3946 - pci_release_regions(instance->pdev);
3947 + megasas_remove_cpx( instance );
3949 + pci_release_selected_regions(instance->pdev,
3950 + pci_select_bars(instance->pdev, IORESOURCE_MEM));
3954 @@ -2140,6 +4692,7 @@ megasas_get_seq_num(struct megasas_insta
3955 dcmd->sge_count = 1;
3956 dcmd->flags = MFI_FRAME_DIR_READ;
3959 dcmd->data_xfer_len = sizeof(struct megasas_evt_log_info);
3960 dcmd->opcode = MR_DCMD_CTRL_EVENT_GET_INFO;
3961 dcmd->sgl.sge32[0].phys_addr = el_info_h;
3962 @@ -2215,6 +4768,8 @@ megasas_register_aen(struct megasas_inst
3963 * Previously issued event registration includes
3964 * current request. Nothing to do.
3966 + printk(KERN_INFO "%s[%d]: already registered\n",
3967 + __FUNCTION__, instance->host->host_no);
3970 curr_aen.members.locale |= prev_aen.members.locale;
3971 @@ -2254,13 +4809,20 @@ megasas_register_aen(struct megasas_inst
3972 dcmd->sge_count = 1;
3973 dcmd->flags = MFI_FRAME_DIR_READ;
3976 dcmd->data_xfer_len = sizeof(struct megasas_evt_detail);
3977 dcmd->opcode = MR_DCMD_CTRL_EVENT_WAIT;
3978 dcmd->mbox.w[0] = seq_num;
3979 + instance->last_seq_num = seq_num;
3980 dcmd->mbox.w[1] = curr_aen.word;
3981 dcmd->sgl.sge32[0].phys_addr = (u32) instance->evt_detail_h;
3982 dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_detail);
3984 + if (instance->aen_cmd != NULL) {
3985 + megasas_return_cmd(instance, cmd);
3990 * Store reference to the cmd used to register for AEN. When an
3991 * application wants us to register for AEN, we have to abort this
3992 @@ -2271,7 +4833,8 @@ megasas_register_aen(struct megasas_inst
3994 * Issue the aen registration frame
3996 - instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
3997 + instance->instancet->fire_cmd(instance,
3998 + cmd->frame_phys_addr, 0, instance->reg_set);
4002 @@ -2304,6 +4867,32 @@ static int megasas_start_aen(struct mega
4007 +sysfs_max_sectors_read(struct kobject *kobj, struct bin_attribute *bin_attr,
4008 + char *buf, loff_t off, size_t count)
4010 + struct device *dev = container_of(kobj, struct device, kobj);
4012 + struct Scsi_Host *host = class_to_shost(dev);
4014 + struct megasas_instance *instance =
4015 + (struct megasas_instance *)host->hostdata;
4017 + count = sprintf(buf,"%u\n", instance->max_sectors_per_req);
4022 +static struct bin_attribute sysfs_max_sectors_attr = {
4024 + .name = "max_sectors",
4025 + .mode = S_IRUSR|S_IRGRP|S_IROTH,
4026 + .owner = THIS_MODULE,
4029 + .read = sysfs_max_sectors_read,
4033 * megasas_io_attach - Attaches this driver to SCSI mid-layer
4034 * @instance: Adapter soft state
4035 @@ -2311,17 +4900,48 @@ static int megasas_start_aen(struct mega
4036 static int megasas_io_attach(struct megasas_instance *instance)
4038 struct Scsi_Host *host = instance->host;
4042 * Export parameters required by SCSI mid-layer
4044 host->irq = instance->pdev->irq;
4045 host->unique_id = instance->unique_id;
4046 - host->can_queue = instance->max_fw_cmds - MEGASAS_INT_CMDS;
4047 + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
4048 + (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
4050 + instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
4053 + instance->max_fw_cmds - MEGASAS_INT_CMDS;
4054 host->this_id = instance->init_id;
4055 host->sg_tablesize = instance->max_num_sge;
4057 + if (instance->fw_support_ieee)
4058 + instance->max_sectors_per_req = MEGASAS_MAX_SECTORS_IEEE;
4060 + * Check if the module parameter value for max_sectors can be used
4062 + if (max_sectors && max_sectors < instance->max_sectors_per_req)
4063 + instance->max_sectors_per_req = max_sectors;
4065 + if (max_sectors) {
4066 + if (((instance->pdev->device ==
4067 + PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
4068 + (instance->pdev->device ==
4069 + PCI_DEVICE_ID_LSI_SAS0079GEN2)) &&
4070 + (max_sectors <= MEGASAS_MAX_SECTORS)) {
4071 + instance->max_sectors_per_req = max_sectors;
4073 + printk(KERN_INFO "megasas: max_sectors should be > 0 and"
4074 + "<= %d (or < 1MB for GEN2 controller)\n",
4075 + instance->max_sectors_per_req);
4080 host->max_sectors = instance->max_sectors_per_req;
4081 - host->cmd_per_lun = 128;
4082 + host->cmd_per_lun = MEGASAS_DEFAULT_CMD_PER_LUN;
4083 host->max_channel = MEGASAS_MAX_CHANNELS - 1;
4084 host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL;
4085 host->max_lun = MEGASAS_MAX_LUN;
4086 @@ -2335,11 +4955,50 @@ static int megasas_io_attach(struct mega
4091 + * Create sysfs entries for module paramaters
4093 + error = sysfs_create_bin_file(&instance->host->shost_dev.kobj,
4094 + &sysfs_max_sectors_attr);
4097 + printk(KERN_INFO "megasas: Error in creating the sysfs entry"
4098 + " max_sectors.\n");
4099 + goto out_remove_host;
4103 * Trigger SCSI to scan our drives
4105 scsi_scan_host(host);
4109 + scsi_remove_host(host);
4115 +megasas_set_dma_mask(struct pci_dev *pdev)
4118 + * All our contollers are capable of performing 64-bit DMA
4121 + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) {
4123 + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
4124 + goto fail_set_dma_mask;
4127 + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
4128 + goto fail_set_dma_mask;
4137 @@ -2375,19 +5034,8 @@ megasas_probe_one(struct pci_dev *pdev,
4139 pci_set_master(pdev);
4142 - * All our contollers are capable of performing 64-bit DMA
4145 - if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) != 0) {
4147 - if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0)
4148 - goto fail_set_dma_mask;
4151 - if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0)
4152 - goto fail_set_dma_mask;
4154 + if (megasas_set_dma_mask(pdev))
4155 + goto fail_set_dma_mask;
4157 host = scsi_host_alloc(&megasas_template,
4158 sizeof(struct megasas_instance));
4159 @@ -2399,6 +5047,7 @@ megasas_probe_one(struct pci_dev *pdev,
4161 instance = (struct megasas_instance *)host->hostdata;
4162 memset(instance, 0, sizeof(*instance));
4163 + atomic_set( &instance->fw_reset_no_pci_access, 0 );
4165 instance->producer = pci_alloc_consistent(pdev, sizeof(u32),
4166 &instance->producer_h);
4167 @@ -2413,6 +5062,11 @@ megasas_probe_one(struct pci_dev *pdev,
4169 *instance->producer = 0;
4170 *instance->consumer = 0;
4171 + instance->flag_ieee = 0;
4172 + instance->ev = NULL;
4173 + instance->issuepend_done = 1;
4174 + instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
4175 + megasas_poll_wait_aen = 0;
4177 instance->evt_detail = pci_alloc_consistent(pdev,
4179 @@ -2429,6 +5083,7 @@ megasas_probe_one(struct pci_dev *pdev,
4180 * Initialize locks and queues
4182 INIT_LIST_HEAD(&instance->cmd_pool);
4183 + INIT_LIST_HEAD(&instance->internal_reset_pending_q);
4185 atomic_set(&instance->fw_outstanding,0);
4187 @@ -2436,9 +5091,12 @@ megasas_probe_one(struct pci_dev *pdev,
4188 init_waitqueue_head(&instance->abort_cmd_wait_q);
4190 spin_lock_init(&instance->cmd_pool_lock);
4191 + spin_lock_init(&instance->hba_lock);
4193 + spin_lock_init(&instance->completion_lock);
4194 + spin_lock_init(&poll_aen_lock);
4196 - sema_init(&instance->aen_mutex, 1);
4197 - sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
4198 + mutex_init(&instance->aen_mutex);
4201 * Initialize PCI related and misc parameters
4202 @@ -2448,9 +5106,20 @@ megasas_probe_one(struct pci_dev *pdev,
4203 instance->unique_id = pdev->bus->number << 8 | pdev->devfn;
4204 instance->init_id = MEGASAS_DEFAULT_INIT_ID;
4206 + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
4207 + (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
4208 + instance->flag_ieee = 1;
4209 + sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
4211 + sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
4213 megasas_dbg_lvl = 0;
4215 + instance->unload = 1;
4216 instance->last_time = 0;
4217 + instance->disableOnlineCtrlReset = 1;
4219 + INIT_WORK(&instance->work_init, process_fw_state_change_wq);
4222 * Initialize MFI Firmware
4223 @@ -2495,6 +5164,7 @@ megasas_probe_one(struct pci_dev *pdev,
4224 if (megasas_io_attach(instance))
4225 goto fail_io_attach;
4227 + instance->unload = 0;
4231 @@ -2541,83 +5211,266 @@ static void megasas_flush_cache(struct m
4232 struct megasas_cmd *cmd;
4233 struct megasas_dcmd_frame *dcmd;
4235 - cmd = megasas_get_cmd(instance);
4236 + if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR)
4239 + cmd = megasas_get_cmd(instance);
4244 + dcmd = &cmd->frame->dcmd;
4246 + memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4248 + dcmd->cmd = MFI_CMD_DCMD;
4249 + dcmd->cmd_status = 0x0;
4250 + dcmd->sge_count = 0;
4251 + dcmd->flags = MFI_FRAME_DIR_NONE;
4252 + dcmd->timeout = 0;
4254 + dcmd->data_xfer_len = 0;
4255 + dcmd->opcode = MR_DCMD_CTRL_CACHE_FLUSH;
4256 + dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;
4258 + megasas_issue_blocked_cmd(instance, cmd);
4260 + megasas_return_cmd(instance, cmd);
4266 + * megasas_shutdown_controller - Instructs FW to shutdown the controller
4267 + * @instance: Adapter soft state
4268 + * @opcode: Shutdown/Hibernate
4270 +static void megasas_shutdown_controller(struct megasas_instance *instance,
4273 + struct megasas_cmd *cmd;
4274 + struct megasas_dcmd_frame *dcmd;
4276 + if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR)
4279 + cmd = megasas_get_cmd(instance);
4284 + if (instance->aen_cmd)
4285 + megasas_issue_blocked_abort_cmd(instance, instance->aen_cmd);
4287 + dcmd = &cmd->frame->dcmd;
4289 + memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4291 + dcmd->cmd = MFI_CMD_DCMD;
4292 + dcmd->cmd_status = 0x0;
4293 + dcmd->sge_count = 0;
4294 + dcmd->flags = MFI_FRAME_DIR_NONE;
4295 + dcmd->timeout = 0;
4297 + dcmd->data_xfer_len = 0;
4298 + dcmd->opcode = opcode;
4300 + megasas_issue_blocked_cmd(instance, cmd);
4302 + megasas_return_cmd(instance, cmd);
4309 + * megasas_suspend - driver suspend entry point
4310 + * @pdev: PCI device structure
4311 + * @state: PCI power state to suspend routine
4314 +megasas_suspend(struct pci_dev *pdev, pm_message_t state)
4316 + struct Scsi_Host *host;
4317 + struct megasas_instance *instance;
4319 + instance = pci_get_drvdata(pdev);
4320 + host = instance->host;
4321 + instance->unload = 1;
4324 + del_timer_sync(&instance->io_completion_timer);
4326 + megasas_flush_cache(instance);
4327 + megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN);
4329 + /* cancel the delayed work if this work still in queue */
4330 + if (instance->ev != NULL) {
4331 + struct megasas_aen_event *ev = instance->ev;
4332 + cancel_delayed_work(
4333 + (struct delayed_work *)&ev->hotplug_work);
4334 + flush_scheduled_work();
4335 + instance->ev = NULL;
4338 + tasklet_kill(&instance->isr_tasklet);
4340 + pci_set_drvdata(instance->pdev, instance);
4341 + instance->instancet->disable_intr(instance->reg_set);
4342 + free_irq(instance->pdev->irq, instance);
4344 + pci_save_state(pdev);
4345 + pci_disable_device(pdev);
4347 + pci_set_power_state(pdev, pci_choose_state(pdev, state));
4353 + * megasas_resume- driver resume entry point
4354 + * @pdev: PCI device structure
4357 +megasas_resume(struct pci_dev *pdev)
4360 + struct Scsi_Host *host;
4361 + struct megasas_instance *instance;
4363 + instance = pci_get_drvdata(pdev);
4364 + host = instance->host;
4365 + pci_set_power_state(pdev, PCI_D0);
4366 + pci_enable_wake(pdev, PCI_D0, 0);
4367 + pci_restore_state(pdev);
4370 + * PCI prepping: enable device set bus mastering and dma mask
4372 + rval = pci_enable_device(pdev);
4375 + printk(KERN_ERR "megasas: Enable device failed\n");
4379 + pci_set_master(pdev);
4381 + if (megasas_set_dma_mask(pdev))
4382 + goto fail_set_dma_mask;
4387 + * Initialize MFI Firmware
4390 - dcmd = &cmd->frame->dcmd;
4391 + *instance->producer = 0;
4392 + *instance->consumer = 0;
4394 - memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4395 + atomic_set(&instance->fw_outstanding, 0);
4397 - dcmd->cmd = MFI_CMD_DCMD;
4398 - dcmd->cmd_status = 0x0;
4399 - dcmd->sge_count = 0;
4400 - dcmd->flags = MFI_FRAME_DIR_NONE;
4401 - dcmd->timeout = 0;
4402 - dcmd->data_xfer_len = 0;
4403 - dcmd->opcode = MR_DCMD_CTRL_CACHE_FLUSH;
4404 - dcmd->mbox.b[0] = MR_FLUSH_CTRL_CACHE | MR_FLUSH_DISK_CACHE;
4406 + * We expect the FW state to be READY
4408 + if (megasas_transition_to_ready(instance))
4409 + goto fail_ready_state;
4411 - megasas_issue_blocked_cmd(instance, cmd);
4412 + if ( megasas_check_cpx_support( instance ) == 0 ){
4413 + if ( megasas_send_cpx_queue_data( instance ) ){
4414 + printk("megasas: Sending cpx queue data to FW failed.\n");
4415 + megasas_remove_cpx(instance);
4417 + instance->cpx_request_queue->consumer_idx = instance->cpx_request_queue->producer_idx = 0;
4420 - megasas_return_cmd(instance, cmd);
4421 + if (megasas_issue_init_mfi(instance))
4422 + goto fail_init_mfi;
4426 + tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc,
4427 + (unsigned long)instance);
4430 - * megasas_shutdown_controller - Instructs FW to shutdown the controller
4431 - * @instance: Adapter soft state
4433 -static void megasas_shutdown_controller(struct megasas_instance *instance)
4435 - struct megasas_cmd *cmd;
4436 - struct megasas_dcmd_frame *dcmd;
4440 + if (request_irq(pdev->irq, megasas_isr, IRQF_SHARED,
4441 + "megasas", instance)) {
4442 + printk(KERN_ERR "megasas: Failed to register IRQ\n");
4446 - cmd = megasas_get_cmd(instance);
4447 + instance->instancet->enable_intr(instance->reg_set);
4452 + * Initiate AEN (Asynchronous Event Notification)
4454 + if (megasas_start_aen(instance))
4455 + printk(KERN_ERR "megasas: Start AEN failed\n");
4457 - if (instance->aen_cmd)
4458 - megasas_issue_blocked_abort_cmd(instance, instance->aen_cmd);
4459 + /* Initialize the cmd completion timer */
4461 + megasas_start_timer(instance, &instance->io_completion_timer,
4462 + megasas_io_completion_timer,
4463 + MEGASAS_COMPLETION_TIMER_INTERVAL);
4464 + instance->unload = 0;
4466 - dcmd = &cmd->frame->dcmd;
4469 - memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
4472 + if (instance->evt_detail)
4473 + pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
4474 + instance->evt_detail,
4475 + instance->evt_detail_h);
4477 - dcmd->cmd = MFI_CMD_DCMD;
4478 - dcmd->cmd_status = 0x0;
4479 - dcmd->sge_count = 0;
4480 - dcmd->flags = MFI_FRAME_DIR_NONE;
4481 - dcmd->timeout = 0;
4482 - dcmd->data_xfer_len = 0;
4483 - dcmd->opcode = MR_DCMD_CTRL_SHUTDOWN;
4484 + if (instance->producer)
4485 + pci_free_consistent(pdev, sizeof(u32), instance->producer,
4486 + instance->producer_h);
4487 + if (instance->consumer)
4488 + pci_free_consistent(pdev, sizeof(u32), instance->consumer,
4489 + instance->consumer_h);
4490 + scsi_host_put(host);
4492 - megasas_issue_blocked_cmd(instance, cmd);
4496 - megasas_return_cmd(instance, cmd);
4497 + pci_disable_device(pdev);
4503 +#define megasas_suspend NULL
4504 +#define megasas_resume NULL
4508 * megasas_detach_one - PCI hot"un"plug entry point
4509 * @pdev: PCI device structure
4511 -static void megasas_detach_one(struct pci_dev *pdev)
4512 +static void __devexit megasas_detach_one(struct pci_dev *pdev)
4515 struct Scsi_Host *host;
4516 struct megasas_instance *instance;
4518 instance = pci_get_drvdata(pdev);
4519 + instance->unload = 1;
4520 host = instance->host;
4523 + del_timer_sync(&instance->io_completion_timer);
4525 scsi_remove_host(instance->host);
4526 megasas_flush_cache(instance);
4527 - megasas_shutdown_controller(instance);
4528 + megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
4530 + /* cancel the delayed work if this work still in queue*/
4531 + if (instance->ev != NULL) {
4532 + struct megasas_aen_event *ev = instance->ev;
4533 + cancel_delayed_work(
4534 + (struct delayed_work *)&ev->hotplug_work);
4535 + flush_scheduled_work();
4536 + instance->ev = NULL;
4539 tasklet_kill(&instance->isr_tasklet);
4542 @@ -2666,7 +5519,9 @@ static void megasas_detach_one(struct pc
4543 static void megasas_shutdown(struct pci_dev *pdev)
4545 struct megasas_instance *instance = pci_get_drvdata(pdev);
4546 + instance->unload = 1;
4547 megasas_flush_cache(instance);
4548 + megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
4552 @@ -2674,6 +5529,7 @@ static void megasas_shutdown(struct pci_
4554 static int megasas_mgmt_open(struct inode *inode, struct file *filep)
4556 + cycle_kernel_lock();
4558 * Allow only those users with admin rights
4560 @@ -2722,6 +5578,23 @@ static int megasas_mgmt_fasync(int fd, s
4564 + * megasas_mgmt_poll - char node "poll" entry point
4566 +static unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait)
4568 + unsigned int mask;
4569 + unsigned long flags;
4570 + poll_wait(file, &megasas_poll_wait, wait);
4571 + spin_lock_irqsave(&poll_aen_lock, flags);
4572 + if (megasas_poll_wait_aen)
4573 + mask = (POLLIN | POLLRDNORM);
4576 + spin_unlock_irqrestore(&poll_aen_lock, flags);
4581 * megasas_mgmt_fw_ioctl - Issues management ioctls to FW
4582 * @instance: Adapter soft state
4583 * @argp: User's ioctl packet
4584 @@ -2738,7 +5611,7 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
4587 dma_addr_t sense_handle;
4589 + unsigned long *sense_ptr;
4591 memset(kbuff_arr, 0, sizeof(kbuff_arr));
4593 @@ -2762,6 +5635,7 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
4595 memcpy(cmd->frame, ioc->frame.raw, 2 * MEGAMFI_FRAME_SIZE);
4596 cmd->frame->hdr.context = cmd->index;
4597 + cmd->frame->hdr.pad_0 = 0;
4600 * The management interface between applications and the fw uses
4601 @@ -2815,7 +5689,7 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
4605 - (u32 *) ((unsigned long)cmd->frame + ioc->sense_off);
4606 + (unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off);
4607 *sense_ptr = sense_handle;
4610 @@ -2843,14 +5717,16 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
4612 if (ioc->sense_len) {
4614 - * sense_ptr points to the location that has the user
4615 + * sense_buff points to the location that has the user
4616 * sense buffer address
4618 - sense_ptr = (u32 *) ((unsigned long)ioc->frame.raw +
4620 + sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw +
4623 if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)),
4624 sense, ioc->sense_len)) {
4625 + printk(KERN_ERR "megasas: Failed to copy out to user "
4630 @@ -2881,20 +5757,6 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
4634 -static struct megasas_instance *megasas_lookup_instance(u16 host_no)
4638 - for (i = 0; i < megasas_mgmt_info.max_index; i++) {
4640 - if ((megasas_mgmt_info.instance[i]) &&
4641 - (megasas_mgmt_info.instance[i]->host->host_no == host_no))
4642 - return megasas_mgmt_info.instance[i];
4648 static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
4650 struct megasas_iocpacket __user *user_ioc =
4651 @@ -2902,6 +5764,9 @@ static int megasas_mgmt_ioctl_fw(struct
4652 struct megasas_iocpacket *ioc;
4653 struct megasas_instance *instance;
4656 + unsigned long flags;
4657 + u32 wait_time = MEGASAS_RESET_WAIT_TIME;
4659 ioc = kmalloc(sizeof(*ioc), GFP_KERNEL);
4661 @@ -2918,6 +5783,17 @@ static int megasas_mgmt_ioctl_fw(struct
4665 + if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
4666 + printk("Controller in crit error\n");
4668 + goto out_kfree_ioc;
4671 + if (instance->unload == 1) {
4673 + goto out_kfree_ioc;
4677 * We will allow only MEGASAS_INT_CMDS number of parallel ioctl cmds
4679 @@ -2925,6 +5801,35 @@ static int megasas_mgmt_ioctl_fw(struct
4680 error = -ERESTARTSYS;
4684 + // If HBA is undergoing a reset recovery, wait for that to complete
4685 + // before issuing this command
4687 + for (i = 0; i < wait_time; i++) {
4689 + spin_lock_irqsave(&instance->hba_lock, flags);
4690 + if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL) {
4691 + spin_unlock_irqrestore(&instance->hba_lock, flags);
4694 + spin_unlock_irqrestore(&instance->hba_lock, flags);
4696 + if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
4697 + printk(KERN_NOTICE "megasas: waiting for controller reset to finish\n");
4703 + spin_lock_irqsave(&instance->hba_lock, flags);
4704 + if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
4705 + spin_unlock_irqrestore(&instance->hba_lock, flags);
4706 + printk("megaraid_sas: %s timed out while waiting for HBA to recover.\n", __FUNCTION__);
4708 + goto out_kfree_ioc;
4710 + spin_unlock_irqrestore(&instance->hba_lock, flags);
4712 error = megasas_mgmt_fw_ioctl(instance, user_ioc, ioc);
4713 up(&instance->ioctl_sem);
4715 @@ -2938,6 +5843,9 @@ static int megasas_mgmt_ioctl_aen(struct
4716 struct megasas_instance *instance;
4717 struct megasas_aen aen;
4720 + unsigned long flags;
4721 + u32 wait_time = MEGASAS_RESET_WAIT_TIME;
4723 if (file->private_data != file) {
4724 printk(KERN_DEBUG "megasas: fasync_helper was not "
4725 @@ -2953,10 +5861,41 @@ static int megasas_mgmt_ioctl_aen(struct
4729 - down(&instance->aen_mutex);
4730 + if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
4734 + if (instance->unload == 1) {
4737 + for (i = 0; i < wait_time; i++) {
4739 + spin_lock_irqsave(&instance->hba_lock, flags);
4740 + if (instance->adprecovery == MEGASAS_HBA_OPERATIONAL) {
4741 + spin_unlock_irqrestore(&instance->hba_lock, flags);
4744 + spin_unlock_irqrestore(&instance->hba_lock, flags);
4746 + if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
4747 + printk(KERN_NOTICE "megasas: waiting for controller reset to finish\n");
4753 + spin_lock_irqsave(&instance->hba_lock, flags);
4754 + if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
4755 + spin_unlock_irqrestore(&instance->hba_lock, flags);
4756 + printk("megaraid_sas: %s timed out while waiting for HBA to recover.\n", __FUNCTION__);
4759 + spin_unlock_irqrestore(&instance->hba_lock, flags);
4761 + mutex_lock(&instance->aen_mutex);
4762 error = megasas_register_aen(instance, aen.seq_num,
4763 aen.class_locale_word);
4764 - up(&instance->aen_mutex);
4765 + mutex_unlock(&instance->aen_mutex);
4769 @@ -2986,6 +5925,8 @@ static int megasas_mgmt_compat_ioctl_fw(
4770 compat_alloc_user_space(sizeof(struct megasas_iocpacket));
4773 + compat_uptr_t ptr;
4776 if (clear_user(ioc, sizeof(*ioc)))
4778 @@ -2998,9 +5939,14 @@ static int megasas_mgmt_compat_ioctl_fw(
4779 copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32)))
4782 - for (i = 0; i < MAX_IOCTL_SGE; i++) {
4783 - compat_uptr_t ptr;
4784 + if (ioc->sense_len) {
4785 + raw_ptr = ioc->frame.raw + ioc->sense_off;
4786 + if (get_user(ptr, (compat_uptr_t *)raw_ptr) ||
4787 + put_user(ptr, (unsigned long *)raw_ptr))
4791 + for (i = 0; i < MAX_IOCTL_SGE; i++) {
4792 if (get_user(ptr, &cioc->sgl[i].iov_base) ||
4793 put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) ||
4794 copy_in_user(&ioc->sgl[i].iov_len,
4795 @@ -3042,6 +5988,7 @@ static const struct file_operations mega
4796 .release = megasas_mgmt_release,
4797 .fasync = megasas_mgmt_fasync,
4798 .unlocked_ioctl = megasas_mgmt_ioctl,
4799 + .poll = megasas_mgmt_poll,
4800 #ifdef CONFIG_COMPAT
4801 .compat_ioctl = megasas_mgmt_compat_ioctl,
4803 @@ -3056,6 +6003,8 @@ static struct pci_driver megasas_pci_dri
4804 .id_table = megasas_pci_table,
4805 .probe = megasas_probe_one,
4806 .remove = __devexit_p(megasas_detach_one),
4807 + .suspend = megasas_suspend,
4808 + .resume = megasas_resume,
4809 .shutdown = megasas_shutdown,
4812 @@ -3081,9 +6030,27 @@ static DRIVER_ATTR(release_date, S_IRUGO
4816 +megasas_sysfs_show_support_poll_for_event(struct device_driver *dd, char *buf)
4818 + return sprintf(buf, "%u\n", support_poll_for_event);
4821 +static DRIVER_ATTR(support_poll_for_event, S_IRUGO,
4822 + megasas_sysfs_show_support_poll_for_event, NULL);
4825 +megasas_sysfs_show_support_device_change(struct device_driver *dd, char *buf)
4827 + return sprintf(buf, "%u\n", support_device_change);
4830 +static DRIVER_ATTR(support_device_change, S_IRUGO,
4831 + megasas_sysfs_show_support_device_change, NULL);
4834 megasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf)
4836 - return sprintf(buf,"%u",megasas_dbg_lvl);
4837 + return sprintf(buf, "%u\n", megasas_dbg_lvl);
4841 @@ -3097,8 +6064,262 @@ megasas_sysfs_set_dbg_lvl(struct device_
4845 -static DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUGO, megasas_sysfs_show_dbg_lvl,
4846 - megasas_sysfs_set_dbg_lvl);
4847 +static DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUSR, megasas_sysfs_show_dbg_lvl,
4848 + megasas_sysfs_set_dbg_lvl);
4851 +megasas_sysfs_show_poll_mode_io(struct device_driver *dd, char *buf)
4853 + return sprintf(buf, "%u\n", poll_mode_io);
4857 +megasas_sysfs_set_poll_mode_io(struct device_driver *dd,
4858 + const char *buf, size_t count)
4860 + int retval = count;
4861 + int tmp = poll_mode_io;
4863 + struct megasas_instance *instance;
4865 + if (sscanf(buf, "%u", &poll_mode_io) < 1) {
4866 + printk(KERN_ERR "megasas: could not set poll_mode_io\n");
4871 + * Check if poll_mode_io is already set or is same as previous value
4873 + if ((tmp && poll_mode_io) || (tmp == poll_mode_io))
4876 + if (poll_mode_io) {
4878 + * Start timers for all adapters
4880 + for (i = 0; i < megasas_mgmt_info.max_index; i++) {
4881 + instance = megasas_mgmt_info.instance[i];
4883 + megasas_start_timer(instance,
4884 + &instance->io_completion_timer,
4885 + megasas_io_completion_timer,
4886 + MEGASAS_COMPLETION_TIMER_INTERVAL);
4891 + * Delete timers for all adapters
4893 + for (i = 0; i < megasas_mgmt_info.max_index; i++) {
4894 + instance = megasas_mgmt_info.instance[i];
4896 + del_timer_sync(&instance->io_completion_timer);
4905 +megasas_aen_polling(struct work_struct *work)
4907 + struct Scsi_Host *host;
4908 + struct scsi_device *sdev1;
4912 + struct megasas_aen_event *ev =
4913 + container_of(work, struct megasas_aen_event, hotplug_work);
4914 + struct megasas_instance *instance = ev->instance;
4915 + union megasas_evt_class_locale class_locale;
4916 + int i, j, doscan = 0;
4921 + printk(KERN_ERR "invalid instance!\n");
4925 + instance->ev = NULL;
4926 + host = instance->host;
4927 + if (instance->evt_detail) {
4929 + switch (instance->evt_detail->code) {
4930 + case MR_EVT_PD_INSERTED:
4931 + if(megasas_get_pd_list(instance) == 0) {
4933 + for (i=0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
4934 + for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
4935 + pd_index = (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
4936 + sdev1 = scsi_device_lookup(host, i, j, 0);
4937 + if (instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) {
4939 + scsi_add_device(host, i, j, 0);
4943 + scsi_device_put(sdev1);
4952 + case MR_EVT_PD_REMOVED:
4953 + if(megasas_get_pd_list(instance) == 0) {
4954 + megasas_get_pd_list(instance);
4955 + for (i=0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
4956 + for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
4957 + pd_index = (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
4958 + sdev1 = scsi_device_lookup(host, i, j, 0);
4959 + if (instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) {
4961 + scsi_device_put(sdev1);
4965 + scsi_remove_device(sdev1);
4966 + scsi_device_put(sdev1);
4976 + case MR_EVT_LD_OFFLINE:
4977 + case MR_EVT_CFG_CLEARED:
4978 + case MR_EVT_LD_DELETED:
4979 + megasas_get_ld_list(instance);
4980 + for (i=0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
4981 + for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
4982 + ld_index = (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
4983 + sdev1 = scsi_device_lookup(host, i+MEGASAS_MAX_LD_CHANNELS, j, 0);
4984 + if (instance->ld_ids[ld_index] != 0xff) {
4986 + scsi_device_put(sdev1);
4991 + scsi_remove_device(sdev1);
4992 + scsi_device_put(sdev1);
4999 + case MR_EVT_LD_CREATED:
5000 + megasas_get_ld_list(instance);
5001 + for (i=0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
5002 + for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
5003 + ld_index = (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
5004 + sdev1 = scsi_device_lookup(host, i+MEGASAS_MAX_LD_CHANNELS, j, 0);
5005 + if (instance->ld_ids[ld_index] != 0xff) {
5007 + scsi_add_device(host, i+2, j, 0);
5011 + scsi_device_put(sdev1);
5017 + case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
5018 + case MR_EVT_FOREIGN_CFG_IMPORTED:
5019 + case MR_EVT_LD_STATE_CHANGE:
5027 + printk(KERN_ERR "invalid evt_detail!\n");
5033 + printk(KERN_INFO "scanning ...\n");
5034 + megasas_get_pd_list(instance);
5035 + for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
5036 + for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
5037 + pd_index = i*MEGASAS_MAX_DEV_PER_CHANNEL + j;
5038 + sdev1 = scsi_device_lookup(host, i, j, 0);
5039 + if (instance->pd_list[pd_index].driveState ==
5040 + MR_PD_STATE_SYSTEM) {
5042 + scsi_add_device(host, i, j, 0);
5044 + scsi_device_put(sdev1);
5048 + scsi_remove_device(sdev1);
5049 + scsi_device_put(sdev1);
5055 + megasas_get_ld_list(instance);
5056 + for (i=0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
5057 + for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
5058 + ld_index = (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
5059 + sdev1 = scsi_device_lookup(host, i+MEGASAS_MAX_LD_CHANNELS, j, 0);
5060 + if (instance->ld_ids[ld_index] != 0xff) {
5062 + scsi_add_device(host, i+2, j, 0);
5064 + scsi_device_put(sdev1);
5068 + scsi_remove_device(sdev1);
5069 + scsi_device_put(sdev1);
5076 + seq_num = instance->evt_detail->seq_num + 1;
5078 + /* Register AEN with FW for latest sequence number plus 1 */
5079 + class_locale.members.reserved = 0;
5080 + class_locale.members.locale = MR_EVT_LOCALE_ALL;
5081 + class_locale.members.class = MR_EVT_CLASS_DEBUG;
5083 + if ( instance->aen_cmd != NULL ) {
5088 + mutex_lock(&instance->aen_mutex);
5089 + error = megasas_register_aen(instance, seq_num,
5090 + class_locale.word);
5091 + mutex_unlock(&instance->aen_mutex);
5094 + printk(KERN_ERR "register aen failed error %x\n", error);
5100 +static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUSR,
5101 + megasas_sysfs_show_poll_mode_io,
5102 + megasas_sysfs_set_poll_mode_io);
5105 * megasas_init - Driver load entry point
5106 @@ -3113,6 +6334,9 @@ static int __init megasas_init(void)
5107 printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION,
5108 MEGASAS_EXT_VERSION);
5110 + support_poll_for_event = 2;
5111 + support_device_change = 1;
5113 memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info));
5116 @@ -3145,15 +6369,41 @@ static int __init megasas_init(void)
5117 &driver_attr_release_date);
5119 goto err_dcf_rel_date;
5121 + rval = driver_create_file(&megasas_pci_driver.driver,
5122 + &driver_attr_support_poll_for_event);
5124 + goto err_dcf_support_poll_for_event;
5126 rval = driver_create_file(&megasas_pci_driver.driver,
5127 &driver_attr_dbg_lvl);
5129 goto err_dcf_dbg_lvl;
5130 + rval = driver_create_file(&megasas_pci_driver.driver,
5131 + &driver_attr_poll_mode_io);
5133 + goto err_dcf_poll_mode_io;
5134 + rval = driver_create_file(&megasas_pci_driver.driver,
5135 + &driver_attr_support_device_change);
5137 + goto err_dcf_support_device_change;
5140 +err_dcf_support_device_change:
5141 + driver_remove_file(&megasas_pci_driver.driver,
5142 + &driver_attr_poll_mode_io);
5144 +err_dcf_poll_mode_io:
5145 + driver_remove_file(&megasas_pci_driver.driver,
5146 + &driver_attr_dbg_lvl);
5148 driver_remove_file(&megasas_pci_driver.driver,
5149 + &driver_attr_support_poll_for_event);
5151 +err_dcf_support_poll_for_event:
5152 + driver_remove_file(&megasas_pci_driver.driver,
5153 &driver_attr_release_date);
5156 driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
5158 @@ -3169,8 +6419,14 @@ err_pcidrv:
5159 static void __exit megasas_exit(void)
5161 driver_remove_file(&megasas_pci_driver.driver,
5162 + &driver_attr_poll_mode_io);
5163 + driver_remove_file(&megasas_pci_driver.driver,
5164 &driver_attr_dbg_lvl);
5165 driver_remove_file(&megasas_pci_driver.driver,
5166 + &driver_attr_support_poll_for_event);
5167 + driver_remove_file(&megasas_pci_driver.driver,
5168 + &driver_attr_support_device_change);
5169 + driver_remove_file(&megasas_pci_driver.driver,
5170 &driver_attr_release_date);
5171 driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
5173 diff -Nurp linux-2.6.22-950/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.22-960/drivers/scsi/megaraid/megaraid_sas.h
5174 --- linux-2.6.22-950/drivers/scsi/megaraid/megaraid_sas.h 2007-07-08 19:32:17.000000000 -0400
5175 +++ linux-2.6.22-960/drivers/scsi/megaraid/megaraid_sas.h 2010-07-20 16:47:48.000000000 -0400
5178 * MegaRAID SAS Driver meta data
5180 -#define MEGASAS_VERSION "00.00.03.10-rc5"
5181 -#define MEGASAS_RELDATE "May 17, 2007"
5182 -#define MEGASAS_EXT_VERSION "Thu May 17 10:09:32 PDT 2007"
5183 +#define MEGASAS_VERSION "00.00.04.33"
5184 +#define MEGASAS_RELDATE "July 20, 2010"
5185 +#define MEGASAS_EXT_VERSION "Tue Jul 20 12:24:32 EDT 2010"
5191 #define PCI_DEVICE_ID_LSI_SAS1078R 0x0060
5192 +#define PCI_DEVICE_ID_LSI_SAS1078DE 0x007C
5193 #define PCI_DEVICE_ID_LSI_VERDE_ZCR 0x0413
5194 +#define PCI_DEVICE_ID_LSI_SAS1078GEN2 0x0078
5195 +#define PCI_DEVICE_ID_LSI_SAS0079GEN2 0x0079
5196 +#define PCI_DEVICE_ID_LSI_SAS0073SKINNY 0x0073
5197 +#define PCI_DEVICE_ID_LSI_SAS0071SKINNY 0x0071
5200 * =====================================
5202 #define MFI_STATE_READY 0xB0000000
5203 #define MFI_STATE_OPERATIONAL 0xC0000000
5204 #define MFI_STATE_FAULT 0xF0000000
5205 +#define MFI_RESET_REQUIRED 0x00000001
5207 #define MEGAMFI_FRAME_SIZE 64
5210 * HOTPLUG : Resume from Hotplug
5211 * MFI_STOP_ADP : Send signal to FW to stop processing
5214 +#define WRITE_SEQUENCE_OFFSET (0x0000000FC) // I20
5215 +#define HOST_DIAGNOSTIC_OFFSET (0x000000F8) // I20
5216 +#define DIAG_WRITE_ENABLE (0x00000080)
5217 +#define DIAG_RESET_ADAPTER (0x00000004)
5219 +#define MFI_ADP_RESET 0x00000040
5220 #define MFI_INIT_ABORT 0x00000001
5221 #define MFI_INIT_READY 0x00000002
5222 #define MFI_INIT_MFIMODE 0x00000004
5224 #define MFI_FRAME_DIR_WRITE 0x0008
5225 #define MFI_FRAME_DIR_READ 0x0010
5226 #define MFI_FRAME_DIR_BOTH 0x0018
5227 +#define MFI_FRAME_IEEE 0x0020
5230 * Definition for cmd_status
5231 @@ -111,12 +126,14 @@
5232 #define MFI_CMD_STP 0x08
5234 #define MR_DCMD_CTRL_GET_INFO 0x01010000
5235 +#define MR_DCMD_LD_GET_LIST 0x03010000
5237 #define MR_DCMD_CTRL_CACHE_FLUSH 0x01101000
5238 #define MR_FLUSH_CTRL_CACHE 0x01
5239 #define MR_FLUSH_DISK_CACHE 0x02
5241 #define MR_DCMD_CTRL_SHUTDOWN 0x01050000
5242 +#define MR_DCMD_HIBERNATE_SHUTDOWN 0x01060000
5243 #define MR_ENABLE_DRIVE_SPINDOWN 0x01
5245 #define MR_DCMD_CTRL_EVENT_GET_INFO 0x01040100
5246 @@ -127,6 +144,29 @@
5247 #define MR_DCMD_CLUSTER 0x08000000
5248 #define MR_DCMD_CLUSTER_RESET_ALL 0x08010100
5249 #define MR_DCMD_CLUSTER_RESET_LD 0x08010200
5250 +#define MR_DCMD_PD_LIST_QUERY 0x02010100
5252 +#define MR_DCMD_CTRL_MISC_CPX 0x0100e200
5253 +#define MR_DCMD_CTRL_MISC_CPX_INIT_DATA_GET 0x0100e201
5254 +#define MR_DCMD_CTRL_MISC_CPX_QUEUE_DATA 0x0100e202
5255 +#define MR_DCMD_CTRL_MISC_CPX_UNREGISTER 0x0100e203
5256 +#define MAX_MR_ROW_SIZE 32
5257 +#define MR_CPX_DIR_WRITE 1
5258 +#define MR_CPX_DIR_READ 0
5259 +#define MR_CPX_VERSION 1
5261 +#define MR_EVT_CFG_CLEARED 0x0004
5263 +#define MR_EVT_LD_STATE_CHANGE 0x0051
5264 +#define MR_EVT_PD_INSERTED 0x005b
5265 +#define MR_EVT_PD_REMOVED 0x0070
5266 +#define MR_EVT_LD_CREATED 0x008a
5267 +#define MR_EVT_LD_DELETED 0x008b
5268 +#define MR_EVT_FOREIGN_CFG_IMPORTED 0x00db
5269 +#define MR_EVT_LD_OFFLINE 0x00fc
5270 +#define MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED 0x0152
5271 +#define MAX_LOGICAL_DRIVES 64
5275 * MFI command completion codes
5276 @@ -247,8 +287,128 @@ enum MR_EVT_ARGS {
5280 + MR_EVT_ARGS_LD_PROP,
5281 + MR_EVT_ARGS_PD_SPARE,
5282 + MR_EVT_ARGS_PD_INDEX,
5283 + MR_EVT_ARGS_DIAG_PASS,
5284 + MR_EVT_ARGS_DIAG_FAIL,
5285 + MR_EVT_ARGS_PD_LBA_LBA,
5286 + MR_EVT_ARGS_PORT_PHY,
5287 + MR_EVT_ARGS_PD_MISSING,
5288 + MR_EVT_ARGS_PD_ADDRESS,
5289 + MR_EVT_ARGS_BITMAP,
5290 + MR_EVT_ARGS_CONNECTOR,
5291 + MR_EVT_ARGS_PD_PD,
5292 + MR_EVT_ARGS_PD_FRU,
5293 + MR_EVT_ARGS_PD_PATHINFO,
5294 + MR_EVT_ARGS_PD_POWER_STATE,
5295 + MR_EVT_ARGS_GENERIC,
5300 + * define constants for device list query options
5302 +enum MR_PD_QUERY_TYPE {
5303 + MR_PD_QUERY_TYPE_ALL = 0,
5304 + MR_PD_QUERY_TYPE_STATE = 1,
5305 + MR_PD_QUERY_TYPE_POWER_STATE = 2,
5306 + MR_PD_QUERY_TYPE_MEDIA_TYPE = 3,
5307 + MR_PD_QUERY_TYPE_SPEED = 4,
5308 + MR_PD_QUERY_TYPE_EXPOSED_TO_HOST = 5,
5309 +} __attribute__ ((packed));
5311 +#define MR_EVT_CFG_CLEARED 0x0004
5312 +#define MR_EVT_LD_STATE_CHANGE 0x0051
5313 +#define MR_EVT_PD_INSERTED 0x005b
5314 +#define MR_EVT_PD_REMOVED 0x0070
5315 +#define MR_EVT_LD_CREATED 0x008a
5316 +#define MR_EVT_LD_DELETED 0x008b
5317 +#define MR_EVT_FOREIGN_CFG_IMPORTED 0x00db
5318 +#define MR_EVT_LD_OFFLINE 0x00fc
5319 +#define MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED 0x0152
5322 + MR_PD_STATE_UNCONFIGURED_GOOD = 0x00,
5323 + MR_PD_STATE_UNCONFIGURED_BAD = 0x01,
5324 + MR_PD_STATE_HOT_SPARE = 0x02,
5325 + MR_PD_STATE_OFFLINE = 0x10,
5326 + MR_PD_STATE_FAILED = 0x11,
5327 + MR_PD_STATE_REBUILD = 0x14,
5328 + MR_PD_STATE_ONLINE = 0x18,
5329 + MR_PD_STATE_COPYBACK = 0x20,
5330 + MR_PD_STATE_SYSTEM = 0x40,
5334 + * defines the physical drive address structure
5336 +struct MR_PD_ADDRESS {
5348 + u8 enclConnectorIndex;
5353 + u8 connectedPortBitmap;
5354 + u8 connectedPortNumbers;
5358 +} __attribute__ ((packed));
5361 + * defines the physical drive list structure
5363 +struct MR_PD_LIST {
5366 + struct MR_PD_ADDRESS addr[1];
5367 +} __attribute__ ((packed));
5370 +struct megasas_pd_list {
5374 +} __attribute__ ((packed));
5377 + * defines the logical drive reference structure
5379 +typedef union _MR_LD_REF { // LD reference structure
5381 + u8 targetId; // LD target id (0 to MAX_TARGET_ID)
5382 + u8 reserved; // reserved to make in line with MR_PD_REF
5383 + u16 seqNum; // Sequence Number
5385 + u32 ref; // shorthand reference to full 32-bits
5386 +} MR_LD_REF; // 4 bytes
5390 + * defines the logical drive list structure
5392 +struct MR_LD_LIST {
5393 + u32 ldCount; // number of LDs
5394 + u32 reserved; // pad to 8-byte boundary
5396 + MR_LD_REF ref; // LD reference
5397 + u8 state; // current LD state (MR_LD_STATE)
5398 + u8 reserved[3]; // pad to 8-byte boundary
5399 + u64 size; // LD size
5400 + } ldList[MAX_LOGICAL_DRIVES];
5401 +} __attribute__ ((packed));
5404 * SAS controller properties
5405 @@ -276,7 +436,45 @@ struct megasas_ctrl_prop {
5406 u16 ecc_bucket_leak_rate;
5407 u8 restore_hotspare_on_insertion;
5408 u8 expose_encl_devices;
5410 + u8 maintainPdFailHistory;
5411 + u8 disallowHostRequestReordering;
5412 + u8 abortCCOnError; // set TRUE to abort CC on detecting an inconsistency
5413 + u8 loadBalanceMode; // load balance mode (MR_LOAD_BALANCE_MODE)
5414 + u8 disableAutoDetectBackplane; // 0 - use auto detect logic of backplanes like SGPIO, i2c SEP using h/w mechansim like GPIO pins
5415 + // 1 - disable auto detect SGPIO,
5416 + // 2 - disable i2c SEP auto detect
5417 + // 3 - disable both auto detect
5418 + u8 snapVDSpace; // % of source LD to be reserved for a VDs snapshot in snapshot repository, for metadata and user data
5419 + // 1=5%, 2=10%, 3=15% and so on
5422 + * Add properties that can be controlled by a bit in the following structure.
5425 + u32 copyBackDisabled : 1; // set TRUE to disable copyBack (0=copback enabled)
5426 + u32 SMARTerEnabled : 1;
5427 + u32 prCorrectUnconfiguredAreas : 1;
5428 + u32 useFdeOnly : 1;
5429 + u32 disableNCQ : 1;
5430 + u32 SSDSMARTerEnabled : 1;
5431 + u32 SSDPatrolReadEnabled : 1;
5432 + u32 enableSpinDownUnconfigured : 1;
5433 + u32 autoEnhancedImport : 1;
5434 + u32 enableSecretKeyControl : 1;
5435 + u32 disableOnlineCtrlReset : 1;
5436 + u32 allowBootWithPinnedCache : 1;
5437 + u32 disableSpinDownHS : 1;
5438 + u32 enableJBOD : 1;
5440 + } OnOffProperties;
5441 + u8 autoSnapVDSpace; // % of source LD to be reserved for auto snapshot in snapshot repository, for metadata and user data
5442 + // 1=5%, 2=10%, 3=15% and so on
5443 + u8 viewSpace; // snapshot writeable VIEWs capacity as a % of source LD capacity. 0=READ only
5444 + // 1=5%, 2=10%, 3=15% and so on
5446 + u16 spinDownTime; // # of idle minutes before device is spun down (0=use FW defaults)
5450 } __attribute__ ((packed));
5452 @@ -536,10 +734,20 @@ struct megasas_ctrl_info {
5453 #define MEGASAS_DEFAULT_INIT_ID -1
5454 #define MEGASAS_MAX_LUN 8
5455 #define MEGASAS_MAX_LD 64
5456 +#define MEGASAS_DEFAULT_CMD_PER_LUN 128
5457 +#define MEGASAS_MAX_PD (MEGASAS_MAX_PD_CHANNELS * \
5458 + MEGASAS_MAX_DEV_PER_CHANNEL)
5459 +#define MEGASAS_MAX_LD_IDS (MEGASAS_MAX_LD_CHANNELS * \
5460 + MEGASAS_MAX_DEV_PER_CHANNEL)
5462 -#define MEGASAS_DBG_LVL 1
5464 +#define MEGASAS_MAX_SECTORS (2*1024)
5465 +#define MEGASAS_MAX_SECTORS_IEEE (2*128)
5466 +#define MEGASAS_DBG_LVL 1
5467 #define MEGASAS_FW_BUSY 1
5470 +#define PTHRU_FRAME 1
5473 * When SCSI mid-layer calls driver's reset routine, driver waits for
5474 @@ -551,6 +759,7 @@ struct megasas_ctrl_info {
5475 #define MEGASAS_RESET_WAIT_TIME 180
5476 #define MEGASAS_INTERNAL_CMD_WAIT_TIME 180
5477 #define MEGASAS_RESET_NOTICE_INTERVAL 5
5479 #define MEGASAS_IOCTL_CMD 0
5480 #define MEGASAS_DEFAULT_CMD_TIMEOUT 90
5482 @@ -562,6 +771,7 @@ struct megasas_ctrl_info {
5485 #define MEGASAS_INT_CMDS 32
5486 +#define MEGASAS_SKINNY_INT_CMDS 5
5489 * FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit
5490 @@ -569,10 +779,25 @@ struct megasas_ctrl_info {
5492 #define IS_DMA64 (sizeof(dma_addr_t) == 8)
5494 +#define MFI_XSCALE_OMR0_CHANGE_INTERRUPT 0x00000001 /* MFI state change interrupt */
5496 +#define MFI_INTR_FLAG_REPLY_MESSAGE 0x00000001
5497 +#define MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE 0x00000002
5498 +#define MFI_G2_OUTBOUND_DOORBELL_CHANGE_INTERRUPT 0x00000004 /* MFI state change interrrupt */
5500 #define MFI_OB_INTR_STATUS_MASK 0x00000002
5501 -#define MFI_POLL_TIMEOUT_SECS 10
5502 +#define MFI_POLL_TIMEOUT_SECS 60
5503 +#define MEGASAS_COMPLETION_TIMER_INTERVAL (HZ/10)
5505 #define MFI_REPLY_1078_MESSAGE_INTERRUPT 0x80000000
5506 +#define MFI_REPLY_GEN2_MESSAGE_INTERRUPT 0x00000001
5507 +#define MFI_GEN2_ENABLE_INTERRUPT_MASK 0x00000001
5508 +#define MFI_REPLY_SKINNY_MESSAGE_INTERRUPT 0x40000000
5509 +#define MFI_SKINNY_ENABLE_INTERRUPT_MASK (0x00000001)
5510 +#define MFI_1068_PCSR_OFFSET 0x84
5511 +#define MFI_1068_FW_HANDSHAKE_OFFSET 0x64
5512 +#define MFI_1068_FW_READY 0xDDDD0000
5516 * register set for both 1068 and 1078 controllers
5517 @@ -580,7 +805,11 @@ struct megasas_ctrl_info {
5520 struct megasas_register_set {
5521 - u32 reserved_0[4]; /*0000h*/
5522 + u32 reserved_0; /*0000h*/
5523 + u32 fusion_seq_offset; /*0008h*/
5524 + u32 fusion_host_diag; /*0004h*/
5525 + u32 reserved_01; /*000Ch*/
5528 u32 inbound_msg_0; /*0010h*/
5529 u32 inbound_msg_1; /*0014h*/
5530 @@ -615,7 +844,10 @@ struct megasas_register_set {
5531 u32 inbound_high_queue_port ; /*00C4h*/
5533 u32 reserved_5; /*00C8h*/
5534 - u32 index_registers[820]; /*00CCh*/
5535 + u32 res_6[11]; /*CCh*/
5538 + u32 index_registers[807]; /*00CCh*/
5540 } __attribute__ ((packed));
5542 @@ -632,11 +864,20 @@ struct megasas_sge64 {
5545 } __attribute__ ((packed));
5547 +struct megasas_sge_skinny {
5553 +} __attribute__ ((packed));
5557 struct megasas_sge32 sge32[1];
5558 struct megasas_sge64 sge64[1];
5559 + struct megasas_sge_skinny sge_skinny[1];
5561 } __attribute__ ((packed));
5563 @@ -1050,16 +1291,177 @@ struct megasas_evt_detail {
5565 } __attribute__ ((packed));
5567 - struct megasas_instance_template {
5568 - void (*fire_cmd)(dma_addr_t ,u32 ,struct megasas_register_set __iomem *);
5569 +#define MIN(a,b) ((a)<(b) ? (a):(b))
5570 +typedef void (*XOR_LOW_LEVEL_GEN_FUNC)(u32 **, u32);
5571 +typedef u8 (*XOR_LOW_LEVEL_CHECK_FUNC)(u32 **, u32);
5573 + * enumerates type of descriptor
5575 +typedef enum _MR_CPX_DESCRIPTOR_TYPE {
5576 + MR_CPX_DESCRIPTOR_TYPE_COPY = 1,
5577 + MR_CPX_DESCRIPTOR_TYPE_XOR = 2
5578 +} MR_CPX_DESCRIPTOR_TYPE;
5580 - void (*enable_intr)(struct megasas_register_set __iomem *) ;
5581 - void (*disable_intr)(struct megasas_register_set __iomem *);
5583 + * status information of copy or xor operation
5585 +typedef enum _MR_CPX_STATUS {
5586 + MR_CPX_STATUS_SUCCESS = 0,
5587 + MR_CPX_STATUS_INCONSISTENT = 1,
5588 + MR_CPX_STATUS_FAILURE = 2,
5591 - int (*clear_intr)(struct megasas_register_set __iomem *);
5593 + * define the XOR opcodes
5595 +typedef enum _mr_cpx_xor_op {
5596 + MR_CPX_XOR_OP_GEN_P = 0x01, // generate P buffer
5597 + MR_CPX_XOR_OP_GEN_Q = 0x02, // generate Q buffer
5598 + MR_CPX_XOR_OP_GEN_PQ = 0x03, // generate P+Q buffers
5599 + MR_CPX_XOR_OP_CHECK_P = 0x11, // check P buffer (and generate if bad)
5600 + MR_CPX_XOR_OP_CHECK_Q = 0x12, // check Q buffer (and generate if bad)
5601 + MR_CPX_XOR_OP_CHECK_PQ = 0x13, // check P+Q buffers (and generate if bad)
5604 +#define MR_CPX_XOR_OP_IS_CHECK(xorOp) ((xorOp & 0x10)!=0) // TRUE if operation is a CHECK operation
5605 +#define MR_CPX_XOR_OP_IS_GEN(xorOp) (!MR_CPX_XOR_OP_IS_CHECK(xorOp)) // TRUE if operation is a GEN operation
5606 +#define MR_CPX_XOR_OP_IS_P(xorOp) ((xorOp & 0x01)!=0) // TRUE if operation is for P or P/Q
5607 +#define MR_CPX_XOR_OP_IS_Q(xorOp) ((xorOp & 0x02)!=0) // TRUE if operation is for Q or P/Q
5608 +#define MR_CPX_XOR_OP_IS_PQ(xorOp) ((xorOp & 0x03)==3) // TRUE if operation is for P/Q
5610 - u32 (*read_fw_status_reg)(struct megasas_register_set __iomem *);
5614 + * this data is passed to driver during driver init.
5616 +struct mr_cpx_init_data {
5617 + u32 cpx_desc_count; // Number of cpx desc required by fw.
5618 + u32 size; // size of the buffer
5619 + u64 phys_addr_cache_buf; // physical address of cache buffer allocated by pre-boot
5621 +} __attribute__ ((packed));
5624 + * header passed with each descriptor
5626 +struct mr_cpx_header {
5627 + u32 context : 24; // context information passed by firmware, to be passed back in response data
5628 + u32 type : 4; // type of descriptor
5630 +} __attribute__ ((packed));
5633 + * xor descriptor data
5635 +struct mr_cpx_xor_descriptor {
5636 + struct mr_cpx_header hdr;
5637 + MR_CPX_XOR_OP op; // xor operation for gen/check of p/q/p+q
5638 + u32 size; // number of bytes to gen/check for this operation
5639 + u32 buff_valid_bitmap; // bitmap of valid buffers for input
5640 + u8 p_idx; // index of p buffer within list (for p/pq gen/check functions)
5641 + u8 q_idx; // index of q buffer within list (for q/pq gen/check functions)
5643 + u32 buff_list[MAX_MR_ROW_SIZE]; // list of buffers for this xor operation (32 bit offset)
5644 + u32 mult_list[MAX_MR_ROW_SIZE]; // list of coefficient multipliers for q operations
5645 +} __attribute__ ((packed));
5649 + * copy buffer for each transfer. each such tranfer between
5650 + * user spare host address and firmware allocated cache data.
5652 +struct mr_cpx_copy_mr_buffer {
5653 + u32 buf; // buffer address/offset
5654 + u32 size; // size of copy
5655 +} __attribute__ ((packed));
5658 + * copy descriptor data
5660 +struct mr_cpx_copy_descriptor {
5661 + struct mr_cpx_header hdr;
5662 + u32 mfi_cmd_cxt; // mfi context
5663 + u32 total_byte_count; // total byte count for this transfer
5664 + u32 host_skip_count; // skip count from starting address of host buffer
5665 + u8 dir; // direction of transfer
5667 + struct mr_cpx_copy_mr_buffer copy_buf[MAX_MR_ROW_SIZE];
5668 +} __attribute__ ((packed)) ;
5671 + * users of this interface must allocate memory for the size of
5672 + * this structure while allocating memory for descriptors
5674 +union mr_cpx_descriptor {
5675 + struct mr_cpx_xor_descriptor cpx_xor_desc;
5676 + struct mr_cpx_copy_descriptor cpx_copy_desc;
5678 +} __attribute__ ((packed));
5683 + * firmware manages producerindex, driver manages consumerindex.
5684 + * number of decriptors is kept as variable. driver must use
5685 + * max host commands supported for allocation.
5687 +struct mr_cpx_request_queue {
5690 + union mr_cpx_descriptor cpxdescriptor[1]; // use max host commands
5691 +} __attribute__ ((packed));
5695 + * response data. this data will be posted by driver after copy/xor
5696 + * operation is compete.
5698 +union mr_cpx_response_data {
5700 + u32 context : 24; // context
5701 + u32 status : 4; // status in the form of cpx_status
5705 +} __attribute__ ((packed));
5710 + * driver manages producerindex, firmware manages consumerindex.
5711 + * number of decriptors is kept as variable. driver must use
5712 + * max host commands supported for allocation.
5714 +struct mr_cpx_response_queue {
5717 + union mr_cpx_response_data cpx_resp_data[1]; // use max host commands
5718 +} __attribute__ ((packed));
5722 + * the size of each of the structure within this is determined at run time.
5723 + * this structure is for document purpose and shows that the structures
5724 + * lay as shown below in memory
5726 +struct mr_cpx_queues {
5727 + struct mr_cpx_request_queue requestqueue;
5728 + struct mr_cpx_response_queue responsequeue;
5729 +} __attribute__ ((packed));
5732 + * driver sends this queue data during mfi init. firmware
5733 + * will not use the interface if the versions do not match.
5735 +struct mr_cpx_queue_data {
5737 + u32 count_queue_entries;
5738 + u64 phys_addr_cpx_queues;
5739 +} __attribute__ ((packed));
5741 +struct megasas_aen_event {
5742 + struct work_struct hotplug_work;
5743 + struct megasas_instance *instance;
5746 struct megasas_instance {
5748 @@ -1074,22 +1476,30 @@ struct megasas_instance {
5749 unsigned long base_addr;
5750 struct megasas_register_set __iomem *reg_set;
5752 + struct megasas_pd_list pd_list[MEGASAS_MAX_PD];
5753 + u8 ld_ids[MEGASAS_MAX_LD_IDS];
5759 u32 max_sectors_per_req;
5762 struct megasas_cmd **cmd_list;
5763 struct list_head cmd_pool;
5764 spinlock_t cmd_pool_lock;
5765 + struct megasas_aen_event *ev;
5766 + spinlock_t hba_lock;
5767 + /* used to synch producer, consumer ptrs in dpc */
5768 + spinlock_t completion_lock;
5769 struct dma_pool *frame_dma_pool;
5770 struct dma_pool *sense_dma_pool;
5772 struct megasas_evt_detail *evt_detail;
5773 dma_addr_t evt_detail_h;
5774 struct megasas_cmd *aen_cmd;
5775 - struct semaphore aen_mutex;
5776 + struct mutex aen_mutex;
5777 struct semaphore ioctl_sem;
5779 struct Scsi_Host *host;
5780 @@ -1099,17 +1509,62 @@ struct megasas_instance {
5782 struct pci_dev *pdev;
5784 + u32 fw_support_ieee;
5786 atomic_t fw_outstanding;
5787 - u32 hw_crit_error;
5788 + atomic_t fw_reset_no_pci_access;
5790 struct megasas_instance_template *instancet;
5791 struct tasklet_struct isr_tasklet;
5792 + struct work_struct work_init;
5797 + u8 issuepend_done;
5798 + u8 disableOnlineCtrlReset;
5800 unsigned long last_time;
5804 + struct timer_list io_completion_timer;
5805 + struct list_head internal_reset_pending_q;
5807 + u32 cpx_supported;
5808 + struct mr_cpx_request_queue *cpx_request_queue;
5809 + dma_addr_t cpx_request_queue_h;
5810 + union mr_cpx_descriptor *cpx_dscrptr;
5811 + u32 cpx_dscrptr_cnt;
5812 + u64 host_mem_phys;
5814 + u8 *host_mem_virt;
5819 + MEGASAS_HBA_OPERATIONAL = 0,
5820 + MEGASAS_ADPRESET_SM_INFAULT = 1,
5821 + MEGASAS_ADPRESET_SM_FW_RESET_SUCCESS = 2,
5822 + MEGASAS_ADPRESET_SM_OPERATIONAL = 3,
5823 + MEGASAS_HW_CRITICAL_ERROR = 4,
5824 + MEGASAS_ADPRESET_INPROG_SIGN = 0xDEADDEAD,
5828 + struct megasas_instance_template {
5829 + void (*fire_cmd)(struct megasas_instance *, dma_addr_t ,u32 ,struct megasas_register_set __iomem *);
5831 + void (*enable_intr)(struct megasas_register_set __iomem *) ;
5832 + void (*disable_intr)(struct megasas_register_set __iomem *);
5834 + int (*clear_intr)(struct megasas_register_set __iomem *);
5836 + u32 (*read_fw_status_reg)(struct megasas_register_set __iomem *);
5837 + int (*adp_reset)(struct megasas_instance *, struct megasas_register_set __iomem *);
5838 + int (*check_reset)(struct megasas_instance *, struct megasas_register_set __iomem *);
5841 #define MEGASAS_IS_LOGICAL(scp) \
5842 (scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1
5844 @@ -1127,7 +1582,9 @@ struct megasas_cmd {
5850 + u8 retry_for_fw_reset;
5853 struct list_head list;
5854 struct scsi_cmnd *scmd;