static int tpci200_register()

in carriers/tpci200.c [239:362]


static int tpci200_register(struct tpci200_board *tpci200)
{
	int i;
	int res;
	phys_addr_t ioidint_base;
	unsigned short slot_ctrl;

	if (pci_enable_device(tpci200->info->pdev) < 0)
		return -ENODEV;

	/* Request IP interface register (Bar 2) */
	res = pci_request_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR,
				 "Carrier IP interface registers");
	if (res) {
		dev_err(&tpci200->info->pdev->dev,
			"(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 2 !",
			tpci200->info->pdev->bus->number,
			tpci200->info->pdev->devfn);
		goto err_disable_device;
	}

	/* Request IO ID INT space (Bar 3) */
	res = pci_request_region(tpci200->info->pdev,
				 TPCI200_IO_ID_INT_SPACES_BAR,
				 "Carrier IO ID INT space");
	if (res) {
		dev_err(&tpci200->info->pdev->dev,
			"(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 3 !",
			tpci200->info->pdev->bus->number,
			tpci200->info->pdev->devfn);
		goto err_ip_interface_bar;
	}

	/* Request MEM8 space (Bar 5) */
	res = pci_request_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR,
				 "Carrier MEM8 space");
	if (res) {
		dev_err(&tpci200->info->pdev->dev,
			"(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 5!",
			tpci200->info->pdev->bus->number,
			tpci200->info->pdev->devfn);
		goto err_io_id_int_spaces_bar;
	}

	/* Request MEM16 space (Bar 4) */
	res = pci_request_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR,
				 "Carrier MEM16 space");
	if (res) {
		dev_err(&tpci200->info->pdev->dev,
			"(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!",
			tpci200->info->pdev->bus->number,
			tpci200->info->pdev->devfn);
		goto err_mem8_space_bar;
	}

	/* Map internal tpci200 driver user space */
	tpci200->info->interface_regs =
		ioremap(pci_resource_start(tpci200->info->pdev,
					   TPCI200_IP_INTERFACE_BAR),
			TPCI200_IFACE_SIZE);
	if (!tpci200->info->interface_regs) {
		dev_err(&tpci200->info->pdev->dev,
			"(bn 0x%X, sn 0x%X) failed to map driver user space!",
			tpci200->info->pdev->bus->number,
			tpci200->info->pdev->devfn);
		res = -ENOMEM;
		goto err_mem16_space_bar;
	}

	/* Initialize lock that protects interface_regs */
	spin_lock_init(&tpci200->regs_lock);

	ioidint_base = pci_resource_start(tpci200->info->pdev,
					  TPCI200_IO_ID_INT_SPACES_BAR);
	tpci200->mod_mem[IPACK_IO_SPACE] = ioidint_base + TPCI200_IO_SPACE_OFF;
	tpci200->mod_mem[IPACK_ID_SPACE] = ioidint_base + TPCI200_ID_SPACE_OFF;
	tpci200->mod_mem[IPACK_INT_SPACE] =
		ioidint_base + TPCI200_INT_SPACE_OFF;
	tpci200->mod_mem[IPACK_MEM8_SPACE] =
		pci_resource_start(tpci200->info->pdev,
				   TPCI200_MEM8_SPACE_BAR);
	tpci200->mod_mem[IPACK_MEM16_SPACE] =
		pci_resource_start(tpci200->info->pdev,
				   TPCI200_MEM16_SPACE_BAR);

	/* Set the default parameters of the slot
	 * INT0 disabled, level sensitive
	 * INT1 disabled, level sensitive
	 * error interrupt disabled
	 * timeout interrupt disabled
	 * recover time disabled
	 * clock rate 8 MHz
	 */
	slot_ctrl = 0;
	for (i = 0; i < TPCI200_NB_SLOT; i++)
		writew(slot_ctrl, &tpci200->info->interface_regs->control[i]);

	res = request_irq(tpci200->info->pdev->irq,
			  tpci200_interrupt, IRQF_SHARED,
			  KBUILD_MODNAME, (void *) tpci200);
	if (res) {
		dev_err(&tpci200->info->pdev->dev,
			"(bn 0x%X, sn 0x%X) unable to register IRQ !",
			tpci200->info->pdev->bus->number,
			tpci200->info->pdev->devfn);
		goto err_interface_regs;
	}

	return 0;

err_interface_regs:
	pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs);
err_mem16_space_bar:
	pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR);
err_mem8_space_bar:
	pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
err_io_id_int_spaces_bar:
	pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
err_ip_interface_bar:
	pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR);
err_disable_device:
	pci_disable_device(tpci200->info->pdev);
	return res;
}