drivers/scsi/arcmsr/arcmsr_hba.c

Source file repositories/reference/linux-study-clean/drivers/scsi/arcmsr/arcmsr_hba.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/arcmsr/arcmsr_hba.c
Extension
.c
Size
152547 bytes
Lines
4823
Domain
Driver Families
Bucket
drivers/scsi
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static struct pci_driver arcmsr_pci_driver = {
	.name			= "arcmsr",
	.id_table		= arcmsr_device_id_table,
	.probe			= arcmsr_probe,
	.remove			= arcmsr_remove,
	.driver.pm		= &arcmsr_pm_ops,
	.shutdown		= arcmsr_shutdown,
};
/*
****************************************************************************
****************************************************************************
*/

static void arcmsr_free_io_queue(struct AdapterControlBlock *acb)
{
	switch (acb->adapter_type) {
	case ACB_ADAPTER_TYPE_B:
	case ACB_ADAPTER_TYPE_D:
	case ACB_ADAPTER_TYPE_E:
	case ACB_ADAPTER_TYPE_F:
		dma_free_coherent(&acb->pdev->dev, acb->ioqueue_size,
			acb->dma_coherent2, acb->dma_coherent_handle2);
		break;
	}
}

static bool arcmsr_remap_pciregion(struct AdapterControlBlock *acb)
{
	struct pci_dev *pdev = acb->pdev;
	switch (acb->adapter_type){
	case ACB_ADAPTER_TYPE_A:{
		acb->pmuA = ioremap(pci_resource_start(pdev,0), pci_resource_len(pdev,0));
		if (!acb->pmuA) {
			printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n", acb->host->host_no);
			return false;
		}
		break;
	}
	case ACB_ADAPTER_TYPE_B:{
		void __iomem *mem_base0, *mem_base1;
		mem_base0 = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
		if (!mem_base0) {
			printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n", acb->host->host_no);
			return false;
		}
		mem_base1 = ioremap(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2));
		if (!mem_base1) {
			iounmap(mem_base0);
			printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n", acb->host->host_no);
			return false;
		}
		acb->mem_base0 = mem_base0;
		acb->mem_base1 = mem_base1;
		break;
	}
	case ACB_ADAPTER_TYPE_C:{
		acb->pmuC = ioremap(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1));
		if (!acb->pmuC) {
			printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n", acb->host->host_no);
			return false;
		}
		if (readl(&acb->pmuC->outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
			writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, &acb->pmuC->outbound_doorbell_clear);/*clear interrupt*/
			return true;
		}
		break;
	}
	case ACB_ADAPTER_TYPE_D: {
		void __iomem *mem_base0;
		unsigned long addr, range;

		addr = (unsigned long)pci_resource_start(pdev, 0);
		range = pci_resource_len(pdev, 0);
		mem_base0 = ioremap(addr, range);
		if (!mem_base0) {
			pr_notice("arcmsr%d: memory mapping region fail\n",
				acb->host->host_no);
			return false;
		}
		acb->mem_base0 = mem_base0;
		break;
		}
	case ACB_ADAPTER_TYPE_E: {
		acb->pmuE = ioremap(pci_resource_start(pdev, 1),
			pci_resource_len(pdev, 1));
		if (!acb->pmuE) {
			pr_notice("arcmsr%d: memory mapping region fail \n",
				acb->host->host_no);
			return false;
		}

Annotation

Implementation Notes