Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 02040670 authored by Ching Huang's avatar Ching Huang Committed by Martin K. Petersen
Browse files

arcmsr: Split dma resource allocation to a new function



Split dma resource allocation and io register assignment from get_config
to a new function arcmsr_alloc_io_queue.

Signed-off-by: default avatarChing Huang <ching2048@areca.com.tw>
Reviewed-by: default avatarTomas Henzl <thenzl@redhat.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent f75ab39a
Loading
Loading
Loading
Loading
+93 −82
Original line number Original line Diff line number Diff line
@@ -498,6 +498,91 @@ static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb)
	}
	}
}
}


static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb)
{
	bool rtn = true;
	void *dma_coherent;
	dma_addr_t dma_coherent_handle;
	struct pci_dev *pdev = acb->pdev;

	switch (acb->adapter_type) {
	case ACB_ADAPTER_TYPE_B: {
		struct MessageUnit_B *reg;
		acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_B), 32);
		dma_coherent = dma_zalloc_coherent(&pdev->dev, acb->roundup_ccbsize,
			&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;
		reg = (struct MessageUnit_B *)dma_coherent;
		acb->pmuB = reg;
		if (acb->pdev->device == PCI_DEVICE_ID_ARECA_1203) {
			reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_1203);
			reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK_1203);
			reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_1203);
			reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK_1203);
		} else {
			reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL);
			reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK);
			reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL);
			reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK);
		}
		reg->message_wbuffer = MEM_BASE1(ARCMSR_MESSAGE_WBUFFER);
		reg->message_rbuffer = MEM_BASE1(ARCMSR_MESSAGE_RBUFFER);
		reg->message_rwbuffer = MEM_BASE1(ARCMSR_MESSAGE_RWBUFFER);
		}
		break;
	case ACB_ADAPTER_TYPE_D: {
		struct MessageUnit_D *reg;

		acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_D), 32);
		dma_coherent = dma_zalloc_coherent(&pdev->dev, acb->roundup_ccbsize,
			&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;
		reg = (struct MessageUnit_D *)dma_coherent;
		acb->pmuD = reg;
		reg->chip_id = MEM_BASE0(ARCMSR_ARC1214_CHIP_ID);
		reg->cpu_mem_config = MEM_BASE0(ARCMSR_ARC1214_CPU_MEMORY_CONFIGURATION);
		reg->i2o_host_interrupt_mask = MEM_BASE0(ARCMSR_ARC1214_I2_HOST_INTERRUPT_MASK);
		reg->sample_at_reset = MEM_BASE0(ARCMSR_ARC1214_SAMPLE_RESET);
		reg->reset_request = MEM_BASE0(ARCMSR_ARC1214_RESET_REQUEST);
		reg->host_int_status = MEM_BASE0(ARCMSR_ARC1214_MAIN_INTERRUPT_STATUS);
		reg->pcief0_int_enable = MEM_BASE0(ARCMSR_ARC1214_PCIE_F0_INTERRUPT_ENABLE);
		reg->inbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE0);
		reg->inbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE1);
		reg->outbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE0);
		reg->outbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE1);
		reg->inbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_INBOUND_DOORBELL);
		reg->outbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL);
		reg->outbound_doorbell_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL_ENABLE);
		reg->inboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_LOW);
		reg->inboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_HIGH);
		reg->inboundlist_write_pointer = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_WRITE_POINTER);
		reg->outboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_LOW);
		reg->outboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_HIGH);
		reg->outboundlist_copy_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_COPY_POINTER);
		reg->outboundlist_read_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_READ_POINTER);
		reg->outboundlist_interrupt_cause = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_CAUSE);
		reg->outboundlist_interrupt_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_ENABLE);
		reg->message_wbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_WBUFFER);
		reg->message_rbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RBUFFER);
		reg->msgcode_rwbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RWBUFFER);
		}
		break;
	default:
		break;
	}
	return rtn;
}

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;
@@ -742,9 +827,12 @@ static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
	if(!error){
	if(!error){
		goto pci_release_regs;
		goto pci_release_regs;
	}
	}
	error = arcmsr_alloc_io_queue(acb);
	if (!error)
		goto unmap_pci_region;
	error = arcmsr_get_firmware_spec(acb);
	error = arcmsr_get_firmware_spec(acb);
	if(!error){
	if(!error){
		goto unmap_pci_region;
		goto free_hbb_mu;
	}
	}
	error = arcmsr_alloc_ccb_pool(acb);
	error = arcmsr_alloc_ccb_pool(acb);
	if(error){
	if(error){
@@ -2624,10 +2712,7 @@ static bool arcmsr_hbaA_get_config(struct AdapterControlBlock *acb)
}
}
static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb)
static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb)
{
{
	struct MessageUnit_B *reg;
	struct MessageUnit_B *reg = acb->pmuB;
	struct pci_dev *pdev = acb->pdev;
	void *dma_coherent;
	dma_addr_t dma_coherent_handle;
	char *acb_firm_model = acb->firm_model;
	char *acb_firm_model = acb->firm_model;
	char *acb_firm_version = acb->firm_version;
	char *acb_firm_version = acb->firm_version;
	char *acb_device_map = acb->device_map;
	char *acb_device_map = acb->device_map;
@@ -2639,33 +2724,6 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb)
	/*firm_version,21,84-99*/
	/*firm_version,21,84-99*/
	int count;
	int count;


	acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_B), 32);
	dma_coherent = dma_alloc_coherent(&pdev->dev, acb->roundup_ccbsize,
			&dma_coherent_handle, GFP_KERNEL);
	if (!dma_coherent){
		printk(KERN_NOTICE
			"arcmsr%d: dma_alloc_coherent got error for hbb mu\n",
			acb->host->host_no);
		return false;
	}
	acb->dma_coherent_handle2 = dma_coherent_handle;
	acb->dma_coherent2 = dma_coherent;
	reg = (struct MessageUnit_B *)dma_coherent;
	acb->pmuB = reg;
	if (acb->pdev->device == PCI_DEVICE_ID_ARECA_1203) {
		reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_1203);
		reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK_1203);
		reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_1203);
		reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK_1203);
	} else {
		reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL);
		reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK);
		reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL);
		reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK);
	}
	reg->message_wbuffer = MEM_BASE1(ARCMSR_MESSAGE_WBUFFER);
	reg->message_rbuffer =  MEM_BASE1(ARCMSR_MESSAGE_RBUFFER);
	reg->message_rwbuffer = MEM_BASE1(ARCMSR_MESSAGE_RWBUFFER);
	iop_firm_model = (char __iomem *)(&reg->message_rwbuffer[15]);	/*firm_model,15,60-67*/
	iop_firm_model = (char __iomem *)(&reg->message_rwbuffer[15]);	/*firm_model,15,60-67*/
	iop_firm_version = (char __iomem *)(&reg->message_rwbuffer[17]);	/*firm_version,17,68-83*/
	iop_firm_version = (char __iomem *)(&reg->message_rwbuffer[17]);	/*firm_version,17,68-83*/
	iop_device_map = (char __iomem *)(&reg->message_rwbuffer[21]);	/*firm_version,21,84-99*/
	iop_device_map = (char __iomem *)(&reg->message_rwbuffer[21]);	/*firm_version,21,84-99*/
