static int i82092aa_pci_probe()

in i82092.c [73:173]


static int i82092aa_pci_probe(struct pci_dev *dev,
			      const struct pci_device_id *id)
{
	unsigned char configbyte;
	int i, ret;

	ret = pci_enable_device(dev);
	if (ret)
		return ret;

	/* PCI Configuration Control */
	pci_read_config_byte(dev, 0x40, &configbyte);

	switch (configbyte&6) {
	case 0:
		socket_count = 2;
		break;
	case 2:
		socket_count = 1;
		break;
	case 4:
	case 6:
		socket_count = 4;
		break;

	default:
		dev_err(&dev->dev,
			"Oops, you did something we didn't think of.\n");
		ret = -EIO;
		goto err_out_disable;
	}
	dev_info(&dev->dev, "configured as a %d socket device.\n",
		 socket_count);

	if (!request_region(pci_resource_start(dev, 0), 2, "i82092aa")) {
		ret = -EBUSY;
		goto err_out_disable;
	}

	for (i = 0; i < socket_count; i++) {
		sockets[i].card_state = 1; /* 1 = present but empty */
		sockets[i].io_base = pci_resource_start(dev, 0);
		sockets[i].dev = dev;
		sockets[i].socket.features |= SS_CAP_PCCARD;
		sockets[i].socket.map_size = 0x1000;
		sockets[i].socket.irq_mask = 0;
		sockets[i].socket.pci_irq  = dev->irq;
		sockets[i].socket.cb_dev  = dev;
		sockets[i].socket.owner = THIS_MODULE;

		sockets[i].number = i;

		if (card_present(i)) {
			sockets[i].card_state = 3;
			dev_dbg(&dev->dev, "slot %i is occupied\n", i);
		} else {
			dev_dbg(&dev->dev, "slot %i is vacant\n", i);
		}
	}

	/* Now, specifiy that all interrupts are to be done as PCI interrupts
	 * bitmask, one bit per event, 1 = PCI interrupt, 0 = ISA interrupt
	 */
	configbyte = 0xFF;

	/* PCI Interrupt Routing Register */
	pci_write_config_byte(dev, 0x50, configbyte);

	/* Register the interrupt handler */
	dev_dbg(&dev->dev, "Requesting interrupt %i\n", dev->irq);
	ret = request_irq(dev->irq, i82092aa_interrupt, IRQF_SHARED,
			  "i82092aa", i82092aa_interrupt);
	if (ret) {
		dev_err(&dev->dev, "Failed to register IRQ %d, aborting\n",
			dev->irq);
		goto err_out_free_res;
	}

	for (i = 0; i < socket_count; i++) {
		sockets[i].socket.dev.parent = &dev->dev;
		sockets[i].socket.ops = &i82092aa_operations;
		sockets[i].socket.resource_ops = &pccard_nonstatic_ops;
		ret = pcmcia_register_socket(&sockets[i].socket);
		if (ret)
			goto err_out_free_sockets;
	}

	return 0;

err_out_free_sockets:
	if (i) {
		for (i--; i >= 0; i--)
			pcmcia_unregister_socket(&sockets[i].socket);
	}
	free_irq(dev->irq, i82092aa_interrupt);
err_out_free_res:
	release_region(pci_resource_start(dev, 0), 2);
err_out_disable:
	pci_disable_device(dev);
	return ret;
}