[SCSI] megaraid_sas: add new controllers (0x78 0x79)

Add the new controllers (0x78 0x79) support to the driver. Those
controllers are LSI's next generation (gen2) SAS controllers.

[akpm@linux-foundation.org: coding-style fixes]
[akpm@linux-foundation.org: parenthesise a macro]
Signed-off-by: Bo Yang <bo.yang@lsi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

authored by Yang, Bo and committed by James Bottomley 6610a6b3 530e6fc1

+112 -2
+108 -2
drivers/scsi/megaraid/megaraid_sas.c
··· 10 * 2 of the License, or (at your option) any later version. 11 * 12 * FILE : megaraid_sas.c 13 - * Version : v00.00.03.20-rc1 14 * 15 * Authors: 16 * (email-id : megaraidlinux@lsi.com) ··· 71 /* ppc IOP */ 72 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078DE)}, 73 /* ppc IOP */ 74 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)}, 75 /* xscale IOP, vega */ 76 {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)}, ··· 325 .disable_intr = megasas_disable_intr_ppc, 326 .clear_intr = megasas_clear_intr_ppc, 327 .read_fw_status_reg = megasas_read_fw_status_reg_ppc, 328 }; 329 330 /** ··· 2079 /* 2080 * Map the message registers 2081 */ 2082 - instance->base_addr = pci_resource_start(instance->pdev, 0); 2083 2084 if (pci_request_regions(instance->pdev, "megasas: LSI")) { 2085 printk(KERN_DEBUG "megasas: IO memory region busy!\n"); ··· 2105 case PCI_DEVICE_ID_LSI_SAS1078R: 2106 case PCI_DEVICE_ID_LSI_SAS1078DE: 2107 instance->instancet = &megasas_instance_template_ppc; 2108 break; 2109 case PCI_DEVICE_ID_LSI_SAS1064R: 2110 case PCI_DEVICE_ID_DELL_PERC5:
··· 10 * 2 of the License, or (at your option) any later version. 11 * 12 * FILE : megaraid_sas.c 13 + * Version : v00.00.04.01-rc1 14 * 15 * Authors: 16 * (email-id : megaraidlinux@lsi.com) ··· 71 /* ppc IOP */ 72 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078DE)}, 73 /* ppc IOP */ 74 + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078GEN2)}, 75 + /* gen2*/ 76 + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0079GEN2)}, 77 + /* gen2*/ 78 {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)}, 79 /* xscale IOP, vega */ 80 {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)}, ··· 321 .disable_intr = megasas_disable_intr_ppc, 322 .clear_intr = megasas_clear_intr_ppc, 323 .read_fw_status_reg = megasas_read_fw_status_reg_ppc, 324 + }; 325 + 326 + /** 327 + * The following functions are defined for gen2 (deviceid : 0x78 0x79) 328 + * controllers 329 + */ 330 + 331 + /** 332 + * megasas_enable_intr_gen2 - Enables interrupts 333 + * @regs: MFI register set 334 + */ 335 + static inline void 336 + megasas_enable_intr_gen2(struct megasas_register_set __iomem *regs) 337 + { 338 + writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear); 339 + 340 + /* write ~0x00000005 (4 & 1) to the intr mask*/ 341 + writel(~MFI_GEN2_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask); 342 + 343 + /* Dummy readl to force pci flush */ 344 + readl(&regs->outbound_intr_mask); 345 + } 346 + 347 + /** 348 + * megasas_disable_intr_gen2 - Disables interrupt 349 + * @regs: MFI register set 350 + */ 351 + static inline void 352 + megasas_disable_intr_gen2(struct megasas_register_set __iomem *regs) 353 + { 354 + u32 mask = 0xFFFFFFFF; 355 + writel(mask, &regs->outbound_intr_mask); 356 + /* Dummy readl to force pci flush */ 357 + readl(&regs->outbound_intr_mask); 358 + } 359 + 360 + /** 361 + * megasas_read_fw_status_reg_gen2 - returns the current FW status value 362 + * @regs: MFI register set 363 + */ 364 + static u32 365 + megasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs) 366 + { 367 + return readl(&(regs)->outbound_scratch_pad); 368 + } 369 + 370 + /** 371 + * megasas_clear_interrupt_gen2 - Check & clear interrupt 372 + * @regs: MFI register set 373 + */ 374 + static int 375 + megasas_clear_intr_gen2(struct megasas_register_set __iomem *regs) 376 + { 377 + u32 status; 378 + /* 379 + * Check if it is our interrupt 380 + */ 381 + status = readl(&regs->outbound_intr_status); 382 + 383 + if (!(status & MFI_GEN2_ENABLE_INTERRUPT_MASK)) 384 + return 1; 385 + 386 + /* 387 + * Clear the interrupt by writing back the same value 388 + */ 389 + writel(status, &regs->outbound_doorbell_clear); 390 + 391 + /* Dummy readl to force pci flush */ 392 + readl(&regs->outbound_intr_status); 393 + 394 + return 0; 395 + } 396 + /** 397 + * megasas_fire_cmd_gen2 - Sends command to the FW 398 + * @frame_phys_addr : Physical address of cmd 399 + * @frame_count : Number of frames for the command 400 + * @regs : MFI register set 401 + */ 402 + static inline void 403 + megasas_fire_cmd_gen2(dma_addr_t frame_phys_addr, u32 frame_count, 404 + struct megasas_register_set __iomem *regs) 405 + { 406 + writel((frame_phys_addr | (frame_count<<1))|1, 407 + &(regs)->inbound_queue_port); 408 + } 409 + 410 + static struct megasas_instance_template megasas_instance_template_gen2 = { 411 + 412 + .fire_cmd = megasas_fire_cmd_gen2, 413 + .enable_intr = megasas_enable_intr_gen2, 414 + .disable_intr = megasas_disable_intr_gen2, 415 + .clear_intr = megasas_clear_intr_gen2, 416 + .read_fw_status_reg = megasas_read_fw_status_reg_gen2, 417 }; 418 419 /** ··· 1982 /* 1983 * Map the message registers 1984 */ 1985 + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078GEN2) || 1986 + (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0079GEN2)) { 1987 + instance->base_addr = pci_resource_start(instance->pdev, 1); 1988 + } else { 1989 + instance->base_addr = pci_resource_start(instance->pdev, 0); 1990 + } 1991 1992 if (pci_request_regions(instance->pdev, "megasas: LSI")) { 1993 printk(KERN_DEBUG "megasas: IO memory region busy!\n"); ··· 2003 case PCI_DEVICE_ID_LSI_SAS1078R: 2004 case PCI_DEVICE_ID_LSI_SAS1078DE: 2005 instance->instancet = &megasas_instance_template_ppc; 2006 + break; 2007 + case PCI_DEVICE_ID_LSI_SAS1078GEN2: 2008 + case PCI_DEVICE_ID_LSI_SAS0079GEN2: 2009 + instance->instancet = &megasas_instance_template_gen2; 2010 break; 2011 case PCI_DEVICE_ID_LSI_SAS1064R: 2012 case PCI_DEVICE_ID_DELL_PERC5:
+4
drivers/scsi/megaraid/megaraid_sas.h
··· 28 #define PCI_DEVICE_ID_LSI_SAS1078R 0x0060 29 #define PCI_DEVICE_ID_LSI_SAS1078DE 0x007C 30 #define PCI_DEVICE_ID_LSI_VERDE_ZCR 0x0413 31 32 /* 33 * ===================================== ··· 582 #define MEGASAS_COMPLETION_TIMER_INTERVAL (HZ/10) 583 584 #define MFI_REPLY_1078_MESSAGE_INTERRUPT 0x80000000 585 586 /* 587 * register set for both 1068 and 1078 controllers
··· 28 #define PCI_DEVICE_ID_LSI_SAS1078R 0x0060 29 #define PCI_DEVICE_ID_LSI_SAS1078DE 0x007C 30 #define PCI_DEVICE_ID_LSI_VERDE_ZCR 0x0413 31 + #define PCI_DEVICE_ID_LSI_SAS1078GEN2 0x0078 32 + #define PCI_DEVICE_ID_LSI_SAS0079GEN2 0x0079 33 34 /* 35 * ===================================== ··· 580 #define MEGASAS_COMPLETION_TIMER_INTERVAL (HZ/10) 581 582 #define MFI_REPLY_1078_MESSAGE_INTERRUPT 0x80000000 583 + #define MFI_REPLY_GEN2_MESSAGE_INTERRUPT 0x00000001 584 + #define MFI_GEN2_ENABLE_INTERRUPT_MASK (0x00000001 | 0x00000004) 585 586 /* 587 * register set for both 1068 and 1078 controllers