V4L/DVB (5212): Pvrusb2: Be more forgiving about encoder firmware size
authorMike Isely <isely@pobox.com>
Thu, 8 Feb 2007 05:02:53 +0000 (02:02 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Wed, 21 Feb 2007 15:35:20 +0000 (13:35 -0200)
The pvrusb2 driver previously rejected encoder firmware whose size was
not a multiple of 8192.  But this is a false check because it's
possible to find cx23416 firmware whose size doesn't conform to this
limit.  So change the firmware loader implementation to be more
forgiving of the image size.

Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/video/pvrusb2/pvrusb2-hdw.c

index 40b2f2a6d3cc88c9e185bc7752dd06b30ae3f17a..a1ca0f5007e075736b6ba6fd6ad29541618c2e3c 100644 (file)
@@ -1209,7 +1209,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
 {
        const struct firmware *fw_entry = NULL;
        void  *fw_ptr;
-       unsigned int pipe, fw_len, fw_done;
+       unsigned int pipe, fw_len, fw_done, bcnt, icnt;
        int actual_length;
        int ret = 0;
        int fwidx;
@@ -1265,11 +1265,11 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
 
        fw_len = fw_entry->size;
 
-       if (fw_len % FIRMWARE_CHUNK_SIZE) {
+       if (fw_len % sizeof(u32)) {
                pvr2_trace(PVR2_TRACE_ERROR_LEGS,
                           "size of %s firmware"
-                          " must be a multiple of 8192B",
-                          fw_files[fwidx]);
+                          " must be a multiple of %u bytes",
+                          fw_files[fwidx],sizeof(u32));
                release_firmware(fw_entry);
                return -1;
        }
@@ -1284,18 +1284,21 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
 
        pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT);
 
-       for (fw_done = 0 ; (fw_done < fw_len) && !ret ;
-            fw_done += FIRMWARE_CHUNK_SIZE ) {
-               int i;
-               memcpy(fw_ptr, fw_entry->data + fw_done, FIRMWARE_CHUNK_SIZE);
-               /* Usbsnoop log  shows that we must swap bytes... */
-               for (i = 0; i < FIRMWARE_CHUNK_SIZE/4 ; i++)
-                       ((u32 *)fw_ptr)[i] = ___swab32(((u32 *)fw_ptr)[i]);
-
-               ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,
-                                   FIRMWARE_CHUNK_SIZE,
+       fw_done = 0;
+       for (fw_done = 0; fw_done < fw_len;) {
+               bcnt = fw_len - fw_done;
+               if (bcnt > FIRMWARE_CHUNK_SIZE) bcnt = FIRMWARE_CHUNK_SIZE;
+               memcpy(fw_ptr, fw_entry->data + fw_done, bcnt);
+               /* Usbsnoop log shows that we must swap bytes... */
+               for (icnt = 0; icnt < bcnt/4 ; icnt++)
+                       ((u32 *)fw_ptr)[icnt] =
+                               ___swab32(((u32 *)fw_ptr)[icnt]);
+
+               ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,bcnt,
                                    &actual_length, HZ);
-               ret |= (actual_length != FIRMWARE_CHUNK_SIZE);
+               ret |= (actual_length != bcnt);
+               if (ret) break;
+               fw_done += bcnt;
        }
 
        trace_firmware("upload of %s : %i / %i ",