summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacek Konieczny2012-09-23 20:22:18 (GMT)
committerJacek Konieczny2012-09-23 20:22:18 (GMT)
commit7b411445e53d670c6cfcee6a4f04815c8ffcf854 (patch)
tree232ea3d9b8356848e325390527a39150e4e48d32
parent130bd18a4be9ab6a2c0b286f6f53eeddef3d2209 (diff)
downloadlibgphoto2-7b411445e53d670c6cfcee6a4f04815c8ffcf854.zip
libgphoto2-7b411445e53d670c6cfcee6a4f04815c8ffcf854.tar.gz
Version: 2.4.14.1 snapshot (fixes some crashes)auto/ti/libgphoto2-2.4.14.1-0.svn14116
-rw-r--r--libgphoto2-svn.patch1033
-rw-r--r--libgphoto2.spec13
2 files changed, 1042 insertions, 4 deletions
diff --git a/libgphoto2-svn.patch b/libgphoto2-svn.patch
new file mode 100644
index 0000000..ddc444e
--- /dev/null
+++ b/libgphoto2-svn.patch
@@ -0,0 +1,1033 @@
+Index: configure.ac
+===================================================================
+--- configure.ac (revision 14002)
++++ configure.ac (revision 14116)
+@@ -5,7 +5,7 @@
+ dnl So lastversion.X.trunk for instance. Bump X if necessary.
+
+ dnl ******* THE NEXT RELEASE VERSION MUST BE 2.4.15 at least or higher!
+-AC_INIT([libgphoto2 photo camera library], [2.4.14], [gphoto-devel@lists.sourceforge.net], [libgphoto2])
++AC_INIT([libgphoto2 photo camera library], [2.4.14.1], [gphoto-devel@lists.sourceforge.net], [libgphoto2])
+ AC_CONFIG_SRCDIR([libgphoto2/gphoto2-version.c])
+ AC_CONFIG_HEADERS([config.h])
+ AC_CONFIG_MACRO_DIR([auto-m4])
+Index: camlibs/ptp2/library.c
+===================================================================
+--- camlibs/ptp2/library.c (revision 14002)
++++ camlibs/ptp2/library.c (revision 14116)
+@@ -623,9 +623,14 @@
+ {"Sony:SLT-A55 (PTP mode)", 0x054c, 0x04a3, 0},
+ /* http://sourceforge.net/tracker/?func=detail&atid=358874&aid=3515558&group_id=8874 */
+ {"Sony:SLT-A35 (PTP mode)", 0x054c, 0x04a7, 0},
++ /* t.ludewig@gmail.com */
++ {"Sony:SLT-A65V (PTP mode)", 0x054c, 0x0574, 0},
+ /* Rudi */
+ {"Sony:DSC-HX100V (PTP mode)",0x054c, 0x0543, 0},
+
++ /* t.ludewig@gmail.com */
++ {"Sony:DSC-HX200V (PTP mode)",0x054c, 0x061f, 0},
++
+ /* Nikon Coolpix 2500: M. Meissner, 05 Oct 2003 */
+ {"Nikon:Coolpix 2500 (PTP mode)", 0x04b0, 0x0109, 0},
+ /* Nikon Coolpix 5700: A. Tanenbaum, 29 Oct 2002 */
+@@ -715,7 +720,7 @@
+ {"Nikon:Coolpix L110 (PTP mode)", 0x04b0, 0x017e, PTP_CAP},
+
+ /* miguel@rozsas.eng.br */
+- {"Nikon:Coolpix P500 (PTP mode)", 0x04b0, 0x0184, 0},
++ {"Nikon:Coolpix P500 (PTP mode)", 0x04b0, 0x0184, PTP_CAP},
+ /* Graeme Wyatt <graeme.wyatt@nookawarra.com> */
+ {"Nikon:Coolpix L120 (PTP mode)", 0x04b0, 0x0185, PTP_CAP},
+ /* Kévin Ottens <ervin@ipsquad.net> */
+@@ -740,6 +745,10 @@
+ {"Nikon:Coolpix S8000 (PTP mode)",0x04b0, 0x021f, 0},
+ /* Aleksej Serdjukov <deletesoftware@yandex.ru> */
+ {"Nikon:Coolpix S5100 (PTP mode)",0x04b0, 0x0220, 0},
++ /* wlady.cs@gmail.com */
++ {"Nikon:Coolpix P300 (PTP mode)", 0x04b0, 0x0221, 0},
++ /* t.ludewig@gmail.com */
++ {"Nikon:Coolpix P510 (PTP mode)", 0x04b0, 0x0223, 0},
+ /* Nikon Coolpix 2000 */
+ {"Nikon:Coolpix 2000 (PTP mode)", 0x04b0, 0x0302, 0},
+ /* From IRC reporter. */
+@@ -810,6 +819,15 @@
+ /* IRC Reporter popolon */
+ {"Nikon:DSC D5100 (PTP mode)", 0x04b0, 0x0429, PTP_CAP|PTP_CAP_PREVIEW},
+
++ /* Roderick Stewart <roderick.stewart@gmail.com> */
++ {"Nikon:DSC D800E (PTP mode)", 0x04b0, 0x042e, PTP_CAP|PTP_CAP_PREVIEW},
++
++ /* http://sourceforge.net/tracker/?func=detail&aid=3536904&group_id=8874&atid=108874 */
++ {"Nikon:V1", 0x04b0, 0x0601, PTP_CAP},
++ /* https://sourceforge.net/tracker/?func=detail&atid=358874&aid=3556403&group_id=8874 */
++ {"Nikon:J1", 0x04b0, 0x0602, PTP_CAP},
++
++
+ #if 0
+ /* Thomas Luzat <thomas.luzat@gmx.net> */
+ /* this was reported as not working, mass storage only:
+@@ -872,6 +890,9 @@
+ {"Olympus:X920", 0x07b4, 0x0116, 0},
+ {"Olympus:X925", 0x07b4, 0x0116, 0},
+
++ /* t.ludewig@gmail.com */
++ {"Olympus:SP-720UZ", 0x07b4, 0x012f, 0},
++
+ /* IRC report */
+ {"Casio:EX-Z120", 0x07cf, 0x1042, 0},
+ /* Andrej Semen (at suse) */
+@@ -1058,6 +1079,8 @@
+
+ /* Martin Lasarsch at SUSE. MTP_PROPLIST returns just 0 entries */
+ {"Canon:Digital IXUS 90 IS", 0x04a9, 0x3174, PTPBUG_DELETE_SENDS_EVENT},
++ /* Daniel Moyne <daniel.moyne@free.fr> */
++ {"Canon:Powershot SD790 IS", 0x04a9, 0x3174, PTPBUG_DELETE_SENDS_EVENT},
+
+ /* https://sourceforge.net/tracker/?func=detail&aid=2722422&group_id=8874&atid=358874 */
+ {"Canon:Digital IXUS 85 IS", 0x04a9, 0x3174, PTPBUG_DELETE_SENDS_EVENT},
+@@ -1177,9 +1200,18 @@
+ /* https://sourceforge.net/tracker/?func=detail&atid=358874&aid=3310995&group_id=8874 */
+ {"Canon:EOS 600D", 0x04a9, 0x3218, PTP_CAP|PTP_CAP_PREVIEW},
+
++ /* analemma88@gmail.com */
++ {"Canon:PowerShot A800", 0x04a9, 0x3226, PTPBUG_DELETE_SENDS_EVENT},
++
+ /* Juha Pesonen <juha.e.pesonen@gmail.com> */
+ {"Canon:PowerShot SX230HS", 0x04a9, 0x3228, PTPBUG_DELETE_SENDS_EVENT},
+
++ /* t.ludewig@gmail.com */
++ {"Canon:PowerShot SX40HS", 0x04a9, 0x3238, PTPBUG_DELETE_SENDS_EVENT},
++
++ /* t.ludewig@gmail.com */
++ {"Canon:EOS 650D", 0x04a9, 0x323b, PTP_CAP|PTP_CAP_PREVIEW},
++
+ /* Konica-Minolta PTP cameras */
+ {"Konica-Minolta:DiMAGE A2 (PTP mode)", 0x132b, 0x0001, 0},
+ {"Konica-Minolta:DiMAGE Z2 (PictBridge mode)", 0x132b, 0x0007, 0},
+@@ -1244,10 +1276,17 @@
+ {"Fuji:FinePix F80EXR", 0x04cb, 0x020e, 0},
+ /* salsaman <salsaman@gmail.com> */
+ {"Fuji:FinePix Z700EXR", 0x04cb, 0x020d, 0},
++ /* https://sourceforge.net/tracker/index.php?func=detail&aid=3556692&group_id=8874&atid=108874 */
++ {"Fuji:FinePix S2950", 0x04cb, 0x0240, 0},
+ /* Luis Arias <kaaloo@gmail.com> */
+ {"Fuji:FinePix X10", 0x04cb, 0x0263, 0},
++ /* t.ludewig@gmail.com */
++ {"Fuji:FinePix S4300", 0x04cb, 0x0265, 0},
++ /* t.ludewig@gmail.com */
++ {"Fuji:FinePix X-S1", 0x04cb, 0x026e, 0},
++ /* t.ludewig@gmail.com */
++ {"Fuji:FinePix HS30EXR", 0x04cb, 0x0271, 0},
+
+-
+ {"Ricoh:Caplio R5 (PTP mode)", 0x05ca, 0x0110, 0},
+ {"Ricoh:Caplio GX (PTP mode)", 0x05ca, 0x0325, 0},
+ {"Sea & Sea:5000G (PTP mode)", 0x05ca, 0x0327, 0},
+@@ -1289,6 +1328,9 @@
+ {"Apple:iPod Touch 3rd Gen (PTP mode)", 0x05ac, 0x1299, 0},
+ {"Apple:iPad (PTP mode)", 0x05ac, 0x129a, 0},
+
++ /* Don Cohen <don-sourceforge-xxzw@isis.cs3-inc.com> */
++ {"Apple:iPhone 4S (PTP mode)", 0x05ac, 0x12a0, 0},
++
+ /* https://sourceforge.net/tracker/index.php?func=detail&aid=1869653&group_id=158745&atid=809061 */
+ {"Pioneer:DVR-LX60D", 0x08e4, 0x0142, 0},
+
+@@ -4555,12 +4597,14 @@
+ unsigned char *ximage = NULL;
+ unsigned int xlen = 0;
+
+- /* If thumb size is 0 then there is no thumbnail at all... */
+- if((size=oi->ThumbCompressedSize)==0) return (GP_ERROR_NOT_SUPPORTED);
++ size=oi->ThumbCompressedSize;
++ /* If thumb size is 0 and the OFC is not a image type (0x3800 / 0xb800)... */
++ if ((size==0) && ((oi->ObjectFormat & 0x7800) != 0x3800))
++ return GP_ERROR_NOT_SUPPORTED;
+ CPR (context, ptp_getthumb(params,
+ params->handles.Handler[object_id],
+ &ximage, &xlen));
+- if (xlen != size)
++ if (size && (xlen != size))
+ gp_log (GP_LOG_ERROR, "get_file_func/GP_FILE_TYPE_PREVIEW", "size mismatch %d vs %d", size, xlen);
+ set_mimetype (camera, file, params->deviceinfo.VendorExtensionID, oi->ThumbFormat);
+ CR (gp_file_set_data_and_size (file, (char*)ximage, xlen));
+Index: camlibs/canon/canon.c
+===================================================================
+--- camlibs/canon/canon.c (revision 14002)
++++ camlibs/canon/canon.c (revision 14116)
+@@ -1333,8 +1333,7 @@
+ if ( is_image ( new_name ) ) {
+ /* Yup, we'll assume that this is the new image. */
+ GP_DEBUG ( " Found our new image file" );
+- strncpy ( path->name, new_name,
+- strlen ( new_name ) );
++ strcpy ( path->name, new_name );
+ strcpy ( path->folder, canon2gphotopath ( camera, path->folder ) );
+
+ /* FIXME: Marcus: make it less large effort... */
+Index: camlibs/ax203/ax203.h
+===================================================================
+--- camlibs/ax203/ax203.h (revision 14002)
++++ camlibs/ax203/ax203.h (revision 14116)
+@@ -49,6 +49,7 @@
+ #define AX203_EEPROM_CMD 0x00
+ #define AX203_GET_VERSION 0x01
+ #define AX203_GET_LCD_SIZE 0x02
++#define AX203_GET_CHECKSUM 0x05 /* Note only seen on 206 sofar */
+
+ #define AX3003_FRAME_CMD 0xCA
+ #define AX3003_SET_TIME 0x01
+@@ -102,6 +103,7 @@
+ int mem_size;
+ int has_4k_sectors;
+ int block_protection_removed;
++ int pp_64k;
+ /* Driver configuration settings */
+ int syncdatetime;
+ };
+Index: camlibs/ax203/README.ax203
+===================================================================
+--- camlibs/ax203/README.ax203 (revision 14002)
++++ camlibs/ax203/README.ax203 (revision 14116)
+@@ -113,6 +113,24 @@
+ to be removed, a lot more of the memory could be used to actually store
+ pictures.
+
++ax206 checksum command
++----------------------
+
++While working on support for the ax206's not quite raw flash access mode
++for eeproms with AAI, like the SST25VF080, I found out that at least the
++ax206 also has a command to read part of the eeprom and generate a 16 bit
++checksum for it. The layout of the scsi cmd buffer for this is as follows:
++byte 0: 0xcd (read from dev)
++byte 1 - 4: 0
++byte 5: 5
++byte 6: 5
++byte 7 - 8: size of area to checksum, byte 7 == MSB, 0 means 65536
++byte 9 - 10: 0
++byte 11 - 13: address to start checksum, byte 11 == MSB
++
++And then readback 64 bytes of scsi data, where the first 2 are the 16 bit
++checksum of all the bytes in the area with byte 0 being the MSB.
++
++
+ Hans de Goede <hdegoede@redhat.com>
+-3 May 2010
++16 Sep 2012
+Index: camlibs/ax203/ax203.c
+===================================================================
+--- camlibs/ax203/ax203.c (revision 14002)
++++ camlibs/ax203/ax203.c (revision 14116)
+@@ -1,6 +1,6 @@
+ /* Appotech ax203 picframe access library
+ *
+- * Copyright (c) 2010 Hans de Goede <hdegoede@redhat.com>
++ * Copyright (c) 2010-2012 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+@@ -43,6 +43,7 @@
+ uint32_t id;
+ int mem_size;
+ int has_4k_sectors;
++ int pp_64k;
+ } ax203_eeprom_info[] = {
+ { "AMIC A25L040", 0x37133037, 524288, 1 },
+ { "AMIC A25L080", 0x37143037, 1048576, 1 },
+@@ -85,9 +86,8 @@
+ { "Spansion S25FL008A", 0x00130201, 1048576, 0 },
+ { "Spansion S25FL016A", 0x00140201, 2097152, 0 },
+
+- /* The SST25VF080 and SST25VF016 (id:0xbf8e25bf & 0xbf4125bf) PP
+- instruction can only program a single byte at a time. Thus they
+- are not supported */
++ { "SST25VF080", 0xbf8e25bf, 1048576, 0, 1 },
++ { "SST25VF016", 0xbf4125bf, 2097152, 0, 1 },
+
+ { "ST M25P08", 0x7f142020, 1048576, 0 },
+ { "ST M25P16", 0x7f152020, 2097152, 0 },
+@@ -123,7 +123,7 @@
+ static int
+ ax203_send_eeprom_cmd(Camera *camera, int to_dev,
+ char *eeprom_cmd, int eeprom_cmd_size,
+- char *data, int data_size)
++ char *data, int data_size, char extra_arg)
+ {
+ char cmd_buffer[16];
+ int i;
+@@ -143,6 +143,8 @@
+ for (i = 0; i < eeprom_cmd_size; i++)
+ cmd_buffer[10 + i] = eeprom_cmd[i];
+
++ cmd_buffer[15] = extra_arg;
++
+ return ax203_send_cmd (camera, to_dev, cmd_buffer, sizeof(cmd_buffer),
+ data, data_size);
+ }
+@@ -194,6 +196,31 @@
+ #endif
+
+ static int
++ax203_get_checksum(Camera *camera, int address, int size)
++{
++ int ret;
++ char cmd_buffer[16];
++ uint8_t buf[2];
++
++ memset (cmd_buffer, 0, sizeof (cmd_buffer));
++
++ cmd_buffer[0] = AX203_FROM_DEV;
++ cmd_buffer[5] = AX203_GET_CHECKSUM;
++ cmd_buffer[6] = AX203_GET_CHECKSUM;
++ cmd_buffer[7] = (size >> 8) & 0xff;
++ cmd_buffer[8] = size & 0xff;
++ cmd_buffer[11] = (address >> 16) & 0xff;
++ cmd_buffer[12] = (address >> 8) & 0xff;
++ cmd_buffer[13] = address & 0xff;
++
++ ret = ax203_send_cmd (camera, 0, cmd_buffer, sizeof(cmd_buffer),
++ (char *)buf, 2);
++ if (ret < 0) return ret;
++
++ return be16atoh(buf);
++}
++
++static int
+ ax3003_get_frame_id(Camera *camera)
+ {
+ int ret;
+@@ -273,7 +300,7 @@
+ {
+ char cmd = SPI_EEPROM_RDID;
+
+- return ax203_send_eeprom_cmd (camera, 0, &cmd, 1, buf, 4);
++ return ax203_send_eeprom_cmd (camera, 0, &cmd, 1, buf, 4, 0);
+ }
+
+ static int
+@@ -281,7 +308,7 @@
+ {
+ char cmd = SPI_EEPROM_RDP;
+
+- return ax203_send_eeprom_cmd (camera, 1, &cmd, 1, NULL, 0);
++ return ax203_send_eeprom_cmd (camera, 1, &cmd, 1, NULL, 0, 0);
+ }
+
+ static int
+@@ -295,11 +322,12 @@
+ cmd[3] = (address) & 0xff;
+
+ return ax203_send_eeprom_cmd (camera, 0, cmd, sizeof(cmd), buf,
+- buf_size);
++ buf_size, 0);
+ }
+
+ static int
+-ax203_eeprom_program_page(Camera *camera, int address, char *buf, int buf_size)
++ax203_eeprom_program_page(Camera *camera, int address, char *buf, int buf_size,
++ char extra_arg)
+ {
+ char cmd[4];
+
+@@ -309,7 +337,7 @@
+ cmd[3] = (address) & 0xff;
+
+ return ax203_send_eeprom_cmd (camera, 1, cmd, sizeof(cmd), buf,
+- buf_size);
++ buf_size, extra_arg);
+ }
+
+ static int
+@@ -317,7 +345,7 @@
+ {
+ char cmd = SPI_EEPROM_WREN;
+
+- return ax203_send_eeprom_cmd (camera, 1, &cmd, 1, NULL, 0);
++ return ax203_send_eeprom_cmd (camera, 1, &cmd, 1, NULL, 0, 0);
+ }
+
+ static int
+@@ -328,7 +356,7 @@
+ cmd[0] = SPI_EEPROM_WRSR;
+ cmd[1] = 0;
+
+- return ax203_send_eeprom_cmd (camera, 1, cmd, sizeof(cmd), NULL, 0);
++ return ax203_send_eeprom_cmd (camera, 1, cmd, sizeof(cmd), NULL, 0, 0);
+ }
+
+ static int
+@@ -341,7 +369,7 @@
+ cmd[2] = (address >> 8) & 0xff;
+ cmd[3] = (address) & 0xff;
+
+- return ax203_send_eeprom_cmd (camera, 1, cmd, sizeof(cmd), NULL, 0);
++ return ax203_send_eeprom_cmd (camera, 1, cmd, sizeof(cmd), NULL, 0, 0);
+ }
+
+ static int
+@@ -354,7 +382,7 @@
+ cmd[2] = (address >> 8) & 0xff;
+ cmd[3] = (address) & 0xff;
+
+- return ax203_send_eeprom_cmd (camera, 1, cmd, sizeof(cmd), NULL, 0);
++ return ax203_send_eeprom_cmd (camera, 1, cmd, sizeof(cmd), NULL, 0, 0);
+ }
+
+ static int
+@@ -380,7 +408,8 @@
+ }
+
+ while (1) {
+- CHECK (ax203_send_eeprom_cmd (camera, 0, &cmd, 1, buf, count))
++ CHECK (ax203_send_eeprom_cmd (camera, 0, &cmd, 1,
++ buf, count, 0))
+ /* We only need to check the last read */
+ if (!(buf[count - 1] & 0x01)) /* Check write in progress bit */
+ break; /* No write in progress, done waiting */
+@@ -445,7 +474,7 @@
+ for (i = 0; i < SPI_EEPROM_SECTOR_SIZE; i += 256) {
+ CHECK (ax203_eeprom_write_enable (camera))
+ CHECK (ax203_eeprom_program_page (camera, base + i,
+- buf + i, 256))
++ buf + i, 256, 0))
+ CHECK (ax203_eeprom_wait_ready (camera))
+ }
+ }
+@@ -1574,12 +1603,24 @@
+ return GP_OK;
+ }
+
++/* The ax3003 and the ax206 with AAI capable eeproms can program 64k at once,
++ this is probably done by special handling inside the firmware. */
+ static int
+-ax203_commit_block_ax3003(Camera *camera, int bss)
++ax203_commit_block_64k_at_once(Camera *camera, int bss)
+ {
+ int block_sector_size = SPI_EEPROM_BLOCK_SIZE / SPI_EEPROM_SECTOR_SIZE;
+ int i, address = bss * SPI_EEPROM_SECTOR_SIZE;
++ int checksum = 0;
++ char extra_arg = 0;
+
++ /* The ax206 (and we assume the same applies for ax203, untested!):
++ 1) Needs the last byte of the scsi cmd to be 2 to enable 64k pp
++ 2) Has an extra checksum function, which we might as well use. */
++ if (camera->pl->frame_version != AX3003_FIRMWARE_3_5_x) {
++ extra_arg = 2;
++ checksum = 1;
++ }
++
+ /* Make sure we have read the entire block before erasing it !! */
+ for (i = 0; i < block_sector_size; i++)
+ CHECK (ax203_check_sector_present (camera, bss + i))
+@@ -1594,14 +1635,31 @@
+ /* Erase the block */
+ CHECK (ax203_erase64k_sector (camera, bss))
+
+- /* And program the block in one large 64k page write, the ax3003
+- probably emulates this in firmware, to avoid usb bus overhead. */
++ /* program the block in one large 64k page write */
+ CHECK (ax203_eeprom_write_enable (camera))
+ CHECK (ax203_eeprom_program_page (camera, address,
+ camera->pl->mem + address,
+- SPI_EEPROM_BLOCK_SIZE))
++ SPI_EEPROM_BLOCK_SIZE, extra_arg))
+ CHECK (ax203_eeprom_wait_ready (camera))
+
++ /* and ask the device to verify the write with a checksum */
++ if (checksum) {
++ checksum = 0;
++ for (i = address; i < (address + SPI_EEPROM_BLOCK_SIZE); i++)
++ checksum += ((uint8_t *)camera->pl->mem)[i];
++ checksum &= 0xffff;
++
++ i = ax203_get_checksum(camera, address, SPI_EEPROM_BLOCK_SIZE);
++ if (i < 0)
++ return i;
++ if (i != checksum) {
++ gp_log (GP_LOG_ERROR, "ax203",
++ "checksum mismatch after programming "
++ "expected %04x, got %04x\n", checksum, i);
++ return GP_ERROR_IO;
++ }
++ }
++
+ for (i = 0; i < block_sector_size; i++)
+ camera->pl->sector_dirty[bss + i] = 0;
+
+@@ -1630,8 +1688,8 @@
+ if (!dirty_sectors)
+ continue;
+
+- if (camera->pl->frame_version == AX3003_FIRMWARE_3_5_x)
+- CHECK (ax203_commit_block_ax3003 (camera, i))
++ if (camera->pl->pp_64k)
++ CHECK (ax203_commit_block_64k_at_once (camera, i))
+ /* There are 16 4k sectors per 64k block, when we need to
+ program 12 or more sectors, programming the entire block
+ becomes faster */
+@@ -1700,9 +1758,13 @@
+
+ camera->pl->mem_size = ax203_eeprom_info[i].mem_size;
+ camera->pl->has_4k_sectors = ax203_eeprom_info[i].has_4k_sectors;
+- GP_DEBUG ("%s EEPROM found, capacity: %d, has 4k sectors: %d",
+- ax203_eeprom_info[i].name, camera->pl->mem_size,
+- camera->pl->has_4k_sectors);
++ camera->pl->pp_64k = ax203_eeprom_info[i].pp_64k;
++ if (camera->pl->frame_version == AX3003_FIRMWARE_3_5_x)
++ camera->pl->pp_64k = 1;
++ GP_DEBUG (
++ "%s EEPROM found, capacity: %d, has 4k sectors: %d, pp_64k %d",
++ ax203_eeprom_info[i].name, camera->pl->mem_size,
++ camera->pl->has_4k_sectors, camera->pl->pp_64k);
+
+ return ax203_init (camera);
+ }
+Index: NEWS
+===================================================================
+--- NEWS (revision 14002)
++++ NEWS (revision 14116)
+@@ -1,3 +1,8 @@
++libgphoto2 2.4.14.1
++
++* ptp2: some fixes
++
++------------------------------------------------------------------------
+ libgphoto2 2.4.14
+
+ packaging:
+Index: libgphoto2_port/libusb1/libusb1.c
+===================================================================
+--- libgphoto2_port/libusb1/libusb1.c (revision 14002)
++++ libgphoto2_port/libusb1/libusb1.c (revision 14116)
+@@ -71,6 +71,10 @@
+
+ int detached;
+
++ time_t devslastchecked;
++ int nrofdevs;
++ struct libusb_device_descriptor *descs;
++ libusb_device **devs;
+ };
+
+ GPPortType
+@@ -79,38 +83,34 @@
+ return (GP_PORT_USB);
+ }
+
+-static time_t gp_devslastchecked = 0;
+-static int gp_nrofdevs = 0;
+-static struct libusb_device_descriptor *gp_descs;
+-static libusb_device **gp_devs;
+
+ static ssize_t
+-load_devicelist (libusb_context *ctx) {
++load_devicelist (GPPortPrivateLibrary *pl) {
+ time_t xtime;
+
+ time(&xtime);
+- if (xtime != gp_devslastchecked) {
+- if (gp_nrofdevs)
+- libusb_free_device_list (gp_devs, 1);
+- free (gp_descs);
+- gp_nrofdevs = 0;
+- gp_devs = NULL;
+- gp_descs = NULL;
++ if (xtime != pl->devslastchecked) {
++ if (pl->nrofdevs)
++ libusb_free_device_list (pl->devs, 1);
++ free (pl->descs);
++ pl->nrofdevs = 0;
++ pl->devs = NULL;
++ pl->descs = NULL;
+ }
+- if (!gp_nrofdevs) {
++ if (!pl->nrofdevs) {
+ int i;
+
+- gp_nrofdevs = libusb_get_device_list (ctx, &gp_devs);
+- gp_descs = malloc (sizeof(gp_descs[0])*gp_nrofdevs);
+- for (i=0;i<gp_nrofdevs;i++) {
++ pl->nrofdevs = libusb_get_device_list (pl->ctx, &pl->devs);
++ pl->descs = malloc (sizeof(pl->descs[0])*pl->nrofdevs);
++ for (i=0;i<pl->nrofdevs;i++) {
+ int ret;
+- ret = libusb_get_device_descriptor(gp_devs[i], &gp_descs[i]);
++ ret = libusb_get_device_descriptor(pl->devs[i], &pl->descs[i]);
+ if (ret)
+ gp_log (GP_LOG_ERROR, "libusb1", "libusb_get_device_descriptor(%d) returned %d", i, ret);
+ }
+ }
+- time (&gp_devslastchecked);
+- return gp_nrofdevs;
++ time (&pl->devslastchecked);
++ return pl->nrofdevs;
+ }
+
+ int
+@@ -119,6 +119,10 @@
+ GPPortInfo info;
+ int nrofdevices = 0;
+ int d, i, i1, i2, unknownint;
++ libusb_context *ctx;
++ libusb_device **devs = NULL;
++ int nrofdevs = 0;
++ struct libusb_device_descriptor *descs;
+
+ /* generic matcher. This will catch passed XXX,YYY entries for instance. */
+ info.type = GP_PORT_USB;
+@@ -126,26 +130,33 @@
+ strcpy (info.path, "^usb:");
+ CHECK (gp_port_info_list_append (list, info));
+
+- libusb_init (NULL);
+- gp_nrofdevs = load_devicelist (NULL);
++ libusb_init (&ctx);
++ nrofdevs = libusb_get_device_list (ctx, &devs);
++ descs = malloc (sizeof(descs[0])*nrofdevs);
++ for (i=0;i<nrofdevs;i++) {
++ int ret;
++ ret = libusb_get_device_descriptor(devs[i], &descs[i]);
++ if (ret)
++ gp_log (GP_LOG_ERROR, "libusb1", "libusb_get_device_descriptor(%d) returned %d", i, ret);
++ }
+
+- for (d = 0; d < gp_nrofdevs; d++) {
++ for (d = 0; d < nrofdevs; d++) {
+ /* Devices which are definitely not cameras. */
+- if ( (gp_descs[d].bDeviceClass == LIBUSB_CLASS_HUB) ||
+- (gp_descs[d].bDeviceClass == LIBUSB_CLASS_HID) ||
+- (gp_descs[d].bDeviceClass == LIBUSB_CLASS_PRINTER) ||
+- (gp_descs[d].bDeviceClass == LIBUSB_CLASS_COMM) ||
+- (gp_descs[d].bDeviceClass == 0xe0) /* wireless / bluetooth */
++ if ( (descs[d].bDeviceClass == LIBUSB_CLASS_HUB) ||
++ (descs[d].bDeviceClass == LIBUSB_CLASS_HID) ||
++ (descs[d].bDeviceClass == LIBUSB_CLASS_PRINTER) ||
++ (descs[d].bDeviceClass == LIBUSB_CLASS_COMM) ||
++ (descs[d].bDeviceClass == 0xe0) /* wireless / bluetooth */
+ )
+ continue;
+ /* excepts HUBs, usually the interfaces have the classes, not
+ * the device */
+ unknownint = 0;
+- for (i = 0; i < gp_descs[d].bNumConfigurations; i++) {
++ for (i = 0; i < descs[d].bNumConfigurations; i++) {
+ struct libusb_config_descriptor *config;
+ int ret;
+
+- ret = libusb_get_config_descriptor (gp_devs[d], i, &config);
++ ret = libusb_get_config_descriptor (devs[d], i, &config);
+ if (ret) {
+ unknownint++;
+ continue;
+@@ -185,22 +196,22 @@
+ /* Redo the same bus/device walk, but now add the ports with usb:x,y notation,
+ * so we can address all USB devices.
+ */
+- for (d = 0; d < gp_nrofdevs; d++) {
++ for (d = 0; d < nrofdevs; d++) {
+ /* Devices which are definitely not cameras. */
+- if ( (gp_descs[d].bDeviceClass == LIBUSB_CLASS_HUB) ||
+- (gp_descs[d].bDeviceClass == LIBUSB_CLASS_HID) ||
+- (gp_descs[d].bDeviceClass == LIBUSB_CLASS_PRINTER) ||
+- (gp_descs[d].bDeviceClass == LIBUSB_CLASS_COMM)
++ if ( (descs[d].bDeviceClass == LIBUSB_CLASS_HUB) ||
++ (descs[d].bDeviceClass == LIBUSB_CLASS_HID) ||
++ (descs[d].bDeviceClass == LIBUSB_CLASS_PRINTER) ||
++ (descs[d].bDeviceClass == LIBUSB_CLASS_COMM)
+ )
+ continue;
+ /* excepts HUBs, usually the interfaces have the classes, not
+ * the device */
+ unknownint = 0;
+- for (i = 0; i < gp_descs[d].bNumConfigurations; i++) {
++ for (i = 0; i < descs[d].bNumConfigurations; i++) {
+ struct libusb_config_descriptor *config;
+ int ret;
+
+- ret = libusb_get_config_descriptor (gp_devs[d], i, &config);
++ ret = libusb_get_config_descriptor (devs[d], i, &config);
+ if (ret) {
+ gp_log (GP_LOG_ERROR, "libusb1", "libusb_get_config_descriptor(%d) returned %d", d, ret);
+ unknownint++;
+@@ -226,8 +237,8 @@
+ info.type = GP_PORT_USB;
+ strcpy (info.name, "Universal Serial Bus");
+ snprintf (info.path,sizeof(info.path), "usb:%03d,%03d",
+- libusb_get_bus_number (gp_devs[d]),
+- libusb_get_device_address (gp_devs[d])
++ libusb_get_bus_number (devs[d]),
++ libusb_get_device_address (devs[d])
+ );
+ CHECK (gp_port_info_list_append (list, info));
+ }
+@@ -239,7 +250,7 @@
+ strcpy (info.path, "usb:");
+ CHECK (gp_port_info_list_append (list, info));
+ }
+- libusb_exit (NULL);
++ libusb_exit (ctx); /* should free all stuff above */
+ return (GP_OK);
+ }
+
+@@ -269,11 +280,10 @@
+ {
+ if (port->pl) {
+ libusb_exit (port->pl->ctx);
++ free (port->pl->descs);
+ free (port->pl);
+ port->pl = NULL;
+ }
+- if (gp_devs) libusb_free_device_list (gp_devs, 1);
+- free (gp_descs);
+ return (GP_OK);
+ }
+
+@@ -744,6 +754,7 @@
+ {
+ char *s;
+ int d, busnr = 0, devnr = 0;
++ GPPortPrivateLibrary *pl = port->pl;
+
+ if (!port)
+ return (GP_ERROR_BAD_PARAMETERS);
+@@ -767,23 +778,23 @@
+ return GP_ERROR_BAD_PARAMETERS;
+ }
+
+- gp_nrofdevs = load_devicelist (port->pl->ctx);
++ pl->nrofdevs = load_devicelist (port->pl);
+
+- for (d = 0; d < gp_nrofdevs; d++) {
++ for (d = 0; d < pl->nrofdevs; d++) {
+ struct libusb_config_descriptor *confdesc;
+ int ret;
+ int config = -1, interface = -1, altsetting = -1;
+
+- if ((gp_descs[d].idVendor != idvendor) ||
+- (gp_descs[d].idProduct != idproduct))
++ if ((pl->descs[d].idVendor != idvendor) ||
++ (pl->descs[d].idProduct != idproduct))
+ continue;
+
+- if (busnr && (busnr != libusb_get_bus_number (gp_devs[d])))
++ if (busnr && (busnr != libusb_get_bus_number (pl->devs[d])))
+ continue;
+- if (devnr && (devnr != libusb_get_device_address (gp_devs[d])))
++ if (devnr && (devnr != libusb_get_device_address (pl->devs[d])))
+ continue;
+
+- port->pl->d = gp_devs[d];
++ port->pl->d = pl->devs[d];
+
+ gp_log (GP_LOG_VERBOSE, "libusb1",
+ "Looking for USB device "
+@@ -791,9 +802,9 @@
+ idvendor, idproduct);
+
+ /* Use the first config, interface and altsetting we find */
+- gp_port_usb_find_first_altsetting(gp_devs[d], &config, &interface, &altsetting);
++ gp_port_usb_find_first_altsetting(pl->devs[d], &config, &interface, &altsetting);
+
+- ret = libusb_get_config_descriptor (gp_devs[d], config, &confdesc);
++ ret = libusb_get_config_descriptor (pl->devs[d], config, &confdesc);
+ if (ret)
+ continue;
+
+@@ -810,11 +821,11 @@
+ port->settings.usb.interface = confdesc->interface[interface].altsetting[altsetting].bInterfaceNumber;
+ port->settings.usb.altsetting = confdesc->interface[interface].altsetting[altsetting].bAlternateSetting;
+
+- port->settings.usb.inep = gp_port_usb_find_ep(gp_devs[d], config, interface, altsetting, LIBUSB_ENDPOINT_IN, LIBUSB_TRANSFER_TYPE_BULK);
+- port->settings.usb.outep = gp_port_usb_find_ep(gp_devs[d], config, interface, altsetting, LIBUSB_ENDPOINT_OUT, LIBUSB_TRANSFER_TYPE_BULK);
+- port->settings.usb.intep = gp_port_usb_find_ep(gp_devs[d], config, interface, altsetting, LIBUSB_ENDPOINT_IN, LIBUSB_TRANSFER_TYPE_INTERRUPT);
++ port->settings.usb.inep = gp_port_usb_find_ep(pl->devs[d], config, interface, altsetting, LIBUSB_ENDPOINT_IN, LIBUSB_TRANSFER_TYPE_BULK);
++ port->settings.usb.outep = gp_port_usb_find_ep(pl->devs[d], config, interface, altsetting, LIBUSB_ENDPOINT_OUT, LIBUSB_TRANSFER_TYPE_BULK);
++ port->settings.usb.intep = gp_port_usb_find_ep(pl->devs[d], config, interface, altsetting, LIBUSB_ENDPOINT_IN, LIBUSB_TRANSFER_TYPE_INTERRUPT);
+
+- port->settings.usb.maxpacketsize = libusb_get_max_packet_size (gp_devs[d], port->settings.usb.inep);
++ port->settings.usb.maxpacketsize = libusb_get_max_packet_size (pl->devs[d], port->settings.usb.inep);
+ gp_log (GP_LOG_VERBOSE, "libusb1",
+ "Detected defaults: config %d, "
+ "interface %d, altsetting %d, "
+@@ -998,6 +1009,8 @@
+ if (class == 666) /* Special hack for MTP devices with MS OS descriptors. */
+ return gp_port_usb_match_mtp_device (dev, configno, interfaceno, altsettingno);
+
++ ret = libusb_get_device_descriptor(dev, &desc);
++
+ if (desc.bDeviceClass == class &&
+ (subclass == -1 ||
+ desc.bDeviceSubClass == subclass) &&
+@@ -1005,7 +1018,6 @@
+ desc.bDeviceProtocol == protocol))
+ return 1;
+
+- ret = libusb_get_device_descriptor(dev, &desc);
+
+ for (i = 0; i < desc.bNumConfigurations; i++) {
+ struct libusb_config_descriptor *config;
+@@ -1045,6 +1057,7 @@
+ {
+ char *s;
+ int d, busnr = 0, devnr = 0;
++ GPPortPrivateLibrary *pl = port->pl;
+
+ if (!port)
+ return (GP_ERROR_BAD_PARAMETERS);
+@@ -1065,14 +1078,14 @@
+ if (!class)
+ return GP_ERROR_BAD_PARAMETERS;
+
+- gp_nrofdevs = load_devicelist (port->pl->ctx);
+- for (d = 0; d < gp_nrofdevs; d++) {
++ pl->nrofdevs = load_devicelist (port->pl);
++ for (d = 0; d < pl->nrofdevs; d++) {
+ struct libusb_config_descriptor *confdesc;
+ int i, ret, config = -1, interface = -1, altsetting = -1;
+
+- if (busnr && (busnr != libusb_get_bus_number (gp_devs[d])))
++ if (busnr && (busnr != libusb_get_bus_number (pl->devs[d])))
+ continue;
+- if (devnr && (devnr != libusb_get_device_address (gp_devs[d])))
++ if (devnr && (devnr != libusb_get_device_address (pl->devs[d])))
+ continue;
+
+ gp_log (GP_LOG_VERBOSE, "gphoto2-port-usb",
+@@ -1080,17 +1093,17 @@
+ "(class 0x%x, subclass, 0x%x, protocol 0x%x)...",
+ class, subclass, protocol);
+
+- ret = gp_port_usb_match_device_by_class(gp_devs[d], class, subclass, protocol, &config, &interface, &altsetting);
++ ret = gp_port_usb_match_device_by_class(pl->devs[d], class, subclass, protocol, &config, &interface, &altsetting);
+ if (!ret)
+ continue;
+
+- port->pl->d = gp_devs[d];
++ port->pl->d = pl->devs[d];
+ gp_log (GP_LOG_VERBOSE, "libusb1",
+ "Found USB class device "
+ "(class 0x%x, subclass, 0x%x, protocol 0x%x)",
+ class, subclass, protocol);
+
+- ret = libusb_get_config_descriptor (gp_devs[d], config, &confdesc);
++ ret = libusb_get_config_descriptor (pl->devs[d], config, &confdesc);
+ if (ret) continue;
+
+ /* Set the defaults */
+@@ -1098,9 +1111,9 @@
+ port->settings.usb.interface = confdesc->interface[interface].altsetting[altsetting].bInterfaceNumber;
+ port->settings.usb.altsetting = confdesc->interface[interface].altsetting[altsetting].bAlternateSetting;
+
+- port->settings.usb.inep = gp_port_usb_find_ep(gp_devs[d], config, interface, altsetting, LIBUSB_ENDPOINT_IN, LIBUSB_TRANSFER_TYPE_BULK);
+- port->settings.usb.outep = gp_port_usb_find_ep(gp_devs[d], config, interface, altsetting, LIBUSB_ENDPOINT_OUT, LIBUSB_TRANSFER_TYPE_BULK);
+- port->settings.usb.intep = gp_port_usb_find_ep(gp_devs[d], config, interface, altsetting, LIBUSB_ENDPOINT_IN, LIBUSB_TRANSFER_TYPE_INTERRUPT);
++ port->settings.usb.inep = gp_port_usb_find_ep(pl->devs[d], config, interface, altsetting, LIBUSB_ENDPOINT_IN, LIBUSB_TRANSFER_TYPE_BULK);
++ port->settings.usb.outep = gp_port_usb_find_ep(pl->devs[d], config, interface, altsetting, LIBUSB_ENDPOINT_OUT, LIBUSB_TRANSFER_TYPE_BULK);
++ port->settings.usb.intep = gp_port_usb_find_ep(pl->devs[d], config, interface, altsetting, LIBUSB_ENDPOINT_IN, LIBUSB_TRANSFER_TYPE_INTERRUPT);
+ port->settings.usb.maxpacketsize = 0;
+ gp_log (GP_LOG_DEBUG, "libusb1", "inep to look for is %02x", port->settings.usb.inep);
+ for (i=0;i<confdesc->interface[interface].altsetting[altsetting].bNumEndpoints;i++) {
+@@ -1117,8 +1130,8 @@
+ port->settings.usb.config,
+ port->settings.usb.interface,
+ port->settings.usb.altsetting,
+- gp_descs[d].idVendor,
+- gp_descs[d].idProduct,
++ pl->descs[d].idVendor,
++ pl->descs[d].idProduct,
+ port->settings.usb.inep,
+ port->settings.usb.outep,
+ port->settings.usb.intep
+Index: libgphoto2_port/usbscsi/linux.c
+===================================================================
+--- libgphoto2_port/usbscsi/linux.c (revision 14002)
++++ libgphoto2_port/usbscsi/linux.c (revision 14116)
+@@ -1,6 +1,6 @@
+ /* SCSI commands to USB Mass storage devices port library for Linux
+ *
+- * Copyright (c) 2010 Hans de Goede <hdegoede@redhat.com>
++ * Copyright (c) 2010-2012 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+@@ -19,6 +19,7 @@
+ #include "config.h"
+ #include <gphoto2/gphoto2-port-library.h>
+
++#include <errno.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+@@ -29,6 +30,7 @@
+ #ifdef HAVE_LIMITS_H
+ # include <limits.h>
+ #endif
++#include <sys/file.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
+ #ifdef HAVE_SYS_PARAM_H
+@@ -40,9 +42,6 @@
+ #ifdef HAVE_SCSI_SG_H
+ # include <scsi/sg.h>
+ #endif
+-#ifdef HAVE_LOCKDEV
+-# include <lockdev.h>
+-#endif
+
+ #include <gphoto2/gphoto2-port-result.h>
+ #include <gphoto2/gphoto2-port-log.h>
+@@ -80,62 +79,37 @@
+ }
+
+ static int
+-gp_port_usbscsi_lock (GPPort *port, const char *path)
++gp_port_usbscsi_lock (GPPort *port)
+ {
+-#ifdef HAVE_LOCKDEV
+- int pid;
+-
+ gp_log (GP_LOG_DEBUG, "gphoto2-port-usbscsi",
+- "Trying to lock '%s'...", path);
++ "Trying to lock '%s'...", port->settings.usbscsi.path);
+
+- pid = dev_lock (path);
+- if (pid) {
+- if (port) {
+- if (pid > 0)
+- gp_port_set_error (port, _("Device '%s' is "
+- "locked by pid %d"), path, pid);
+- else
+- gp_port_set_error (port, _("Device '%s' could "
+- "not be locked (dev_lock returned "
+- "%d)"), path, pid);
++ if (flock(port->pl->fd, LOCK_EX | LOCK_NB) != 0) {
++ switch (errno) {
++ case EWOULDBLOCK:
++ gp_port_set_error (port,
++ _("Device '%s' is locked by another app."),
++ port->settings.usbscsi.path);
++ return GP_ERROR_IO_LOCK;
++ default:
++ gp_port_set_error (port,
++ _("Failed to lock '%s' (%m)."),
++ port->settings.usbscsi.path);
++ return GP_ERROR_IO;
+ }
+- return GP_ERROR_IO_LOCK;
+ }
+-#else
+-# ifdef __GCC__
+-# warning No locking library found.
+-# warning You will run into problems if you use
+-# warning gphoto2 with a usbscsi picframe in
+-# warning combination with Konqueror (KDE) or Nautilus (GNOME).
+-# warning This will *not* concern USB cameras.
+-# endif
+-#endif
+
+ return GP_OK;
+ }
+
+ static int
+-gp_port_usbscsi_unlock (GPPort *port, const char *path)
++gp_port_usbscsi_unlock (GPPort *port)
+ {
+-#ifdef HAVE_LOCKDEV
+- int pid;
+-
+- pid = dev_unlock (path, 0);
+- if (pid) {
+- if (port) {
+- if (pid > 0)
+- gp_port_set_error (port, _("Device '%s' could "
+- "not be unlocked as it is locked by "
+- "pid %d."), path, pid);
+- else
+- gp_port_set_error (port, _("Device '%s' could "
+- "not be unlocked (dev_unlock "
+- "returned %d)"), path, pid);
+- }
+- return GP_ERROR_IO_LOCK;
++ if (flock(port->pl->fd, LOCK_UN) != 0) {
++ gp_port_set_error (port, _("Failed to unlock '%s' (%m)."),
++ port->settings.usbscsi.path);
++ return GP_ERROR_IO;
+ }
+-#endif /* !HAVE_LOCKDEV */
+-
+ return GP_OK;
+ }
+
+@@ -269,34 +243,36 @@
+ const int max_tries = 5;
+ const char *path = port->settings.usbscsi.path;
+
+- result = gp_port_usbscsi_lock (port, path);
+- if (result != GP_OK) {
+- for (i = 0; i < max_tries; i++) {
+- result = gp_port_usbscsi_lock (port, path);
+- if (result == GP_OK)
+- break;
+- gp_log (GP_LOG_DEBUG, "gphoto2-port-usbscsi",
+- "Failed to get a lock, trying again...");
+- sleep (1);
+- }
+- CHECK (result)
+- }
+ port->pl->fd = open (path, O_RDWR);
+ if (port->pl->fd == -1) {
+- gp_port_usbscsi_unlock (port, path);
+ gp_port_set_error (port, _("Failed to open '%s' (%m)."), path);
+ return GP_ERROR_IO;
+ }
+
+- return GP_OK;
++ result = gp_port_usbscsi_lock (port);
++ for (i = 0; i < max_tries && result == GP_ERROR_IO_LOCK; i++) {
++ gp_log (GP_LOG_DEBUG, "gphoto2-port-usbscsi",
++ "Failed to get a lock, trying again...");
++ sleep (1);
++ result = gp_port_usbscsi_lock (port);
++ }
++ if (result != GP_OK) {
++ close (port->pl->fd);
++ port->pl->fd = -1;
++ }
++ return result;
+ }
+
+ static int
+ gp_port_usbscsi_close (GPPort *port)
+ {
++ int result;
++
+ if (!port || port->pl->fd == -1)
+ return GP_OK;
+
++ result = gp_port_usbscsi_unlock (port);
++
+ if (close (port->pl->fd) == -1) {
+ gp_port_set_error (port, _("Could not close "
+ "'%s' (%m)."), port->settings.usbscsi.path);
+@@ -304,10 +280,7 @@
+ }
+ port->pl->fd = -1;
+
+- CHECK (gp_port_usbscsi_unlock (port,
+- port->settings.usbscsi.path))
+-
+- return GP_OK;
++ return result;
+ }
+
+ static int gp_port_usbscsi_send_scsi_cmd (GPPort *port, int to_dev, char *cmd,
+@@ -338,7 +311,7 @@
+ io_hdr.mx_sb_len = sense_size;
+ io_hdr.dxferp = (unsigned char *)data;
+ io_hdr.dxfer_len = data_size;
+- io_hdr.timeout = 500;
++ io_hdr.timeout = 1500;
+
+ if (ioctl (port->pl->fd, SG_IO, &io_hdr) < 0)
+ {
diff --git a/libgphoto2.spec b/libgphoto2.spec
index 3d859bd..c11ccfb 100644
--- a/libgphoto2.spec
+++ b/libgphoto2.spec
@@ -11,15 +11,19 @@ Summary(es.UTF-8): Foto GNU (gphoto) Release 2
Summary(pl.UTF-8): Biblioteki obsługi kamer cyfrowych
Summary(pt_BR.UTF-8): GNU Photo - programa GNU para câmeras digitais
Name: libgphoto2
-Version: 2.4.14
-Release: 2
+%define base_version 2.4.14
+%define snap 14116
+Version: 2.4.14.1
+Release: 0.svn%{snap}
License: LGPL v2+
Group: Libraries
-Source0: http://downloads.sourceforge.net/gphoto/%{name}-%{version}.tar.bz2
+Source0: http://downloads.sourceforge.net/gphoto/%{name}-%{base_version}.tar.bz2
# Source0-md5: c7fc6cafa6343f2457976dbe9f2d9d68
Patch0: %{name}-mode-owner-group.patch
Patch1: %{name}-IXANY.patch
Patch2: %{name}-increase_max_entries.patch
+# svn diff -r 14002:%{snap}
+Patch3: %{name}-svn.patch
URL: http://www.gphoto.org/
BuildRequires: autoconf >= 2.59
BuildRequires: automake >= 1:1.9
@@ -164,12 +168,13 @@ Plik z informacjami o urządzeniach HAL-a do obsługi kamer cyfrowych
w przestrzeni użytkownika.
%prep
-%setup -q
+%setup -q -n %{name}-%{base_version}
%patch0 -p1
%ifarch alpha
%patch1 -p1
%endif
%patch2 -p1
+%patch3 -p0
%{__rm} po/stamp-po libgphoto2_port/po/stamp-po