diff options
author | Yang, Bo <Bo.Yang@lsi.com> | 2009-10-06 16:31:54 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-10-29 13:03:18 -0400 |
commit | 879111224d0784eab623fe8130a1f4481e0e1966 (patch) | |
tree | 4f4f3a1aa5c3abb240e74a96ca7968c93beb4fc5 /drivers/scsi/megaraid | |
parent | 72c4fd36dc7f755a5245ef2495fe27d5084d776d (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.c | 139 | ||||
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas.h | 4 |
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 | */ | ||
345 | static inline void | ||
346 | megasas_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(®s->outbound_intr_mask); | ||
354 | } | ||
355 | |||
356 | /** | ||
357 | * megasas_disable_intr_skinny - Disables interrupt | ||
358 | * @regs: MFI register set | ||
359 | */ | ||
360 | static inline void | ||
361 | megasas_disable_intr_skinny(struct megasas_register_set __iomem *regs) | ||
362 | { | ||
363 | u32 mask = 0xFFFFFFFF; | ||
364 | writel(mask, ®s->outbound_intr_mask); | ||
365 | /* Dummy readl to force pci flush */ | ||
366 | readl(®s->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 | */ | ||
373 | static u32 | ||
374 | megasas_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 | */ | ||
383 | static int | ||
384 | megasas_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(®s->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, ®s->outbound_intr_status); | ||
400 | |||
401 | /* | ||
402 | * dummy read to flush PCI | ||
403 | */ | ||
404 | readl(®s->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 | */ | ||
415 | static inline void | ||
416 | megasas_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 | |||
424 | static 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 |