@@ -2674,13 +2732,13 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb)
	writel(ARCMSR_MESSAGE_START_DRIVER_MODE, reg->drv2iop_doorbell);
	writel(ARCMSR_MESSAGE_START_DRIVER_MODE, reg->drv2iop_doorbell);
	if (!arcmsr_hbaB_wait_msgint_ready(acb)) {
	if (!arcmsr_hbaB_wait_msgint_ready(acb)) {
		printk(KERN_ERR "arcmsr%d: can't set driver mode.\n", acb->host->host_no);
		printk(KERN_ERR "arcmsr%d: can't set driver mode.\n", acb->host->host_no);
		goto err_free_dma;
		return false;
	}
	}
	writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell);
	writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell);
	if (!arcmsr_hbaB_wait_msgint_ready(acb)) {
	if (!arcmsr_hbaB_wait_msgint_ready(acb)) {
		printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \
		printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \
			miscellaneous data' timeout \n", acb->host->host_no);
			miscellaneous data' timeout \n", acb->host->host_no);
		goto err_free_dma;
		return false;
	}
	}
	count = 8;
	count = 8;
	while (count){
	while (count){
@@ -2723,10 +2781,6 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb)
	acb->firm_cfg_version = readl(&reg->message_rwbuffer[25]);  /*firm_cfg_version,25,100-103*/
	acb->firm_cfg_version = readl(&reg->message_rwbuffer[25]);  /*firm_cfg_version,25,100-103*/
	/*firm_ide_channels,4,16-19*/
	/*firm_ide_channels,4,16-19*/
	return true;
	return true;
err_free_dma:
	dma_free_coherent(&acb->pdev->dev, acb->roundup_ccbsize,
			acb->dma_coherent2, acb->dma_coherent_handle2);
	return false;
}
}


