static void release_iso_resource(struct client *client, struct client_resource *resource) { struct iso_resource *r = container_of(resource, struct iso_resource, resource); spin_lock_irq(&client->lock); r->todo = ISO_RES_DEALLOC; schedule_iso_resource(r); spin_unlock_irq(&client->lock); }
static int init_iso_resource(struct client *client, struct fw_cdev_allocate_iso_resource *request, int todo) { struct iso_resource_event *e1, *e2; struct iso_resource *r; int ret; if ((request->channels == 0 && request->bandwidth == 0) || request->bandwidth > BANDWIDTH_AVAILABLE_INITIAL || request->bandwidth < 0) return -EINVAL; r = kmalloc(sizeof(*r), GFP_KERNEL); e1 = kmalloc(sizeof(*e1), GFP_KERNEL); e2 = kmalloc(sizeof(*e2), GFP_KERNEL); if (r == NULL || e1 == NULL || e2 == NULL) { ret = -ENOMEM; goto fail; } INIT_DELAYED_WORK(&r->work, iso_resource_work); r->client = client; r->todo = todo; r->generation = -1; r->channels = request->channels; r->bandwidth = request->bandwidth; r->e_alloc = e1; r->e_dealloc = e2; e1->resource.closure = request->closure; e1->resource.type = FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED; e2->resource.closure = request->closure; e2->resource.type = FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED; if (todo == ISO_RES_ALLOC) { r->resource.release = release_iso_resource; ret = add_client_resource(client, &r->resource, GFP_KERNEL); if (ret < 0) goto fail; } else { r->resource.release = NULL; r->resource.handle = -1; schedule_iso_resource(r); } request->handle = r->resource.handle; return 0; fail: kfree(r); kfree(e1); kfree(e2); return ret; }