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 = ¥ta_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;
}