diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index 017629e3cf84..10159c07d295 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -612,8 +612,24 @@ static int smscore_notify_callbacks(struct smscore_device_t *coredev, } static struct -smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, - dma_addr_t common_buffer_phys) +smscore_buffer_t *smscore_create_usb_buffer(int buffer_size) +{ + struct smscore_buffer_t *cb; + + cb = kzalloc_obj(*cb); + if (!cb) + return NULL; + cb->p = kzalloc(buffer_size, GFP_KERNEL); + if (!cb->p) { + kfree(cb); + return NULL; + } + return cb; +} + +static struct +smscore_buffer_t *smscore_create_dma_buffer(u8 *buffer, void *common_buffer, + dma_addr_t common_buffer_phys) { struct smscore_buffer_t *cb; @@ -622,9 +638,8 @@ smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, return NULL; cb->p = buffer; - cb->offset_in_common = buffer - (u8 *) common_buffer; if (common_buffer_phys) - cb->phys = common_buffer_phys + cb->offset_in_common; + cb->phys = common_buffer_phys + (buffer - (u8 *) common_buffer); return cb; } @@ -684,27 +699,32 @@ int smscore_register_device(struct smsdevice_params_t *params, init_waitqueue_head(&dev->buffer_mng_waitq); /* alloc common buffer */ - dev->common_buffer_size = params->buffer_size * params->num_buffers; - if (params->usb_device) - buffer = kzalloc(dev->common_buffer_size, GFP_KERNEL); - else + if (params->usb_device) { + dev->common_dma_buffer_size = 0; + buffer = NULL; + } else { + dev->common_dma_buffer_size = params->buffer_size * params->num_buffers; buffer = dma_alloc_coherent(params->device, - dev->common_buffer_size, - &dev->common_buffer_phys, + dev->common_dma_buffer_size, + &dev->common_dma_buffer_phys, GFP_KERNEL | dev->gfp_buf_flags); - if (!buffer) { - smscore_unregister_device(dev); - return -ENOMEM; + if (!buffer) { + smscore_unregister_device(dev); + return -ENOMEM; + } } - dev->common_buffer = buffer; + dev->common_dma_buffer = buffer; /* prepare dma buffers */ for (; dev->num_buffers < params->num_buffers; dev->num_buffers++, buffer += params->buffer_size) { struct smscore_buffer_t *cb; - cb = smscore_createbuffer(buffer, dev->common_buffer, - dev->common_buffer_phys); + if (params->usb_device) + cb = smscore_create_usb_buffer(params->buffer_size); + else + cb = smscore_create_dma_buffer(buffer, dev->common_dma_buffer, + dev->common_dma_buffer_phys); if (!cb) { smscore_unregister_device(dev); return -ENOMEM; @@ -1204,6 +1224,8 @@ void smscore_unregister_device(struct smscore_device_t *coredev) while (!list_empty(&coredev->buffers)) { cb = (struct smscore_buffer_t *) coredev->buffers.next; list_del(&cb->entry); + if (coredev->usb_device) + kfree(cb->p); kfree(cb); num_buffers++; } @@ -1223,15 +1245,11 @@ void smscore_unregister_device(struct smscore_device_t *coredev) pr_debug("freed %d buffers\n", num_buffers); - if (coredev->common_buffer) { - if (coredev->usb_device) - kfree(coredev->common_buffer); - else - dma_free_coherent(coredev->device, - coredev->common_buffer_size, - coredev->common_buffer, - coredev->common_buffer_phys); - } + if (coredev->common_dma_buffer) + dma_free_coherent(coredev->device, + coredev->common_dma_buffer_size, + coredev->common_dma_buffer, + coredev->common_dma_buffer_phys); kfree(coredev->fw_buf); list_del(&coredev->entry); diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h index d945a2d6d624..a06c8af6eb3a 100644 --- a/drivers/media/common/siano/smscoreapi.h +++ b/drivers/media/common/siano/smscoreapi.h @@ -112,7 +112,6 @@ struct smscore_buffer_t { /* private members, read-only for clients */ void *p; dma_addr_t phys; - unsigned long offset_in_common; }; struct smsdevice_params_t { @@ -154,9 +153,9 @@ struct smscore_device_t { spinlock_t bufferslock; int num_buffers; - void *common_buffer; - int common_buffer_size; - dma_addr_t common_buffer_phys; + void *common_dma_buffer; + int common_dma_buffer_size; + dma_addr_t common_dma_buffer_phys; void *context; struct device *device;