static int carm_init_one()

in sx8.c [1399:1552]


static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
	struct carm_host *host;
	int rc;
	struct request_queue *q;
	unsigned int i;

	printk_once(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");

	rc = pci_enable_device(pdev);
	if (rc)
		return rc;

	rc = pci_request_regions(pdev, DRV_NAME);
	if (rc)
		goto err_out;

	rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
	if (rc) {
		printk(KERN_ERR DRV_NAME "(%s): DMA mask failure\n",
			pci_name(pdev));
		goto err_out_regions;
	}

	host = kzalloc(sizeof(*host), GFP_KERNEL);
	if (!host) {
		rc = -ENOMEM;
		goto err_out_regions;
	}

	host->pdev = pdev;
	spin_lock_init(&host->lock);
	INIT_WORK(&host->fsm_task, carm_fsm_task);
	init_completion(&host->probe_comp);

	host->mmio = ioremap(pci_resource_start(pdev, 0),
			     pci_resource_len(pdev, 0));
	if (!host->mmio) {
		printk(KERN_ERR DRV_NAME "(%s): MMIO alloc failure\n",
		       pci_name(pdev));
		rc = -ENOMEM;
		goto err_out_kfree;
	}

	rc = carm_init_shm(host);
	if (rc) {
		printk(KERN_ERR DRV_NAME "(%s): DMA SHM alloc failure\n",
		       pci_name(pdev));
		goto err_out_iounmap;
	}

	memset(&host->tag_set, 0, sizeof(host->tag_set));
	host->tag_set.ops = &carm_mq_ops;
	host->tag_set.cmd_size = sizeof(struct carm_request);
	host->tag_set.nr_hw_queues = 1;
	host->tag_set.nr_maps = 1;
	host->tag_set.queue_depth = max_queue;
	host->tag_set.numa_node = NUMA_NO_NODE;
	host->tag_set.flags = BLK_MQ_F_SHOULD_MERGE;

	rc = blk_mq_alloc_tag_set(&host->tag_set);
	if (rc)
		goto err_out_dma_free;

	q = blk_mq_init_queue(&host->tag_set);
	if (IS_ERR(q)) {
		rc = PTR_ERR(q);
		blk_mq_free_tag_set(&host->tag_set);
		goto err_out_dma_free;
	}

	host->oob_q = q;
	q->queuedata = host;

	/*
	 * Figure out which major to use: 160, 161, or dynamic
	 */
	if (!test_and_set_bit(0, &carm_major_alloc))
		host->major = 160;
	else if (!test_and_set_bit(1, &carm_major_alloc))
		host->major = 161;
	else
		host->flags |= FL_DYN_MAJOR;

	host->id = carm_host_id;
	sprintf(host->name, DRV_NAME "%d", carm_host_id);

	rc = register_blkdev(host->major, host->name);
	if (rc < 0)
		goto err_out_free_majors;
	if (host->flags & FL_DYN_MAJOR)
		host->major = rc;

	for (i = 0; i < CARM_MAX_PORTS; i++) {
		rc = carm_init_disk(host, i);
		if (rc)
			goto err_out_blkdev_disks;
	}

	pci_set_master(pdev);

	rc = request_irq(pdev->irq, carm_interrupt, IRQF_SHARED, DRV_NAME, host);
	if (rc) {
		printk(KERN_ERR DRV_NAME "(%s): irq alloc failure\n",
		       pci_name(pdev));
		goto err_out_blkdev_disks;
	}

	rc = carm_init_host(host);
	if (rc)
		goto err_out_free_irq;

	DPRINTK("waiting for probe_comp\n");
	host->probe_err = -ENODEV;
	wait_for_completion(&host->probe_comp);
	if (host->probe_err) {
		rc = host->probe_err;
		goto err_out_free_irq;
	}

	printk(KERN_INFO "%s: pci %s, ports %d, io %llx, irq %u, major %d\n",
	       host->name, pci_name(pdev), (int) CARM_MAX_PORTS,
	       (unsigned long long)pci_resource_start(pdev, 0),
		   pdev->irq, host->major);

	carm_host_id++;
	pci_set_drvdata(pdev, host);
	return 0;

err_out_free_irq:
	free_irq(pdev->irq, host);
err_out_blkdev_disks:
	for (i = 0; i < CARM_MAX_PORTS; i++)
		carm_free_disk(host, i);
	unregister_blkdev(host->major, host->name);
err_out_free_majors:
	if (host->major == 160)
		clear_bit(0, &carm_major_alloc);
	else if (host->major == 161)
		clear_bit(1, &carm_major_alloc);
	blk_cleanup_queue(host->oob_q);
	blk_mq_free_tag_set(&host->tag_set);
err_out_dma_free:
	dma_free_coherent(&pdev->dev, CARM_SHM_SIZE, host->shm, host->shm_dma);
err_out_iounmap:
	iounmap(host->mmio);
err_out_kfree:
	kfree(host);
err_out_regions:
	pci_release_regions(pdev);
err_out:
	pci_disable_device(pdev);
	return rc;
}