static bool arcmsr_hbaC_get_config(struct AdapterControlBlock *pACB)
static bool arcmsr_hbaC_get_config(struct AdapterControlBlock *pACB)
@@ -2797,49 +2851,8 @@ static bool arcmsr_hbaD_get_config(struct AdapterControlBlock *acb)
	char __iomem *iop_firm_version;
	char __iomem *iop_firm_version;
	char __iomem *iop_device_map;
	char __iomem *iop_device_map;
	u32 count;
	u32 count;
	struct MessageUnit_D *reg;
	struct MessageUnit_D *reg = acb->pmuD;
	void *dma_coherent2;
	dma_addr_t dma_coherent_handle2;
	struct pci_dev *pdev = acb->pdev;


	acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_D), 32);
	dma_coherent2 = dma_alloc_coherent(&pdev->dev, acb->roundup_ccbsize,
		&dma_coherent_handle2, GFP_KERNEL);
	if (!dma_coherent2) {
		pr_notice("DMA allocation failed...\n");
		return false;
	}
	memset(dma_coherent2, 0, acb->roundup_ccbsize);
	acb->dma_coherent_handle2 = dma_coherent_handle2;
	acb->dma_coherent2 = dma_coherent2;
	reg = (struct MessageUnit_D *)dma_coherent2;
	acb->pmuD = reg;
	reg->chip_id = MEM_BASE0(ARCMSR_ARC1214_CHIP_ID);
	reg->cpu_mem_config = MEM_BASE0(ARCMSR_ARC1214_CPU_MEMORY_CONFIGURATION);
	reg->i2o_host_interrupt_mask = MEM_BASE0(ARCMSR_ARC1214_I2_HOST_INTERRUPT_MASK);
	reg->sample_at_reset = MEM_BASE0(ARCMSR_ARC1214_SAMPLE_RESET);
	reg->reset_request = MEM_BASE0(ARCMSR_ARC1214_RESET_REQUEST);
	reg->host_int_status = MEM_BASE0(ARCMSR_ARC1214_MAIN_INTERRUPT_STATUS);
	reg->pcief0_int_enable = MEM_BASE0(ARCMSR_ARC1214_PCIE_F0_INTERRUPT_ENABLE);
	reg->inbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE0);
	reg->inbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE1);
	reg->outbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE0);
	reg->outbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE1);
	reg->inbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_INBOUND_DOORBELL);
	reg->outbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL);
	reg->outbound_doorbell_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL_ENABLE);
	reg->inboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_LOW);
	reg->inboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_HIGH);
	reg->inboundlist_write_pointer = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_WRITE_POINTER);
	reg->outboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_LOW);
	reg->outboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_HIGH);
	reg->outboundlist_copy_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_COPY_POINTER);
	reg->outboundlist_read_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_READ_POINTER);
	reg->outboundlist_interrupt_cause = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_CAUSE);
	reg->outboundlist_interrupt_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_ENABLE);
	reg->message_wbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_WBUFFER);
	reg->message_rbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RBUFFER);
	reg->msgcode_rwbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RWBUFFER);
	iop_firm_model = (char __iomem *)(&reg->msgcode_rwbuffer[15]);
	iop_firm_model = (char __iomem *)(&reg->msgcode_rwbuffer[15]);
	iop_firm_version = (char __iomem *)(&reg->msgcode_rwbuffer[17]);
	iop_firm_version = (char __iomem *)(&reg->msgcode_rwbuffer[17]);
	iop_device_map = (char __iomem *)(&reg->msgcode_rwbuffer[21]);
	iop_device_map = (char __iomem *)(&reg->msgcode_rwbuffer[21]);
@@ -2854,8 +2867,6 @@ static bool arcmsr_hbaD_get_config(struct AdapterControlBlock *acb)
	if (!arcmsr_hbaD_wait_msgint_ready(acb)) {
	if (!arcmsr_hbaD_wait_msgint_ready(acb)) {
		pr_notice("arcmsr%d: wait get adapter firmware "
		pr_notice("arcmsr%d: wait get adapter firmware "
			"miscellaneous data timeout\n", acb->host->host_no);
			"miscellaneous data timeout\n", acb->host->host_no);
		dma_free_coherent(&acb->pdev->dev, acb->roundup_ccbsize,
			acb->dma_coherent2, acb->dma_coherent_handle2);
		return false;
		return false;
	}
	}
	count = 8;
	count = 8;