static int yenta_probe()

in yenta_socket.c [1158:1300]


static int yenta_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
	struct yenta_socket *socket;
	int ret;

	/*
	 * If we failed to assign proper bus numbers for this cardbus
	 * controller during PCI probe, its subordinate pci_bus is NULL.
	 * Bail out if so.
	 */
	if (!dev->subordinate) {
		dev_err(&dev->dev, "no bus associated! (try 'pci=assign-busses')\n");
		return -ENODEV;
	}

	socket = kzalloc(sizeof(struct yenta_socket), GFP_KERNEL);
	if (!socket)
		return -ENOMEM;

	/* prepare pcmcia_socket */
	socket->socket.ops = &yenta_socket_operations;
	socket->socket.resource_ops = &pccard_nonstatic_ops;
	socket->socket.dev.parent = &dev->dev;
	socket->socket.driver_data = socket;
	socket->socket.owner = THIS_MODULE;
	socket->socket.features = SS_CAP_PAGE_REGS | SS_CAP_PCCARD;
	socket->socket.map_size = 0x1000;
	socket->socket.cb_dev = dev;

	/* prepare struct yenta_socket */
	socket->dev = dev;
	pci_set_drvdata(dev, socket);

	/*
	 * Do some basic sanity checking..
	 */
	if (pci_enable_device(dev)) {
		ret = -EBUSY;
		goto free;
	}

	ret = pci_request_regions(dev, "yenta_socket");
	if (ret)
		goto disable;

	if (!pci_resource_start(dev, 0)) {
		dev_err(&dev->dev, "No cardbus resource!\n");
		ret = -ENODEV;
		goto release;
	}

	/*
	 * Ok, start setup.. Map the cardbus registers,
	 * and request the IRQ.
	 */
	socket->base = ioremap(pci_resource_start(dev, 0), 0x1000);
	if (!socket->base) {
		ret = -ENOMEM;
		goto release;
	}

	/*
	 * report the subsystem vendor and device for help debugging
	 * the irq stuff...
	 */
	dev_info(&dev->dev, "CardBus bridge found [%04x:%04x]\n",
		 dev->subsystem_vendor, dev->subsystem_device);

	yenta_config_init(socket);

	/* Disable all events */
	cb_writel(socket, CB_SOCKET_MASK, 0x0);

	/* Set up the bridge regions.. */
	yenta_allocate_resources(socket);

	socket->cb_irq = dev->irq;

	/* Do we have special options for the device? */
	if (id->driver_data != CARDBUS_TYPE_DEFAULT &&
	    id->driver_data < ARRAY_SIZE(cardbus_type)) {
		socket->type = &cardbus_type[id->driver_data];

		ret = socket->type->override(socket);
		if (ret < 0)
			goto unmap;
	}

	/* We must finish initialization here */

	if (!socket->cb_irq || request_irq(socket->cb_irq, yenta_interrupt, IRQF_SHARED, "yenta", socket)) {
		/* No IRQ or request_irq failed. Poll */
		socket->cb_irq = 0; /* But zero is a valid IRQ number. */
		timer_setup(&socket->poll_timer, yenta_interrupt_wrapper, 0);
		mod_timer(&socket->poll_timer, jiffies + HZ);
		dev_info(&dev->dev,
			 "no PCI IRQ, CardBus support disabled for this socket.\n");
		dev_info(&dev->dev,
			 "check your BIOS CardBus, BIOS IRQ or ACPI settings.\n");
	} else {
		socket->socket.features |= SS_CAP_CARDBUS;
	}

	/* Figure out what the dang thing can do for the PCMCIA layer... */
	yenta_interrogate(socket);
	yenta_get_socket_capabilities(socket, isa_interrupts);
	dev_info(&dev->dev, "Socket status: %08x\n",
		 cb_readl(socket, CB_SOCKET_STATE));

	yenta_fixup_parent_bridge(dev->subordinate);

	/* Register it with the pcmcia layer.. */
	ret = pcmcia_register_socket(&socket->socket);
	if (ret)
		goto free_irq;

	/* Add the yenta register attributes */
	ret = device_create_file(&dev->dev, &dev_attr_yenta_registers);
	if (ret)
		goto unregister_socket;

	return ret;

	/* error path... */
 unregister_socket:
	pcmcia_unregister_socket(&socket->socket);
 free_irq:
	if (socket->cb_irq)
		free_irq(socket->cb_irq, socket);
	else
		del_timer_sync(&socket->poll_timer);
 unmap:
	iounmap(socket->base);
	yenta_free_resources(socket);
 release:
	pci_release_regions(dev);
 disable:
	pci_disable_device(dev);
 free:
	pci_set_drvdata(dev, NULL);
	kfree(socket);
	return ret;
}