aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/megaraid
diff options
context:
space:
mode:
authorYang, Bo <Bo.Yang@lsi.com>2009-10-06 16:31:54 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-10-29 13:03:18 -0400
commit879111224d0784eab623fe8130a1f4481e0e1966 (patch)
tree4f4f3a1aa5c3abb240e74a96ca7968c93beb4fc5 /drivers/scsi/megaraid
parent72c4fd36dc7f755a5245ef2495fe27d5084d776d (diff)
[SCSI] megaraid_sas: Add new megaraid SAS 2 controller support to the driver
Add the new megaraid sas 2 controller to the driver. megaraid sas2 is LSI next generation SAS products. driver add the interface to support this product. Signed-off-by Bo Yang<bo.yang@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/megaraid')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c139
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h4
2 files changed, 138 insertions, 5 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 012141378f3b..b6e43271883c 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -76,6 +76,10 @@ static struct pci_device_id megasas_pci_table[] = {
76 /* gen2*/ 76 /* gen2*/
77 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0079GEN2)}, 77 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0079GEN2)},
78 /* gen2*/ 78 /* gen2*/
79 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0073SKINNY)},
80 /* skinny*/
81 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0071SKINNY)},
82 /* skinny*/
79 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)}, 83 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)},
80 /* xscale IOP, vega */ 84 /* xscale IOP, vega */
81 {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)}, 85 {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
@@ -335,6 +339,99 @@ static struct megasas_instance_template megasas_instance_template_ppc = {
335}; 339};
336 340
337/** 341/**
342 * megasas_enable_intr_skinny - Enables interrupts
343 * @regs: MFI register set
344 */
345static inline void
346megasas_enable_intr_skinny(struct megasas_register_set __iomem *regs)
347{
348 writel(0xFFFFFFFF, &(regs)->outbound_intr_mask);
349
350 writel(~MFI_SKINNY_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
351
352 /* Dummy readl to force pci flush */
353 readl(&regs->outbound_intr_mask);
354}
355
356/**
357 * megasas_disable_intr_skinny - Disables interrupt
358 * @regs: MFI register set
359 */
360static inline void
361megasas_disable_intr_skinny(struct megasas_register_set __iomem *regs)
362{
363 u32 mask = 0xFFFFFFFF;
364 writel(mask, &regs->outbound_intr_mask);
365 /* Dummy readl to force pci flush */
366 readl(&regs->outbound_intr_mask);
367}
368
369/**
370 * megasas_read_fw_status_reg_skinny - returns the current FW status value
371 * @regs: MFI register set
372 */
373static u32
374megasas_read_fw_status_reg_skinny(struct megasas_register_set __iomem *regs)
375{
376 return readl(&(regs)->outbound_scratch_pad);
377}
378
379/**
380 * megasas_clear_interrupt_skinny - Check & clear interrupt
381 * @regs: MFI register set
382 */
383static int
384megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs)
385{
386 u32 status;
387 /*
388 * Check if it is our interrupt
389 */
390 status = readl(&regs->outbound_intr_status);
391
392 if (!(status & MFI_SKINNY_ENABLE_INTERRUPT_MASK)) {
393 return 1;
394 }
395
396 /*
397 * Clear the interrupt by writing back the same value
398 */
399 writel(status, &regs->outbound_intr_status);
400
401 /*
402 * dummy read to flush PCI
403 */
404 readl(&regs->outbound_intr_status);
405
406 return 0;
407}
408
409/**
410 * megasas_fire_cmd_skinny - Sends command to the FW
411 * @frame_phys_addr : Physical address of cmd
412 * @frame_count : Number of frames for the command
413 * @regs : MFI register set
414 */
415static inline void
416megasas_fire_cmd_skinny(dma_addr_t frame_phys_addr, u32 frame_count,
417 struct megasas_register_set __iomem *regs)
418{
419 writel(0, &(regs)->inbound_high_queue_port);
420 writel((frame_phys_addr | (frame_count<<1))|1,
421 &(regs)->inbound_low_queue_port);
422}
423
424static struct megasas_instance_template megasas_instance_template_skinny = {
425
426 .fire_cmd = megasas_fire_cmd_skinny,
427 .enable_intr = megasas_enable_intr_skinny,
428 .disable_intr = megasas_disable_intr_skinny,
429 .clear_intr = megasas_clear_intr_skinny,
430 .read_fw_status_reg = megasas_read_fw_status_reg_skinny,
431};
432
433
434/**
338* The following functions are defined for gen2 (deviceid : 0x78 0x79) 435* The following functions are defined for gen2 (deviceid : 0x78 0x79)
339* controllers 436* controllers
340*/ 437*/
@@ -1587,16 +1684,34 @@ megasas_transition_to_ready(struct megasas_instance* instance)
1587 /* 1684 /*
1588 * Set the CLR bit in inbound doorbell 1685 * Set the CLR bit in inbound doorbell
1589 */ 1686 */
1590 writel(MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG, 1687 if ((instance->pdev->device == \
1591 &instance->reg_set->inbound_doorbell); 1688 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
1689 (instance->pdev->device ==
1690 PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
1691
1692 writel(
1693 MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
1694 &instance->reg_set->reserved_0[0]);
1695 } else {
1696 writel(
1697 MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
1698 &instance->reg_set->inbound_doorbell);
1699 }
1592 1700
1593 max_wait = 2; 1701 max_wait = 2;
1594 cur_state = MFI_STATE_WAIT_HANDSHAKE; 1702 cur_state = MFI_STATE_WAIT_HANDSHAKE;
1595 break; 1703 break;
1596 1704
1597 case MFI_STATE_BOOT_MESSAGE_PENDING: 1705 case MFI_STATE_BOOT_MESSAGE_PENDING:
1598 writel(MFI_INIT_HOTPLUG, 1706 if ((instance->pdev->device ==
1599 &instance->reg_set->inbound_doorbell); 1707 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
1708 (instance->pdev->device ==
1709 PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
1710 writel(MFI_INIT_HOTPLUG,
1711 &instance->reg_set->reserved_0[0]);
1712 } else
1713 writel(MFI_INIT_HOTPLUG,
1714 &instance->reg_set->inbound_doorbell);
1600 1715
1601 max_wait = 10; 1716 max_wait = 10;
1602 cur_state = MFI_STATE_BOOT_MESSAGE_PENDING; 1717 cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
@@ -1607,7 +1722,15 @@ megasas_transition_to_ready(struct megasas_instance* instance)
1607 * Bring it to READY state; assuming max wait 10 secs 1722 * Bring it to READY state; assuming max wait 10 secs
1608 */ 1723 */
1609 instance->instancet->disable_intr(instance->reg_set); 1724 instance->instancet->disable_intr(instance->reg_set);
1610 writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell); 1725 if ((instance->pdev->device ==
1726 PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
1727 (instance->pdev->device ==
1728 PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
1729 writel(MFI_RESET_FLAGS,
1730 &instance->reg_set->reserved_0[0]);
1731 } else
1732 writel(MFI_RESET_FLAGS,
1733 &instance->reg_set->inbound_doorbell);
1611 1734
1612 max_wait = 60; 1735 max_wait = 60;
1613 cur_state = MFI_STATE_OPERATIONAL; 1736 cur_state = MFI_STATE_OPERATIONAL;
@@ -2112,6 +2235,8 @@ static int megasas_init_mfi(struct megasas_instance *instance)
2112 * Map the message registers 2235 * Map the message registers
2113 */ 2236 */
2114 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078GEN2) || 2237 if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
2238 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
2239 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
2115 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0079GEN2)) { 2240 (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0079GEN2)) {
2116 instance->base_addr = pci_resource_start(instance->pdev, 1); 2241 instance->base_addr = pci_resource_start(instance->pdev, 1);
2117 } else { 2242 } else {
@@ -2142,6 +2267,10 @@ static int megasas_init_mfi(struct megasas_instance *instance)
2142 case PCI_DEVICE_ID_LSI_SAS0079GEN2: 2267 case PCI_DEVICE_ID_LSI_SAS0079GEN2:
2143 instance->instancet = &megasas_instance_template_gen2; 2268 instance->instancet = &megasas_instance_template_gen2;
2144 break; 2269 break;
2270 case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
2271 case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
2272 instance->instancet = &megasas_instance_template_skinny;
2273 break;
2145 case PCI_DEVICE_ID_LSI_SAS1064R: 2274 case PCI_DEVICE_ID_LSI_SAS1064R:
2146 case PCI_DEVICE_ID_DELL_PERC5: 2275 case PCI_DEVICE_ID_DELL_PERC5:
2147 default: 2276 default:
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 900359fd3fb9..365a96172070 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -30,6 +30,8 @@
30#define PCI_DEVICE_ID_LSI_VERDE_ZCR 0x0413 30#define PCI_DEVICE_ID_LSI_VERDE_ZCR 0x0413
31#define PCI_DEVICE_ID_LSI_SAS1078GEN2 0x0078 31#define PCI_DEVICE_ID_LSI_SAS1078GEN2 0x0078
32#define PCI_DEVICE_ID_LSI_SAS0079GEN2 0x0079 32#define PCI_DEVICE_ID_LSI_SAS0079GEN2 0x0079
33#define PCI_DEVICE_ID_LSI_SAS0073SKINNY 0x0073
34#define PCI_DEVICE_ID_LSI_SAS0071SKINNY 0x0071
33 35
34/* 36/*
35 * ===================================== 37 * =====================================
@@ -584,6 +586,8 @@ struct megasas_ctrl_info {
584#define MFI_REPLY_1078_MESSAGE_INTERRUPT 0x80000000 586#define MFI_REPLY_1078_MESSAGE_INTERRUPT 0x80000000
585#define MFI_REPLY_GEN2_MESSAGE_INTERRUPT 0x00000001 587#define MFI_REPLY_GEN2_MESSAGE_INTERRUPT 0x00000001
586#define MFI_GEN2_ENABLE_INTERRUPT_MASK (0x00000001 | 0x00000004) 588#define MFI_GEN2_ENABLE_INTERRUPT_MASK (0x00000001 | 0x00000004)
589#define MFI_REPLY_SKINNY_MESSAGE_INTERRUPT 0x40000000
590#define MFI_SKINNY_ENABLE_INTERRUPT_MASK (0x00000001)
587 591
588/* 592/*
589* register set for both 1068 and 1078 controllers 593* register set for both 1068 and 1078 controllers