in bridges/vme_fake.c [1064:1239]
static int __init fake_init(void)
{
int retval, i;
struct list_head *pos = NULL, *n;
struct vme_bridge *fake_bridge;
struct fake_driver *fake_device;
struct vme_master_resource *master_image;
struct vme_slave_resource *slave_image;
struct vme_lm_resource *lm;
/* We need a fake parent device */
vme_root = __root_device_register("vme", THIS_MODULE);
/* If we want to support more than one bridge at some point, we need to
* dynamically allocate this so we get one per device.
*/
fake_bridge = kzalloc(sizeof(*fake_bridge), GFP_KERNEL);
if (!fake_bridge) {
retval = -ENOMEM;
goto err_struct;
}
fake_device = kzalloc(sizeof(*fake_device), GFP_KERNEL);
if (!fake_device) {
retval = -ENOMEM;
goto err_driver;
}
fake_bridge->driver_priv = fake_device;
fake_bridge->parent = vme_root;
fake_device->parent = fake_bridge;
/* Initialize wait queues & mutual exclusion flags */
mutex_init(&fake_device->vme_int);
mutex_init(&fake_bridge->irq_mtx);
tasklet_init(&fake_device->int_tasklet, fake_VIRQ_tasklet,
(unsigned long) fake_bridge);
strcpy(fake_bridge->name, driver_name);
/* Add master windows to list */
INIT_LIST_HEAD(&fake_bridge->master_resources);
for (i = 0; i < FAKE_MAX_MASTER; i++) {
master_image = kmalloc(sizeof(*master_image), GFP_KERNEL);
if (!master_image) {
retval = -ENOMEM;
goto err_master;
}
master_image->parent = fake_bridge;
spin_lock_init(&master_image->lock);
master_image->locked = 0;
master_image->number = i;
master_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
VME_A64;
master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
VME_PROG | VME_DATA;
master_image->width_attr = VME_D16 | VME_D32;
memset(&master_image->bus_resource, 0,
sizeof(struct resource));
master_image->kern_base = NULL;
list_add_tail(&master_image->list,
&fake_bridge->master_resources);
}
/* Add slave windows to list */
INIT_LIST_HEAD(&fake_bridge->slave_resources);
for (i = 0; i < FAKE_MAX_SLAVE; i++) {
slave_image = kmalloc(sizeof(*slave_image), GFP_KERNEL);
if (!slave_image) {
retval = -ENOMEM;
goto err_slave;
}
slave_image->parent = fake_bridge;
mutex_init(&slave_image->mtx);
slave_image->locked = 0;
slave_image->number = i;
slave_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
VME_A64 | VME_CRCSR | VME_USER1 | VME_USER2 |
VME_USER3 | VME_USER4;
slave_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
VME_PROG | VME_DATA;
list_add_tail(&slave_image->list,
&fake_bridge->slave_resources);
}
/* Add location monitor to list */
INIT_LIST_HEAD(&fake_bridge->lm_resources);
lm = kmalloc(sizeof(*lm), GFP_KERNEL);
if (!lm) {
retval = -ENOMEM;
goto err_lm;
}
lm->parent = fake_bridge;
mutex_init(&lm->mtx);
lm->locked = 0;
lm->number = 1;
lm->monitors = 4;
list_add_tail(&lm->list, &fake_bridge->lm_resources);
fake_bridge->slave_get = fake_slave_get;
fake_bridge->slave_set = fake_slave_set;
fake_bridge->master_get = fake_master_get;
fake_bridge->master_set = fake_master_set;
fake_bridge->master_read = fake_master_read;
fake_bridge->master_write = fake_master_write;
fake_bridge->master_rmw = fake_master_rmw;
fake_bridge->irq_set = fake_irq_set;
fake_bridge->irq_generate = fake_irq_generate;
fake_bridge->lm_set = fake_lm_set;
fake_bridge->lm_get = fake_lm_get;
fake_bridge->lm_attach = fake_lm_attach;
fake_bridge->lm_detach = fake_lm_detach;
fake_bridge->slot_get = fake_slot_get;
fake_bridge->alloc_consistent = fake_alloc_consistent;
fake_bridge->free_consistent = fake_free_consistent;
pr_info("Board is%s the VME system controller\n",
(geoid == 1) ? "" : " not");
pr_info("VME geographical address is set to %d\n", geoid);
retval = fake_crcsr_init(fake_bridge);
if (retval) {
pr_err("CR/CSR configuration failed.\n");
goto err_crcsr;
}
retval = vme_register_bridge(fake_bridge);
if (retval != 0) {
pr_err("Chip Registration failed.\n");
goto err_reg;
}
exit_pointer = fake_bridge;
return 0;
err_reg:
fake_crcsr_exit(fake_bridge);
err_crcsr:
err_lm:
/* resources are stored in link list */
list_for_each_safe(pos, n, &fake_bridge->lm_resources) {
lm = list_entry(pos, struct vme_lm_resource, list);
list_del(pos);
kfree(lm);
}
err_slave:
/* resources are stored in link list */
list_for_each_safe(pos, n, &fake_bridge->slave_resources) {
slave_image = list_entry(pos, struct vme_slave_resource, list);
list_del(pos);
kfree(slave_image);
}
err_master:
/* resources are stored in link list */
list_for_each_safe(pos, n, &fake_bridge->master_resources) {
master_image = list_entry(pos, struct vme_master_resource,
list);
list_del(pos);
kfree(master_image);
}
kfree(fake_device);
err_driver:
kfree(fake_bridge);
err_struct:
return retval;
}