aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorEzequiel GarcĂ­a <elezegarcia@gmail.com>2012-02-24 09:24:15 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-15 07:54:14 -0400
commit20c50af28aa9301b1f5bf0ba571068f663f7b0ac (patch)
tree8db149680edf32a9ee40241ab2ed87124ef73641 /drivers/staging
parentab019fd41d993911ba32db0204bb1233682705ee (diff)
[media] staging: easycap: Split buffer and video urb allocation
When the device is probed, this driver allocates frame buffers, field buffers, isoc buffers and urbs. This patch just split this into separate functions, which helps clearing the currently gigantic probe function. Signed-off-by: Ezequiel Garcia <elezegarcia@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/media/easycap/easycap_main.c375
1 files changed, 211 insertions, 164 deletions
diff --git a/drivers/staging/media/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c
index c4198be6344c..6d7cdef58800 100644
--- a/drivers/staging/media/easycap/easycap_main.c
+++ b/drivers/staging/media/easycap/easycap_main.c
@@ -3045,6 +3045,203 @@ static int populate_inputset(struct easycap *peasycap)
3045 return 0; 3045 return 0;
3046} 3046}
3047 3047
3048static int alloc_framebuffers(struct easycap *peasycap)
3049{
3050 int i, j;
3051 void *pbuf;
3052
3053 JOM(4, "allocating %i frame buffers of size %li\n",
3054 FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE);
3055 JOM(4, ".... each scattered over %li pages\n",
3056 FRAME_BUFFER_SIZE/PAGE_SIZE);
3057
3058 for (i = 0; i < FRAME_BUFFER_MANY; i++) {
3059 for (j = 0; j < FRAME_BUFFER_SIZE/PAGE_SIZE; j++) {
3060 if (peasycap->frame_buffer[i][j].pgo)
3061 SAM("attempting to reallocate framebuffers\n");
3062 else {
3063 pbuf = (void *)__get_free_page(GFP_KERNEL);
3064 if (!pbuf) {
3065 SAM("ERROR: Could not allocate "
3066 "framebuffer %i page %i\n", i, j);
3067 return -ENOMEM;
3068 }
3069 peasycap->allocation_video_page += 1;
3070 peasycap->frame_buffer[i][j].pgo = pbuf;
3071 }
3072 peasycap->frame_buffer[i][j].pto =
3073 peasycap->frame_buffer[i][j].pgo;
3074 }
3075 }
3076
3077 peasycap->frame_fill = 0;
3078 peasycap->frame_read = 0;
3079 JOM(4, "allocation of frame buffers done: %i pages\n", i*j);
3080
3081 return 0;
3082}
3083
3084static int alloc_fieldbuffers(struct easycap *peasycap)
3085{
3086 int i, j;
3087 void *pbuf;
3088
3089 JOM(4, "allocating %i field buffers of size %li\n",
3090 FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE);
3091 JOM(4, ".... each scattered over %li pages\n",
3092 FIELD_BUFFER_SIZE/PAGE_SIZE);
3093
3094 for (i = 0; i < FIELD_BUFFER_MANY; i++) {
3095 for (j = 0; j < FIELD_BUFFER_SIZE/PAGE_SIZE; j++) {
3096 if (peasycap->field_buffer[i][j].pgo) {
3097 SAM("ERROR: attempting to reallocate "
3098 "fieldbuffers\n");
3099 } else {
3100 pbuf = (void *) __get_free_page(GFP_KERNEL);
3101 if (!pbuf) {
3102 SAM("ERROR: Could not allocate "
3103 "fieldbuffer %i page %i\n", i, j);
3104 return -ENOMEM;
3105 }
3106 peasycap->allocation_video_page += 1;
3107 peasycap->field_buffer[i][j].pgo = pbuf;
3108 }
3109 peasycap->field_buffer[i][j].pto =
3110 peasycap->field_buffer[i][j].pgo;
3111 }
3112 /* TODO: Hardcoded 0x0200 meaning? */
3113 peasycap->field_buffer[i][0].kount = 0x0200;
3114 }
3115 peasycap->field_fill = 0;
3116 peasycap->field_page = 0;
3117 peasycap->field_read = 0;
3118 JOM(4, "allocation of field buffers done: %i pages\n", i*j);
3119
3120 return 0;
3121}
3122
3123static int alloc_isocbuffers(struct easycap *peasycap)
3124{
3125 int i;
3126 void *pbuf;
3127
3128 JOM(4, "allocating %i isoc video buffers of size %i\n",
3129 VIDEO_ISOC_BUFFER_MANY,
3130 peasycap->video_isoc_buffer_size);
3131 JOM(4, ".... each occupying contiguous memory pages\n");
3132
3133 for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) {
3134 pbuf = (void *)__get_free_pages(GFP_KERNEL,
3135 VIDEO_ISOC_ORDER);
3136 if (!pbuf) {
3137 SAM("ERROR: Could not allocate isoc "
3138 "video buffer %i\n", i);
3139 return -ENOMEM;
3140 }
3141 peasycap->allocation_video_page += BIT(VIDEO_ISOC_ORDER);
3142
3143 peasycap->video_isoc_buffer[i].pgo = pbuf;
3144 peasycap->video_isoc_buffer[i].pto =
3145 pbuf + peasycap->video_isoc_buffer_size;
3146 peasycap->video_isoc_buffer[i].kount = i;
3147 }
3148 JOM(4, "allocation of isoc video buffers done: %i pages\n",
3149 i * (0x01 << VIDEO_ISOC_ORDER));
3150 return 0;
3151}
3152
3153static int create_video_urbs(struct easycap *peasycap)
3154{
3155 struct urb *purb;
3156 struct data_urb *pdata_urb;
3157 int i, j;
3158
3159 JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY);
3160 JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n",
3161 peasycap->video_isoc_framesperdesc);
3162 JOM(4, "using %i=peasycap->video_isoc_maxframesize\n",
3163 peasycap->video_isoc_maxframesize);
3164 JOM(4, "using %i=peasycap->video_isoc_buffer_sizen",
3165 peasycap->video_isoc_buffer_size);
3166
3167 for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) {
3168 purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc,
3169 GFP_KERNEL);
3170 if (!purb) {
3171 SAM("ERROR: usb_alloc_urb returned NULL for buffer "
3172 "%i\n", i);
3173 return -ENOMEM;
3174 }
3175
3176 peasycap->allocation_video_urb += 1;
3177 pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
3178 if (!pdata_urb) {
3179 SAM("ERROR: Could not allocate struct data_urb.\n");
3180 return -ENOMEM;
3181 }
3182
3183 peasycap->allocation_video_struct +=
3184 sizeof(struct data_urb);
3185
3186 pdata_urb->purb = purb;
3187 pdata_urb->isbuf = i;
3188 pdata_urb->length = 0;
3189 list_add_tail(&(pdata_urb->list_head),
3190 peasycap->purb_video_head);
3191
3192 if (!i) {
3193 JOM(4, "initializing video urbs thus:\n");
3194 JOM(4, " purb->interval = 1;\n");
3195 JOM(4, " purb->dev = peasycap->pusb_device;\n");
3196 JOM(4, " purb->pipe = usb_rcvisocpipe"
3197 "(peasycap->pusb_device,%i);\n",
3198 peasycap->video_endpointnumber);
3199 JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
3200 JOM(4, " purb->transfer_buffer = peasycap->"
3201 "video_isoc_buffer[.].pgo;\n");
3202 JOM(4, " purb->transfer_buffer_length = %i;\n",
3203 peasycap->video_isoc_buffer_size);
3204 JOM(4, " purb->complete = easycap_complete;\n");
3205 JOM(4, " purb->context = peasycap;\n");
3206 JOM(4, " purb->start_frame = 0;\n");
3207 JOM(4, " purb->number_of_packets = %i;\n",
3208 peasycap->video_isoc_framesperdesc);
3209 JOM(4, " for (j = 0; j < %i; j++)\n",
3210 peasycap->video_isoc_framesperdesc);
3211 JOM(4, " {\n");
3212 JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",
3213 peasycap->video_isoc_maxframesize);
3214 JOM(4, " purb->iso_frame_desc[j].length = %i;\n",
3215 peasycap->video_isoc_maxframesize);
3216 JOM(4, " }\n");
3217 }
3218
3219 purb->interval = 1;
3220 purb->dev = peasycap->pusb_device;
3221 purb->pipe = usb_rcvisocpipe(peasycap->pusb_device,
3222 peasycap->video_endpointnumber);
3223
3224 purb->transfer_flags = URB_ISO_ASAP;
3225 purb->transfer_buffer = peasycap->video_isoc_buffer[i].pgo;
3226 purb->transfer_buffer_length =
3227 peasycap->video_isoc_buffer_size;
3228
3229 purb->complete = easycap_complete;
3230 purb->context = peasycap;
3231 purb->start_frame = 0;
3232 purb->number_of_packets = peasycap->video_isoc_framesperdesc;
3233
3234 for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) {
3235 purb->iso_frame_desc[j].offset =
3236 j * peasycap->video_isoc_maxframesize;
3237 purb->iso_frame_desc[j].length =
3238 peasycap->video_isoc_maxframesize;
3239 }
3240 }
3241 JOM(4, "allocation of %i struct urb done.\n", i);
3242 return 0;
3243}
3244
3048static const struct v4l2_file_operations v4l2_fops = { 3245static const struct v4l2_file_operations v4l2_fops = {
3049 .owner = THIS_MODULE, 3246 .owner = THIS_MODULE,
3050 .open = easycap_open_noinode, 3247 .open = easycap_open_noinode,
@@ -3067,7 +3264,7 @@ static int easycap_usb_probe(struct usb_interface *intf,
3067 struct urb *purb; 3264 struct urb *purb;
3068 struct easycap *peasycap; 3265 struct easycap *peasycap;
3069 struct data_urb *pdata_urb; 3266 struct data_urb *pdata_urb;
3070 int i, j, k, m, rc; 3267 int i, j, k, rc;
3071 u8 bInterfaceNumber; 3268 u8 bInterfaceNumber;
3072 u8 bInterfaceClass; 3269 u8 bInterfaceClass;
3073 u8 bInterfaceSubClass; 3270 u8 bInterfaceSubClass;
@@ -3416,173 +3613,23 @@ static int easycap_usb_probe(struct usb_interface *intf,
3416 */ 3613 */
3417 INIT_LIST_HEAD(&(peasycap->urb_video_head)); 3614 INIT_LIST_HEAD(&(peasycap->urb_video_head));
3418 peasycap->purb_video_head = &(peasycap->urb_video_head); 3615 peasycap->purb_video_head = &(peasycap->urb_video_head);
3419 JOM(4, "allocating %i frame buffers of size %li\n",
3420 FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE);
3421 JOM(4, ".... each scattered over %li pages\n",
3422 FRAME_BUFFER_SIZE/PAGE_SIZE);
3423
3424 for (k = 0; k < FRAME_BUFFER_MANY; k++) {
3425 for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) {
3426 if (peasycap->frame_buffer[k][m].pgo)
3427 SAM("attempting to reallocate frame "
3428 " buffers\n");
3429 else {
3430 pbuf = (void *)__get_free_page(GFP_KERNEL);
3431 if (!pbuf) {
3432 SAM("ERROR: Could not allocate frame "
3433 "buffer %i page %i\n", k, m);
3434 return -ENOMEM;
3435 }
3436
3437 peasycap->allocation_video_page += 1;
3438 peasycap->frame_buffer[k][m].pgo = pbuf;
3439 }
3440 peasycap->frame_buffer[k][m].pto =
3441 peasycap->frame_buffer[k][m].pgo;
3442 }
3443 }
3444 3616
3445 peasycap->frame_fill = 0; 3617 rc = alloc_framebuffers(peasycap);
3446 peasycap->frame_read = 0; 3618 if (rc < 0)
3447 JOM(4, "allocation of frame buffers done: %i pages\n", k * 3619 return rc;
3448 m);
3449 JOM(4, "allocating %i field buffers of size %li\n",
3450 FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE);
3451 JOM(4, ".... each scattered over %li pages\n",
3452 FIELD_BUFFER_SIZE/PAGE_SIZE);
3453
3454 for (k = 0; k < FIELD_BUFFER_MANY; k++) {
3455 for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) {
3456 if (peasycap->field_buffer[k][m].pgo) {
3457 SAM("ERROR: attempting to reallocate "
3458 "field buffers\n");
3459 } else {
3460 pbuf = (void *) __get_free_page(GFP_KERNEL);
3461 if (!pbuf) {
3462 SAM("ERROR: Could not allocate field"
3463 " buffer %i page %i\n", k, m);
3464 return -ENOMEM;
3465 }
3466
3467 peasycap->allocation_video_page += 1;
3468 peasycap->field_buffer[k][m].pgo = pbuf;
3469 }
3470 peasycap->field_buffer[k][m].pto =
3471 peasycap->field_buffer[k][m].pgo;
3472 }
3473 peasycap->field_buffer[k][0].kount = 0x0200;
3474 }
3475 peasycap->field_fill = 0;
3476 peasycap->field_page = 0;
3477 peasycap->field_read = 0;
3478 JOM(4, "allocation of field buffers done: %i pages\n", k *
3479 m);
3480 JOM(4, "allocating %i isoc video buffers of size %i\n",
3481 VIDEO_ISOC_BUFFER_MANY,
3482 peasycap->video_isoc_buffer_size);
3483 JOM(4, ".... each occupying contiguous memory pages\n");
3484
3485 for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) {
3486 pbuf = (void *)__get_free_pages(GFP_KERNEL,
3487 VIDEO_ISOC_ORDER);
3488 if (!pbuf) {
3489 SAM("ERROR: Could not allocate isoc video buffer "
3490 "%i\n", k);
3491 return -ENOMEM;
3492 }
3493 peasycap->allocation_video_page +=
3494 BIT(VIDEO_ISOC_ORDER);
3495
3496 peasycap->video_isoc_buffer[k].pgo = pbuf;
3497 peasycap->video_isoc_buffer[k].pto =
3498 pbuf + peasycap->video_isoc_buffer_size;
3499 peasycap->video_isoc_buffer[k].kount = k;
3500 }
3501 JOM(4, "allocation of isoc video buffers done: %i pages\n",
3502 k * (0x01 << VIDEO_ISOC_ORDER));
3503
3504 /* Allocate and initialize multiple struct usb */
3505 JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY);
3506 JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n",
3507 peasycap->video_isoc_framesperdesc);
3508 JOM(4, "using %i=peasycap->video_isoc_maxframesize\n",
3509 peasycap->video_isoc_maxframesize);
3510 JOM(4, "using %i=peasycap->video_isoc_buffer_sizen",
3511 peasycap->video_isoc_buffer_size);
3512
3513 for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) {
3514 purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc,
3515 GFP_KERNEL);
3516 if (!purb) {
3517 SAM("ERROR: usb_alloc_urb returned NULL for buffer "
3518 "%i\n", k);
3519 return -ENOMEM;
3520 }
3521
3522 peasycap->allocation_video_urb += 1;
3523 pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
3524 if (!pdata_urb) {
3525 SAM("ERROR: Could not allocate struct data_urb.\n");
3526 return -ENOMEM;
3527 }
3528
3529 peasycap->allocation_video_struct +=
3530 sizeof(struct data_urb);
3531 3620
3532 pdata_urb->purb = purb; 3621 rc = alloc_fieldbuffers(peasycap);
3533 pdata_urb->isbuf = k; 3622 if (rc < 0)
3534 pdata_urb->length = 0; 3623 return rc;
3535 list_add_tail(&(pdata_urb->list_head),
3536 peasycap->purb_video_head);
3537 3624
3538 /* Initialize allocated urbs */ 3625 rc = alloc_isocbuffers(peasycap);
3539 if (!k) { 3626 if (rc < 0)
3540 JOM(4, "initializing video urbs thus:\n"); 3627 return rc;
3541 JOM(4, " purb->interval = 1;\n");
3542 JOM(4, " purb->dev = peasycap->pusb_device;\n");
3543 JOM(4, " purb->pipe = usb_rcvisocpipe"
3544 "(peasycap->pusb_device,%i);\n",
3545 peasycap->video_endpointnumber);
3546 JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
3547 JOM(4, " purb->transfer_buffer = peasycap->"
3548 "video_isoc_buffer[.].pgo;\n");
3549 JOM(4, " purb->transfer_buffer_length = %i;\n",
3550 peasycap->video_isoc_buffer_size);
3551 JOM(4, " purb->complete = easycap_complete;\n");
3552 JOM(4, " purb->context = peasycap;\n");
3553 JOM(4, " purb->start_frame = 0;\n");
3554 JOM(4, " purb->number_of_packets = %i;\n",
3555 peasycap->video_isoc_framesperdesc);
3556 JOM(4, " for (j = 0; j < %i; j++)\n",
3557 peasycap->video_isoc_framesperdesc);
3558 JOM(4, " {\n");
3559 JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",
3560 peasycap->video_isoc_maxframesize);
3561 JOM(4, " purb->iso_frame_desc[j].length = %i;\n",
3562 peasycap->video_isoc_maxframesize);
3563 JOM(4, " }\n");
3564 }
3565 3628
3566 purb->interval = 1; 3629 /* Allocate and initialize video urbs */
3567 purb->dev = peasycap->pusb_device; 3630 rc = create_video_urbs(peasycap);
3568 purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, 3631 if (rc < 0)
3569 peasycap->video_endpointnumber); 3632 return rc;
3570 purb->transfer_flags = URB_ISO_ASAP;
3571 purb->transfer_buffer = peasycap->video_isoc_buffer[k].pgo;
3572 purb->transfer_buffer_length =
3573 peasycap->video_isoc_buffer_size;
3574 purb->complete = easycap_complete;
3575 purb->context = peasycap;
3576 purb->start_frame = 0;
3577 purb->number_of_packets = peasycap->video_isoc_framesperdesc;
3578 for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) {
3579 purb->iso_frame_desc[j].offset = j *
3580 peasycap->video_isoc_maxframesize;
3581 purb->iso_frame_desc[j].length =
3582 peasycap->video_isoc_maxframesize;
3583 }
3584 }
3585 JOM(4, "allocation of %i struct urb done.\n", k);
3586 3633
3587 /* Save pointer peasycap in this interface */ 3634 /* Save pointer peasycap in this interface */
3588 usb_set_intfdata(intf, peasycap); 3635 usb_set_intfdata(intf, peasycap);