Commit 6bae38dd authored by Martin K. Petersen's avatar Martin K. Petersen

Merge patch series "scsi: arcmsr: support Areca ARC-1688 Raid controller"

Driver update from ching Huang <ching2048@areca.com.tw>.
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parents f38d4eda 56610811
...@@ -50,7 +50,7 @@ struct device_attribute; ...@@ -50,7 +50,7 @@ struct device_attribute;
#define ARCMSR_MAX_OUTSTANDING_CMD 1024 #define ARCMSR_MAX_OUTSTANDING_CMD 1024
#define ARCMSR_DEFAULT_OUTSTANDING_CMD 128 #define ARCMSR_DEFAULT_OUTSTANDING_CMD 128
#define ARCMSR_MIN_OUTSTANDING_CMD 32 #define ARCMSR_MIN_OUTSTANDING_CMD 32
#define ARCMSR_DRIVER_VERSION "v1.50.00.13-20230206" #define ARCMSR_DRIVER_VERSION "v1.51.00.14-20230915"
#define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_SCSI_INITIATOR_ID 255
#define ARCMSR_MAX_XFER_SECTORS 512 #define ARCMSR_MAX_XFER_SECTORS 512
#define ARCMSR_MAX_XFER_SECTORS_B 4096 #define ARCMSR_MAX_XFER_SECTORS_B 4096
...@@ -78,9 +78,13 @@ struct device_attribute; ...@@ -78,9 +78,13 @@ struct device_attribute;
#ifndef PCI_DEVICE_ID_ARECA_1203 #ifndef PCI_DEVICE_ID_ARECA_1203
#define PCI_DEVICE_ID_ARECA_1203 0x1203 #define PCI_DEVICE_ID_ARECA_1203 0x1203
#endif #endif
#ifndef PCI_DEVICE_ID_ARECA_1883
#define PCI_DEVICE_ID_ARECA_1883 0x1883
#endif
#ifndef PCI_DEVICE_ID_ARECA_1884 #ifndef PCI_DEVICE_ID_ARECA_1884
#define PCI_DEVICE_ID_ARECA_1884 0x1884 #define PCI_DEVICE_ID_ARECA_1884 0x1884
#endif #endif
#define PCI_DEVICE_ID_ARECA_1886_0 0x1886
#define PCI_DEVICE_ID_ARECA_1886 0x188A #define PCI_DEVICE_ID_ARECA_1886 0x188A
#define ARCMSR_HOURS (1000 * 60 * 60 * 4) #define ARCMSR_HOURS (1000 * 60 * 60 * 4)
#define ARCMSR_MINUTES (1000 * 60 * 60) #define ARCMSR_MINUTES (1000 * 60 * 60)
...@@ -818,6 +822,23 @@ typedef struct deliver_completeQ { ...@@ -818,6 +822,23 @@ typedef struct deliver_completeQ {
uint16_t cmdLMID; // reserved (0) uint16_t cmdLMID; // reserved (0)
uint16_t cmdFlag2; // reserved (0) uint16_t cmdFlag2; // reserved (0)
} DeliverQ, CompletionQ, *pDeliver_Q, *pCompletion_Q; } DeliverQ, CompletionQ, *pDeliver_Q, *pCompletion_Q;
#define ARCMSR_XOR_SEG_SIZE (1024 * 1024)
struct HostRamBuf {
uint32_t hrbSignature; // must be "HRBS"
uint32_t hrbSize; // total sg size, be multiples of MB
uint32_t hrbRes[2]; // reserved, must be set to 0
};
struct Xor_sg {
dma_addr_t xorPhys;
uint64_t xorBufLen;
};
struct XorHandle {
dma_addr_t xorPhys;
uint64_t xorBufLen;
void *xorVirt;
};
/* /*
******************************************************************************* *******************************************************************************
** Adapter Control Block ** Adapter Control Block
...@@ -929,6 +950,7 @@ struct AdapterControlBlock ...@@ -929,6 +950,7 @@ struct AdapterControlBlock
char firm_model[12]; char firm_model[12];
char firm_version[20]; char firm_version[20];
char device_map[20]; /*21,84-99*/ char device_map[20]; /*21,84-99*/
uint32_t firm_PicStatus;
struct work_struct arcmsr_do_message_isr_bh; struct work_struct arcmsr_do_message_isr_bh;
struct timer_list eternal_timer; struct timer_list eternal_timer;
unsigned short fw_flag; unsigned short fw_flag;
...@@ -937,6 +959,7 @@ struct AdapterControlBlock ...@@ -937,6 +959,7 @@ struct AdapterControlBlock
#define FW_DEADLOCK 0x0010 #define FW_DEADLOCK 0x0010
uint32_t maxOutstanding; uint32_t maxOutstanding;
int vector_count; int vector_count;
int xor_mega;
uint32_t maxFreeCCB; uint32_t maxFreeCCB;
struct timer_list refresh_timer; struct timer_list refresh_timer;
uint32_t doneq_index; uint32_t doneq_index;
...@@ -946,6 +969,10 @@ struct AdapterControlBlock ...@@ -946,6 +969,10 @@ struct AdapterControlBlock
uint32_t completionQ_entry; uint32_t completionQ_entry;
pCompletion_Q pCompletionQ; pCompletion_Q pCompletionQ;
uint32_t completeQ_size; uint32_t completeQ_size;
void *xorVirt;
dma_addr_t xorPhys;
unsigned int init2cfg_size;
unsigned int xorVirtOffset;
};/* HW_DEVICE_EXTENSION */ };/* HW_DEVICE_EXTENSION */
/* /*
******************************************************************************* *******************************************************************************
......
...@@ -214,8 +214,12 @@ static struct pci_device_id arcmsr_device_id_table[] = { ...@@ -214,8 +214,12 @@ static struct pci_device_id arcmsr_device_id_table[] = {
.driver_data = ACB_ADAPTER_TYPE_A}, .driver_data = ACB_ADAPTER_TYPE_A},
{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1880), {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1880),
.driver_data = ACB_ADAPTER_TYPE_C}, .driver_data = ACB_ADAPTER_TYPE_C},
{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1883),
.driver_data = ACB_ADAPTER_TYPE_C},
{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1884), {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1884),
.driver_data = ACB_ADAPTER_TYPE_E}, .driver_data = ACB_ADAPTER_TYPE_E},
{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1886_0),
.driver_data = ACB_ADAPTER_TYPE_F},
{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1886), {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1886),
.driver_data = ACB_ADAPTER_TYPE_F}, .driver_data = ACB_ADAPTER_TYPE_F},
{0, 0}, /* Terminating entry */ {0, 0}, /* Terminating entry */
...@@ -747,6 +751,57 @@ static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb) ...@@ -747,6 +751,57 @@ static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb)
return rtn; return rtn;
} }
static int arcmsr_alloc_xor_buffer(struct AdapterControlBlock *acb)
{
int rc = 0;
struct pci_dev *pdev = acb->pdev;
void *dma_coherent;
dma_addr_t dma_coherent_handle;
int i, xor_ram;
struct Xor_sg *pXorPhys;
void **pXorVirt;
struct HostRamBuf *pRamBuf;
// allocate 1 MB * N physically continuous memory for XOR engine.
xor_ram = (acb->firm_PicStatus >> 24) & 0x0f;
acb->xor_mega = (xor_ram - 1) * 32 + 128 + 3;
acb->init2cfg_size = sizeof(struct HostRamBuf) +
(sizeof(struct XorHandle) * acb->xor_mega);
dma_coherent = dma_alloc_coherent(&pdev->dev, acb->init2cfg_size,
&dma_coherent_handle, GFP_KERNEL);
acb->xorVirt = dma_coherent;
acb->xorPhys = dma_coherent_handle;
pXorPhys = (struct Xor_sg *)((unsigned long)dma_coherent +
sizeof(struct HostRamBuf));
acb->xorVirtOffset = sizeof(struct HostRamBuf) +
(sizeof(struct Xor_sg) * acb->xor_mega);
pXorVirt = (void **)((unsigned long)dma_coherent +
(unsigned long)acb->xorVirtOffset);
for (i = 0; i < acb->xor_mega; i++) {
dma_coherent = dma_alloc_coherent(&pdev->dev,
ARCMSR_XOR_SEG_SIZE,
&dma_coherent_handle, GFP_KERNEL);
if (dma_coherent) {
pXorPhys->xorPhys = dma_coherent_handle;
pXorPhys->xorBufLen = ARCMSR_XOR_SEG_SIZE;
*pXorVirt = dma_coherent;
pXorPhys++;
pXorVirt++;
} else {
pr_info("arcmsr%d: alloc max XOR buffer = 0x%x MB\n",
acb->host->host_no, i);
rc = -ENOMEM;
break;
}
}
pRamBuf = (struct HostRamBuf *)acb->xorVirt;
pRamBuf->hrbSignature = 0x53425248; //HRBS
pRamBuf->hrbSize = i * ARCMSR_XOR_SEG_SIZE;
pRamBuf->hrbRes[0] = 0;
pRamBuf->hrbRes[1] = 0;
return rc;
}
static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
{ {
struct pci_dev *pdev = acb->pdev; struct pci_dev *pdev = acb->pdev;
...@@ -836,7 +891,11 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) ...@@ -836,7 +891,11 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
acb->completionQ_entry = acb->ioqueue_size / sizeof(struct deliver_completeQ); acb->completionQ_entry = acb->ioqueue_size / sizeof(struct deliver_completeQ);
acb->doneq_index = 0; acb->doneq_index = 0;
break; break;
} }
if ((acb->firm_PicStatus >> 24) & 0x0f) {
if (arcmsr_alloc_xor_buffer(acb))
return -ENOMEM;
}
return 0; return 0;
} }
...@@ -2022,6 +2081,29 @@ static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb) ...@@ -2022,6 +2081,29 @@ static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb)
static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb) static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb)
{ {
if (acb->xor_mega) {
struct Xor_sg *pXorPhys;
void **pXorVirt;
int i;
pXorPhys = (struct Xor_sg *)(acb->xorVirt +
sizeof(struct HostRamBuf));
pXorVirt = (void **)((unsigned long)acb->xorVirt +
(unsigned long)acb->xorVirtOffset);
for (i = 0; i < acb->xor_mega; i++) {
if (pXorPhys->xorPhys) {
dma_free_coherent(&acb->pdev->dev,
ARCMSR_XOR_SEG_SIZE,
*pXorVirt, pXorPhys->xorPhys);
pXorPhys->xorPhys = 0;
*pXorVirt = NULL;
}
pXorPhys++;
pXorVirt++;
}
dma_free_coherent(&acb->pdev->dev, acb->init2cfg_size,
acb->xorVirt, acb->xorPhys);
}
dma_free_coherent(&acb->pdev->dev, acb->uncache_size, acb->dma_coherent, acb->dma_coherent_handle); dma_free_coherent(&acb->pdev->dev, acb->uncache_size, acb->dma_coherent, acb->dma_coherent_handle);
} }
...@@ -3309,6 +3391,10 @@ static void arcmsr_get_adapter_config(struct AdapterControlBlock *pACB, uint32_t ...@@ -3309,6 +3391,10 @@ static void arcmsr_get_adapter_config(struct AdapterControlBlock *pACB, uint32_t
pACB->firm_sdram_size = readl(&rwbuffer[3]); pACB->firm_sdram_size = readl(&rwbuffer[3]);
pACB->firm_hd_channels = readl(&rwbuffer[4]); pACB->firm_hd_channels = readl(&rwbuffer[4]);
pACB->firm_cfg_version = readl(&rwbuffer[25]); pACB->firm_cfg_version = readl(&rwbuffer[25]);
if (pACB->adapter_type == ACB_ADAPTER_TYPE_F)
pACB->firm_PicStatus = readl(&rwbuffer[30]);
else
pACB->firm_PicStatus = 0;
pr_notice("Areca RAID Controller%d: Model %s, F/W %s\n", pr_notice("Areca RAID Controller%d: Model %s, F/W %s\n",
pACB->host->host_no, pACB->host->host_no,
pACB->firm_model, pACB->firm_model,
...@@ -4096,6 +4182,12 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb) ...@@ -4096,6 +4182,12 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)
acb->msgcode_rwbuffer[5] = lower_32_bits(acb->dma_coherent_handle2); acb->msgcode_rwbuffer[5] = lower_32_bits(acb->dma_coherent_handle2);
acb->msgcode_rwbuffer[6] = upper_32_bits(acb->dma_coherent_handle2); acb->msgcode_rwbuffer[6] = upper_32_bits(acb->dma_coherent_handle2);
acb->msgcode_rwbuffer[7] = acb->completeQ_size; acb->msgcode_rwbuffer[7] = acb->completeQ_size;
if (acb->xor_mega) {
acb->msgcode_rwbuffer[8] = 0x455AA; //Linux init 2
acb->msgcode_rwbuffer[9] = 0;
acb->msgcode_rwbuffer[10] = lower_32_bits(acb->xorPhys);
acb->msgcode_rwbuffer[11] = upper_32_bits(acb->xorPhys);
}
writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, &reg->inbound_msgaddr0); writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, &reg->inbound_msgaddr0);
acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE; acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
writel(acb->out_doorbell, &reg->iobound_doorbell); writel(acb->out_doorbell, &reg->iobound_doorbell);
...@@ -4706,9 +4798,11 @@ static const char *arcmsr_info(struct Scsi_Host *host) ...@@ -4706,9 +4798,11 @@ static const char *arcmsr_info(struct Scsi_Host *host)
case PCI_DEVICE_ID_ARECA_1680: case PCI_DEVICE_ID_ARECA_1680:
case PCI_DEVICE_ID_ARECA_1681: case PCI_DEVICE_ID_ARECA_1681:
case PCI_DEVICE_ID_ARECA_1880: case PCI_DEVICE_ID_ARECA_1880:
case PCI_DEVICE_ID_ARECA_1883:
case PCI_DEVICE_ID_ARECA_1884: case PCI_DEVICE_ID_ARECA_1884:
type = "SAS/SATA"; type = "SAS/SATA";
break; break;
case PCI_DEVICE_ID_ARECA_1886_0:
case PCI_DEVICE_ID_ARECA_1886: case PCI_DEVICE_ID_ARECA_1886:
type = "NVMe/SAS/SATA"; type = "NVMe/SAS/SATA";
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment