mirror of
https://git.proxmox.com/git/mirror_ubuntu-kernels.git
synced 2025-12-08 04:09:37 +00:00
scsi: arcmsr: Add support for ARC-1886 series RAID controllers
Add support for ARC-1886 series RAID controllers. [mkp: apply zeroday build warning fixes] Link: https://lore.kernel.org/r/78ae03d0ac05054c721cc3a94f41f9e656a5e176.camel@areca.com.tw Signed-off-by: ching Huang <ching2048@areca.com.tw> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
893f4a14b1
commit
ae897ae28f
@ -80,6 +80,7 @@ struct device_attribute;
|
|||||||
#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 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)
|
||||||
/*
|
/*
|
||||||
@ -436,6 +437,21 @@ struct FIRMWARE_INFO
|
|||||||
#define ARCMSR_HBEMU_DOORBELL_SYNC 0x100
|
#define ARCMSR_HBEMU_DOORBELL_SYNC 0x100
|
||||||
#define ARCMSR_ARC188X_RESET_ADAPTER 0x00000004
|
#define ARCMSR_ARC188X_RESET_ADAPTER 0x00000004
|
||||||
#define ARCMSR_ARC1884_DiagWrite_ENABLE 0x00000080
|
#define ARCMSR_ARC1884_DiagWrite_ENABLE 0x00000080
|
||||||
|
|
||||||
|
/*
|
||||||
|
*******************************************************************************
|
||||||
|
** SPEC. for Areca Type F adapter
|
||||||
|
*******************************************************************************
|
||||||
|
*/
|
||||||
|
#define ARCMSR_SIGNATURE_1886 0x188617D3
|
||||||
|
// Doorbell and interrupt definition are same as Type E adapter
|
||||||
|
/* ARC-1886 doorbell sync */
|
||||||
|
#define ARCMSR_HBFMU_DOORBELL_SYNC 0x100
|
||||||
|
//set host rw buffer physical address at inbound message 0, 1 (low,high)
|
||||||
|
#define ARCMSR_HBFMU_DOORBELL_SYNC1 0x300
|
||||||
|
#define ARCMSR_HBFMU_MESSAGE_FIRMWARE_OK 0x80000000
|
||||||
|
#define ARCMSR_HBFMU_MESSAGE_NO_VOLUME_CHANGE 0x20000000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
** ARECA SCSI COMMAND DESCRIPTOR BLOCK size 0x1F8 (504)
|
** ARECA SCSI COMMAND DESCRIPTOR BLOCK size 0x1F8 (504)
|
||||||
@ -720,6 +736,80 @@ struct MessageUnit_E{
|
|||||||
uint32_t msgcode_rwbuffer[256]; /*2200 23FF*/
|
uint32_t msgcode_rwbuffer[256]; /*2200 23FF*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
*********************************************************************
|
||||||
|
** Messaging Unit (MU) of Type F processor(LSI)
|
||||||
|
*********************************************************************
|
||||||
|
*/
|
||||||
|
struct MessageUnit_F {
|
||||||
|
uint32_t iobound_doorbell; /*0000 0003*/
|
||||||
|
uint32_t write_sequence_3xxx; /*0004 0007*/
|
||||||
|
uint32_t host_diagnostic_3xxx; /*0008 000B*/
|
||||||
|
uint32_t posted_outbound_doorbell; /*000C 000F*/
|
||||||
|
uint32_t master_error_attribute; /*0010 0013*/
|
||||||
|
uint32_t master_error_address_low; /*0014 0017*/
|
||||||
|
uint32_t master_error_address_high; /*0018 001B*/
|
||||||
|
uint32_t hcb_size; /*001C 001F*/
|
||||||
|
uint32_t inbound_doorbell; /*0020 0023*/
|
||||||
|
uint32_t diagnostic_rw_data; /*0024 0027*/
|
||||||
|
uint32_t diagnostic_rw_address_low; /*0028 002B*/
|
||||||
|
uint32_t diagnostic_rw_address_high; /*002C 002F*/
|
||||||
|
uint32_t host_int_status; /*0030 0033*/
|
||||||
|
uint32_t host_int_mask; /*0034 0037*/
|
||||||
|
uint32_t dcr_data; /*0038 003B*/
|
||||||
|
uint32_t dcr_address; /*003C 003F*/
|
||||||
|
uint32_t inbound_queueport; /*0040 0043*/
|
||||||
|
uint32_t outbound_queueport; /*0044 0047*/
|
||||||
|
uint32_t hcb_pci_address_low; /*0048 004B*/
|
||||||
|
uint32_t hcb_pci_address_high; /*004C 004F*/
|
||||||
|
uint32_t iop_int_status; /*0050 0053*/
|
||||||
|
uint32_t iop_int_mask; /*0054 0057*/
|
||||||
|
uint32_t iop_inbound_queue_port; /*0058 005B*/
|
||||||
|
uint32_t iop_outbound_queue_port; /*005C 005F*/
|
||||||
|
uint32_t inbound_free_list_index; /*0060 0063*/
|
||||||
|
uint32_t inbound_post_list_index; /*0064 0067*/
|
||||||
|
uint32_t reply_post_producer_index; /*0068 006B*/
|
||||||
|
uint32_t reply_post_consumer_index; /*006C 006F*/
|
||||||
|
uint32_t inbound_doorbell_clear; /*0070 0073*/
|
||||||
|
uint32_t i2o_message_unit_control; /*0074 0077*/
|
||||||
|
uint32_t last_used_message_source_address_low; /*0078 007B*/
|
||||||
|
uint32_t last_used_message_source_address_high; /*007C 007F*/
|
||||||
|
uint32_t pull_mode_data_byte_count[4]; /*0080 008F*/
|
||||||
|
uint32_t message_dest_address_index; /*0090 0093*/
|
||||||
|
uint32_t done_queue_not_empty_int_counter_timer; /*0094 0097*/
|
||||||
|
uint32_t utility_A_int_counter_timer; /*0098 009B*/
|
||||||
|
uint32_t outbound_doorbell; /*009C 009F*/
|
||||||
|
uint32_t outbound_doorbell_clear; /*00A0 00A3*/
|
||||||
|
uint32_t message_source_address_index; /*00A4 00A7*/
|
||||||
|
uint32_t message_done_queue_index; /*00A8 00AB*/
|
||||||
|
uint32_t reserved0; /*00AC 00AF*/
|
||||||
|
uint32_t inbound_msgaddr0; /*00B0 00B3*/
|
||||||
|
uint32_t inbound_msgaddr1; /*00B4 00B7*/
|
||||||
|
uint32_t outbound_msgaddr0; /*00B8 00BB*/
|
||||||
|
uint32_t outbound_msgaddr1; /*00BC 00BF*/
|
||||||
|
uint32_t inbound_queueport_low; /*00C0 00C3*/
|
||||||
|
uint32_t inbound_queueport_high; /*00C4 00C7*/
|
||||||
|
uint32_t outbound_queueport_low; /*00C8 00CB*/
|
||||||
|
uint32_t outbound_queueport_high; /*00CC 00CF*/
|
||||||
|
uint32_t iop_inbound_queue_port_low; /*00D0 00D3*/
|
||||||
|
uint32_t iop_inbound_queue_port_high; /*00D4 00D7*/
|
||||||
|
uint32_t iop_outbound_queue_port_low; /*00D8 00DB*/
|
||||||
|
uint32_t iop_outbound_queue_port_high; /*00DC 00DF*/
|
||||||
|
uint32_t message_dest_queue_port_low; /*00E0 00E3*/
|
||||||
|
uint32_t message_dest_queue_port_high; /*00E4 00E7*/
|
||||||
|
uint32_t last_used_message_dest_address_low; /*00E8 00EB*/
|
||||||
|
uint32_t last_used_message_dest_address_high; /*00EC 00EF*/
|
||||||
|
uint32_t message_done_queue_base_address_low; /*00F0 00F3*/
|
||||||
|
uint32_t message_done_queue_base_address_high; /*00F4 00F7*/
|
||||||
|
uint32_t host_diagnostic; /*00F8 00FB*/
|
||||||
|
uint32_t write_sequence; /*00FC 00FF*/
|
||||||
|
uint32_t reserved1[46]; /*0100 01B7*/
|
||||||
|
uint32_t reply_post_producer_index1; /*01B8 01BB*/
|
||||||
|
uint32_t reply_post_consumer_index1; /*01BC 01BF*/
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MESG_RW_BUFFER_SIZE (256 * 3)
|
||||||
|
|
||||||
typedef struct deliver_completeQ {
|
typedef struct deliver_completeQ {
|
||||||
uint16_t cmdFlag;
|
uint16_t cmdFlag;
|
||||||
uint16_t cmdSMID;
|
uint16_t cmdSMID;
|
||||||
@ -739,6 +829,7 @@ struct AdapterControlBlock
|
|||||||
#define ACB_ADAPTER_TYPE_C 0x00000002 /* hbc L IOP */
|
#define ACB_ADAPTER_TYPE_C 0x00000002 /* hbc L IOP */
|
||||||
#define ACB_ADAPTER_TYPE_D 0x00000003 /* hbd M IOP */
|
#define ACB_ADAPTER_TYPE_D 0x00000003 /* hbd M IOP */
|
||||||
#define ACB_ADAPTER_TYPE_E 0x00000004 /* hba L IOP */
|
#define ACB_ADAPTER_TYPE_E 0x00000004 /* hba L IOP */
|
||||||
|
#define ACB_ADAPTER_TYPE_F 0x00000005 /* hba L IOP */
|
||||||
u32 ioqueue_size;
|
u32 ioqueue_size;
|
||||||
struct pci_dev * pdev;
|
struct pci_dev * pdev;
|
||||||
struct Scsi_Host * host;
|
struct Scsi_Host * host;
|
||||||
@ -760,10 +851,16 @@ struct AdapterControlBlock
|
|||||||
struct MessageUnit_C __iomem *pmuC;
|
struct MessageUnit_C __iomem *pmuC;
|
||||||
struct MessageUnit_D *pmuD;
|
struct MessageUnit_D *pmuD;
|
||||||
struct MessageUnit_E __iomem *pmuE;
|
struct MessageUnit_E __iomem *pmuE;
|
||||||
|
struct MessageUnit_F __iomem *pmuF;
|
||||||
};
|
};
|
||||||
/* message unit ATU inbound base address0 */
|
/* message unit ATU inbound base address0 */
|
||||||
void __iomem *mem_base0;
|
void __iomem *mem_base0;
|
||||||
void __iomem *mem_base1;
|
void __iomem *mem_base1;
|
||||||
|
//0x000 - COMPORT_IN (Host sent to ROC)
|
||||||
|
uint32_t *message_wbuffer;
|
||||||
|
//0x100 - COMPORT_OUT (ROC sent to Host)
|
||||||
|
uint32_t *message_rbuffer;
|
||||||
|
uint32_t *msgcode_rwbuffer; //0x200 - BIOS_AREA
|
||||||
uint32_t acb_flags;
|
uint32_t acb_flags;
|
||||||
u16 dev_id;
|
u16 dev_id;
|
||||||
uint8_t adapter_index;
|
uint8_t adapter_index;
|
||||||
@ -846,6 +943,7 @@ struct AdapterControlBlock
|
|||||||
uint32_t out_doorbell;
|
uint32_t out_doorbell;
|
||||||
uint32_t completionQ_entry;
|
uint32_t completionQ_entry;
|
||||||
pCompletion_Q pCompletionQ;
|
pCompletion_Q pCompletionQ;
|
||||||
|
uint32_t completeQ_size;
|
||||||
};/* HW_DEVICE_EXTENSION */
|
};/* HW_DEVICE_EXTENSION */
|
||||||
/*
|
/*
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
|
|||||||
@ -133,6 +133,7 @@ static void arcmsr_hbaC_message_isr(struct AdapterControlBlock *pACB);
|
|||||||
static void arcmsr_hbaD_message_isr(struct AdapterControlBlock *acb);
|
static void arcmsr_hbaD_message_isr(struct AdapterControlBlock *acb);
|
||||||
static void arcmsr_hbaE_message_isr(struct AdapterControlBlock *acb);
|
static void arcmsr_hbaE_message_isr(struct AdapterControlBlock *acb);
|
||||||
static void arcmsr_hbaE_postqueue_isr(struct AdapterControlBlock *acb);
|
static void arcmsr_hbaE_postqueue_isr(struct AdapterControlBlock *acb);
|
||||||
|
static void arcmsr_hbaF_postqueue_isr(struct AdapterControlBlock *acb);
|
||||||
static void arcmsr_hardware_reset(struct AdapterControlBlock *acb);
|
static void arcmsr_hardware_reset(struct AdapterControlBlock *acb);
|
||||||
static const char *arcmsr_info(struct Scsi_Host *);
|
static const char *arcmsr_info(struct Scsi_Host *);
|
||||||
static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
|
static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
|
||||||
@ -209,6 +210,8 @@ static struct pci_device_id arcmsr_device_id_table[] = {
|
|||||||
.driver_data = ACB_ADAPTER_TYPE_C},
|
.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),
|
||||||
|
.driver_data = ACB_ADAPTER_TYPE_F},
|
||||||
{0, 0}, /* Terminating entry */
|
{0, 0}, /* Terminating entry */
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(pci, arcmsr_device_id_table);
|
MODULE_DEVICE_TABLE(pci, arcmsr_device_id_table);
|
||||||
@ -232,12 +235,12 @@ static void arcmsr_free_io_queue(struct AdapterControlBlock *acb)
|
|||||||
switch (acb->adapter_type) {
|
switch (acb->adapter_type) {
|
||||||
case ACB_ADAPTER_TYPE_B:
|
case ACB_ADAPTER_TYPE_B:
|
||||||
case ACB_ADAPTER_TYPE_D:
|
case ACB_ADAPTER_TYPE_D:
|
||||||
case ACB_ADAPTER_TYPE_E: {
|
case ACB_ADAPTER_TYPE_E:
|
||||||
|
case ACB_ADAPTER_TYPE_F:
|
||||||
dma_free_coherent(&acb->pdev->dev, acb->ioqueue_size,
|
dma_free_coherent(&acb->pdev->dev, acb->ioqueue_size,
|
||||||
acb->dma_coherent2, acb->dma_coherent_handle2);
|
acb->dma_coherent2, acb->dma_coherent_handle2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool arcmsr_remap_pciregion(struct AdapterControlBlock *acb)
|
static bool arcmsr_remap_pciregion(struct AdapterControlBlock *acb)
|
||||||
@ -310,6 +313,19 @@ static bool arcmsr_remap_pciregion(struct AdapterControlBlock *acb)
|
|||||||
acb->out_doorbell = 0;
|
acb->out_doorbell = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ACB_ADAPTER_TYPE_F: {
|
||||||
|
acb->pmuF = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
|
||||||
|
if (!acb->pmuF) {
|
||||||
|
pr_notice("arcmsr%d: memory mapping region fail\n",
|
||||||
|
acb->host->host_no);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
writel(0, &acb->pmuF->host_int_status); /* clear interrupt */
|
||||||
|
writel(ARCMSR_HBFMU_DOORBELL_SYNC, &acb->pmuF->iobound_doorbell);
|
||||||
|
acb->in_doorbell = 0;
|
||||||
|
acb->out_doorbell = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -333,6 +349,9 @@ static void arcmsr_unmap_pciregion(struct AdapterControlBlock *acb)
|
|||||||
case ACB_ADAPTER_TYPE_E:
|
case ACB_ADAPTER_TYPE_E:
|
||||||
iounmap(acb->pmuE);
|
iounmap(acb->pmuE);
|
||||||
break;
|
break;
|
||||||
|
case ACB_ADAPTER_TYPE_F:
|
||||||
|
iounmap(acb->pmuF);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -561,6 +580,7 @@ static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb)
|
|||||||
arcmsr_hbaD_flush_cache(acb);
|
arcmsr_hbaD_flush_cache(acb);
|
||||||
break;
|
break;
|
||||||
case ACB_ADAPTER_TYPE_E:
|
case ACB_ADAPTER_TYPE_E:
|
||||||
|
case ACB_ADAPTER_TYPE_F:
|
||||||
arcmsr_hbaE_flush_cache(acb);
|
arcmsr_hbaE_flush_cache(acb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -618,6 +638,27 @@ static void arcmsr_hbaD_assign_regAddr(struct AdapterControlBlock *acb)
|
|||||||
reg->msgcode_rwbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RWBUFFER);
|
reg->msgcode_rwbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RWBUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void arcmsr_hbaF_assign_regAddr(struct AdapterControlBlock *acb)
|
||||||
|
{
|
||||||
|
dma_addr_t host_buffer_dma;
|
||||||
|
struct MessageUnit_F __iomem *pmuF;
|
||||||
|
|
||||||
|
memset(acb->dma_coherent2, 0xff, acb->completeQ_size);
|
||||||
|
acb->message_wbuffer = (uint32_t *)round_up((unsigned long)acb->dma_coherent2 +
|
||||||
|
acb->completeQ_size, 4);
|
||||||
|
acb->message_rbuffer = ((void *)acb->message_wbuffer) + 0x100;
|
||||||
|
acb->msgcode_rwbuffer = ((void *)acb->message_wbuffer) + 0x200;
|
||||||
|
memset((void *)acb->message_wbuffer, 0, MESG_RW_BUFFER_SIZE);
|
||||||
|
host_buffer_dma = round_up(acb->dma_coherent_handle2 + acb->completeQ_size, 4);
|
||||||
|
pmuF = acb->pmuF;
|
||||||
|
/* host buffer low address, bit0:1 all buffer active */
|
||||||
|
writel(lower_32_bits(host_buffer_dma | 1), &pmuF->inbound_msgaddr0);
|
||||||
|
/* host buffer high address */
|
||||||
|
writel(upper_32_bits(host_buffer_dma), &pmuF->inbound_msgaddr1);
|
||||||
|
/* set host buffer physical address */
|
||||||
|
writel(ARCMSR_HBFMU_DOORBELL_SYNC1, &pmuF->iobound_doorbell);
|
||||||
|
}
|
||||||
|
|
||||||
static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb)
|
static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb)
|
||||||
{
|
{
|
||||||
bool rtn = true;
|
bool rtn = true;
|
||||||
@ -671,6 +712,28 @@ static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb)
|
|||||||
acb->doneq_index = 0;
|
acb->doneq_index = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ACB_ADAPTER_TYPE_F: {
|
||||||
|
uint32_t QueueDepth;
|
||||||
|
uint32_t depthTbl[] = {256, 512, 1024, 128, 64, 32};
|
||||||
|
|
||||||
|
arcmsr_wait_firmware_ready(acb);
|
||||||
|
QueueDepth = depthTbl[readl(&acb->pmuF->outbound_msgaddr1) & 7];
|
||||||
|
acb->completeQ_size = sizeof(struct deliver_completeQ) * QueueDepth + 128;
|
||||||
|
acb->ioqueue_size = roundup(acb->completeQ_size + MESG_RW_BUFFER_SIZE, 32);
|
||||||
|
dma_coherent = dma_alloc_coherent(&pdev->dev, acb->ioqueue_size,
|
||||||
|
&dma_coherent_handle, GFP_KERNEL);
|
||||||
|
if (!dma_coherent) {
|
||||||
|
pr_notice("arcmsr%d: DMA allocation failed\n", acb->host->host_no);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
acb->dma_coherent_handle2 = dma_coherent_handle;
|
||||||
|
acb->dma_coherent2 = dma_coherent;
|
||||||
|
acb->pCompletionQ = dma_coherent;
|
||||||
|
acb->completionQ_entry = acb->completeQ_size / sizeof(struct deliver_completeQ);
|
||||||
|
acb->doneq_index = 0;
|
||||||
|
arcmsr_hbaF_assign_regAddr(acb);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -705,6 +768,7 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
|
|||||||
acb->host->sg_tablesize = max_sg_entrys;
|
acb->host->sg_tablesize = max_sg_entrys;
|
||||||
roundup_ccbsize = roundup(sizeof(struct CommandControlBlock) + (max_sg_entrys - 1) * sizeof(struct SG64ENTRY), 32);
|
roundup_ccbsize = roundup(sizeof(struct CommandControlBlock) + (max_sg_entrys - 1) * sizeof(struct SG64ENTRY), 32);
|
||||||
acb->uncache_size = roundup_ccbsize * acb->maxFreeCCB;
|
acb->uncache_size = roundup_ccbsize * acb->maxFreeCCB;
|
||||||
|
if (acb->adapter_type != ACB_ADAPTER_TYPE_F)
|
||||||
acb->uncache_size += acb->ioqueue_size;
|
acb->uncache_size += acb->ioqueue_size;
|
||||||
dma_coherent = dma_alloc_coherent(&pdev->dev, acb->uncache_size, &dma_coherent_handle, GFP_KERNEL);
|
dma_coherent = dma_alloc_coherent(&pdev->dev, acb->uncache_size, &dma_coherent_handle, GFP_KERNEL);
|
||||||
if(!dma_coherent){
|
if(!dma_coherent){
|
||||||
@ -728,6 +792,7 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
|
|||||||
case ACB_ADAPTER_TYPE_C:
|
case ACB_ADAPTER_TYPE_C:
|
||||||
case ACB_ADAPTER_TYPE_D:
|
case ACB_ADAPTER_TYPE_D:
|
||||||
case ACB_ADAPTER_TYPE_E:
|
case ACB_ADAPTER_TYPE_E:
|
||||||
|
case ACB_ADAPTER_TYPE_F:
|
||||||
ccb_tmp->cdb_phyaddr = cdb_phyaddr;
|
ccb_tmp->cdb_phyaddr = cdb_phyaddr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -746,8 +811,10 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
|
|||||||
ccb_tmp = (struct CommandControlBlock *)((unsigned long)ccb_tmp + roundup_ccbsize);
|
ccb_tmp = (struct CommandControlBlock *)((unsigned long)ccb_tmp + roundup_ccbsize);
|
||||||
dma_coherent_handle = next_ccb_phy;
|
dma_coherent_handle = next_ccb_phy;
|
||||||
}
|
}
|
||||||
|
if (acb->adapter_type != ACB_ADAPTER_TYPE_F) {
|
||||||
acb->dma_coherent_handle2 = dma_coherent_handle;
|
acb->dma_coherent_handle2 = dma_coherent_handle;
|
||||||
acb->dma_coherent2 = ccb_tmp;
|
acb->dma_coherent2 = ccb_tmp;
|
||||||
|
}
|
||||||
switch (acb->adapter_type) {
|
switch (acb->adapter_type) {
|
||||||
case ACB_ADAPTER_TYPE_B:
|
case ACB_ADAPTER_TYPE_B:
|
||||||
acb->pmuB = (struct MessageUnit_B *)acb->dma_coherent2;
|
acb->pmuB = (struct MessageUnit_B *)acb->dma_coherent2;
|
||||||
@ -813,6 +880,11 @@ static void arcmsr_message_isr_bh_fn(struct work_struct *work)
|
|||||||
devicemap = (char __iomem *)(®->msgcode_rwbuffer[21]);
|
devicemap = (char __iomem *)(®->msgcode_rwbuffer[21]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ACB_ADAPTER_TYPE_F: {
|
||||||
|
signature = (uint32_t __iomem *)(&acb->msgcode_rwbuffer[0]);
|
||||||
|
devicemap = (char __iomem *)(&acb->msgcode_rwbuffer[21]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (readl(signature) != ARCMSR_SIGNATURE_GET_CONFIG)
|
if (readl(signature) != ARCMSR_SIGNATURE_GET_CONFIG)
|
||||||
return;
|
return;
|
||||||
@ -998,6 +1070,7 @@ static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||||||
if(!error){
|
if(!error){
|
||||||
goto free_hbb_mu;
|
goto free_hbb_mu;
|
||||||
}
|
}
|
||||||
|
if (acb->adapter_type != ACB_ADAPTER_TYPE_F)
|
||||||
arcmsr_free_io_queue(acb);
|
arcmsr_free_io_queue(acb);
|
||||||
error = arcmsr_alloc_ccb_pool(acb);
|
error = arcmsr_alloc_ccb_pool(acb);
|
||||||
if(error){
|
if(error){
|
||||||
@ -1111,6 +1184,14 @@ static int arcmsr_resume(struct pci_dev *pdev)
|
|||||||
acb->out_doorbell = 0;
|
acb->out_doorbell = 0;
|
||||||
acb->doneq_index = 0;
|
acb->doneq_index = 0;
|
||||||
break;
|
break;
|
||||||
|
case ACB_ADAPTER_TYPE_F:
|
||||||
|
writel(0, &acb->pmuF->host_int_status);
|
||||||
|
writel(ARCMSR_HBFMU_DOORBELL_SYNC, &acb->pmuF->iobound_doorbell);
|
||||||
|
acb->in_doorbell = 0;
|
||||||
|
acb->out_doorbell = 0;
|
||||||
|
acb->doneq_index = 0;
|
||||||
|
arcmsr_hbaF_assign_regAddr(acb);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
arcmsr_iop_init(acb);
|
arcmsr_iop_init(acb);
|
||||||
arcmsr_init_get_devmap_timer(acb);
|
arcmsr_init_get_devmap_timer(acb);
|
||||||
@ -1123,6 +1204,8 @@ controller_stop:
|
|||||||
controller_unregister:
|
controller_unregister:
|
||||||
scsi_remove_host(host);
|
scsi_remove_host(host);
|
||||||
arcmsr_free_ccb_pool(acb);
|
arcmsr_free_ccb_pool(acb);
|
||||||
|
if (acb->adapter_type == ACB_ADAPTER_TYPE_F)
|
||||||
|
arcmsr_free_io_queue(acb);
|
||||||
arcmsr_unmap_pciregion(acb);
|
arcmsr_unmap_pciregion(acb);
|
||||||
pci_release_regions(pdev);
|
pci_release_regions(pdev);
|
||||||
scsi_host_put(host);
|
scsi_host_put(host);
|
||||||
@ -1215,6 +1298,7 @@ static uint8_t arcmsr_abort_allcmd(struct AdapterControlBlock *acb)
|
|||||||
rtnval = arcmsr_hbaD_abort_allcmd(acb);
|
rtnval = arcmsr_hbaD_abort_allcmd(acb);
|
||||||
break;
|
break;
|
||||||
case ACB_ADAPTER_TYPE_E:
|
case ACB_ADAPTER_TYPE_E:
|
||||||
|
case ACB_ADAPTER_TYPE_F:
|
||||||
rtnval = arcmsr_hbaE_abort_allcmd(acb);
|
rtnval = arcmsr_hbaE_abort_allcmd(acb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1290,7 +1374,8 @@ static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb)
|
|||||||
writel(ARCMSR_ARC1214_ALL_INT_DISABLE, reg->pcief0_int_enable);
|
writel(ARCMSR_ARC1214_ALL_INT_DISABLE, reg->pcief0_int_enable);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACB_ADAPTER_TYPE_E: {
|
case ACB_ADAPTER_TYPE_E:
|
||||||
|
case ACB_ADAPTER_TYPE_F: {
|
||||||
struct MessageUnit_E __iomem *reg = acb->pmuE;
|
struct MessageUnit_E __iomem *reg = acb->pmuE;
|
||||||
orig_mask = readl(®->host_int_mask);
|
orig_mask = readl(®->host_int_mask);
|
||||||
writel(orig_mask | ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR | ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR, ®->host_int_mask);
|
writel(orig_mask | ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR | ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR, ®->host_int_mask);
|
||||||
@ -1497,6 +1582,9 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
|
|||||||
case ACB_ADAPTER_TYPE_E:
|
case ACB_ADAPTER_TYPE_E:
|
||||||
arcmsr_hbaE_postqueue_isr(acb);
|
arcmsr_hbaE_postqueue_isr(acb);
|
||||||
break;
|
break;
|
||||||
|
case ACB_ADAPTER_TYPE_F:
|
||||||
|
arcmsr_hbaF_postqueue_isr(acb);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1551,6 +1639,8 @@ static void arcmsr_free_pcidev(struct AdapterControlBlock *acb)
|
|||||||
pdev = acb->pdev;
|
pdev = acb->pdev;
|
||||||
arcmsr_free_irq(pdev, acb);
|
arcmsr_free_irq(pdev, acb);
|
||||||
arcmsr_free_ccb_pool(acb);
|
arcmsr_free_ccb_pool(acb);
|
||||||
|
if (acb->adapter_type == ACB_ADAPTER_TYPE_F)
|
||||||
|
arcmsr_free_io_queue(acb);
|
||||||
arcmsr_unmap_pciregion(acb);
|
arcmsr_unmap_pciregion(acb);
|
||||||
pci_release_regions(pdev);
|
pci_release_regions(pdev);
|
||||||
scsi_host_put(host);
|
scsi_host_put(host);
|
||||||
@ -1608,6 +1698,8 @@ static void arcmsr_remove(struct pci_dev *pdev)
|
|||||||
}
|
}
|
||||||
arcmsr_free_irq(pdev, acb);
|
arcmsr_free_irq(pdev, acb);
|
||||||
arcmsr_free_ccb_pool(acb);
|
arcmsr_free_ccb_pool(acb);
|
||||||
|
if (acb->adapter_type == ACB_ADAPTER_TYPE_F)
|
||||||
|
arcmsr_free_io_queue(acb);
|
||||||
arcmsr_unmap_pciregion(acb);
|
arcmsr_unmap_pciregion(acb);
|
||||||
pci_release_regions(pdev);
|
pci_release_regions(pdev);
|
||||||
scsi_host_put(host);
|
scsi_host_put(host);
|
||||||
@ -1685,7 +1777,8 @@ static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb,
|
|||||||
writel(intmask_org | mask, reg->pcief0_int_enable);
|
writel(intmask_org | mask, reg->pcief0_int_enable);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACB_ADAPTER_TYPE_E: {
|
case ACB_ADAPTER_TYPE_E:
|
||||||
|
case ACB_ADAPTER_TYPE_F: {
|
||||||
struct MessageUnit_E __iomem *reg = acb->pmuE;
|
struct MessageUnit_E __iomem *reg = acb->pmuE;
|
||||||
|
|
||||||
mask = ~(ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR | ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR);
|
mask = ~(ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR | ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR);
|
||||||
@ -1829,6 +1922,19 @@ static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandContr
|
|||||||
writel(ccb_post_stamp, &pmu->inbound_queueport_low);
|
writel(ccb_post_stamp, &pmu->inbound_queueport_low);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ACB_ADAPTER_TYPE_F: {
|
||||||
|
struct MessageUnit_F __iomem *pmu = acb->pmuF;
|
||||||
|
u32 ccb_post_stamp, arc_cdb_size;
|
||||||
|
|
||||||
|
if (ccb->arc_cdb_size <= 0x300)
|
||||||
|
arc_cdb_size = (ccb->arc_cdb_size - 1) >> 6 | 1;
|
||||||
|
else
|
||||||
|
arc_cdb_size = (((ccb->arc_cdb_size + 0xff) >> 8) + 2) << 1 | 1;
|
||||||
|
ccb_post_stamp = (ccb->smid | arc_cdb_size);
|
||||||
|
writel(0, &pmu->inbound_queueport_high);
|
||||||
|
writel(ccb_post_stamp, &pmu->inbound_queueport_low);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1912,6 +2018,7 @@ static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb)
|
|||||||
arcmsr_hbaD_stop_bgrb(acb);
|
arcmsr_hbaD_stop_bgrb(acb);
|
||||||
break;
|
break;
|
||||||
case ACB_ADAPTER_TYPE_E:
|
case ACB_ADAPTER_TYPE_E:
|
||||||
|
case ACB_ADAPTER_TYPE_F:
|
||||||
arcmsr_hbaE_stop_bgrb(acb);
|
arcmsr_hbaE_stop_bgrb(acb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1947,7 +2054,8 @@ static void arcmsr_iop_message_read(struct AdapterControlBlock *acb)
|
|||||||
reg->inbound_doorbell);
|
reg->inbound_doorbell);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACB_ADAPTER_TYPE_E: {
|
case ACB_ADAPTER_TYPE_E:
|
||||||
|
case ACB_ADAPTER_TYPE_F: {
|
||||||
struct MessageUnit_E __iomem *reg = acb->pmuE;
|
struct MessageUnit_E __iomem *reg = acb->pmuE;
|
||||||
acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_DATA_READ_OK;
|
acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_DATA_READ_OK;
|
||||||
writel(acb->out_doorbell, ®->iobound_doorbell);
|
writel(acb->out_doorbell, ®->iobound_doorbell);
|
||||||
@ -1993,7 +2101,8 @@ static void arcmsr_iop_message_wrote(struct AdapterControlBlock *acb)
|
|||||||
reg->inbound_doorbell);
|
reg->inbound_doorbell);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACB_ADAPTER_TYPE_E: {
|
case ACB_ADAPTER_TYPE_E:
|
||||||
|
case ACB_ADAPTER_TYPE_F: {
|
||||||
struct MessageUnit_E __iomem *reg = acb->pmuE;
|
struct MessageUnit_E __iomem *reg = acb->pmuE;
|
||||||
acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_DATA_WRITE_OK;
|
acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_DATA_WRITE_OK;
|
||||||
writel(acb->out_doorbell, ®->iobound_doorbell);
|
writel(acb->out_doorbell, ®->iobound_doorbell);
|
||||||
@ -2032,6 +2141,10 @@ struct QBUFFER __iomem *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *acb)
|
|||||||
qbuffer = (struct QBUFFER __iomem *)®->message_rbuffer;
|
qbuffer = (struct QBUFFER __iomem *)®->message_rbuffer;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ACB_ADAPTER_TYPE_F: {
|
||||||
|
qbuffer = (struct QBUFFER __iomem *)acb->message_rbuffer;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return qbuffer;
|
return qbuffer;
|
||||||
}
|
}
|
||||||
@ -2066,6 +2179,9 @@ static struct QBUFFER __iomem *arcmsr_get_iop_wqbuffer(struct AdapterControlBloc
|
|||||||
pqbuffer = (struct QBUFFER __iomem *)®->message_wbuffer;
|
pqbuffer = (struct QBUFFER __iomem *)®->message_wbuffer;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ACB_ADAPTER_TYPE_F:
|
||||||
|
pqbuffer = (struct QBUFFER __iomem *)acb->message_wbuffer;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return pqbuffer;
|
return pqbuffer;
|
||||||
}
|
}
|
||||||
@ -2480,6 +2596,36 @@ static void arcmsr_hbaE_postqueue_isr(struct AdapterControlBlock *acb)
|
|||||||
spin_unlock_irqrestore(&acb->doneq_lock, flags);
|
spin_unlock_irqrestore(&acb->doneq_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void arcmsr_hbaF_postqueue_isr(struct AdapterControlBlock *acb)
|
||||||
|
{
|
||||||
|
uint32_t doneq_index;
|
||||||
|
uint16_t cmdSMID;
|
||||||
|
int error;
|
||||||
|
struct MessageUnit_F __iomem *phbcmu;
|
||||||
|
struct CommandControlBlock *ccb;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&acb->doneq_lock, flags);
|
||||||
|
doneq_index = acb->doneq_index;
|
||||||
|
phbcmu = acb->pmuF;
|
||||||
|
while (1) {
|
||||||
|
cmdSMID = acb->pCompletionQ[doneq_index].cmdSMID;
|
||||||
|
if (cmdSMID == 0xffff)
|
||||||
|
break;
|
||||||
|
ccb = acb->pccb_pool[cmdSMID];
|
||||||
|
error = (acb->pCompletionQ[doneq_index].cmdFlag &
|
||||||
|
ARCMSR_CCBREPLY_FLAG_ERROR_MODE1) ? true : false;
|
||||||
|
arcmsr_drain_donequeue(acb, ccb, error);
|
||||||
|
acb->pCompletionQ[doneq_index].cmdSMID = 0xffff;
|
||||||
|
doneq_index++;
|
||||||
|
if (doneq_index >= acb->completionQ_entry)
|
||||||
|
doneq_index = 0;
|
||||||
|
}
|
||||||
|
acb->doneq_index = doneq_index;
|
||||||
|
writel(doneq_index, &phbcmu->reply_post_consumer_index);
|
||||||
|
spin_unlock_irqrestore(&acb->doneq_lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
**********************************************************************************
|
**********************************************************************************
|
||||||
** Handle a message interrupt
|
** Handle a message interrupt
|
||||||
@ -2670,6 +2816,31 @@ static irqreturn_t arcmsr_hbaE_handle_isr(struct AdapterControlBlock *pACB)
|
|||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static irqreturn_t arcmsr_hbaF_handle_isr(struct AdapterControlBlock *pACB)
|
||||||
|
{
|
||||||
|
uint32_t host_interrupt_status;
|
||||||
|
struct MessageUnit_F __iomem *phbcmu = pACB->pmuF;
|
||||||
|
|
||||||
|
host_interrupt_status = readl(&phbcmu->host_int_status) &
|
||||||
|
(ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR |
|
||||||
|
ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR);
|
||||||
|
if (!host_interrupt_status)
|
||||||
|
return IRQ_NONE;
|
||||||
|
do {
|
||||||
|
/* MU post queue interrupts*/
|
||||||
|
if (host_interrupt_status & ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR)
|
||||||
|
arcmsr_hbaF_postqueue_isr(pACB);
|
||||||
|
|
||||||
|
/* MU ioctl transfer doorbell interrupts*/
|
||||||
|
if (host_interrupt_status & ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR)
|
||||||
|
arcmsr_hbaE_doorbell_isr(pACB);
|
||||||
|
|
||||||
|
host_interrupt_status = readl(&phbcmu->host_int_status);
|
||||||
|
} while (host_interrupt_status & (ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR |
|
||||||
|
ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR));
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb)
|
static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb)
|
||||||
{
|
{
|
||||||
switch (acb->adapter_type) {
|
switch (acb->adapter_type) {
|
||||||
@ -2683,6 +2854,8 @@ static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb)
|
|||||||
return arcmsr_hbaD_handle_isr(acb);
|
return arcmsr_hbaD_handle_isr(acb);
|
||||||
case ACB_ADAPTER_TYPE_E:
|
case ACB_ADAPTER_TYPE_E:
|
||||||
return arcmsr_hbaE_handle_isr(acb);
|
return arcmsr_hbaE_handle_isr(acb);
|
||||||
|
case ACB_ADAPTER_TYPE_F:
|
||||||
|
return arcmsr_hbaF_handle_isr(acb);
|
||||||
default:
|
default:
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
}
|
}
|
||||||
@ -3231,6 +3404,31 @@ static bool arcmsr_hbaE_get_config(struct AdapterControlBlock *pACB)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool arcmsr_hbaF_get_config(struct AdapterControlBlock *pACB)
|
||||||
|
{
|
||||||
|
struct MessageUnit_F __iomem *reg = pACB->pmuF;
|
||||||
|
uint32_t intmask_org;
|
||||||
|
|
||||||
|
/* disable all outbound interrupt */
|
||||||
|
intmask_org = readl(®->host_int_mask); /* disable outbound message0 int */
|
||||||
|
writel(intmask_org | ARCMSR_HBEMU_ALL_INTMASKENABLE, ®->host_int_mask);
|
||||||
|
/* wait firmware ready */
|
||||||
|
arcmsr_wait_firmware_ready(pACB);
|
||||||
|
/* post "get config" instruction */
|
||||||
|
writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0);
|
||||||
|
|
||||||
|
pACB->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
|
||||||
|
writel(pACB->out_doorbell, ®->iobound_doorbell);
|
||||||
|
/* wait message ready */
|
||||||
|
if (!arcmsr_hbaE_wait_msgint_ready(pACB)) {
|
||||||
|
pr_notice("arcmsr%d: wait get adapter firmware miscellaneous data timeout\n",
|
||||||
|
pACB->host->host_no);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
arcmsr_get_adapter_config(pACB, pACB->msgcode_rwbuffer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool arcmsr_get_firmware_spec(struct AdapterControlBlock *acb)
|
static bool arcmsr_get_firmware_spec(struct AdapterControlBlock *acb)
|
||||||
{
|
{
|
||||||
bool rtn = false;
|
bool rtn = false;
|
||||||
@ -3251,6 +3449,9 @@ static bool arcmsr_get_firmware_spec(struct AdapterControlBlock *acb)
|
|||||||
case ACB_ADAPTER_TYPE_E:
|
case ACB_ADAPTER_TYPE_E:
|
||||||
rtn = arcmsr_hbaE_get_config(acb);
|
rtn = arcmsr_hbaE_get_config(acb);
|
||||||
break;
|
break;
|
||||||
|
case ACB_ADAPTER_TYPE_F:
|
||||||
|
rtn = arcmsr_hbaF_get_config(acb);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3621,6 +3822,7 @@ static int arcmsr_polling_ccbdone(struct AdapterControlBlock *acb,
|
|||||||
rtn = arcmsr_hbaD_polling_ccbdone(acb, poll_ccb);
|
rtn = arcmsr_hbaD_polling_ccbdone(acb, poll_ccb);
|
||||||
break;
|
break;
|
||||||
case ACB_ADAPTER_TYPE_E:
|
case ACB_ADAPTER_TYPE_E:
|
||||||
|
case ACB_ADAPTER_TYPE_F:
|
||||||
rtn = arcmsr_hbaE_polling_ccbdone(acb, poll_ccb);
|
rtn = arcmsr_hbaE_polling_ccbdone(acb, poll_ccb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3701,6 +3903,16 @@ static void arcmsr_set_iop_datetime(struct timer_list *t)
|
|||||||
writel(pacb->out_doorbell, ®->iobound_doorbell);
|
writel(pacb->out_doorbell, ®->iobound_doorbell);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ACB_ADAPTER_TYPE_F: {
|
||||||
|
struct MessageUnit_F __iomem *reg = pacb->pmuF;
|
||||||
|
|
||||||
|
pacb->msgcode_rwbuffer[0] = datetime.b.msg_time[0];
|
||||||
|
pacb->msgcode_rwbuffer[1] = datetime.b.msg_time[1];
|
||||||
|
writel(ARCMSR_INBOUND_MESG0_SYNC_TIMER, ®->inbound_msgaddr0);
|
||||||
|
pacb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
|
||||||
|
writel(pacb->out_doorbell, ®->iobound_doorbell);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (sys_tz.tz_minuteswest)
|
if (sys_tz.tz_minuteswest)
|
||||||
next_time = ARCMSR_HOURS;
|
next_time = ARCMSR_HOURS;
|
||||||
@ -3726,6 +3938,7 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)
|
|||||||
dma_coherent_handle = acb->dma_coherent_handle2;
|
dma_coherent_handle = acb->dma_coherent_handle2;
|
||||||
break;
|
break;
|
||||||
case ACB_ADAPTER_TYPE_E:
|
case ACB_ADAPTER_TYPE_E:
|
||||||
|
case ACB_ADAPTER_TYPE_F:
|
||||||
dma_coherent_handle = acb->dma_coherent_handle +
|
dma_coherent_handle = acb->dma_coherent_handle +
|
||||||
offsetof(struct CommandControlBlock, arcmsr_cdb);
|
offsetof(struct CommandControlBlock, arcmsr_cdb);
|
||||||
break;
|
break;
|
||||||
@ -3843,11 +4056,8 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)
|
|||||||
writel(cdb_phyaddr, ®->msgcode_rwbuffer[2]);
|
writel(cdb_phyaddr, ®->msgcode_rwbuffer[2]);
|
||||||
writel(cdb_phyaddr_hi32, ®->msgcode_rwbuffer[3]);
|
writel(cdb_phyaddr_hi32, ®->msgcode_rwbuffer[3]);
|
||||||
writel(acb->ccbsize, ®->msgcode_rwbuffer[4]);
|
writel(acb->ccbsize, ®->msgcode_rwbuffer[4]);
|
||||||
dma_coherent_handle = acb->dma_coherent_handle2;
|
writel(lower_32_bits(acb->dma_coherent_handle2), ®->msgcode_rwbuffer[5]);
|
||||||
cdb_phyaddr = (uint32_t)(dma_coherent_handle & 0xffffffff);
|
writel(upper_32_bits(acb->dma_coherent_handle2), ®->msgcode_rwbuffer[6]);
|
||||||
cdb_phyaddr_hi32 = (uint32_t)((dma_coherent_handle >> 16) >> 16);
|
|
||||||
writel(cdb_phyaddr, ®->msgcode_rwbuffer[5]);
|
|
||||||
writel(cdb_phyaddr_hi32, ®->msgcode_rwbuffer[6]);
|
|
||||||
writel(acb->ioqueue_size, ®->msgcode_rwbuffer[7]);
|
writel(acb->ioqueue_size, ®->msgcode_rwbuffer[7]);
|
||||||
writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, ®->inbound_msgaddr0);
|
writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, ®->inbound_msgaddr0);
|
||||||
acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
|
acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
|
||||||
@ -3859,6 +4069,27 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ACB_ADAPTER_TYPE_F: {
|
||||||
|
struct MessageUnit_F __iomem *reg = acb->pmuF;
|
||||||
|
|
||||||
|
acb->msgcode_rwbuffer[0] = ARCMSR_SIGNATURE_SET_CONFIG;
|
||||||
|
acb->msgcode_rwbuffer[1] = ARCMSR_SIGNATURE_1886;
|
||||||
|
acb->msgcode_rwbuffer[2] = cdb_phyaddr;
|
||||||
|
acb->msgcode_rwbuffer[3] = cdb_phyaddr_hi32;
|
||||||
|
acb->msgcode_rwbuffer[4] = acb->ccbsize;
|
||||||
|
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[7] = acb->completeQ_size;
|
||||||
|
writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, ®->inbound_msgaddr0);
|
||||||
|
acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
|
||||||
|
writel(acb->out_doorbell, ®->iobound_doorbell);
|
||||||
|
if (!arcmsr_hbaE_wait_msgint_ready(acb)) {
|
||||||
|
pr_notice("arcmsr%d: 'set command Q window' timeout\n",
|
||||||
|
acb->host->host_no);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -3907,7 +4138,8 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb)
|
|||||||
ARCMSR_ARC1214_MESSAGE_FIRMWARE_OK) == 0);
|
ARCMSR_ARC1214_MESSAGE_FIRMWARE_OK) == 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACB_ADAPTER_TYPE_E: {
|
case ACB_ADAPTER_TYPE_E:
|
||||||
|
case ACB_ADAPTER_TYPE_F: {
|
||||||
struct MessageUnit_E __iomem *reg = acb->pmuE;
|
struct MessageUnit_E __iomem *reg = acb->pmuE;
|
||||||
do {
|
do {
|
||||||
if (!(acb->acb_flags & ACB_F_IOP_INITED))
|
if (!(acb->acb_flags & ACB_F_IOP_INITED))
|
||||||
@ -3955,10 +4187,23 @@ static void arcmsr_request_device_map(struct timer_list *t)
|
|||||||
writel(acb->out_doorbell, ®->iobound_doorbell);
|
writel(acb->out_doorbell, ®->iobound_doorbell);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ACB_ADAPTER_TYPE_F: {
|
||||||
|
struct MessageUnit_F __iomem *reg = acb->pmuF;
|
||||||
|
uint32_t outMsg1 = readl(®->outbound_msgaddr1);
|
||||||
|
|
||||||
|
if (!(outMsg1 & ARCMSR_HBFMU_MESSAGE_FIRMWARE_OK) ||
|
||||||
|
(outMsg1 & ARCMSR_HBFMU_MESSAGE_NO_VOLUME_CHANGE))
|
||||||
|
goto nxt6s;
|
||||||
|
writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0);
|
||||||
|
acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
|
||||||
|
writel(acb->out_doorbell, ®->iobound_doorbell);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
acb->acb_flags |= ACB_F_MSG_GET_CONFIG;
|
acb->acb_flags |= ACB_F_MSG_GET_CONFIG;
|
||||||
|
nxt6s:
|
||||||
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
|
mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4040,6 +4285,7 @@ static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb)
|
|||||||
arcmsr_hbaD_start_bgrb(acb);
|
arcmsr_hbaD_start_bgrb(acb);
|
||||||
break;
|
break;
|
||||||
case ACB_ADAPTER_TYPE_E:
|
case ACB_ADAPTER_TYPE_E:
|
||||||
|
case ACB_ADAPTER_TYPE_F:
|
||||||
arcmsr_hbaE_start_bgrb(acb);
|
arcmsr_hbaE_start_bgrb(acb);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -4119,7 +4365,8 @@ static void arcmsr_clear_doorbell_queue_buffer(struct AdapterControlBlock *acb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACB_ADAPTER_TYPE_E: {
|
case ACB_ADAPTER_TYPE_E:
|
||||||
|
case ACB_ADAPTER_TYPE_F: {
|
||||||
struct MessageUnit_E __iomem *reg = acb->pmuE;
|
struct MessageUnit_E __iomem *reg = acb->pmuE;
|
||||||
uint32_t i, tmp;
|
uint32_t i, tmp;
|
||||||
|
|
||||||
@ -4246,7 +4493,8 @@ static bool arcmsr_reset_in_progress(struct AdapterControlBlock *acb)
|
|||||||
true : false;
|
true : false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACB_ADAPTER_TYPE_E:{
|
case ACB_ADAPTER_TYPE_E:
|
||||||
|
case ACB_ADAPTER_TYPE_F:{
|
||||||
struct MessageUnit_E __iomem *reg = acb->pmuE;
|
struct MessageUnit_E __iomem *reg = acb->pmuE;
|
||||||
rtn = (readl(®->host_diagnostic_3xxx) &
|
rtn = (readl(®->host_diagnostic_3xxx) &
|
||||||
ARCMSR_ARC188X_RESET_ADAPTER) ? true : false;
|
ARCMSR_ARC188X_RESET_ADAPTER) ? true : false;
|
||||||
@ -4445,6 +4693,9 @@ static const char *arcmsr_info(struct Scsi_Host *host)
|
|||||||
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:
|
||||||
|
type = "NVMe/SAS/SATA";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
type = "unknown";
|
type = "unknown";
|
||||||
raid6 = 0;
|
raid6 = 0;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user