Compare commits
138 Commits
1.1.0.pl01
...
1.1.8
Author | SHA1 | Date | |
---|---|---|---|
ea08843afb | |||
d13085ec2d | |||
ef65e13508 | |||
dd171ebc29 | |||
dff3e97daa | |||
83e2d20322 | |||
303a2670be | |||
3b96910327 | |||
6c9b5a4419 | |||
cf181bdcd6 | |||
cc65aa9df6 | |||
b4ff95c2e7 | |||
a1158a118b | |||
afe242f920 | |||
854ebd647c | |||
42b6c22dca | |||
a247f7e7e9 | |||
cad8abef74 | |||
a504de4b58 | |||
126e73d19d | |||
ac4bfb128c | |||
8e97da0078 | |||
d6c8792a24 | |||
dcf6f74e5a | |||
39df1cdc4e | |||
3862b8d339 | |||
02255c89be | |||
3c7e723114 | |||
63c04b8c9b | |||
7d1c712c09 | |||
6b821fcd92 | |||
29f202a6fe | |||
2cae912040 | |||
3f7a92cc84 | |||
5faa1c25b0 | |||
f986fe83ff | |||
15192c2bfa | |||
9b042009fb | |||
15c6c539db | |||
824e610824 | |||
dbd2e28366 | |||
6cc3012284 | |||
ff1e0eb54e | |||
cbcae473ad | |||
fb841a7d08 | |||
207a702767 | |||
4c10e60dae | |||
7c1666cdce | |||
da3aba8ef5 | |||
822bdf8b7b | |||
880c95d9a4 | |||
d12589771b | |||
b7ecdb1014 | |||
fdb981db72 | |||
16724f3eef | |||
8cc1fc1ca7 | |||
421870ae51 | |||
006d1a32fb | |||
7ed9f978a8 | |||
b7c07ef18f | |||
1c66174a2e | |||
43b2f73217 | |||
2c282adafb | |||
1d64ff428e | |||
c813de47c2 | |||
d39843a974 | |||
8c25db0148 | |||
46719fbc5c | |||
93b65ac4e5 | |||
3e58712c36 | |||
f6fc14de13 | |||
4bba05f186 | |||
82697b2b8b | |||
ae91e331a7 | |||
df41e7b9ff | |||
49e91d491d | |||
a0a230e38b | |||
e05e813234 | |||
c5718b7a4c | |||
b81585e082 | |||
91e2256ffb | |||
38b30d5e5f | |||
44b0314449 | |||
3a993efb9f | |||
d9e6bde437 | |||
71c9dc9f28 | |||
35e553a808 | |||
fe812ffde2 | |||
a2965e9993 | |||
d073709328 | |||
7e6dadeb02 | |||
fe5efd7b37 | |||
7778536f45 | |||
60dde60ebd | |||
76c4c76722 | |||
2e20a4f888 | |||
62944e3b21 | |||
b0a4b7c15c | |||
ecc8bbc71f | |||
b47a0e6884 | |||
64f7f5d609 | |||
4e287dbfed | |||
13895a6518 | |||
f12ce229ae | |||
58d8f3b3c2 | |||
34c86e88d9 | |||
a2d2ec150b | |||
54325147ee | |||
7620840490 | |||
0894f7773e | |||
706f8b937d | |||
ec9bc5678b | |||
a751af6caa | |||
570346b3a5 | |||
f73698c0cb | |||
c11378f1a0 | |||
a734e868bd | |||
653586b97e | |||
3cec04dbe3 | |||
2d8047afcf | |||
781beb3a27 | |||
79e09728ac | |||
3f7210dfff | |||
c03149241d | |||
2433c1f68e | |||
9eb60cd8fc | |||
15e18501d9 | |||
ed8b303d62 | |||
9fbae8df29 | |||
04005adaf4 | |||
45da5c9934 | |||
64b1ab5b3d | |||
404717f305 | |||
e5ea8f75e6 | |||
eb01c9c6c5 | |||
c1ff7b9812 | |||
d6e90bb71f | |||
ae7f38c15a |
38
ChangeLog
38
ChangeLog
@ -1,6 +1,40 @@
|
|||||||
SVN trunk (to become libburn-1.0.8.pl00.tar.gz)
|
libburn-1.1.8.tar.gz Mon Nov 21 2011
|
||||||
===============================================================================
|
===============================================================================
|
||||||
- no novelties yet
|
* Bug fix: Misinterpreted mode page 2A if block descriptors are present
|
||||||
|
* Enabled recognition of QEMU DVD-ROM 0.12
|
||||||
|
* Avoiding to intermediately close and open drive device file
|
||||||
|
* New API call burn_drive_re_assess()
|
||||||
|
|
||||||
|
libburn-1.1.6.tar.gz Tue Sep 27 2011
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: stdio sizes > 4 TB - 32 kB caused integer rollover
|
||||||
|
* Worked around a collision with Linux udev which lets links vanish
|
||||||
|
|
||||||
|
libburn-1.1.4.tar.gz Sun Aug 07 2011
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Some drives return -150 as NWA of blank CD, rather than 0.
|
||||||
|
libburn forwarded this misleading information to the application.
|
||||||
|
* Bug fix: Some drives returned wrong CD sizes after having burned DVD-R
|
||||||
|
* Bug fix: Empty ROM drive was mistaken to hold an unsuitable disc
|
||||||
|
* Bug fix: Avoiding to load speed descriptor list twice
|
||||||
|
* New API call burn_lookup_device_link()
|
||||||
|
* New API call burn_disc_get_phys_format_info()
|
||||||
|
* New cdrskin option --device_links
|
||||||
|
|
||||||
|
Release 1.1.2 was skipped to get back in sync with libisoburn.
|
||||||
|
|
||||||
|
libburn-1.1.0.pl01.tar.gz Mon Jun 20 2011
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: libburn-1.1.0 compiled only on Linux, FreeBSD, and Solaris
|
||||||
|
|
||||||
|
libburn-1.1.0.tar.gz Sat Jun 18 2011
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: burn_disc_format() on DVD-RW issued wrong block size with type 00h
|
||||||
|
* New API call burn_disc_next_track_is_damaged()
|
||||||
|
* New API call burn_disc_close_damaged()
|
||||||
|
* Dropped suffix .plXY from tarball name
|
||||||
|
|
||||||
|
Release 1.0.8 was skipped to get back in sync with libisofs and libisoburn.
|
||||||
|
|
||||||
libburn-1.0.6.pl00.tar.gz Sat Apr 9 2011
|
libburn-1.0.6.pl00.tar.gz Sat Apr 9 2011
|
||||||
===============================================================================
|
===============================================================================
|
||||||
|
@ -118,9 +118,9 @@ test_structest_CPPFLAGS = -Ilibburn
|
|||||||
test_structest_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
test_structest_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
||||||
test_structest_SOURCES = test/structest.c
|
test_structest_SOURCES = test/structest.c
|
||||||
|
|
||||||
## cdrskin construction site - ts A60816 - B10409
|
## cdrskin construction site - ts A60816 - B10808
|
||||||
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
||||||
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_1_0_7
|
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_1_1_8
|
||||||
|
|
||||||
# cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
# cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
||||||
# ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking
|
# ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking
|
||||||
|
65
README
65
README
@ -11,7 +11,7 @@ Still containing parts of Libburn. By Derek Foreman <derek@signalmarketing.com>
|
|||||||
and Ben Jansens <xor@orodu.net>
|
and Ben Jansens <xor@orodu.net>
|
||||||
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
||||||
|
|
||||||
http://files.libburnia-project.org/releases/libburn-1.0.6.pl00.tar.gz
|
http://files.libburnia-project.org/releases/libburn-1.1.8.tar.gz
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -19,10 +19,10 @@ Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
|||||||
|
|
||||||
From tarball
|
From tarball
|
||||||
|
|
||||||
Obtain libburn-1.0.6.pl00.tar.gz, take it to a directory of your choice and do:
|
Obtain libburn-1.1.8.tar.gz, take it to a directory of your choice and do:
|
||||||
|
|
||||||
tar xzf libburn-1.0.6.pl00.tar.gz
|
tar xzf libburn-1.1.8.tar.gz
|
||||||
cd libburn-1.0.6
|
cd libburn-1.1.8
|
||||||
./configure --prefix=/usr
|
./configure --prefix=/usr
|
||||||
make
|
make
|
||||||
|
|
||||||
@ -92,6 +92,21 @@ Make sure to re-compile all source files after running ./configure
|
|||||||
make install
|
make install
|
||||||
|
|
||||||
|
|
||||||
|
Linux only:
|
||||||
|
|
||||||
|
libburn tries to avoid a collision with udev's drive examination by waiting
|
||||||
|
0.1 seconds before opening the device file for a longer time, after udev
|
||||||
|
might have been alarmed by drive scanning activities.
|
||||||
|
The waiting time can be set at ./configure time with microsecond granularity.
|
||||||
|
E.g. 2 seconds:
|
||||||
|
CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=2000000"
|
||||||
|
./configure ...options...
|
||||||
|
Waiting can be disabled by zero waiting time:
|
||||||
|
CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=0"
|
||||||
|
Alternatively, libburn can try to be nice by opening the device file,
|
||||||
|
closing it immediately, waiting, and only then opening it for real:
|
||||||
|
CFLAGS="$CFLAGS -DLibburn_udev_extra_open_cyclE -DLibburn_udev_wait_useC=500000"
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
An important part of the project, libisofs, is hosted in a bzr repository at
|
An important part of the project, libisofs, is hosted in a bzr repository at
|
||||||
@ -110,7 +125,7 @@ See README files there.
|
|||||||
|
|
||||||
libburnia-project.org is an open-source software project for reading, mastering
|
libburnia-project.org is an open-source software project for reading, mastering
|
||||||
and writing optical discs.
|
and writing optical discs.
|
||||||
For now this means CD media, all DVD media except DVD-R DL, all BD media.
|
For now this means CD media, all DVD media, all BD media.
|
||||||
|
|
||||||
The project comprises of several more or less interdependent parts which
|
The project comprises of several more or less interdependent parts which
|
||||||
together strive to be a usable foundation for application development.
|
together strive to be a usable foundation for application development.
|
||||||
@ -180,7 +195,8 @@ The project components (list subject to growth, hopefully):
|
|||||||
sparse emulation of cdrecord and a more laborate one of mkisofs.
|
sparse emulation of cdrecord and a more laborate one of mkisofs.
|
||||||
All features of xorriso are also available via a C language API
|
All features of xorriso are also available via a C language API
|
||||||
of libisoburn.
|
of libisoburn.
|
||||||
See xorriso/README for more.
|
A static compilation of xorriso and the libraries is dedicated
|
||||||
|
to the GNU Operating System. See xorriso/README_gnu_xorriso .
|
||||||
|
|
||||||
- "test" is a collection of application gestures and examples given by the
|
- "test" is a collection of application gestures and examples given by the
|
||||||
authors of the library features. The burn API example of libburn
|
authors of the library features. The burn API example of libburn
|
||||||
@ -613,6 +629,43 @@ Project history as far as known to me:
|
|||||||
up to 103 characters. xorriso fixes two bugs and makes use of the library
|
up to 103 characters. xorriso fixes two bugs and makes use of the library
|
||||||
improvements.
|
improvements.
|
||||||
|
|
||||||
|
- Thu Apr 14 2011 release libisoburn-1.0.8:
|
||||||
|
A bug in the mkisofs emulation of xorriso could cause options to be ignored.
|
||||||
|
The problem was freshly introduced with libisoburn-1.0.6.
|
||||||
|
|
||||||
|
- Fri May 13 2011 release libisofs-1.0.8:
|
||||||
|
Fixes a few rarely occurring bugs that have been found during the last month.
|
||||||
|
|
||||||
|
- Sat Jun 18 2011 release 1.1.0:
|
||||||
|
The consumption of stack memory was reduced. Statical program analysis found
|
||||||
|
some rarely occuring memory leaks. Several small bugs were fixed.
|
||||||
|
The suffix .plXY was dropped from tarball names of libburn and libisoburn.
|
||||||
|
|
||||||
|
- Mon Jun 20 2011 patch release libburn-1.1.0.pl01:
|
||||||
|
libburn-1.1.0 compiled only on Linux, FreeBSD, and Solaris, but not on
|
||||||
|
other X/Open compliant systems.
|
||||||
|
|
||||||
|
- Fri Jul 08 2011 release libisofs-1.1.2 and libisoburn-1.1.2:
|
||||||
|
A severe regression was fixed in libisoburn and xorriso, which was introduced
|
||||||
|
with version 1.0.6. It caused ISO 9660 images to be unreadable if they were
|
||||||
|
written to a write-only random-access file. E.g. by: xorrisofs ... >image.iso
|
||||||
|
|
||||||
|
- Mon Aug 08 2011 release 1.1.4:
|
||||||
|
Several bugs were fixed in libburn. The most severe of them prevented xorriso
|
||||||
|
on some drives from burning mountable ISO 9660 images to CD media.
|
||||||
|
New means to list drives by their udev symbolic links help to deal with
|
||||||
|
the non-persistent drive addresses on modern GNU/Linux.
|
||||||
|
|
||||||
|
- Tue Sep 27 2011 release 1.1.6:
|
||||||
|
libisoburn now comes with a test suite. See releng/README. Bugs were fixed
|
||||||
|
in several rarely used features. Processing of ACL and extattr was enabled
|
||||||
|
on FreeBSD. Workarounds try to cope with vanishing udev links on GNU/Linux.
|
||||||
|
|
||||||
|
- Mon Nov 21 2011 release libburn-1.1.8 and libisoburn-1.1.8:
|
||||||
|
libburn avoids to close and open drive device files while operating on them.
|
||||||
|
xorriso emulation mode xorrecord now has an own manual. libburn and xorriso
|
||||||
|
were prepared to operate on qemu virtio-blk-pci devices.
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
cdrskin. By Thomas Schmitt <scdbackup@gmx.net>
|
cdrskin. By Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Integrated sub project of libburnia-project.org but also published via:
|
Integrated sub project of libburnia-project.org but also published via:
|
||||||
http://scdbackup.sourceforge.net/cdrskin_eng.html
|
http://scdbackup.sourceforge.net/cdrskin_eng.html
|
||||||
http://scdbackup.sourceforge.net/cdrskin-1.0.7.tar.gz
|
http://scdbackup.sourceforge.net/cdrskin-1.1.8.tar.gz
|
||||||
|
|
||||||
Copyright (C) 2006-2011 Thomas Schmitt, provided under GPL version 2 or later.
|
Copyright (C) 2006-2011 Thomas Schmitt, provided under GPL version 2 or later.
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
@ -26,10 +26,10 @@ By using this software you agree to the disclaimer at the end of this text
|
|||||||
|
|
||||||
Compilation, First Glimpse, Installation
|
Compilation, First Glimpse, Installation
|
||||||
|
|
||||||
Obtain cdrskin-1.0.7.tar.gz, take it to a directory of your choice and do:
|
Obtain cdrskin-1.1.8.tar.gz, take it to a directory of your choice and do:
|
||||||
|
|
||||||
tar xzf cdrskin-1.0.7.tar.gz
|
tar xzf cdrskin-1.1.8.tar.gz
|
||||||
cd cdrskin-1.0.7
|
cd cdrskin-1.1.8
|
||||||
|
|
||||||
Within that directory execute:
|
Within that directory execute:
|
||||||
|
|
||||||
@ -438,6 +438,22 @@ It will not read startup files, will abort on option dev_translation= ,
|
|||||||
will not have a fifo buffer, and will not be able to put out help texts or
|
will not have a fifo buffer, and will not be able to put out help texts or
|
||||||
debugging messages.
|
debugging messages.
|
||||||
|
|
||||||
|
|
||||||
|
Linux only:
|
||||||
|
|
||||||
|
libburn tries to avoid a collision with udev's drive examination by waiting
|
||||||
|
0.1 seconds before opening the device file for a longer time, after udev
|
||||||
|
might have been alarmed by drive scanning activities.
|
||||||
|
The waiting time can be set at ./configure time with microsecond granularity.
|
||||||
|
E.g. 2 seconds:
|
||||||
|
CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=2000000"
|
||||||
|
./configure ...options...
|
||||||
|
Waiting can be disabled by zero waiting time:
|
||||||
|
CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=0"
|
||||||
|
Alternatively, libburn can try to be nice by opening the device file,
|
||||||
|
closing it immediately, waiting, and only then opening it for real:
|
||||||
|
CFLAGS="$CFLAGS -DLibburn_udev_extra_open_cyclE -DLibburn_udev_wait_useC=500000"
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
System Dependend Drive Permission Examples
|
System Dependend Drive Permission Examples
|
||||||
@ -560,7 +576,7 @@ contributions in a due way.
|
|||||||
Based on and sub project of:
|
Based on and sub project of:
|
||||||
libburnia-project.org
|
libburnia-project.org
|
||||||
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Copyright (C) 2006-2010 Mario Danic, Thomas Schmitt
|
Copyright (C) 2006-2011 Mario Danic, Thomas Schmitt
|
||||||
|
|
||||||
libburnia-project.org is inspired by and in other components still containing
|
libburnia-project.org is inspired by and in other components still containing
|
||||||
parts of
|
parts of
|
||||||
|
@ -38,8 +38,9 @@ original="./libburn_svn_release.tgz"
|
|||||||
# My changes are in $changes , mainly in $changes/cdrskin
|
# My changes are in $changes , mainly in $changes/cdrskin
|
||||||
changes="./libburn-release"
|
changes="./libburn-release"
|
||||||
|
|
||||||
skin_release="1.0.6"
|
skin_release="1.1.8"
|
||||||
patch_level=".pl00"
|
patch_level=""
|
||||||
|
# patch_level=".pl00"
|
||||||
skin_rev="$skin_release""$patch_level"
|
skin_rev="$skin_release""$patch_level"
|
||||||
|
|
||||||
# The result directory and the name of the result tarballs
|
# The result directory and the name of the result tarballs
|
@ -38,7 +38,7 @@ original="./libburn_svn.tgz"
|
|||||||
# My changes are in $changes , mainly in $changes/cdrskin
|
# My changes are in $changes , mainly in $changes/cdrskin
|
||||||
changes="./libburn-develop"
|
changes="./libburn-develop"
|
||||||
|
|
||||||
skin_release="1.0.7"
|
skin_release="1.1.9"
|
||||||
patch_level=""
|
patch_level=""
|
||||||
skin_rev="$skin_release""$patch_level"
|
skin_rev="$skin_release""$patch_level"
|
||||||
|
|
@ -634,7 +634,7 @@ return: <0 = error , 0 = idle , 1 = did some work
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
double buffer_space;
|
double buffer_space;
|
||||||
int can_read,can_write= 0,ret,did_work= 0,idx,sod,eop_is_near,eop_idx;
|
int can_read,can_write= 0,ret,did_work= 0,idx,sod, eop_idx;
|
||||||
|
|
||||||
buffer_space= Cdrfifo_tell_buffer_space(o,0);
|
buffer_space= Cdrfifo_tell_buffer_space(o,0);
|
||||||
if(o->dest_fd>=0) if(FD_ISSET((o->dest_fd),wts)) {
|
if(o->dest_fd>=0) if(FD_ISSET((o->dest_fd),wts)) {
|
||||||
@ -644,7 +644,7 @@ return: <0 = error , 0 = idle , 1 = did some work
|
|||||||
if(o->read_idx+can_write > o->buffer_size)
|
if(o->read_idx+can_write > o->buffer_size)
|
||||||
can_write= o->buffer_size - o->read_idx;
|
can_write= o->buffer_size - o->read_idx;
|
||||||
if(o->follow_up_fd_idx>=0) {
|
if(o->follow_up_fd_idx>=0) {
|
||||||
eop_is_near= Cdrfifo_eop_adjust(o,&can_write,&eop_idx,0);
|
Cdrfifo_eop_adjust(o,&can_write,&eop_idx,0);
|
||||||
if(can_write<=0)
|
if(can_write<=0)
|
||||||
goto after_write;
|
goto after_write;
|
||||||
}
|
}
|
||||||
@ -1039,9 +1039,9 @@ int Test_mixed_bs(char **paths, int path_count,
|
|||||||
bit0= debugging verbousity
|
bit0= debugging verbousity
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
int fd_in[100],fd_out[100],ret,pipe_fds[100][2],real_out[100];
|
int fd_in[100],fd_out[100],ret,pipe_fds[100][2];
|
||||||
int i,iv,stall_counter= 0,cycle_counter= 0.0;
|
int i,iv,stall_counter= 0,cycle_counter= 0.0;
|
||||||
char buf[10240], target_path[80];
|
char target_path[80];
|
||||||
double in_counter, out_counter, prev_in= -1.0, prev_out= -1.0;
|
double in_counter, out_counter, prev_in= -1.0, prev_out= -1.0;
|
||||||
struct CdrfifO *ff_in= NULL, *ff_out= NULL;
|
struct CdrfifO *ff_in= NULL, *ff_out= NULL;
|
||||||
|
|
||||||
@ -1109,9 +1109,8 @@ int Test_multi(int fs_size, double speed_limit, double interval, int flag)
|
|||||||
bit0= debugging verbousity
|
bit0= debugging verbousity
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
int fd_in[4],fd_out[4],ret,pipe_fds[4][2],real_out[4],pipe_idx;
|
int fd_in[4],fd_out[4],ret,pipe_fds[4][2];
|
||||||
int i,iv;
|
int i,iv;
|
||||||
char buf[10240];
|
|
||||||
struct CdrfifO *ff1= NULL,*ff2= NULL;
|
struct CdrfifO *ff1= NULL,*ff2= NULL;
|
||||||
|
|
||||||
/* open four pairs of fds */
|
/* open four pairs of fds */
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
.\" First parameter, NAME, should be all caps
|
.\" First parameter, NAME, should be all caps
|
||||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||||
.\" other parameters are allowed: see man(7), man(1)
|
.\" other parameters are allowed: see man(7), man(1)
|
||||||
.TH CDRSKIN 1 "Jan 09, 2011"
|
.TH CDRSKIN 1 "Jul 28, 2011"
|
||||||
.\" Please adjust this date whenever revising the manpage.
|
.\" Please adjust this date whenever revising the manpage.
|
||||||
.\"
|
.\"
|
||||||
.\" Some roff macros, for reference:
|
.\" Some roff macros, for reference:
|
||||||
@ -256,7 +256,7 @@ that it has to be formatted again. If in doubt, just give it a try.
|
|||||||
.br
|
.br
|
||||||
The drives, CD, DVD, or BD burners, are accessed via addresses which
|
The drives, CD, DVD, or BD burners, are accessed via addresses which
|
||||||
are specific to libburn and the operating system. Those addresses get listed
|
are specific to libburn and the operating system. Those addresses get listed
|
||||||
by a run of \fBcdrskin --devices\fP.
|
by a run of \fBcdrskin --devices\fP or \fBcdrskin --device_links\fP.
|
||||||
.br
|
.br
|
||||||
On Linux, they are device files which traditionally do not offer
|
On Linux, they are device files which traditionally do not offer
|
||||||
w-permissions for normal users. Because libburn needs rw-permission,
|
w-permissions for normal users. Because libburn needs rw-permission,
|
||||||
@ -512,7 +512,7 @@ cdrskin will not write CD-ROM XA but rather strip the header bytes and write as
|
|||||||
.TP
|
.TP
|
||||||
.BI dev= target
|
.BI dev= target
|
||||||
Set the address of the drive to use. Valid are at least the
|
Set the address of the drive to use. Valid are at least the
|
||||||
addresses listed with option --devices,
|
addresses listed with options --devices or --device_links,
|
||||||
X,Y,Z addresses listed with option -scanbus,
|
X,Y,Z addresses listed with option -scanbus,
|
||||||
ATA:X,Y,Z addresses listed with options dev=ATA -scanbus,
|
ATA:X,Y,Z addresses listed with options dev=ATA -scanbus,
|
||||||
and volatile libburn drive numbers (numbering starts at "0").
|
and volatile libburn drive numbers (numbering starts at "0").
|
||||||
@ -881,6 +881,17 @@ Number dev='Devicefile' rw-Permissions : 'Vendor' 'Model'
|
|||||||
Number and Devicefile can both be used with option dev=, but number is
|
Number and Devicefile can both be used with option dev=, but number is
|
||||||
volatile (numbering changes if drives become busy).
|
volatile (numbering changes if drives become busy).
|
||||||
.TP
|
.TP
|
||||||
|
.BI \--device_links
|
||||||
|
Like --devices, but presenting the drives with addresses of symbolic links
|
||||||
|
which point to the actual device files.
|
||||||
|
.br
|
||||||
|
Modern GNU/Linux systems may shuffle drive addresses from boot to boot.
|
||||||
|
The udev daemon is supposed to create links which always point to the
|
||||||
|
same drive, regardless of its system address.
|
||||||
|
Option --device_links shows the addresses of such links if they begin
|
||||||
|
by "/dev/dvd" or "/dev/cd".
|
||||||
|
Precedence is: "dvdrw", "cdrw", "dvd", "cdrom", "cd".
|
||||||
|
.TP
|
||||||
.BI direct_write_amount= size
|
.BI direct_write_amount= size
|
||||||
Do not write a session with tracks but rather make an appropriate number of
|
Do not write a session with tracks but rather make an appropriate number of
|
||||||
direct write operations with no preparations. Flushing the drive buffer will
|
direct write operations with no preparations. Flushing the drive buffer will
|
||||||
@ -1136,7 +1147,7 @@ Wether this leads to senseful behavior depends on operating system and kernel.
|
|||||||
.TP
|
.TP
|
||||||
.BI drive_scsi_dev_family= sr | scd | sg
|
.BI drive_scsi_dev_family= sr | scd | sg
|
||||||
Linux specific: Select a SCSI device file family to be scanned for by
|
Linux specific: Select a SCSI device file family to be scanned for by
|
||||||
options --devices and -scanbus.
|
options --devices, --device_links and -scanbus.
|
||||||
Normally this is /dev/sgN on kernel versions < 2.6 and /dev/srN
|
Normally this is /dev/sgN on kernel versions < 2.6 and /dev/srN
|
||||||
on kernels >= 2.6 . This option allows to explicitly override that default
|
on kernels >= 2.6 . This option allows to explicitly override that default
|
||||||
in order to meet other programs at a common device file for each drive.
|
in order to meet other programs at a common device file for each drive.
|
||||||
@ -1242,7 +1253,7 @@ cdrskin -scanbus
|
|||||||
.br
|
.br
|
||||||
cdrskin dev=ATA -scanbus
|
cdrskin dev=ATA -scanbus
|
||||||
.br
|
.br
|
||||||
cdrskin --devices
|
cdrskin --device_links
|
||||||
.SS
|
.SS
|
||||||
.B Get info about a particular drive or loaded media:
|
.B Get info about a particular drive or loaded media:
|
||||||
.br
|
.br
|
||||||
|
1391
cdrskin/cdrskin.c
1391
cdrskin/cdrskin.c
File diff suppressed because it is too large
Load Diff
@ -65,7 +65,7 @@ connected via SCSI, PATA (aka IDE, ATA), USB, or SATA.
|
|||||||
GPL software included:<BR>
|
GPL software included:<BR>
|
||||||
</H2>
|
</H2>
|
||||||
<DL>
|
<DL>
|
||||||
<DT>libburn-1.0.6</DT>
|
<DT>libburn-1.1.8</DT>
|
||||||
<DD>(founded by Derek Foreman and Ben Jansens,
|
<DD>(founded by Derek Foreman and Ben Jansens,
|
||||||
developed and maintained since August 2006 by
|
developed and maintained since August 2006 by
|
||||||
Thomas Schmitt from team of libburnia-project.org)
|
Thomas Schmitt from team of libburnia-project.org)
|
||||||
@ -200,9 +200,16 @@ Standalone ISO 9660 multi-session CD/DVD/BD tool
|
|||||||
<P>
|
<P>
|
||||||
<DL>
|
<DL>
|
||||||
<DT>Download as source code (see README):</DT>
|
<DT>Download as source code (see README):</DT>
|
||||||
<DD><A HREF="cdrskin-1.0.6.pl00.tar.gz">cdrskin-1.0.6.pl00.tar.gz</A>
|
<DD><A HREF="cdrskin-1.1.8.tar.gz">cdrskin-1.1.8.tar.gz</A>
|
||||||
(870 KB).
|
(870 KB).
|
||||||
</DD>
|
</DD>
|
||||||
|
<DD><A HREF="cdrskin-1.1.8.tar.gz.sig">cdrskin-1.1.8.tar.gz.sig</A></DD>
|
||||||
|
<DD>
|
||||||
|
(detached GPG signature for verification by
|
||||||
|
<KBD>gpg --verify cdrskin-1.1.8.tar.gz.sig cdrskin-1.1.8.tar.gz</KBD>
|
||||||
|
<BR>
|
||||||
|
after <KBD>gpg --keyserver keys.gnupg.net --recv-keys ABC0A854</KBD>).
|
||||||
|
</DD>
|
||||||
<DD>
|
<DD>
|
||||||
The cdrskin tarballs are source code identical with libburn releases
|
The cdrskin tarballs are source code identical with libburn releases
|
||||||
of the same version number.
|
of the same version number.
|
||||||
@ -250,18 +257,24 @@ cdrskin_0.4.2.pl00-x86-suse9_0-static.tar.gz</A>, (310 KB), -static compiled,
|
|||||||
<HR>
|
<HR>
|
||||||
|
|
||||||
<P>
|
<P>
|
||||||
Enhancements towards previous stable version cdrskin-1.0.4.pl00:
|
Enhancements towards previous stable version cdrskin-1.1.6:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>Burning DVD-R DAO with 2 kB size granularity rather than 32 kB</LI>
|
<LI>
|
||||||
|
Avoiding to intermediately close and open drive device file
|
||||||
|
</LI>
|
||||||
|
<LI>
|
||||||
|
Enabled recognition of QEMU DVD-ROM 0.12
|
||||||
</LI>
|
</LI>
|
||||||
<!--
|
<!--
|
||||||
<LI>none</LI>
|
<LI>none</LI>
|
||||||
-->
|
-->
|
||||||
</UL>
|
</UL>
|
||||||
|
|
||||||
Bug fixes towards cdrskin-1.0.4.pl00:
|
Bug fixes towards cdrskin-1.1.6:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>none</LI>
|
<LI>
|
||||||
|
Misinterpreted mode page 2A if block descriptors are present
|
||||||
|
</LI>
|
||||||
<!--
|
<!--
|
||||||
<LI>none</LI>
|
<LI>none</LI>
|
||||||
-->
|
-->
|
||||||
@ -271,8 +284,8 @@ Bug fixes towards cdrskin-1.0.4.pl00:
|
|||||||
|
|
||||||
<P>
|
<P>
|
||||||
<DL>
|
<DL>
|
||||||
<DT><H3>Development snapshot, version 1.0.7 :</H3></DT>
|
<DT><H3>Development snapshot, version 1.1.9 :</H3></DT>
|
||||||
<DD>Enhancements towards current stable version 1.0.6.pl00:
|
<DD>Enhancements towards current stable version 1.1.8:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>none yet</LI>
|
<LI>none yet</LI>
|
||||||
<!--
|
<!--
|
||||||
@ -282,7 +295,7 @@ Bug fixes towards cdrskin-1.0.4.pl00:
|
|||||||
</UL>
|
</UL>
|
||||||
</DD>
|
</DD>
|
||||||
|
|
||||||
<DD>Bug fixes towards cdrskin-1.0.6.pl00:
|
<DD>Bug fixes towards cdrskin-1.1.8:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>none yet</LI>
|
<LI>none yet</LI>
|
||||||
<!--
|
<!--
|
||||||
@ -292,10 +305,10 @@ Bug fixes towards cdrskin-1.0.4.pl00:
|
|||||||
</DD>
|
</DD>
|
||||||
|
|
||||||
<DD> </DD>
|
<DD> </DD>
|
||||||
<DD><A HREF="README_cdrskin_devel">README 1.0.7</A>
|
<DD><A HREF="README_cdrskin_devel">README 1.1.9</A>
|
||||||
<DD><A HREF="cdrskin__help_devel">cdrskin-1.0.7 --help</A></DD>
|
<DD><A HREF="cdrskin__help_devel">cdrskin-1.1.9 --help</A></DD>
|
||||||
<DD><A HREF="cdrskin_help_devel">cdrskin-1.0.7 -help</A></DD>
|
<DD><A HREF="cdrskin_help_devel">cdrskin-1.1.9 -help</A></DD>
|
||||||
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 1.0.7)</A></DD>
|
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 1.1.9)</A></DD>
|
||||||
<DD> </DD>
|
<DD> </DD>
|
||||||
<DT>Maintainers of cdrskin unstable packages please use SVN of
|
<DT>Maintainers of cdrskin unstable packages please use SVN of
|
||||||
<A HREF="http://libburnia-project.org"> libburnia-project.org</A></DT>
|
<A HREF="http://libburnia-project.org"> libburnia-project.org</A></DT>
|
||||||
@ -315,7 +328,7 @@ admins with full system souvereignty.</DT>
|
|||||||
<A HREF="README_cdrskin_devel">upcoming README</A> ):
|
<A HREF="README_cdrskin_devel">upcoming README</A> ):
|
||||||
</DD>
|
</DD>
|
||||||
<DD>
|
<DD>
|
||||||
<A HREF="cdrskin-1.0.7.tar.gz">cdrskin-1.0.7.tar.gz</A>
|
<A HREF="cdrskin-1.1.9.tar.gz">cdrskin-1.1.9.tar.gz</A>
|
||||||
(870 KB).
|
(870 KB).
|
||||||
</DD>
|
</DD>
|
||||||
|
|
||||||
@ -465,10 +478,11 @@ First of all: this relationship is single sided, as cdrskin has to be aware of
|
|||||||
cdrecord but not vice versa.
|
cdrecord but not vice versa.
|
||||||
<BR>
|
<BR>
|
||||||
<BR>
|
<BR>
|
||||||
I am a long time user of cdrecord and it works fine for me.
|
I was a long time user of cdrecord and it worked fine for me.
|
||||||
Especially i do appreciate its write mode -tao which allows to pipe arbitrary
|
Especially i do appreciate its write mode -tao which allows to pipe arbitrary
|
||||||
data on CD and CD-RW via stdin. cdrecord is reliable, versatile and well
|
data on CD and CD-RW via stdin. cdrecord is reliable, versatile and well
|
||||||
maintained. So for me - there would be no problem with it.
|
maintained. So for me - there would be no problem with using it for
|
||||||
|
burning CDs.
|
||||||
<BR>
|
<BR>
|
||||||
But the author of cdrecord and the Linux kernel people foster a very hostile
|
But the author of cdrecord and the Linux kernel people foster a very hostile
|
||||||
relationship. Ok, that's their business, not mine (or ours if you are with me).
|
relationship. Ok, that's their business, not mine (or ours if you are with me).
|
||||||
|
@ -1 +1 @@
|
|||||||
#define Cdrskin_timestamP "2011.06.14.152832"
|
#define Cdrskin_timestamP "2011.11.20.100001"
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -200,9 +200,10 @@ main()
|
|||||||
Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0);
|
Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0);
|
||||||
|
|
||||||
if(1) { /* change to 0 in order to wait for external signals */
|
if(1) { /* change to 0 in order to wait for external signals */
|
||||||
char *cpt= NULL,c;
|
char *cpt= NULL, c= ' ';
|
||||||
printf("Intentionally provoking SIGSEGV ...\n");
|
printf("Intentionally provoking SIGSEGV ...\n");
|
||||||
c= *cpt;
|
c= *cpt;
|
||||||
|
printf("Strange: The system ignored a SIGSEGV: c= %u\n", (unsigned int) c);
|
||||||
} else {
|
} else {
|
||||||
printf("killme: %d\n",getpid());
|
printf("killme: %d\n",getpid());
|
||||||
sleep(3600);
|
sleep(3600);
|
||||||
|
@ -8,7 +8,7 @@ debug_opts="-O2"
|
|||||||
def_opts=
|
def_opts=
|
||||||
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
|
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
|
||||||
fifo_opts=""
|
fifo_opts=""
|
||||||
libvers="-DCdrskin_libburn_1_0_7"
|
libvers="-DCdrskin_libburn_1_1_8"
|
||||||
|
|
||||||
# To be used if Makefile.am uses libburn_libburn_la_CFLAGS
|
# To be used if Makefile.am uses libburn_libburn_la_CFLAGS
|
||||||
# burn="libburn/libburn_libburn_la-"
|
# burn="libburn/libburn_libburn_la-"
|
||||||
@ -19,7 +19,7 @@ libdax_msgs_o="$burn"libdax_msgs.o
|
|||||||
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
||||||
do_strip=0
|
do_strip=0
|
||||||
static_opts=
|
static_opts=
|
||||||
warn_opts="-Wall"
|
warn_opts="-Wall -Wextra -Wno-unused-parameter"
|
||||||
libcdio=
|
libcdio=
|
||||||
fifo_source="cdrskin/cdrfifo.c"
|
fifo_source="cdrskin/cdrfifo.c"
|
||||||
compile_cdrskin=1
|
compile_cdrskin=1
|
||||||
@ -41,31 +41,21 @@ do
|
|||||||
elif test "$i" = "-compile_dewav"
|
elif test "$i" = "-compile_dewav"
|
||||||
then
|
then
|
||||||
compile_dewav=1
|
compile_dewav=1
|
||||||
elif test "$i" = "-cvs_A60220"
|
elif test "$i" = "-libburn_1_1_8"
|
||||||
then
|
then
|
||||||
libvers="-DCdrskin_libburn_cvs_A60220_tS"
|
libvers="-DCdrskin_libburn_1_1_8"
|
||||||
libdax_audioxtr_o=
|
|
||||||
libdax_msgs_o="$burn"message.o
|
|
||||||
cleanup_src_or_obj="-DCleanup_has_no_libburn_os_H cdrskin/cleanup.c"
|
|
||||||
elif test "$i" = "-libburn_1_0_6"
|
|
||||||
then
|
|
||||||
libvers="-DCdrskin_libburn_1_0_6"
|
|
||||||
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
||||||
libdax_msgs_o="$burn"libdax_msgs.o
|
libdax_msgs_o="$burn"libdax_msgs.o
|
||||||
cleanup_src_or_obj="$burn"cleanup.o
|
cleanup_src_or_obj="$burn"cleanup.o
|
||||||
elif test "$i" = "-libburn_svn"
|
elif test "$i" = "-libburn_svn"
|
||||||
then
|
then
|
||||||
libvers="-DCdrskin_libburn_1_0_7"
|
libvers="-DCdrskin_libburn_1_1_9"
|
||||||
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
||||||
libdax_msgs_o="$burn"libdax_msgs.o
|
libdax_msgs_o="$burn"libdax_msgs.o
|
||||||
cleanup_src_or_obj="$burn"cleanup.o
|
cleanup_src_or_obj="$burn"cleanup.o
|
||||||
elif test "$i" = "-newapi" -o "$i" = "-experimental"
|
elif test "$i" = "-newapi" -o "$i" = "-experimental"
|
||||||
then
|
then
|
||||||
def_opts="$def_opts -DCdrskin_new_api_tesT"
|
def_opts="$def_opts -DCdrskin_new_api_tesT"
|
||||||
elif test "$i" = "-oldfashioned"
|
|
||||||
then
|
|
||||||
def_opts="$def_opts -DCdrskin_oldfashioned_api_usE"
|
|
||||||
cleanup_src_or_obj="-DCleanup_has_no_libburn_os_H cdrskin/cleanup.c"
|
|
||||||
elif test "$i" = "-no_largefile"
|
elif test "$i" = "-no_largefile"
|
||||||
then
|
then
|
||||||
largefile_opts=
|
largefile_opts=
|
||||||
@ -109,7 +99,7 @@ do
|
|||||||
echo "Options:"
|
echo "Options:"
|
||||||
echo " -compile_cdrfifo compile program cdrskin/cdrfifo."
|
echo " -compile_cdrfifo compile program cdrskin/cdrfifo."
|
||||||
echo " -compile_dewav compile program test/dewav without libburn."
|
echo " -compile_dewav compile program test/dewav without libburn."
|
||||||
echo " -libburn_1_0_6 set macro to match libburn-1.0.6"
|
echo " -libburn_1_1_8 set macro to match libburn-1.1.8"
|
||||||
echo " -libburn_svn set macro to match current libburn-SVN."
|
echo " -libburn_svn set macro to match current libburn-SVN."
|
||||||
echo " -dvd_obs_64k 64 KB default size for DVD/BD writing."
|
echo " -dvd_obs_64k 64 KB default size for DVD/BD writing."
|
||||||
echo " -use_libcdio link with -lcdio because libburn uses it."
|
echo " -use_libcdio link with -lcdio because libburn uses it."
|
||||||
@ -117,7 +107,6 @@ do
|
|||||||
echo " -use_no_libburn_fifo use cdrfifo even for single track non-CD"
|
echo " -use_no_libburn_fifo use cdrfifo even for single track non-CD"
|
||||||
echo " -use_no_cdrfifo always use fifo of libburn and never cdrfifo"
|
echo " -use_no_cdrfifo always use fifo of libburn and never cdrfifo"
|
||||||
echo " -experimental use newly introduced libburn features."
|
echo " -experimental use newly introduced libburn features."
|
||||||
echo " -oldfashioned use pre-0.2.2 libburn features only."
|
|
||||||
echo " -do_diet produce capability reduced lean version."
|
echo " -do_diet produce capability reduced lean version."
|
||||||
echo " -do_strip apply program strip to compiled programs."
|
echo " -do_strip apply program strip to compiled programs."
|
||||||
echo " -g produce debuggable programm."
|
echo " -g produce debuggable programm."
|
||||||
|
@ -59,6 +59,7 @@ then
|
|||||||
-e 's/<\/body>/<BR><HR><FONT SIZE=-1><CENTER>(HTML generated from '"$manpage"'.1 on '"$(date)"' by '$(basename "$0")' )<\/CENTER><\/FONT><\/body>/' \
|
-e 's/<\/body>/<BR><HR><FONT SIZE=-1><CENTER>(HTML generated from '"$manpage"'.1 on '"$(date)"' by '$(basename "$0")' )<\/CENTER><\/FONT><\/body>/' \
|
||||||
-e 's/See section FILES/See section <A HREF="#FILES">FILES<\/A>/' \
|
-e 's/See section FILES/See section <A HREF="#FILES">FILES<\/A>/' \
|
||||||
-e 's/See section EXAMPLES/See section <A HREF="#EXAMPLES">EXAMPLES<\/A>/' \
|
-e 's/See section EXAMPLES/See section <A HREF="#EXAMPLES">EXAMPLES<\/A>/' \
|
||||||
|
-e 's/−/-/g' \
|
||||||
<"$2" >"$htmlpage"
|
<"$2" >"$htmlpage"
|
||||||
|
|
||||||
set +x
|
set +x
|
||||||
|
22
configure.ac
22
configure.ac
@ -1,4 +1,4 @@
|
|||||||
AC_INIT([libburn], [1.0.7], [http://libburnia-project.org])
|
AC_INIT([libburn], [1.1.8], [http://libburnia-project.org])
|
||||||
AC_PREREQ([2.50])
|
AC_PREREQ([2.50])
|
||||||
dnl AC_CONFIG_HEADER([config.h])
|
dnl AC_CONFIG_HEADER([config.h])
|
||||||
|
|
||||||
@ -10,7 +10,7 @@ LIBBURNIA_SET_FLAGS
|
|||||||
AM_INIT_AUTOMAKE([subdir-objects])
|
AM_INIT_AUTOMAKE([subdir-objects])
|
||||||
AC_CONFIG_MACRO_DIR([./])
|
AC_CONFIG_MACRO_DIR([./])
|
||||||
|
|
||||||
dnl Notes by ts A71207 - B10409 :
|
dnl Notes about version numbers and .so numbers:
|
||||||
dnl
|
dnl
|
||||||
dnl Regrettably the meaning of the various version types was misunderstood
|
dnl Regrettably the meaning of the various version types was misunderstood
|
||||||
dnl before version 0.4.1.
|
dnl before version 0.4.1.
|
||||||
@ -91,6 +91,10 @@ dnl 1.0.0 = libburn.so.4.57.0
|
|||||||
dnl 1.0.2 = libburn.so.4.59.0
|
dnl 1.0.2 = libburn.so.4.59.0
|
||||||
dnl 1.0.4 = libburn.so.4.61.0
|
dnl 1.0.4 = libburn.so.4.61.0
|
||||||
dnl 1.0.6 = libburn.so.4.63.0
|
dnl 1.0.6 = libburn.so.4.63.0
|
||||||
|
dnl 1.1.0 = libburn.so.4.65.0
|
||||||
|
dnl 1.1.4 = libburn.so.4.67.0
|
||||||
|
dnl 1.1.6 = libburn.so.4.69.0
|
||||||
|
dnl 1.1.8 = libburn.so.4.71.0
|
||||||
dnl
|
dnl
|
||||||
dnl So LT_CURRENT, LT_REVISION and LT_AGE get set directly here.
|
dnl So LT_CURRENT, LT_REVISION and LT_AGE get set directly here.
|
||||||
dnl SONAME of the emerging library is LT_CURRENT - LT_AGE.
|
dnl SONAME of the emerging library is LT_CURRENT - LT_AGE.
|
||||||
@ -115,8 +119,8 @@ dnl If BURN_*_VERSION changes, be sure to change AC_INIT above to match.
|
|||||||
dnl
|
dnl
|
||||||
dnl As said: Only copies. Original in libburn/libburn.h : burn_header_version_*
|
dnl As said: Only copies. Original in libburn/libburn.h : burn_header_version_*
|
||||||
BURN_MAJOR_VERSION=1
|
BURN_MAJOR_VERSION=1
|
||||||
BURN_MINOR_VERSION=0
|
BURN_MINOR_VERSION=1
|
||||||
BURN_MICRO_VERSION=7
|
BURN_MICRO_VERSION=8
|
||||||
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
||||||
|
|
||||||
AC_SUBST(BURN_MAJOR_VERSION)
|
AC_SUBST(BURN_MAJOR_VERSION)
|
||||||
@ -127,14 +131,14 @@ AC_SUBST(BURN_VERSION)
|
|||||||
dnl Libtool versioning
|
dnl Libtool versioning
|
||||||
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
||||||
dnl
|
dnl
|
||||||
dnl ### This is the release version libburn-1.0.6
|
dnl This is the release version libburn-1.1.8
|
||||||
dnl This is the development version after above release version
|
dnl ### This is the development version after above release version
|
||||||
dnl LT_CURRENT++, LT_AGE++ has not yet happened.
|
dnl LT_CURRENT++, LT_AGE++ has not yet happened.
|
||||||
dnl ### LT_CURRENT++, LT_AGE++ has happened meanwhile.
|
dnl ### LT_CURRENT++, LT_AGE++ has happened meanwhile.
|
||||||
dnl
|
dnl
|
||||||
dnl SONAME = 67 - 63 = 4 . Linux library name = libburn.so.4.63.0
|
dnl SONAME = 75 - 71 = 4 . Linux library name = libburn.so.4.71.0
|
||||||
LT_CURRENT=67
|
LT_CURRENT=75
|
||||||
LT_AGE=63
|
LT_AGE=71
|
||||||
LT_REVISION=0
|
LT_REVISION=0
|
||||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -183,11 +183,6 @@ static void remove_worker(pthread_t th)
|
|||||||
{
|
{
|
||||||
struct w_list *a, *l = NULL;
|
struct w_list *a, *l = NULL;
|
||||||
|
|
||||||
#ifdef Libburn_detach_done_workeR
|
|
||||||
int ret;
|
|
||||||
char msg[80];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (a = workers; a; l = a, a = a->next)
|
for (a = workers; a; l = a, a = a->next)
|
||||||
if (a->thread == th) {
|
if (a->thread == th) {
|
||||||
if (l)
|
if (l)
|
||||||
@ -200,8 +195,12 @@ static void remove_worker(pthread_t th)
|
|||||||
/* Alternative : threads get detached and thus should
|
/* Alternative : threads get detached and thus should
|
||||||
dispose themselves.
|
dispose themselves.
|
||||||
*/
|
*/
|
||||||
ret = pthread_detach(th);
|
pthread_detach(th);
|
||||||
/*
|
/*
|
||||||
|
int ret;
|
||||||
|
char msg[80];
|
||||||
|
|
||||||
|
ret = pthread_detach(th);
|
||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
"remove_workers(): pid= %lu pthread_detach(%lu)= %d",
|
"remove_workers(): pid= %lu pthread_detach(%lu)= %d",
|
||||||
(unsigned long) getpid(), (unsigned long) th, ret);
|
(unsigned long) getpid(), (unsigned long) th, ret);
|
||||||
@ -585,7 +584,6 @@ static void *write_disc_worker_func(struct w_list *w)
|
|||||||
|
|
||||||
void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
struct write_opts o;
|
struct write_opts o;
|
||||||
char *reasons= NULL;
|
char *reasons= NULL;
|
||||||
struct burn_drive *d;
|
struct burn_drive *d;
|
||||||
@ -648,7 +646,7 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
|||||||
tests in burn_*_write_sync()
|
tests in burn_*_write_sync()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
BURN_ALLOC_MEM(reasons, char, BURN_REASONS_LEN + 80);
|
BURN_ALLOC_MEM_VOID(reasons, char, BURN_REASONS_LEN + 80);
|
||||||
strcpy(reasons, "Write job parameters are unsuitable:\n");
|
strcpy(reasons, "Write job parameters are unsuitable:\n");
|
||||||
if (burn_precheck_write(opts, disc, reasons + strlen(reasons), 1)
|
if (burn_precheck_write(opts, disc, reasons + strlen(reasons), 1)
|
||||||
<= 0) {
|
<= 0) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
cleanup.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net>
|
cleanup.c , Copyright 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
|
||||||
A signal handler which cleans up an application and exits.
|
A signal handler which cleans up an application and exits.
|
||||||
|
|
||||||
@ -205,9 +205,10 @@ main()
|
|||||||
Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0);
|
Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0);
|
||||||
|
|
||||||
if(1) { /* change to 0 in order to wait for external signals */
|
if(1) { /* change to 0 in order to wait for external signals */
|
||||||
char *cpt= NULL,c;
|
char *cpt= NULL, c= ' ';
|
||||||
printf("Intentionally provoking SIGSEGV ...\n");
|
printf("Intentionally provoking SIGSEGV ...\n");
|
||||||
c= *cpt;
|
c= *cpt;
|
||||||
|
printf("Strange: The system ignored a SIGSEGV: c= %u\n", (unsigned int) c);
|
||||||
} else {
|
} else {
|
||||||
printf("killme: %d\n",getpid());
|
printf("killme: %d\n",getpid());
|
||||||
sleep(3600);
|
sleep(3600);
|
||||||
|
@ -25,20 +25,4 @@ void burn_set_verbosity(int v)
|
|||||||
burn_verbosity = v;
|
burn_verbosity = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void burn_print(int level, const char *a, ...)
|
|
||||||
{
|
|
||||||
#ifdef WIN32
|
|
||||||
char debug_string_data[256];
|
|
||||||
#endif
|
|
||||||
va_list vl;
|
|
||||||
|
|
||||||
if (level <= burn_verbosity) {
|
|
||||||
va_start(vl, a);
|
|
||||||
#ifdef WIN32
|
|
||||||
vsprintf(debug_string_data, a, vl);
|
|
||||||
OutputDebugString(debug_string_data);
|
|
||||||
#else
|
|
||||||
vfprintf(stderr, a, vl);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
491
libburn/drive.c
491
libburn/drive.c
@ -15,6 +15,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
/* ts A61007 */
|
/* ts A61007 */
|
||||||
/* #include <a ssert.h> */
|
/* #include <a ssert.h> */
|
||||||
@ -310,59 +311,197 @@ int burn_drive_inquire_media(struct burn_drive *d)
|
|||||||
if (d->current_profile == -1 || d->current_is_cd_profile)
|
if (d->current_profile == -1 || d->current_is_cd_profile)
|
||||||
d->read_toc(d);
|
d->read_toc(d);
|
||||||
|
|
||||||
/* ts A70314 */
|
/* ts A70314 , B10712 */
|
||||||
d->status = BURN_DISC_UNSUITABLE;
|
if (d->status != BURN_DISC_EMPTY)
|
||||||
|
d->status = BURN_DISC_UNSUITABLE;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ts B10730 */
|
||||||
|
/* Send a default mode page 05 to CD and DVD-R-oids */
|
||||||
|
int burn_drive_send_default_page_05(struct burn_drive *d, int flag)
|
||||||
|
{
|
||||||
|
struct burn_write_opts *opts;
|
||||||
|
|
||||||
|
if (d->sent_default_page_05)
|
||||||
|
return 0;
|
||||||
|
if (!((d->status == BURN_DISC_APPENDABLE ||
|
||||||
|
d->status == BURN_DISC_BLANK) &&
|
||||||
|
(d->current_is_cd_profile || d->current_profile == 0x11 ||
|
||||||
|
d->current_profile == 0x14 || d->current_profile == 0x15)))
|
||||||
|
return 0;
|
||||||
|
opts = burn_write_opts_new(d);
|
||||||
|
if (opts == NULL)
|
||||||
|
return -1;
|
||||||
|
if (d->status == BURN_DISC_APPENDABLE)
|
||||||
|
burn_write_opts_set_write_type(opts,
|
||||||
|
BURN_WRITE_TAO, BURN_BLOCK_MODE1);
|
||||||
|
else
|
||||||
|
burn_write_opts_set_write_type(opts,
|
||||||
|
BURN_WRITE_SAO, BURN_BLOCK_SAO);
|
||||||
|
d->send_write_parameters(d, opts);
|
||||||
|
burn_write_opts_free(opts);
|
||||||
|
d->sent_default_page_05 = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A70924 */
|
||||||
|
int burn_drive__fd_from_special_adr(char *adr)
|
||||||
|
{
|
||||||
|
int fd = -1, i;
|
||||||
|
|
||||||
|
if (strcmp(adr, "-") == 0)
|
||||||
|
fd = 1;
|
||||||
|
if(strncmp(adr, "/dev/fd/", 8) == 0) {
|
||||||
|
for (i = 8; adr[i]; i++)
|
||||||
|
if (!isdigit(adr[i]))
|
||||||
|
break;
|
||||||
|
if (i> 8 && adr[i] == 0)
|
||||||
|
fd = atoi(adr + 8);
|
||||||
|
}
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @param flag bit0= accept read-only files and return 2 in this case
|
||||||
|
bit1= accept write-only files and return 3 in this case
|
||||||
|
*/
|
||||||
|
static int burn_drive__is_rdwr(char *fname, int *stat_ret,
|
||||||
|
struct stat *stbuf_ret,
|
||||||
|
off_t *read_size_ret, int flag)
|
||||||
|
{
|
||||||
|
int fd, is_rdwr = 1, ret, getfl_ret, st_ret, mask;
|
||||||
|
struct stat stbuf;
|
||||||
|
off_t read_size = 0;
|
||||||
|
|
||||||
|
memset(&stbuf, 0, sizeof(struct stat));
|
||||||
|
fd = burn_drive__fd_from_special_adr(fname);
|
||||||
|
if (fd >= 0)
|
||||||
|
st_ret = fstat(fd, &stbuf);
|
||||||
|
else
|
||||||
|
st_ret = stat(fname, &stbuf);
|
||||||
|
if (st_ret != -1) {
|
||||||
|
is_rdwr = burn_os_is_2k_seekrw(fname, 0);
|
||||||
|
ret = 1;
|
||||||
|
if (S_ISREG(stbuf.st_mode))
|
||||||
|
read_size = stbuf.st_size;
|
||||||
|
else if (is_rdwr)
|
||||||
|
ret = burn_os_stdio_capacity(fname, &read_size);
|
||||||
|
if (ret <= 0 ||
|
||||||
|
read_size / (off_t) 2048 >= (off_t) 0x7ffffff0)
|
||||||
|
read_size = (off_t) 0x7ffffff0 * (off_t) 2048;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_rdwr && fd >= 0) {
|
||||||
|
getfl_ret = fcntl(fd, F_GETFL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
fprintf(stderr, "LIBBURN_DEBUG: burn_drive__is_rdwr: getfl_ret = %lX , O_RDWR = %lX , & = %lX , O_RDONLY = %lX\n", (unsigned long) getfl_ret, (unsigned long) O_RDWR, (unsigned long) (getfl_ret & O_RDWR), (unsigned long) O_RDONLY);
|
||||||
|
*/
|
||||||
|
|
||||||
|
mask = O_RDWR | O_WRONLY | O_RDONLY;
|
||||||
|
|
||||||
|
if (getfl_ret == -1 || (getfl_ret & mask) != O_RDWR)
|
||||||
|
is_rdwr = 0;
|
||||||
|
if ((flag & 1) && getfl_ret != -1 &&
|
||||||
|
(getfl_ret & mask) == O_RDONLY)
|
||||||
|
is_rdwr = 2;
|
||||||
|
if ((flag & 2) && getfl_ret != -1 &&
|
||||||
|
(getfl_ret & mask) == O_WRONLY)
|
||||||
|
is_rdwr = 3;
|
||||||
|
}
|
||||||
|
if (stat_ret != NULL)
|
||||||
|
*stat_ret = st_ret;
|
||||||
|
if (stbuf_ret != NULL)
|
||||||
|
memcpy(stbuf_ret, &stbuf, sizeof(struct stat));
|
||||||
|
if (read_size_ret != NULL)
|
||||||
|
*read_size_ret = read_size;
|
||||||
|
return is_rdwr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int burn_drive_grab_stdio(struct burn_drive *d, int flag)
|
||||||
|
{
|
||||||
|
int stat_ret = -1, is_rdwr, ret;
|
||||||
|
struct stat stbuf;
|
||||||
|
off_t read_size= 0, size= 0;
|
||||||
|
char fd_name[40], *name_pt = NULL;
|
||||||
|
|
||||||
|
if(d->stdio_fd >= 0) {
|
||||||
|
sprintf(fd_name, "/dev/fd/%d", d->stdio_fd);
|
||||||
|
name_pt = fd_name;
|
||||||
|
} else if (d->devname[0]) {
|
||||||
|
name_pt = d->devname;
|
||||||
|
}
|
||||||
|
if (name_pt != NULL) {
|
||||||
|
/* re-assess d->media_read_capacity and free space */
|
||||||
|
is_rdwr = burn_drive__is_rdwr(name_pt, &stat_ret, &stbuf,
|
||||||
|
&read_size, 1 | 2);
|
||||||
|
/* despite its name : last valid address, not size */
|
||||||
|
d->media_read_capacity =
|
||||||
|
read_size / 2048 - !(read_size % 2048);
|
||||||
|
if ((stat_ret == -1 || is_rdwr) && d->devname[0]) {
|
||||||
|
ret = burn_os_stdio_capacity(d->devname, &size);
|
||||||
|
if (ret > 0)
|
||||||
|
burn_drive_set_media_capacity_remaining(d,
|
||||||
|
size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d->released = 0;
|
||||||
|
d->current_profile = 0xffff;
|
||||||
|
if(d->drive_role == 2 || d->drive_role == 3) {
|
||||||
|
d->status = BURN_DISC_BLANK;
|
||||||
|
} else if(d->drive_role == 4) {
|
||||||
|
if (d->media_read_capacity > 0)
|
||||||
|
d->status = BURN_DISC_FULL;
|
||||||
|
else
|
||||||
|
d->status = BURN_DISC_EMPTY;
|
||||||
|
} else if(d->drive_role == 5) {
|
||||||
|
if (stat_ret != -1 && S_ISREG(stbuf.st_mode) &&
|
||||||
|
stbuf.st_size > 0) {
|
||||||
|
d->status = BURN_DISC_APPENDABLE;
|
||||||
|
if (stbuf.st_size / (off_t) 2048
|
||||||
|
>= 0x7ffffff0) {
|
||||||
|
d->status = BURN_DISC_FULL;
|
||||||
|
d->role_5_nwa = 0x7ffffff0;
|
||||||
|
} else
|
||||||
|
d->role_5_nwa = stbuf.st_size / 2048 +
|
||||||
|
!!(stbuf.st_size % 2048);
|
||||||
|
} else
|
||||||
|
d->status = BURN_DISC_BLANK;
|
||||||
|
} else {
|
||||||
|
d->status = BURN_DISC_EMPTY;
|
||||||
|
d->current_profile = 0;
|
||||||
|
}
|
||||||
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int burn_drive_grab(struct burn_drive *d, int le)
|
int burn_drive_grab(struct burn_drive *d, int le)
|
||||||
{
|
{
|
||||||
int errcode;
|
int errcode;
|
||||||
/* ts A61125 - B10314 */
|
/* ts A61125 - B10314 */
|
||||||
int ret, sose, stat_ret = -1;
|
int ret, sose;
|
||||||
struct stat stbuf;
|
|
||||||
|
|
||||||
if (!d->released) {
|
if (!d->released) {
|
||||||
burn_print(1, "can't grab - already grabbed\n");
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00020189, LIBDAX_MSGS_SEV_FATAL,
|
||||||
|
LIBDAX_MSGS_PRIO_LOW,
|
||||||
|
"Drive is already grabbed by libburn", 0, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(d->drive_role != 1) {
|
if(d->drive_role != 1) {
|
||||||
d->released = 0;
|
ret = burn_drive_grab_stdio(d, 0);
|
||||||
d->current_profile = 0xffff;
|
return ret;
|
||||||
if (d->devname[0])
|
|
||||||
stat_ret = stat(d->devname, &stbuf);
|
|
||||||
if(d->drive_role == 2 || d->drive_role == 3) {
|
|
||||||
d->status = BURN_DISC_BLANK;
|
|
||||||
} else if(d->drive_role == 4) {
|
|
||||||
if (d->media_read_capacity > 0)
|
|
||||||
d->status = BURN_DISC_FULL;
|
|
||||||
else
|
|
||||||
d->status = BURN_DISC_EMPTY;
|
|
||||||
} else if(d->drive_role == 5) {
|
|
||||||
if (stat_ret != -1 && S_ISREG(stbuf.st_mode) &&
|
|
||||||
stbuf.st_size > 0) {
|
|
||||||
d->status = BURN_DISC_APPENDABLE;
|
|
||||||
d->role_5_nwa = stbuf.st_size / 2048 +
|
|
||||||
!!(stbuf.st_size % 2048);
|
|
||||||
} else
|
|
||||||
d->status = BURN_DISC_BLANK;
|
|
||||||
} else {
|
|
||||||
d->status = BURN_DISC_EMPTY;
|
|
||||||
d->current_profile = 0;
|
|
||||||
}
|
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
d->status = BURN_DISC_UNREADY;
|
d->status = BURN_DISC_UNREADY;
|
||||||
errcode = d->grab(d);
|
errcode = d->grab(d);
|
||||||
|
if (errcode == 0)
|
||||||
if (errcode == 0) {
|
|
||||||
burn_print(1, "low level drive grab failed\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
d->busy = BURN_DRIVE_GRABBING;
|
d->busy = BURN_DRIVE_GRABBING;
|
||||||
|
|
||||||
if (le)
|
if (le)
|
||||||
@ -379,6 +518,8 @@ int burn_drive_grab(struct burn_drive *d, int le)
|
|||||||
d->silent_on_scsi_error = 1;
|
d->silent_on_scsi_error = 1;
|
||||||
/* ts A61125 : outsourced media state inquiry aspects */
|
/* ts A61125 : outsourced media state inquiry aspects */
|
||||||
ret = burn_drive_inquire_media(d);
|
ret = burn_drive_inquire_media(d);
|
||||||
|
|
||||||
|
burn_drive_send_default_page_05(d, 0);
|
||||||
d->silent_on_scsi_error = sose;
|
d->silent_on_scsi_error = sose;
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
return ret;
|
return ret;
|
||||||
@ -474,7 +615,6 @@ struct burn_drive *burn_drive_finish_enum(struct burn_drive *d)
|
|||||||
/* try to get the drive info */
|
/* try to get the drive info */
|
||||||
ret = t->grab(t);
|
ret = t->grab(t);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
burn_print(2, "getting drive info\n");
|
|
||||||
t->getcaps(t);
|
t->getcaps(t);
|
||||||
t->unlock(t);
|
t->unlock(t);
|
||||||
t->released = 1;
|
t->released = 1;
|
||||||
@ -499,7 +639,9 @@ ex:
|
|||||||
|
|
||||||
|
|
||||||
/* ts A61125 : model aspects of burn_drive_release */
|
/* ts A61125 : model aspects of burn_drive_release */
|
||||||
int burn_drive_mark_unready(struct burn_drive *d)
|
/* @param flag bit3= do not close d->stdio_fd
|
||||||
|
*/
|
||||||
|
int burn_drive_mark_unready(struct burn_drive *d, int flag)
|
||||||
{
|
{
|
||||||
/* ts A61020 : mark media info as invalid */
|
/* ts A61020 : mark media info as invalid */
|
||||||
d->start_lba= -2000000000;
|
d->start_lba= -2000000000;
|
||||||
@ -519,21 +661,23 @@ int burn_drive_mark_unready(struct burn_drive *d)
|
|||||||
burn_disc_free(d->disc);
|
burn_disc_free(d->disc);
|
||||||
d->disc = NULL;
|
d->disc = NULL;
|
||||||
}
|
}
|
||||||
if (d->stdio_fd >= 0)
|
if (!(flag & 8)) {
|
||||||
close (d->stdio_fd);
|
if (d->stdio_fd >= 0)
|
||||||
d->stdio_fd = -1;
|
close (d->stdio_fd);
|
||||||
|
d->stdio_fd = -1;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A70918 : outsourced from burn_drive_release() and enhanced */
|
/* ts A70918 : outsourced from burn_drive_release() and enhanced */
|
||||||
/** @param flag bit0-2 = mode : 0=unlock , 1=unlock+eject , 2=leave locked
|
/** @param flag bit0-2 = mode : 0=unlock , 1=unlock+eject , 2=leave locked
|
||||||
|
bit3= do not call d->release()
|
||||||
*/
|
*/
|
||||||
int burn_drive_release_fl(struct burn_drive *d, int flag)
|
int burn_drive_release_fl(struct burn_drive *d, int flag)
|
||||||
{
|
{
|
||||||
if (d->released) {
|
if (d->released) {
|
||||||
/* ts A61007 */
|
/* ts A61007 */
|
||||||
/* burn_print(1, "second release on drive!\n"); */
|
|
||||||
libdax_msgs_submit(libdax_messenger,
|
libdax_msgs_submit(libdax_messenger,
|
||||||
d->global_index, 0x00020105,
|
d->global_index, 0x00020105,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
@ -559,15 +703,17 @@ int burn_drive_release_fl(struct burn_drive *d, int flag)
|
|||||||
d->unlock(d);
|
d->unlock(d);
|
||||||
if ((flag & 7) == 1)
|
if ((flag & 7) == 1)
|
||||||
d->eject(d);
|
d->eject(d);
|
||||||
burn_drive_snooze(d, 0);
|
if (!(flag & 8)) {
|
||||||
d->release(d);
|
burn_drive_snooze(d, 0);
|
||||||
|
d->release(d);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d->needs_sync_cache = 0; /* just to be sure */
|
d->needs_sync_cache = 0; /* just to be sure */
|
||||||
d->released = 1;
|
d->released = 1;
|
||||||
|
|
||||||
/* ts A61125 : outsourced model aspects */
|
/* ts A61125 : outsourced model aspects */
|
||||||
burn_drive_mark_unready(d);
|
burn_drive_mark_unready(d, flag & 8);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,6 +741,36 @@ void burn_drive_release(struct burn_drive *d, int le)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11002 */
|
||||||
|
/* API */
|
||||||
|
int burn_drive_re_assess(struct burn_drive *d, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (d->released) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00020108,
|
||||||
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Drive is not grabbed on burn_drive_re_assess()",
|
||||||
|
0, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
burn_drive_release_fl(d, 2 | 8);
|
||||||
|
|
||||||
|
if(d->drive_role != 1) {
|
||||||
|
ret = burn_drive_grab_stdio(d, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->busy = BURN_DRIVE_GRABBING;
|
||||||
|
ret = burn_drive_inquire_media(d);
|
||||||
|
burn_drive_send_default_page_05(d, 0);
|
||||||
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
|
d->released = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A70918 */
|
/* ts A70918 */
|
||||||
/* API */
|
/* API */
|
||||||
int burn_drive_leave_locked(struct burn_drive *d, int flag)
|
int burn_drive_leave_locked(struct burn_drive *d, int flag)
|
||||||
@ -650,9 +826,6 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
burn_print(1, "erasing drive %s %s\n", d->idata->vendor,
|
|
||||||
d->idata->product);
|
|
||||||
|
|
||||||
if (d->drive_role == 5) { /* Random access write-only drive */
|
if (d->drive_role == 5) { /* Random access write-only drive */
|
||||||
ret = truncate(d->devname, (off_t) 0);
|
ret = truncate(d->devname, (off_t) 0);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
@ -699,7 +872,7 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
|
|||||||
d->progress.sector = 0x10000;
|
d->progress.sector = 0x10000;
|
||||||
|
|
||||||
/* ts A61125 : update media state records */
|
/* ts A61125 : update media state records */
|
||||||
burn_drive_mark_unready(d);
|
burn_drive_mark_unready(d, 0);
|
||||||
if (d->drive_role == 1)
|
if (d->drive_role == 1)
|
||||||
burn_drive_inquire_media(d);
|
burn_drive_inquire_media(d);
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
@ -753,7 +926,7 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag)
|
|||||||
goto ex;
|
goto ex;
|
||||||
|
|
||||||
/* update media state records */
|
/* update media state records */
|
||||||
burn_drive_mark_unready(d);
|
burn_drive_mark_unready(d, 0);
|
||||||
burn_drive_inquire_media(d);
|
burn_drive_inquire_media(d);
|
||||||
if (flag & 1) {
|
if (flag & 1) {
|
||||||
/* write size in zeros */;
|
/* write size in zeros */;
|
||||||
@ -932,17 +1105,6 @@ void burn_drive_cancel(struct burn_drive *d)
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts A61007 : defunct because unused */
|
|
||||||
#if 0
|
|
||||||
int burn_drive_get_block_types(struct burn_drive *d,
|
|
||||||
enum burn_write_types write_type)
|
|
||||||
{
|
|
||||||
burn_print(12, "write type: %d\n", write_type);
|
|
||||||
a ssert( /* (write_type >= BURN_WRITE_PACKET) && */
|
|
||||||
(write_type <= BURN_WRITE_RAW));
|
|
||||||
return d->block_types[write_type];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void strip_spaces(char *str)
|
static void strip_spaces(char *str)
|
||||||
{
|
{
|
||||||
@ -1179,7 +1341,7 @@ int burn_drive_forget(struct burn_drive *d, int force)
|
|||||||
if(occup > 0)
|
if(occup > 0)
|
||||||
if(force < 1)
|
if(force < 1)
|
||||||
return 0;
|
return 0;
|
||||||
if(occup > 10)
|
if(occup >= 10)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* >>> do any drive calming here */;
|
/* >>> do any drive calming here */;
|
||||||
@ -1201,7 +1363,9 @@ int burn_drive_info_forget(struct burn_drive_info *info, int force)
|
|||||||
|
|
||||||
void burn_drive_info_free(struct burn_drive_info drive_infos[])
|
void burn_drive_info_free(struct burn_drive_info drive_infos[])
|
||||||
{
|
{
|
||||||
|
#ifndef Libburn_free_all_drives_on_infO
|
||||||
int i;
|
int i;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ts A60904 : ticket 62, contribution by elmom */
|
/* ts A60904 : ticket 62, contribution by elmom */
|
||||||
/* clarifying the meaning and the identity of the victim */
|
/* clarifying the meaning and the identity of the victim */
|
||||||
@ -1394,79 +1558,6 @@ char *burn_drive_whitelist_item(int idx, int flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A70924 */
|
|
||||||
int burn_drive__fd_from_special_adr(char *adr)
|
|
||||||
{
|
|
||||||
int fd = -1, i;
|
|
||||||
|
|
||||||
if (strcmp(adr, "-") == 0)
|
|
||||||
fd = 1;
|
|
||||||
if(strncmp(adr, "/dev/fd/", 8) == 0) {
|
|
||||||
for (i = 8; adr[i]; i++)
|
|
||||||
if (!isdigit(adr[i]))
|
|
||||||
break;
|
|
||||||
if (i> 8 && adr[i] == 0)
|
|
||||||
fd = atoi(adr + 8);
|
|
||||||
}
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* @param flag bit0= accept read-only files and return 2 in this case
|
|
||||||
bit1= accept write-only files and return 3 in this case
|
|
||||||
*/
|
|
||||||
static int burn_drive__is_rdwr(char *fname, int *stat_ret,
|
|
||||||
struct stat *stbuf_ret,
|
|
||||||
off_t *read_size_ret, int flag)
|
|
||||||
{
|
|
||||||
int fd, is_rdwr = 1, ret, getfl_ret, st_ret, mask;
|
|
||||||
struct stat stbuf;
|
|
||||||
off_t read_size = 0;
|
|
||||||
|
|
||||||
memset(&stbuf, 0, sizeof(struct stat));
|
|
||||||
fd = burn_drive__fd_from_special_adr(fname);
|
|
||||||
if (fd >= 0)
|
|
||||||
st_ret = fstat(fd, &stbuf);
|
|
||||||
else
|
|
||||||
st_ret = stat(fname, &stbuf);
|
|
||||||
if (st_ret != -1) {
|
|
||||||
is_rdwr = burn_os_is_2k_seekrw(fname, 0);
|
|
||||||
if (S_ISREG(stbuf.st_mode))
|
|
||||||
read_size = stbuf.st_size;
|
|
||||||
else if (is_rdwr) {
|
|
||||||
ret = burn_os_stdio_capacity(fname, &read_size);
|
|
||||||
if (ret <= 0)
|
|
||||||
read_size = (off_t) 0x7ffffff0 * (off_t) 2048;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_rdwr && fd >= 0) {
|
|
||||||
getfl_ret = fcntl(fd, F_GETFL);
|
|
||||||
|
|
||||||
/*
|
|
||||||
fprintf(stderr, "LIBBURN_DEBUG: burn_drive__is_rdwr: getfl_ret = %lX , O_RDWR = %lX , & = %lX , O_RDONLY = %lX\n", (unsigned long) getfl_ret, (unsigned long) O_RDWR, (unsigned long) (getfl_ret & O_RDWR), (unsigned long) O_RDONLY);
|
|
||||||
*/
|
|
||||||
|
|
||||||
mask = O_RDWR | O_WRONLY | O_RDONLY;
|
|
||||||
|
|
||||||
if (getfl_ret == -1 || (getfl_ret & mask) != O_RDWR)
|
|
||||||
is_rdwr = 0;
|
|
||||||
if ((flag & 1) && getfl_ret != -1 &&
|
|
||||||
(getfl_ret & mask) == O_RDONLY)
|
|
||||||
is_rdwr = 2;
|
|
||||||
if ((flag & 2) && getfl_ret != -1 &&
|
|
||||||
(getfl_ret & mask) == O_WRONLY)
|
|
||||||
is_rdwr = 3;
|
|
||||||
}
|
|
||||||
if (stat_ret != NULL)
|
|
||||||
*stat_ret = st_ret;
|
|
||||||
if (stbuf_ret != NULL)
|
|
||||||
memcpy(stbuf_ret, &stbuf, sizeof(struct stat));
|
|
||||||
if (read_size_ret != NULL)
|
|
||||||
*read_size_ret = read_size;
|
|
||||||
return is_rdwr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int burn_role_by_access(char *fname, int flag)
|
static int burn_role_by_access(char *fname, int flag)
|
||||||
{
|
{
|
||||||
/* We normally need _LARGEFILE64_SOURCE defined by the build system.
|
/* We normally need _LARGEFILE64_SOURCE defined by the build system.
|
||||||
@ -1580,8 +1671,13 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
|
|||||||
(burn_drive_role_4_allowed & 8)) {
|
(burn_drive_role_4_allowed & 8)) {
|
||||||
d->status = BURN_DISC_APPENDABLE;
|
d->status = BURN_DISC_APPENDABLE;
|
||||||
d->block_types[BURN_WRITE_SAO] = 0;
|
d->block_types[BURN_WRITE_SAO] = 0;
|
||||||
d->role_5_nwa = stbuf.st_size / 2048 +
|
if (stbuf.st_size / (off_t) 2048
|
||||||
!!(stbuf.st_size % 2048);
|
>= 0x7ffffff0) {
|
||||||
|
d->status = BURN_DISC_FULL;
|
||||||
|
d->role_5_nwa = 0x7ffffff0;
|
||||||
|
} else
|
||||||
|
d->role_5_nwa = stbuf.st_size / 2048 +
|
||||||
|
!!(stbuf.st_size % 2048);
|
||||||
} else {
|
} else {
|
||||||
d->status = BURN_DISC_BLANK;
|
d->status = BURN_DISC_BLANK;
|
||||||
d->block_types[BURN_WRITE_SAO] =
|
d->block_types[BURN_WRITE_SAO] =
|
||||||
@ -1681,7 +1777,7 @@ int burn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], char* adr,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (n_drives <= 0)
|
if (n_drives == 0)
|
||||||
return 0;
|
return 0;
|
||||||
/*
|
/*
|
||||||
fprintf(stderr, "libburn: experimental: n_drives %d , drivetop %d\n",
|
fprintf(stderr, "libburn: experimental: n_drives %d , drivetop %d\n",
|
||||||
@ -2009,8 +2105,9 @@ int burn_drive_convert_fs_adr_sub(char *path, char adr[], int *rec_count)
|
|||||||
burn_drive_is_enumerable_adr(path)) {
|
burn_drive_is_enumerable_adr(path)) {
|
||||||
if(strlen(path) >= BURN_DRIVE_ADR_LEN)
|
if(strlen(path) >= BURN_DRIVE_ADR_LEN)
|
||||||
return -1;
|
return -1;
|
||||||
burn_drive_adr_debug_msg(
|
if (strncmp(path, "stdio:", 6) != 0)
|
||||||
"burn_drive_is_enumerable_adr( %s ) is true", path);
|
burn_drive_adr_debug_msg(
|
||||||
|
"burn_drive_is_enumerable_adr( %s ) is true", path);
|
||||||
strcpy(adr, path);
|
strcpy(adr, path);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -2042,6 +2139,7 @@ int burn_drive_convert_fs_adr_sub(char *path, char adr[], int *rec_count)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
/** Try to convert a given existing filesystem address into a persistent drive
|
/** Try to convert a given existing filesystem address into a persistent drive
|
||||||
address. */
|
address. */
|
||||||
int burn_drive_convert_fs_adr(char *path, char adr[])
|
int burn_drive_convert_fs_adr(char *path, char adr[])
|
||||||
@ -2053,6 +2151,88 @@ int burn_drive_convert_fs_adr(char *path, char adr[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int burn_lookup_device_link(char *dev_adr, char link_adr[],
|
||||||
|
char *dir_adr, char **ranks, int rank_count, int flag)
|
||||||
|
{
|
||||||
|
DIR *dirpt= NULL;
|
||||||
|
struct dirent *entry;
|
||||||
|
struct stat link_stbuf;
|
||||||
|
char *adr= NULL, *namept, *sys_adr= NULL;
|
||||||
|
int ret, name_rank, found_rank= 0x7fffffff, dirlen, i, rec_count = 0;
|
||||||
|
static char default_ranks_data[][8] =
|
||||||
|
{"dvdrw", "cdrw", "dvd", "cdrom", "cd"};
|
||||||
|
char *default_ranks[5];
|
||||||
|
|
||||||
|
link_adr[0] = 0;
|
||||||
|
if (ranks == NULL) {
|
||||||
|
for (i = 0; i < 5; i++)
|
||||||
|
default_ranks[i] = default_ranks_data[i];
|
||||||
|
ranks = default_ranks;
|
||||||
|
rank_count= 5;
|
||||||
|
}
|
||||||
|
dirlen= strlen(dir_adr) + 1;
|
||||||
|
if (strlen(dir_adr) + 1 >= BURN_DRIVE_ADR_LEN) {
|
||||||
|
|
||||||
|
/* >>> Issue warning about oversized directory address */;
|
||||||
|
|
||||||
|
{ret = 0; goto ex;}
|
||||||
|
}
|
||||||
|
BURN_ALLOC_MEM(adr, char, BURN_DRIVE_ADR_LEN);
|
||||||
|
BURN_ALLOC_MEM(sys_adr, char, BURN_DRIVE_ADR_LEN);
|
||||||
|
|
||||||
|
dirpt = opendir(dir_adr);
|
||||||
|
if (dirpt == NULL)
|
||||||
|
{ret = 0; goto ex;}
|
||||||
|
strcpy(adr, dir_adr);
|
||||||
|
strcat(adr, "/");
|
||||||
|
namept = adr + strlen(dir_adr) + 1;
|
||||||
|
while(1) {
|
||||||
|
entry = readdir(dirpt);
|
||||||
|
if(entry == NULL)
|
||||||
|
break;
|
||||||
|
if (strlen(entry->d_name) + dirlen >= BURN_DRIVE_ADR_LEN)
|
||||||
|
continue;
|
||||||
|
strcpy(namept, entry->d_name);
|
||||||
|
if(lstat(adr, &link_stbuf) == -1)
|
||||||
|
continue;
|
||||||
|
if((link_stbuf.st_mode & S_IFMT) != S_IFLNK)
|
||||||
|
continue;
|
||||||
|
/* Determine rank and omit uninteresting ones */
|
||||||
|
for(name_rank= 0; name_rank < rank_count; name_rank++)
|
||||||
|
if(strncmp(namept, ranks[name_rank],
|
||||||
|
strlen(ranks[name_rank])) == 0)
|
||||||
|
break;
|
||||||
|
/* we look for lowest rank */
|
||||||
|
if(name_rank >= rank_count ||
|
||||||
|
name_rank > found_rank ||
|
||||||
|
(name_rank == found_rank &&
|
||||||
|
strcmp(namept, link_adr + dirlen) >= 0))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Does name point to the same device as dev_adr ? */
|
||||||
|
ret= burn_drive_resolve_link(adr, sys_adr, &rec_count, 2);
|
||||||
|
if(ret < 0)
|
||||||
|
goto ex;
|
||||||
|
if(ret == 0)
|
||||||
|
continue;
|
||||||
|
if(strcmp(dev_adr, sys_adr) == 0) {
|
||||||
|
strcpy(link_adr, adr);
|
||||||
|
found_rank= name_rank;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret= 2;
|
||||||
|
if(found_rank < 0x7fffffff)
|
||||||
|
ret= 1;
|
||||||
|
ex:;
|
||||||
|
if(dirpt != NULL)
|
||||||
|
closedir(dirpt);
|
||||||
|
BURN_FREE_MEM(adr);
|
||||||
|
BURN_FREE_MEM(sys_adr);
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** A pacifier function suitable for burn_abort.
|
/** A pacifier function suitable for burn_abort.
|
||||||
@param handle If not NULL, a pointer to a text suitable for printf("%s")
|
@param handle If not NULL, a pointer to a text suitable for printf("%s")
|
||||||
*/
|
*/
|
||||||
@ -2137,7 +2317,7 @@ int burn_abort_5(int patience,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(occup <= 10) {
|
if(occup < 10) {
|
||||||
if (drive_array[i].drive_role != 1)
|
if (drive_array[i].drive_role != 1)
|
||||||
/* occup == -1 comes early */
|
/* occup == -1 comes early */
|
||||||
usleep(1000000);
|
usleep(1000000);
|
||||||
@ -2596,11 +2776,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
|
|||||||
size = d->media_capacity_remaining;
|
size = d->media_capacity_remaining;
|
||||||
burn_os_stdio_capacity(d->devname, &size);
|
burn_os_stdio_capacity(d->devname, &size);
|
||||||
burn_drive_set_media_capacity_remaining(d, size);
|
burn_drive_set_media_capacity_remaining(d, size);
|
||||||
|
o->start_range_high = d->media_capacity_remaining;
|
||||||
/* >>> This looks wrong ! */
|
|
||||||
/* >>> should add file size */
|
|
||||||
o->start_range_high = size;
|
|
||||||
|
|
||||||
o->start_alignment = 2048; /* imposting a drive, not a file */
|
o->start_alignment = 2048; /* imposting a drive, not a file */
|
||||||
o->might_do_sao = 4;
|
o->might_do_sao = 4;
|
||||||
o->might_do_tao = 2;
|
o->might_do_tao = 2;
|
||||||
@ -2615,10 +2791,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
|
|||||||
|
|
||||||
/* >>> start_range_low = file size rounded to 2048 */;
|
/* >>> start_range_low = file size rounded to 2048 */;
|
||||||
|
|
||||||
/* >>> This looks wrong ! */
|
o->start_range_high = d->media_capacity_remaining;
|
||||||
/* >>> should add file size */
|
|
||||||
o->start_range_high = size;
|
|
||||||
|
|
||||||
o->start_alignment = 2048; /* imposting a drive, not a file */
|
o->start_alignment = 2048; /* imposting a drive, not a file */
|
||||||
if (s == BURN_DISC_APPENDABLE) {
|
if (s == BURN_DISC_APPENDABLE) {
|
||||||
if (wt == BURN_WRITE_SAO || wt == BURN_WRITE_RAW)
|
if (wt == BURN_WRITE_SAO || wt == BURN_WRITE_RAW)
|
||||||
@ -3031,10 +3204,13 @@ int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid,
|
|||||||
*/
|
*/
|
||||||
int burn_drive_set_media_capacity_remaining(struct burn_drive *d, off_t value)
|
int burn_drive_set_media_capacity_remaining(struct burn_drive *d, off_t value)
|
||||||
{
|
{
|
||||||
|
if (value / (off_t) 2048 > (off_t) 0x7ffffff0)
|
||||||
|
value = ((off_t) 0x7ffffff0) * (off_t) 2048;
|
||||||
d->media_capacity_remaining = value;
|
d->media_capacity_remaining = value;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A81215 : API */
|
/* ts A81215 : API */
|
||||||
int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag)
|
int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag)
|
||||||
{
|
{
|
||||||
@ -3088,7 +3264,7 @@ int burn_disc_get_cd_info(struct burn_drive *d, char disc_type[80],
|
|||||||
}
|
}
|
||||||
*disc_id = d->disc_id;
|
*disc_id = d->disc_id;
|
||||||
memcpy(bar_code, d->disc_bar_code, 8);
|
memcpy(bar_code, d->disc_bar_code, 8);
|
||||||
bar_code[9]= 0;
|
bar_code[8]= 0;
|
||||||
*app_code = d->disc_app_code;
|
*app_code = d->disc_app_code;
|
||||||
*valid = d->disc_info_valid;
|
*valid = d->disc_info_valid;
|
||||||
return 1;
|
return 1;
|
||||||
@ -3109,6 +3285,23 @@ int burn_disc_get_bd_spare_info(struct burn_drive *d,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B10801 : API */
|
||||||
|
int burn_disc_get_phys_format_info(struct burn_drive *d, int *disk_category,
|
||||||
|
char **book_name, int *part_version, int *num_layers,
|
||||||
|
int *num_blocks, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (burn_drive_get_drive_role(d) != 1)
|
||||||
|
return 0;
|
||||||
|
*disk_category = *part_version = *num_layers = *num_blocks = 0;
|
||||||
|
ret = mmc_get_phys_format_info(d, disk_category, book_name,
|
||||||
|
part_version, num_layers, num_blocks, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ts B10525 : API */
|
/* ts B10525 : API */
|
||||||
int burn_disc_next_track_is_damaged(struct burn_drive *d, int flag)
|
int burn_disc_next_track_is_damaged(struct burn_drive *d, int flag)
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ struct burn_drive *burn_drive_finish_enum(struct burn_drive *d);
|
|||||||
int burn_drive_inquire_media(struct burn_drive *d);
|
int burn_drive_inquire_media(struct burn_drive *d);
|
||||||
|
|
||||||
/* ts A61125 : model aspects of burn_drive_release */
|
/* ts A61125 : model aspects of burn_drive_release */
|
||||||
int burn_drive_mark_unready(struct burn_drive *d);
|
int burn_drive_mark_unready(struct burn_drive *d, int flag);
|
||||||
|
|
||||||
|
|
||||||
/* ts A61226 */
|
/* ts A61226 */
|
||||||
@ -151,4 +151,8 @@ int burn_abort_5(int patience,
|
|||||||
int (*pacifier_func)(void *handle, int patience, int elapsed),
|
int (*pacifier_func)(void *handle, int patience, int elapsed),
|
||||||
void *handle, int elapsed, int flag);
|
void *handle, int elapsed, int flag);
|
||||||
|
|
||||||
|
/* ts B10730 */
|
||||||
|
/* Send a default mode page 05 to CD and DVD-R-oids */
|
||||||
|
int burn_drive_send_default_page_05(struct burn_drive *d, int flag);
|
||||||
|
|
||||||
#endif /* __DRIVE */
|
#endif /* __DRIVE */
|
||||||
|
@ -625,7 +625,9 @@ void burn_fifo_next_interval(struct burn_source *source,
|
|||||||
|
|
||||||
*interval_min_fill = fs->interval_min_fill;
|
*interval_min_fill = fs->interval_min_fill;
|
||||||
ret = burn_fifo_inquire_status(source,
|
ret = burn_fifo_inquire_status(source,
|
||||||
&size, &free_bytes, &status_text);
|
&size, &free_bytes, &status_text);
|
||||||
|
if (ret < 0)
|
||||||
|
return;
|
||||||
fs->interval_min_fill = size - free_bytes - 1;
|
fs->interval_min_fill = size - free_bytes - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,12 @@ void *burn_alloc_mem(size_t size, size_t count, int flag);
|
|||||||
ret= -1; goto ex; \
|
ret= -1; goto ex; \
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
#define BURN_ALLOC_MEM_VOID(pt, typ, count) { \
|
||||||
|
pt= (typ *) burn_alloc_mem(sizeof(typ), (size_t) (count), 0); \
|
||||||
|
if(pt == NULL) { \
|
||||||
|
goto ex; \
|
||||||
|
} }
|
||||||
|
|
||||||
#define BURN_FREE_MEM(pt) { \
|
#define BURN_FREE_MEM(pt) { \
|
||||||
if(pt != NULL) \
|
if(pt != NULL) \
|
||||||
free((char *) pt); \
|
free((char *) pt); \
|
||||||
|
@ -561,9 +561,9 @@ struct burn_drive_info
|
|||||||
char revision[5];
|
char revision[5];
|
||||||
|
|
||||||
/** Invalid: Was: "Location of the drive in the filesystem." */
|
/** Invalid: Was: "Location of the drive in the filesystem." */
|
||||||
/** This string has no meaning any more. Once it stored the persistent
|
/** This string has no meaning any more. Once it stored the drive
|
||||||
drive address. Now always use function burn_drive_d_get_adr() to
|
device file address. Now always use function burn_drive_d_get_adr()
|
||||||
inquire a persistent address. ^^^^^^ ALWAYS ^^^^^^^^ */
|
to inquire a device file address. ^^^^^ ALWAYS ^^^^^^^*/
|
||||||
char location[17];
|
char location[17];
|
||||||
|
|
||||||
/** Can the drive read DVD-RAM discs */
|
/** Can the drive read DVD-RAM discs */
|
||||||
@ -782,7 +782,7 @@ int burn_abort_pacifier(void *handle, int patience, int elapsed);
|
|||||||
void burn_set_verbosity(int level);
|
void burn_set_verbosity(int level);
|
||||||
|
|
||||||
/* ts A91111 */
|
/* ts A91111 */
|
||||||
/** Enable resp. disable logging of SCSI commands (currently GNU/Linux only).
|
/** Enable resp. disable logging of SCSI commands.
|
||||||
This call can be made at any time - even before burn_initialize().
|
This call can be made at any time - even before burn_initialize().
|
||||||
It is in effect for all active drives and currently not very thread
|
It is in effect for all active drives and currently not very thread
|
||||||
safe for multiple drives.
|
safe for multiple drives.
|
||||||
@ -840,7 +840,7 @@ void burn_allow_untested_profiles(int yes);
|
|||||||
|
|
||||||
|
|
||||||
/* ts A60823 */
|
/* ts A60823 */
|
||||||
/** Aquire a drive with known persistent address.
|
/** Aquire a drive with known device file address.
|
||||||
|
|
||||||
This is the sysadmin friendly way to open one drive and to leave all
|
This is the sysadmin friendly way to open one drive and to leave all
|
||||||
others untouched. It bundles the following API calls to form a
|
others untouched. It bundles the following API calls to form a
|
||||||
@ -912,7 +912,7 @@ void burn_allow_untested_profiles(int yes);
|
|||||||
when it is no longer needed.
|
when it is no longer needed.
|
||||||
This is a result from call burn_drive_scan(). See there.
|
This is a result from call burn_drive_scan(). See there.
|
||||||
Use with driveno 0 only.
|
Use with driveno 0 only.
|
||||||
@param adr The persistent address of the desired drive. Either once
|
@param adr The device file address of the desired drive. Either once
|
||||||
obtained by burn_drive_d_get_adr() or composed skillfully by
|
obtained by burn_drive_d_get_adr() or composed skillfully by
|
||||||
application resp. its user. E.g. "/dev/sr0".
|
application resp. its user. E.g. "/dev/sr0".
|
||||||
Consider to preprocess it by burn_drive_convert_fs_adr().
|
Consider to preprocess it by burn_drive_convert_fs_adr().
|
||||||
@ -994,25 +994,25 @@ void burn_drive_info_free(struct burn_drive_info drive_infos[]);
|
|||||||
|
|
||||||
/* ts A60823 */
|
/* ts A60823 */
|
||||||
/* @since 0.2.2 */
|
/* @since 0.2.2 */
|
||||||
/** Maximum length+1 to expect with a persistent drive address string */
|
/** Maximum length+1 to expect with a drive device file address string */
|
||||||
#define BURN_DRIVE_ADR_LEN 1024
|
#define BURN_DRIVE_ADR_LEN 1024
|
||||||
|
|
||||||
/* ts A70906 */
|
/* ts A70906 */
|
||||||
/** Inquire the persistent address of the given drive.
|
/** Inquire the device file address of the given drive.
|
||||||
@param drive The drive to inquire.
|
@param drive The drive to inquire.
|
||||||
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN
|
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN
|
||||||
characters size. The persistent address gets copied to it.
|
characters size. The device file address gets copied to it.
|
||||||
@return >0 success , <=0 error (due to libburn internal problem)
|
@return >0 success , <=0 error (due to libburn internal problem)
|
||||||
@since 0.4.0
|
@since 0.4.0
|
||||||
*/
|
*/
|
||||||
int burn_drive_d_get_adr(struct burn_drive *drive, char adr[]);
|
int burn_drive_d_get_adr(struct burn_drive *drive, char adr[]);
|
||||||
|
|
||||||
/* A60823 */
|
/* A60823 */
|
||||||
/** Inquire the persistent address of a drive via a given drive_info object.
|
/** Inquire the device file address of a drive via a given drive_info object.
|
||||||
(Note: This is a legacy call.)
|
(Note: This is a legacy call.)
|
||||||
@param drive_info The drive to inquire.Usually some &(drive_infos[driveno])
|
@param drive_info The drive to inquire.Usually some &(drive_infos[driveno])
|
||||||
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN
|
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN
|
||||||
characters size. The persistent address gets copied to it.
|
characters size. The device file address gets copied to it.
|
||||||
@return >0 success , <=0 error (due to libburn internal problem)
|
@return >0 success , <=0 error (due to libburn internal problem)
|
||||||
@since 0.2.6
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
@ -1020,21 +1020,23 @@ int burn_drive_get_adr(struct burn_drive_info *drive_info, char adr[]);
|
|||||||
|
|
||||||
|
|
||||||
/* ts A60922 ticket 33 */
|
/* ts A60922 ticket 33 */
|
||||||
/** Evaluate whether the given address would be a possible persistent drive
|
/** Evaluate whether the given address would be a drive device file address
|
||||||
address of libburn.
|
which could be listed by a run of burn_drive_scan(). No check is made
|
||||||
|
whether a device file with this address exists or whether it leads
|
||||||
|
to a usable MMC drive.
|
||||||
@return 1 means yes, 0 means no
|
@return 1 means yes, 0 means no
|
||||||
@since 0.2.6
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
int burn_drive_is_enumerable_adr(char *adr);
|
int burn_drive_is_enumerable_adr(char *adr);
|
||||||
|
|
||||||
/* ts A60922 ticket 33 */
|
/* ts A60922 ticket 33 */
|
||||||
/** Try to convert a given existing filesystem address into a persistent drive
|
/** Try to convert a given existing filesystem address into a drive device file
|
||||||
address. This succeeds with symbolic links or if a hint about the drive's
|
address. This succeeds with symbolic links or if a hint about the drive's
|
||||||
system address can be read from the filesystem object and a matching drive
|
system address can be read from the filesystem object and a matching drive
|
||||||
is found.
|
is found.
|
||||||
@param path The address of an existing file system object
|
@param path The address of an existing file system object
|
||||||
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN
|
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN
|
||||||
characters size. The persistent address gets copied to it.
|
characters size. The device file address gets copied to it.
|
||||||
@return 1 = success , 0 = failure , -1 = severe error
|
@return 1 = success , 0 = failure , -1 = severe error
|
||||||
@since 0.2.6
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
@ -1042,7 +1044,7 @@ int burn_drive_convert_fs_adr(char *path, char adr[]);
|
|||||||
|
|
||||||
/* ts A60923 */
|
/* ts A60923 */
|
||||||
/** Try to convert a given SCSI address of bus,host,channel,target,lun into
|
/** Try to convert a given SCSI address of bus,host,channel,target,lun into
|
||||||
a persistent drive address. If a SCSI address component parameter is < 0
|
a drive device file address. If a SCSI address component parameter is < 0
|
||||||
then it is not decisive and the first enumerated address which matches
|
then it is not decisive and the first enumerated address which matches
|
||||||
the >= 0 parameters is taken as result.
|
the >= 0 parameters is taken as result.
|
||||||
Note: bus and (host,channel) are supposed to be redundant.
|
Note: bus and (host,channel) are supposed to be redundant.
|
||||||
@ -1052,17 +1054,50 @@ int burn_drive_convert_fs_adr(char *path, char adr[]);
|
|||||||
@param target_no "Target Number" or "SCSI Id" (a device)
|
@param target_no "Target Number" or "SCSI Id" (a device)
|
||||||
@param lun_no "Logical Unit Number" (a sub device)
|
@param lun_no "Logical Unit Number" (a sub device)
|
||||||
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN
|
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN
|
||||||
characters size. The persistent address gets copied to it.
|
characters size. The device file address gets copied to it.
|
||||||
@return 1 = success , 0 = failure , -1 = severe error
|
@return 1 = success , 0 = failure , -1 = severe error
|
||||||
@since 0.2.6
|
@since 0.2.6
|
||||||
*/
|
*/
|
||||||
int burn_drive_convert_scsi_adr(int bus_no, int host_no, int channel_no,
|
int burn_drive_convert_scsi_adr(int bus_no, int host_no, int channel_no,
|
||||||
int target_no, int lun_no, char adr[]);
|
int target_no, int lun_no, char adr[]);
|
||||||
|
|
||||||
|
/* ts B10728 */
|
||||||
|
/** Try to convert a given drive device file address into the address of a
|
||||||
|
symbolic link that points to this drive address.
|
||||||
|
Modern GNU/Linux systems may shuffle drive addresses from boot to boot.
|
||||||
|
The udev daemon is supposed to create links which always point to the
|
||||||
|
same drive, regardless of its system address.
|
||||||
|
This call tries to find such links.
|
||||||
|
@param dev_adr Should contain a drive address as returned by
|
||||||
|
burn_drive_scan().
|
||||||
|
@param link_adr An application provided array of at least
|
||||||
|
BURN_DRIVE_ADR_LEN characters size. The found link
|
||||||
|
address gets copied to it.
|
||||||
|
@param dir_adr The address of the directory where to look for links.
|
||||||
|
Normally: "/dev"
|
||||||
|
@param templ An array of pointers to name templates, which
|
||||||
|
links have to match. A symbolic link in dir_adr matches
|
||||||
|
a name template if it begins by that text. E.g.
|
||||||
|
link address "/dev/dvdrw1" matches template "dvdrw".
|
||||||
|
If templ is NULL, then the default array gets used:
|
||||||
|
{"dvdrw", "cdrw", "dvd", "cdrom", "cd"}
|
||||||
|
If several links would match, then a link will win,
|
||||||
|
which matches the template with the lowest array index.
|
||||||
|
Among these candidates, the one with the lowest strcmp()
|
||||||
|
rank will be chosen as link_adr.
|
||||||
|
@param num_templ Number of array elements in templ.
|
||||||
|
@param flag Bitfield for control purposes. Unused yet. Submit 0.
|
||||||
|
@return <0 severe error, 0 failed to search, 2 nothing found
|
||||||
|
1 success, link_adr is valid
|
||||||
|
@since 1.1.4
|
||||||
|
*/
|
||||||
|
int burn_lookup_device_link(char *dev_adr, char link_adr[],
|
||||||
|
char *dir_adr, char **templ, int num_templ, int flag);
|
||||||
|
|
||||||
/* ts A60923 - A61005 */
|
/* ts A60923 - A61005 */
|
||||||
/** Try to obtain bus,host,channel,target,lun from path. If there is an SCSI
|
/** Try to obtain bus,host,channel,target,lun from path. If there is an SCSI
|
||||||
address at all, then this call should succeed with a persistent
|
address at all, then this call should succeed with a drive device file
|
||||||
drive address obtained via burn_drive_d_get_adr(). It is also supposed to
|
address obtained via burn_drive_d_get_adr(). It is also supposed to
|
||||||
succeed with any device file of a (possibly emulated) SCSI device.
|
succeed with any device file of a (possibly emulated) SCSI device.
|
||||||
@return 1 = success , 0 = failure , -1 = severe error
|
@return 1 = success , 0 = failure , -1 = severe error
|
||||||
@since 0.2.6
|
@since 0.2.6
|
||||||
@ -1111,6 +1146,17 @@ int burn_drive_probe_cd_write_modes(struct burn_drive_info *drive_info);
|
|||||||
int burn_drive_snooze(struct burn_drive *d, int flag);
|
int burn_drive_snooze(struct burn_drive *d, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/** Re-assess drive and media status. This should be done after a drive
|
||||||
|
underwent a status change and shall be further used without intermediate
|
||||||
|
burn_drive_release(), burn_drive_grab(). E.g. after blanking or burning.
|
||||||
|
@param drive The already grabbed drive to re-assess.
|
||||||
|
@param flag Unused yet. Submit 0.
|
||||||
|
@return 1 success , <= 0 could not determine drive and media state
|
||||||
|
@since 1.1.8
|
||||||
|
*/
|
||||||
|
int burn_drive_re_assess(struct burn_drive *d, int flag);
|
||||||
|
|
||||||
|
|
||||||
/** Release a drive. This should not be done until the drive is no longer
|
/** Release a drive. This should not be done until the drive is no longer
|
||||||
busy (see burn_drive_get_status).
|
busy (see burn_drive_get_status).
|
||||||
@param drive The drive to release.
|
@param drive The drive to release.
|
||||||
@ -1261,6 +1307,27 @@ int burn_disc_get_cd_info(struct burn_drive *d, char disc_type[80],
|
|||||||
int burn_disc_get_bd_spare_info(struct burn_drive *d,
|
int burn_disc_get_bd_spare_info(struct burn_drive *d,
|
||||||
int *alloc_blocks, int *free_blocks, int flag);
|
int *alloc_blocks, int *free_blocks, int flag);
|
||||||
|
|
||||||
|
/* ts B10801 */
|
||||||
|
/** Retrieve some media information which is mainly specific to media of
|
||||||
|
the DVD-R family: DVD-R , DVD-RW , DVD-R DL , HD DVD-R
|
||||||
|
Currently the information cannot be retrieved from other media types.
|
||||||
|
@param d The drive to query.
|
||||||
|
@param disk_category returns DVD Book to which the media complies
|
||||||
|
@param book_name returns a pointer to the book name of disk_category.
|
||||||
|
This memory is static. Do not alter or free it !
|
||||||
|
@param part_version returns the Media Version in the DVD Book
|
||||||
|
@param num_layers returns the number of media layers
|
||||||
|
@param num_blocks returns the number of blocks between pysical start
|
||||||
|
and physical end of the media
|
||||||
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@return 1 = reply prarameters are valid,
|
||||||
|
<=0 = reply is invalid (e.g. because no DVD-R)
|
||||||
|
@since 1.1.4
|
||||||
|
*/
|
||||||
|
int burn_disc_get_phys_format_info(struct burn_drive *d, int *disk_category,
|
||||||
|
char **book_name, int *part_version, int *num_layers,
|
||||||
|
int *num_blocks, int flag);
|
||||||
|
|
||||||
/* ts A61110 */
|
/* ts A61110 */
|
||||||
/** Read start lba and Next Writeable Address of a track from media.
|
/** Read start lba and Next Writeable Address of a track from media.
|
||||||
Usually a track lba is obtained from the result of burn_track_get_entry().
|
Usually a track lba is obtained from the result of burn_track_get_entry().
|
||||||
@ -1294,6 +1361,30 @@ int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
|
|||||||
*/
|
*/
|
||||||
int burn_disc_next_track_is_damaged(struct burn_drive *d, int flag);
|
int burn_disc_next_track_is_damaged(struct burn_drive *d, int flag);
|
||||||
|
|
||||||
|
/* ts B10527 */
|
||||||
|
/** Try to close the last track and session of media which have bit0 set in
|
||||||
|
the return value of call burn_disc_next_track_is_damaged().
|
||||||
|
Whether it helps depends much on the reason why the media is reported
|
||||||
|
as damaged by the drive.
|
||||||
|
This call works only for profiles 0x09 CD-R, 0x0a CD-RW, 0x11 DVD-R,
|
||||||
|
0x14 DVD-RW sequential, 0x1b DVD+R, 0x2b DVD+R DL, 0x41 BD-R sequential.
|
||||||
|
Note: After writing it is advised to give up the drive and to grab it again
|
||||||
|
in order to learn about its view on the new media state.
|
||||||
|
@param o Write options created by burn_write_opts_new() and
|
||||||
|
manipulated by burn_write_opts_set_multi().
|
||||||
|
burn_write_opts_set_write_type() should be set to
|
||||||
|
BURN_WRITE_TAO, burn_write_opts_set_simulate() should be
|
||||||
|
set to 0.
|
||||||
|
@param flag Bitfield for control purposes
|
||||||
|
bit0= force close, even if no damage was seen
|
||||||
|
@return <=0 media not marked as damaged, or media type not suitable,
|
||||||
|
or closing attempted but failed
|
||||||
|
1= attempt finished without error indication
|
||||||
|
@since 1.1.0
|
||||||
|
*/
|
||||||
|
int burn_disc_close_damaged(struct burn_write_opts *o, int flag);
|
||||||
|
|
||||||
|
|
||||||
/* ts A70131 */
|
/* ts A70131 */
|
||||||
/** Read start lba of the first track in the last complete session.
|
/** Read start lba of the first track in the last complete session.
|
||||||
This is the first parameter of mkisofs option -C. The second parameter
|
This is the first parameter of mkisofs option -C. The second parameter
|
||||||
@ -1315,6 +1406,9 @@ int burn_disc_get_msc1(struct burn_drive *d, int *start_lba);
|
|||||||
An eventual start address from burn_write_opts_set_start_byte() will be
|
An eventual start address from burn_write_opts_set_start_byte() will be
|
||||||
subtracted from the obtained capacity estimation. Negative results get
|
subtracted from the obtained capacity estimation. Negative results get
|
||||||
defaulted to 0.
|
defaulted to 0.
|
||||||
|
If the drive is actually a file in a large filesystem or a large block
|
||||||
|
device, then the capacity is curbed to a maximum of 0x7ffffff0 blocks
|
||||||
|
= 4 TB - 32 KB.
|
||||||
@param d The drive to query.
|
@param d The drive to query.
|
||||||
@param o If not NULL: write parameters to be set on drive before query
|
@param o If not NULL: write parameters to be set on drive before query
|
||||||
@return number of most probably available free bytes
|
@return number of most probably available free bytes
|
||||||
@ -1608,8 +1702,13 @@ int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
|
|||||||
of data and audio tracks. You must use BURN_WRITE_TAO for such sessions.
|
of data and audio tracks. You must use BURN_WRITE_TAO for such sessions.
|
||||||
To be set by burn_write_opts_set_write_type().
|
To be set by burn_write_opts_set_write_type().
|
||||||
Note: This function is not suitable for overwriting data in the middle of
|
Note: This function is not suitable for overwriting data in the middle of
|
||||||
a valid data area because it is allowed to append trailing data.
|
a valid data area because it is allowed to append trailing data.
|
||||||
For exact random access overwriting use burn_random_access_write().
|
For exact random access overwriting use burn_random_access_write().
|
||||||
|
Note: After writing it is advised to give up the drive and to grab it again
|
||||||
|
in order to learn about its view on the new media state.
|
||||||
|
Note: Before mounting the written media it might be necessary to eject
|
||||||
|
and reload in order to allow the operating system to notice the new
|
||||||
|
media state.
|
||||||
@param o The options for the writing operation.
|
@param o The options for the writing operation.
|
||||||
@param disc The struct burn_disc * that described the disc to be created
|
@param disc The struct burn_disc * that described the disc to be created
|
||||||
*/
|
*/
|
||||||
@ -2173,7 +2272,11 @@ int burn_drive_set_buffer_waiting(struct burn_drive *d, int enable,
|
|||||||
int min_percent, int max_percent);
|
int min_percent, int max_percent);
|
||||||
|
|
||||||
|
|
||||||
/* these are for my debugging, they will disappear */
|
/* these are for my [Derek Foreman's ?] debugging, they will disappear */
|
||||||
|
/* ts B11012 :
|
||||||
|
Of course, API symbols will not disappear. But these functions are of
|
||||||
|
few use, as they only print DEBUG messages.
|
||||||
|
*/
|
||||||
void burn_structure_print_disc(struct burn_disc *d);
|
void burn_structure_print_disc(struct burn_disc *d);
|
||||||
void burn_structure_print_session(struct burn_session *s);
|
void burn_structure_print_session(struct burn_session *s);
|
||||||
void burn_structure_print_track(struct burn_track *t);
|
void burn_structure_print_track(struct burn_track *t);
|
||||||
@ -2230,7 +2333,7 @@ void burn_write_opts_set_format(struct burn_write_opts *opts, int format);
|
|||||||
This corresponds to the Test Write bit in MMC mode page 05h. Several media
|
This corresponds to the Test Write bit in MMC mode page 05h. Several media
|
||||||
types do not support this. See struct burn_multi_caps.might_simulate for
|
types do not support this. See struct burn_multi_caps.might_simulate for
|
||||||
actual availability of this feature.
|
actual availability of this feature.
|
||||||
If the media is suitable, the drive will perform burn_write_disc() as a
|
If the media is suitable, the drive will perform burn_disc_write() as a
|
||||||
simulation instead of effective write operations. This means that the
|
simulation instead of effective write operations. This means that the
|
||||||
media content and burn_disc_get_status() stay unchanged.
|
media content and burn_disc_get_status() stay unchanged.
|
||||||
Note: With stdio-drives, the target file gets eventually created, opened,
|
Note: With stdio-drives, the target file gets eventually created, opened,
|
||||||
@ -2707,8 +2810,8 @@ void burn_version(int *major, int *minor, int *micro);
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
#define burn_header_version_major 1
|
#define burn_header_version_major 1
|
||||||
#define burn_header_version_minor 0
|
#define burn_header_version_minor 1
|
||||||
#define burn_header_version_micro 7
|
#define burn_header_version_micro 8
|
||||||
/** Note:
|
/** Note:
|
||||||
Above version numbers are also recorded in configure.ac because libtool
|
Above version numbers are also recorded in configure.ac because libtool
|
||||||
wants them as parameters at build time.
|
wants them as parameters at build time.
|
||||||
@ -2984,6 +3087,8 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
|
|||||||
can be read via burn_read_data() although some of them may never have been
|
can be read via burn_read_data() although some of them may never have been
|
||||||
recorded. If tracks are recognizable then it is better to only read
|
recorded. If tracks are recognizable then it is better to only read
|
||||||
LBAs which are part of some track.
|
LBAs which are part of some track.
|
||||||
|
If the drive is actually a large file or block device, then the capacity
|
||||||
|
is curbed to a maximum of 0x7ffffff0 blocks = 4 TB - 32 KB.
|
||||||
@param d The drive from which to read
|
@param d The drive from which to read
|
||||||
@param capacity Will return the result if valid
|
@param capacity Will return the result if valid
|
||||||
@param flag Bitfield for control purposes: Unused yet, submit 0.
|
@param flag Bitfield for control purposes: Unused yet, submit 0.
|
||||||
@ -3035,6 +3140,8 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
|||||||
3= stdio-drive, sequential, write-only
|
3= stdio-drive, sequential, write-only
|
||||||
4= stdio-drive, random access, read-only
|
4= stdio-drive, random access, read-only
|
||||||
(only if enabled by burn_allow_drive_role_4())
|
(only if enabled by burn_allow_drive_role_4())
|
||||||
|
5= stdio-drive, random access, write-only
|
||||||
|
(only if enabled by burn_allow_drive_role_4())
|
||||||
@since 0.4.0
|
@since 0.4.0
|
||||||
*/
|
*/
|
||||||
int burn_drive_get_drive_role(struct burn_drive *d);
|
int burn_drive_get_drive_role(struct burn_drive *d);
|
||||||
|
@ -20,6 +20,7 @@ burn_disc_get_formats;
|
|||||||
burn_disc_get_media_id;
|
burn_disc_get_media_id;
|
||||||
burn_disc_get_msc1;
|
burn_disc_get_msc1;
|
||||||
burn_disc_get_multi_caps;
|
burn_disc_get_multi_caps;
|
||||||
|
burn_disc_get_phys_format_info;
|
||||||
burn_disc_get_profile;
|
burn_disc_get_profile;
|
||||||
burn_disc_get_sectors;
|
burn_disc_get_sectors;
|
||||||
burn_disc_get_sessions;
|
burn_disc_get_sessions;
|
||||||
@ -58,6 +59,7 @@ burn_drive_is_enumerable_adr;
|
|||||||
burn_drive_leave_locked;
|
burn_drive_leave_locked;
|
||||||
burn_drive_obtain_scsi_adr;
|
burn_drive_obtain_scsi_adr;
|
||||||
burn_drive_probe_cd_write_modes;
|
burn_drive_probe_cd_write_modes;
|
||||||
|
burn_drive_re_assess;
|
||||||
burn_drive_release;
|
burn_drive_release;
|
||||||
burn_drive_scan;
|
burn_drive_scan;
|
||||||
burn_drive_scan_and_grab;
|
burn_drive_scan_and_grab;
|
||||||
@ -81,6 +83,7 @@ burn_guess_manufacturer;
|
|||||||
burn_initialize;
|
burn_initialize;
|
||||||
burn_is_aborting;
|
burn_is_aborting;
|
||||||
burn_lba_to_msf;
|
burn_lba_to_msf;
|
||||||
|
burn_lookup_device_link;
|
||||||
burn_msf_to_lba;
|
burn_msf_to_lba;
|
||||||
burn_msf_to_sectors;
|
burn_msf_to_sectors;
|
||||||
burn_msgs_obtain;
|
burn_msgs_obtain;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
/* libdax_msgs
|
/* libdax_msgs
|
||||||
Message handling facility of libdax.
|
Message handling facility of libburn and libisofs.
|
||||||
Copyright (C) 2006-2011 Thomas Schmitt <scdbackup@gmx.net>,
|
Copyright (C) 2006-2011 Thomas Schmitt <scdbackup@gmx.net>,
|
||||||
provided under GPL version 2 or later.
|
provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
@ -574,6 +574,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
|||||||
0x00020186 (WARNING,HIGH) = Track damaged and not closed
|
0x00020186 (WARNING,HIGH) = Track damaged and not closed
|
||||||
0x00020187 (NOTE,HIGH) = Track not marked as damaged. No action taken.
|
0x00020187 (NOTE,HIGH) = Track not marked as damaged. No action taken.
|
||||||
0x00020188 (FAILURE,HIGH) = Cannot close damaged track on given media type
|
0x00020188 (FAILURE,HIGH) = Cannot close damaged track on given media type
|
||||||
|
0x00020189 (FATAL,HIGH) = Drive is already grabbed by libburn
|
||||||
|
|
||||||
libdax_audioxtr:
|
libdax_audioxtr:
|
||||||
0x00020200 (SORRY,HIGH) = Cannot open audio source file
|
0x00020200 (SORRY,HIGH) = Cannot open audio source file
|
||||||
|
160
libburn/mmc.c
160
libburn/mmc.c
@ -305,13 +305,12 @@ void mmc_send_cue_sheet(struct burn_drive *d, struct cue_sheet *s)
|
|||||||
{
|
{
|
||||||
struct buffer *buf = NULL;
|
struct buffer *buf = NULL;
|
||||||
struct command *c;
|
struct command *c;
|
||||||
int ret = 1;
|
|
||||||
|
|
||||||
c = &(d->casual_command);
|
c = &(d->casual_command);
|
||||||
mmc_start_if_needed(d, 0);
|
mmc_start_if_needed(d, 0);
|
||||||
if (mmc_function_spy(d, "mmc_send_cue_sheet") <= 0)
|
if (mmc_function_spy(d, "mmc_send_cue_sheet") <= 0)
|
||||||
return;
|
return;
|
||||||
BURN_ALLOC_MEM(buf, struct buffer, 1);
|
BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
|
||||||
scsi_init_command(c, MMC_SEND_CUE_SHEET, sizeof(MMC_SEND_CUE_SHEET));
|
scsi_init_command(c, MMC_SEND_CUE_SHEET, sizeof(MMC_SEND_CUE_SHEET));
|
||||||
c->retry = 1;
|
c->retry = 1;
|
||||||
c->page = buf;
|
c->page = buf;
|
||||||
@ -445,6 +444,11 @@ int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa)
|
|||||||
*nwa = mmc_four_char_to_int(data + 12);
|
*nwa = mmc_four_char_to_int(data + 12);
|
||||||
num = mmc_four_char_to_int(data + 16);
|
num = mmc_four_char_to_int(data + 16);
|
||||||
|
|
||||||
|
/* Pioneer BD-RW BDR-205 and LITE-ON LTR-48125S return -150 as *nwa
|
||||||
|
of blank media */
|
||||||
|
if (*nwa < *lba && d->status == BURN_DISC_BLANK)
|
||||||
|
*nwa = *lba;
|
||||||
|
|
||||||
#ifdef Libburn_pioneer_dvr_216d_load_mode5
|
#ifdef Libburn_pioneer_dvr_216d_load_mode5
|
||||||
/* >>> memorize track mode : data[6] & 0xf */;
|
/* >>> memorize track mode : data[6] & 0xf */;
|
||||||
#endif
|
#endif
|
||||||
@ -611,10 +615,9 @@ void mmc_get_event(struct burn_drive *d)
|
|||||||
struct command *c;
|
struct command *c;
|
||||||
int alloc_len = 8, len, evt_code, loops = 0;
|
int alloc_len = 8, len, evt_code, loops = 0;
|
||||||
unsigned char *evt;
|
unsigned char *evt;
|
||||||
int ret;
|
|
||||||
|
|
||||||
c = &(d->casual_command);
|
c = &(d->casual_command);
|
||||||
BURN_ALLOC_MEM(buf, struct buffer, 1);
|
BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
|
||||||
if (mmc_function_spy(d, "mmc_get_event") <= 0)
|
if (mmc_function_spy(d, "mmc_get_event") <= 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
|
||||||
@ -846,8 +849,6 @@ void mmc_write_12(struct burn_drive *d, int start, struct buffer *buf)
|
|||||||
|
|
||||||
len = buf->sectors;
|
len = buf->sectors;
|
||||||
|
|
||||||
burn_print(100, "trying to write %d at %d\n", len, start);
|
|
||||||
|
|
||||||
scsi_init_command(c, MMC_WRITE_12, sizeof(MMC_WRITE_12));
|
scsi_init_command(c, MMC_WRITE_12, sizeof(MMC_WRITE_12));
|
||||||
c->retry = 1;
|
c->retry = 1;
|
||||||
mmc_int_to_four_char(c->opcode + 2, start);
|
mmc_int_to_four_char(c->opcode + 2, start);
|
||||||
@ -910,8 +911,6 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
|
|||||||
/* ts A61009 : buffer fill problems are to be handled by caller */
|
/* ts A61009 : buffer fill problems are to be handled by caller */
|
||||||
/* a ssert(buf->bytes >= buf->sectors);*/ /* can be == at 0... */
|
/* a ssert(buf->bytes >= buf->sectors);*/ /* can be == at 0... */
|
||||||
|
|
||||||
burn_print(100, "trying to write %d at %d\n", len, start);
|
|
||||||
|
|
||||||
/* ts A70711 */
|
/* ts A70711 */
|
||||||
if(d->wait_for_buffer_free)
|
if(d->wait_for_buffer_free)
|
||||||
mmc_wait_for_buffer_free(d, buf);
|
mmc_wait_for_buffer_free(d, buf);
|
||||||
@ -1340,7 +1339,7 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
|
|||||||
struct buffer *buf = NULL;
|
struct buffer *buf = NULL;
|
||||||
struct command *c = NULL;
|
struct command *c = NULL;
|
||||||
int dlen;
|
int dlen;
|
||||||
int i, bpl= 12, old_alloc_len, t_idx, ret;
|
int i, old_alloc_len, t_idx, ret;
|
||||||
unsigned char *tdata;
|
unsigned char *tdata;
|
||||||
char *msg = NULL;
|
char *msg = NULL;
|
||||||
|
|
||||||
@ -1435,8 +1434,6 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
|
|||||||
{ret = 0; goto ex;}
|
{ret = 0; goto ex;}
|
||||||
tdata = c->page->data + 4;
|
tdata = c->page->data + 4;
|
||||||
|
|
||||||
burn_print(12, "TOC:\n");
|
|
||||||
|
|
||||||
d->disc = burn_disc_create();
|
d->disc = burn_disc_create();
|
||||||
if (d->disc == NULL) /* ts A70825 */
|
if (d->disc == NULL) /* ts A70825 */
|
||||||
{ret = 0; goto ex;}
|
{ret = 0; goto ex;}
|
||||||
@ -1450,20 +1447,9 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ts A61022 */
|
/* ts A61022 */
|
||||||
burn_print(bpl, "-----------------------------------\n");
|
|
||||||
|
|
||||||
for (i = 0; i < d->toc_entries; i++, tdata += 11) {
|
for (i = 0; i < d->toc_entries; i++, tdata += 11) {
|
||||||
|
|
||||||
/* ts A61022: was burn_print level 12 */
|
|
||||||
burn_print(bpl, "S %d, PT %2.2Xh, TNO %d :", tdata[0],tdata[3],
|
|
||||||
tdata[2]);
|
|
||||||
burn_print(bpl, " MSF(%d:%d:%d)", tdata[4],tdata[5],tdata[6]);
|
|
||||||
burn_print(bpl, " PMSF(%d:%d:%d %d)",
|
|
||||||
tdata[8], tdata[9], tdata[10],
|
|
||||||
burn_msf_to_lba(tdata[8], tdata[9], tdata[10]));
|
|
||||||
burn_print(bpl, " - control %d, adr %d\n", tdata[1] & 0xF,
|
|
||||||
tdata[1] >> 4);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
fprintf(stderr, "libburn_experimental: toc entry #%d : %d %d %d\n",i,tdata[8], tdata[9], tdata[10]);
|
fprintf(stderr, "libburn_experimental: toc entry #%d : %d %d %d\n",i,tdata[8], tdata[9], tdata[10]);
|
||||||
*/
|
*/
|
||||||
@ -1515,9 +1501,6 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
|
|||||||
&d->toc_entry[i];
|
&d->toc_entry[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts A61022 */
|
|
||||||
burn_print(bpl, "-----------------------------------\n");
|
|
||||||
|
|
||||||
/* ts A70131 : was (d->status != BURN_DISC_BLANK) */
|
/* ts A70131 : was (d->status != BURN_DISC_BLANK) */
|
||||||
if (d->status == BURN_DISC_UNREADY)
|
if (d->status == BURN_DISC_UNREADY)
|
||||||
d->status = BURN_DISC_FULL;
|
d->status = BURN_DISC_FULL;
|
||||||
@ -1587,6 +1570,8 @@ void mmc_read_toc(struct burn_drive *d)
|
|||||||
*/
|
*/
|
||||||
if (alloc_len >= 15)
|
if (alloc_len >= 15)
|
||||||
ret = mmc_read_toc_al(d, &alloc_len);
|
ret = mmc_read_toc_al(d, &alloc_len);
|
||||||
|
if (ret <= 0)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1750,6 +1735,7 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len)
|
|||||||
/* ts A70131 : had to move mmc_read_toc() to end of function */
|
/* ts A70131 : had to move mmc_read_toc() to end of function */
|
||||||
int do_read_toc = 0, disc_status, len, old_alloc_len;
|
int do_read_toc = 0, disc_status, len, old_alloc_len;
|
||||||
int ret, number_of_sessions = -1;
|
int ret, number_of_sessions = -1;
|
||||||
|
int key, asc, ascq;
|
||||||
|
|
||||||
BURN_ALLOC_MEM(buf, struct buffer, 1);
|
BURN_ALLOC_MEM(buf, struct buffer, 1);
|
||||||
BURN_ALLOC_MEM(c, struct command, 1);
|
BURN_ALLOC_MEM(c, struct command, 1);
|
||||||
@ -1759,6 +1745,8 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len)
|
|||||||
d->erasable = 0;
|
d->erasable = 0;
|
||||||
d->last_track_no = 1;
|
d->last_track_no = 1;
|
||||||
|
|
||||||
|
/* ts B10730 */
|
||||||
|
d->sent_default_page_05 = 0;
|
||||||
/* ts A70212 - A70215 */
|
/* ts A70212 - A70215 */
|
||||||
d->media_capacity_remaining = 0;
|
d->media_capacity_remaining = 0;
|
||||||
d->media_lba_limit = 0;
|
d->media_lba_limit = 0;
|
||||||
@ -1785,6 +1773,22 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len)
|
|||||||
d->issue_command(d, c);
|
d->issue_command(d, c);
|
||||||
|
|
||||||
if (c->error) {
|
if (c->error) {
|
||||||
|
spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
|
||||||
|
if (key == 5 && asc == 0x20 && ascq == 0) {
|
||||||
|
/* ts B11031 : qemu -cdrom does not know
|
||||||
|
051h READ DISC INFORMATION
|
||||||
|
*/
|
||||||
|
ret = mmc_read_toc_fmt0(d);
|
||||||
|
if (ret > 0) {
|
||||||
|
|
||||||
|
/* >>> ??? anything more to be set ? */;
|
||||||
|
|
||||||
|
mmc_read_capacity(d);
|
||||||
|
*alloc_len = 0;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
{ret = 0; goto ex;}
|
{ret = 0; goto ex;}
|
||||||
}
|
}
|
||||||
@ -2012,6 +2016,9 @@ void mmc_read_disc_info(struct burn_drive *d)
|
|||||||
fprintf(stderr,"LIBBURN_DEBUG: 51h alloc_len = %d , ret = %d\n",
|
fprintf(stderr,"LIBBURN_DEBUG: 51h alloc_len = %d , ret = %d\n",
|
||||||
alloc_len, ret);
|
alloc_len, ret);
|
||||||
*/
|
*/
|
||||||
|
if (ret <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
/* for now there is no need to inquire the variable lenght part */
|
/* for now there is no need to inquire the variable lenght part */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2020,7 +2027,7 @@ void mmc_read_atip(struct burn_drive *d)
|
|||||||
{
|
{
|
||||||
struct buffer *buf = NULL;
|
struct buffer *buf = NULL;
|
||||||
struct command *c = NULL;
|
struct command *c = NULL;
|
||||||
int alloc_len = 28, ret = 0;
|
int alloc_len = 28;
|
||||||
|
|
||||||
/* ts A61021 */
|
/* ts A61021 */
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
@ -2035,8 +2042,8 @@ void mmc_read_atip(struct burn_drive *d)
|
|||||||
4234, 5646, 7056, 8468, -12, -13, -14, -15};
|
4234, 5646, 7056, 8468, -12, -13, -14, -15};
|
||||||
/* 24, 32, 40, 48, -, -, -, - */
|
/* 24, 32, 40, 48, -, -, -, - */
|
||||||
|
|
||||||
BURN_ALLOC_MEM(buf, struct buffer, 1);
|
BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
|
||||||
BURN_ALLOC_MEM(c, struct command, 1);
|
BURN_ALLOC_MEM_VOID(c, struct command, 1);
|
||||||
mmc_start_if_needed(d, 1);
|
mmc_start_if_needed(d, 1);
|
||||||
if (mmc_function_spy(d, "mmc_read_atip") <= 0)
|
if (mmc_function_spy(d, "mmc_read_atip") <= 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
@ -2087,7 +2094,7 @@ void mmc_read_atip(struct burn_drive *d)
|
|||||||
fprintf(stderr,"libburn_experimental: Returned ATIP Data\n");
|
fprintf(stderr,"libburn_experimental: Returned ATIP Data\n");
|
||||||
for(i= 0; i<28; i++)
|
for(i= 0; i<28; i++)
|
||||||
fprintf(stderr,"%3.3d (0x%2.2x)%s",
|
fprintf(stderr,"%3.3d (0x%2.2x)%s",
|
||||||
data[i],data[i],((i+1)%5 ? " ":"\n"));
|
data[i],data[i],(((i + 1) % 5) ? " " : "\n"));
|
||||||
fprintf(stderr,"\n");
|
fprintf(stderr,"\n");
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -2197,7 +2204,7 @@ void mmc_read_sectors(struct burn_drive *d,
|
|||||||
const struct burn_read_opts *o, struct buffer *buf)
|
const struct burn_read_opts *o, struct buffer *buf)
|
||||||
{
|
{
|
||||||
int temp;
|
int temp;
|
||||||
int errorblock, req;
|
int req;
|
||||||
struct command *c;
|
struct command *c;
|
||||||
|
|
||||||
c = &(d->casual_command);
|
c = &(d->casual_command);
|
||||||
@ -2212,8 +2219,6 @@ void mmc_read_sectors(struct burn_drive *d,
|
|||||||
/* ts A61006 : i second that question */
|
/* ts A61006 : i second that question */
|
||||||
/* a ssert(d->busy); */
|
/* a ssert(d->busy); */
|
||||||
|
|
||||||
burn_print(12, "reading %d from %d\n", len, start);
|
|
||||||
|
|
||||||
scsi_init_command(c, MMC_READ_CD, sizeof(MMC_READ_CD));
|
scsi_init_command(c, MMC_READ_CD, sizeof(MMC_READ_CD));
|
||||||
c->retry = 1;
|
c->retry = 1;
|
||||||
temp = start;
|
temp = start;
|
||||||
@ -2249,19 +2254,6 @@ void mmc_read_sectors(struct burn_drive *d,
|
|||||||
c->page = buf;
|
c->page = buf;
|
||||||
c->dir = FROM_DRIVE;
|
c->dir = FROM_DRIVE;
|
||||||
d->issue_command(d, c);
|
d->issue_command(d, c);
|
||||||
|
|
||||||
if (c->error) {
|
|
||||||
burn_print(12, "got an error over here\n");
|
|
||||||
burn_print(12, "%d, %d, %d, %d\n", c->sense[3], c->sense[4],
|
|
||||||
c->sense[5], c->sense[6]);
|
|
||||||
errorblock =
|
|
||||||
(c->sense[3] << 24) + (c->sense[4] << 16) +
|
|
||||||
(c->sense[5] << 8) + c->sense[6];
|
|
||||||
c->page->sectors = errorblock - start + 1;
|
|
||||||
burn_print(1, "error on block %d\n", errorblock);
|
|
||||||
burn_print(12, "error on block %d\n", errorblock);
|
|
||||||
burn_print(12, "returning %d sectors\n", c->page->sectors);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mmc_erase(struct burn_drive *d, int fast)
|
void mmc_erase(struct burn_drive *d, int fast)
|
||||||
@ -2378,14 +2370,14 @@ int mmc_set_streaming(struct burn_drive *d,
|
|||||||
eff_end_lba = end_lba;
|
eff_end_lba = end_lba;
|
||||||
|
|
||||||
sprintf(msg, "mmc_set_streaming: end_lba=%d , r=%d , w=%d",
|
sprintf(msg, "mmc_set_streaming: end_lba=%d , r=%d , w=%d",
|
||||||
end_lba, r_speed, w_speed);
|
eff_end_lba, r_speed, w_speed);
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002,
|
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002,
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||||
msg, 0, 0);
|
msg, 0, 0);
|
||||||
|
|
||||||
/* start_lba is 0 , 1000 = 1 second as base time for data rate */
|
/* start_lba is 0 , 1000 = 1 second as base time for data rate */
|
||||||
for (b = 0; b < 4 ; b++) {
|
for (b = 0; b < 4 ; b++) {
|
||||||
pd[8+b] = (end_lba >> (24 - 8 * b)) & 0xff;
|
pd[8+b] = (eff_end_lba >> (24 - 8 * b)) & 0xff;
|
||||||
pd[12+b] = (r_speed >> (24 - 8 * b)) & 0xff;
|
pd[12+b] = (r_speed >> (24 - 8 * b)) & 0xff;
|
||||||
pd[16+b] = (1000 >> (24 - 8 * b)) & 0xff;
|
pd[16+b] = (1000 >> (24 - 8 * b)) & 0xff;
|
||||||
pd[20+b] = (w_speed >> (24 - 8 * b)) & 0xff;
|
pd[20+b] = (w_speed >> (24 - 8 * b)) & 0xff;
|
||||||
@ -2483,12 +2475,15 @@ void mmc_set_speed(struct burn_drive *d, int r, int w)
|
|||||||
static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
|
static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
|
||||||
{
|
{
|
||||||
struct buffer *buf = NULL;
|
struct buffer *buf = NULL;
|
||||||
int len, cp, descr_len = 0, feature_code, prf_number, only_current = 1;
|
int len, cp, descr_len = 0, feature_code, only_current = 1;
|
||||||
int old_alloc_len, only_current_profile = 0, key, asc, ascq, ret;
|
int old_alloc_len, only_current_profile = 0, key, asc, ascq, ret;
|
||||||
unsigned char *descr, *prf, *up_to, *prf_end;
|
unsigned char *descr, *prf, *up_to, *prf_end;
|
||||||
struct command *c = NULL;
|
struct command *c = NULL;
|
||||||
int phys_if_std = 0;
|
int phys_if_std = 0;
|
||||||
char *phys_name = "";
|
char *phys_name = "";
|
||||||
|
#ifdef Libburn_print_feature_descriptorS
|
||||||
|
int prf_number;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (*alloc_len < 8)
|
if (*alloc_len < 8)
|
||||||
{ret = 0; goto ex;}
|
{ret = 0; goto ex;}
|
||||||
@ -2655,9 +2650,9 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
|
|||||||
for (prf = descr + 4; prf + 2 < prf_end; prf += 4) {
|
for (prf = descr + 4; prf + 2 < prf_end; prf += 4) {
|
||||||
if (only_current_profile && !(prf[2] & 1))
|
if (only_current_profile && !(prf[2] & 1))
|
||||||
continue;
|
continue;
|
||||||
prf_number = (prf[0] << 8) | prf[1];
|
|
||||||
|
|
||||||
#ifdef Libburn_print_feature_descriptorS
|
#ifdef Libburn_print_feature_descriptorS
|
||||||
|
prf_number = (prf[0] << 8) | prf[1];
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"LIBBURN_EXPERIMENTAL : %s profile %4.4Xh \"%s\"\n",
|
"LIBBURN_EXPERIMENTAL : %s profile %4.4Xh \"%s\"\n",
|
||||||
prf[2] & 1 ? "+" : "-",
|
prf[2] & 1 ? "+" : "-",
|
||||||
@ -2710,7 +2705,7 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
|
|||||||
|
|
||||||
} else if (feature_code == 0x01) {
|
} else if (feature_code == 0x01) {
|
||||||
phys_if_std = (descr[4] << 24) | (descr[5] << 16) |
|
phys_if_std = (descr[4] << 24) | (descr[5] << 16) |
|
||||||
(descr[6] << 8) | descr[9];
|
(descr[6] << 8) | descr[7];
|
||||||
if (phys_if_std == 1)
|
if (phys_if_std == 1)
|
||||||
phys_name = "SCSI Family";
|
phys_name = "SCSI Family";
|
||||||
else if(phys_if_std == 2)
|
else if(phys_if_std == 2)
|
||||||
@ -2961,13 +2956,13 @@ void mmc_sync_cache(struct burn_drive *d)
|
|||||||
{
|
{
|
||||||
struct command *c = NULL;
|
struct command *c = NULL;
|
||||||
char *msg = NULL;
|
char *msg = NULL;
|
||||||
int key, asc, ascq, ret;
|
int key, asc, ascq;
|
||||||
|
|
||||||
if (mmc_function_spy(d, "mmc_sync_cache") <= 0)
|
if (mmc_function_spy(d, "mmc_sync_cache") <= 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
|
||||||
BURN_ALLOC_MEM(c, struct command, 1);
|
BURN_ALLOC_MEM_VOID(c, struct command, 1);
|
||||||
BURN_ALLOC_MEM(msg, char, 256);
|
BURN_ALLOC_MEM_VOID(msg, char, 256);
|
||||||
|
|
||||||
scsi_init_command(c, MMC_SYNC_CACHE, sizeof(MMC_SYNC_CACHE));
|
scsi_init_command(c, MMC_SYNC_CACHE, sizeof(MMC_SYNC_CACHE));
|
||||||
c->retry = 1;
|
c->retry = 1;
|
||||||
@ -3724,10 +3719,16 @@ static int mmc_get_write_performance_al(struct burn_drive *d,
|
|||||||
struct buffer *buf = NULL;
|
struct buffer *buf = NULL;
|
||||||
int len, i, b, num_descr, ret, old_alloc_len;
|
int len, i, b, num_descr, ret, old_alloc_len;
|
||||||
int exact_bit, read_speed, write_speed;
|
int exact_bit, read_speed, write_speed;
|
||||||
|
|
||||||
|
/* >>> ts B10702: This rule seems questionable:
|
||||||
|
TSST SH-203 delivers here for CD only 7040k
|
||||||
|
whereas mode page 2Ah gives 1412k to 7056k
|
||||||
|
*/
|
||||||
/* if this call delivers usable data then they should override
|
/* if this call delivers usable data then they should override
|
||||||
previously recorded min/max speed and not compete with them */
|
previously recorded min/max speed and not compete with them */
|
||||||
int min_write_speed = 0x7fffffff, max_write_speed = 0;
|
int min_write_speed = 0x7fffffff, max_write_speed = 0;
|
||||||
int min_read_speed = 0x7fffffff, max_read_speed = 0;
|
int min_read_speed = 0x7fffffff, max_read_speed = 0;
|
||||||
|
|
||||||
struct command *c = NULL;
|
struct command *c = NULL;
|
||||||
unsigned long end_lba;
|
unsigned long end_lba;
|
||||||
unsigned char *pd;
|
unsigned char *pd;
|
||||||
@ -3789,6 +3790,10 @@ static int mmc_get_write_performance_al(struct burn_drive *d,
|
|||||||
if (len < 12)
|
if (len < 12)
|
||||||
{ret = 0; goto ex;}
|
{ret = 0; goto ex;}
|
||||||
|
|
||||||
|
/* ts B10702 : overriding the questionable override rule */
|
||||||
|
min_write_speed = d->mdata->min_write_speed;
|
||||||
|
max_write_speed = d->mdata->max_write_speed;
|
||||||
|
|
||||||
pd = c->page->data;
|
pd = c->page->data;
|
||||||
if (num_descr > *max_descr)
|
if (num_descr > *max_descr)
|
||||||
num_descr = *max_descr;
|
num_descr = *max_descr;
|
||||||
@ -4471,6 +4476,55 @@ ex:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B10801
|
||||||
|
MMC-5, 6.23.3.2.1 Format Code 00h: Physical Format Information
|
||||||
|
6.23.3.2.16 Format Code 10h: Format Information of
|
||||||
|
Control Data Zone in the Lead-in
|
||||||
|
disk_category
|
||||||
|
*/
|
||||||
|
int mmc_get_phys_format_info(struct burn_drive *d, int *disk_category,
|
||||||
|
char **book_name, int *part_version, int *num_layers,
|
||||||
|
int *num_blocks, int flag)
|
||||||
|
{
|
||||||
|
int ret, reply_len, prf;
|
||||||
|
char *reply = NULL;
|
||||||
|
static char book_names[][16] = {
|
||||||
|
"DVD-ROM", "DVD-RAM", "DVD-R", "DVD-RW",
|
||||||
|
"HD DVD-ROM", "HD DVD-RAM", "HD DVD-R", "unknown",
|
||||||
|
"unknown", "DVD+RW", "DVD+R", "unknown", "unknown",
|
||||||
|
"unknown", "DVD+RW DL", "DVD+R DL", "unknown"
|
||||||
|
};
|
||||||
|
|
||||||
|
prf = d->current_profile;
|
||||||
|
if (!(prf == 0x11 || prf == 0x13 || prf == 0x14 || prf == 0x15 ||
|
||||||
|
prf == 0x51))
|
||||||
|
return 0; /* Not a [HD] DVD-R[W] loaded */
|
||||||
|
ret = mmc_read_disc_structure(d, 0, 0, 0x10, 12, &reply,
|
||||||
|
&reply_len, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
goto ex;
|
||||||
|
if(reply_len < 12) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||||
|
"READ DISC STRUCTURE format 10h: Less than 12 bytes",
|
||||||
|
0, 0);
|
||||||
|
{ret = 0; goto ex;}
|
||||||
|
}
|
||||||
|
*disk_category = (reply[0] >> 4) & 0xf;
|
||||||
|
*book_name = book_names[*disk_category];
|
||||||
|
*part_version = reply[0] & 0xf;
|
||||||
|
*num_layers = ((reply[2] >> 5) & 0x3) + 1;
|
||||||
|
*num_blocks = ((reply[9] << 16) | (reply[10] << 8) | reply[11]) -
|
||||||
|
((reply[5] << 16) | (reply[6] << 8) | reply[7]) + 1;
|
||||||
|
ret = 1;
|
||||||
|
ex:;
|
||||||
|
if (reply != NULL)
|
||||||
|
free(reply);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A61021 : the mmc specific part of sg.c:enumerate_common()
|
/* ts A61021 : the mmc specific part of sg.c:enumerate_common()
|
||||||
*/
|
*/
|
||||||
int mmc_setup_drive(struct burn_drive *d)
|
int mmc_setup_drive(struct burn_drive *d)
|
||||||
|
@ -110,4 +110,9 @@ int mmc_start_if_needed(struct burn_drive *d, int flag);
|
|||||||
int mmc_get_bd_spare_info(struct burn_drive *d,
|
int mmc_get_bd_spare_info(struct burn_drive *d,
|
||||||
int *alloc_blocks, int *free_blocks, int flag);
|
int *alloc_blocks, int *free_blocks, int flag);
|
||||||
|
|
||||||
|
/* ts B10801 */
|
||||||
|
int mmc_get_phys_format_info(struct burn_drive *d, int *disk_category,
|
||||||
|
char **book_name, int *part_version, int *num_layers,
|
||||||
|
int *num_blocks, int flag);
|
||||||
|
|
||||||
#endif /*__MMC*/
|
#endif /*__MMC*/
|
||||||
|
@ -115,7 +115,6 @@ drive, or only store a subset of the _opts structs in drives */
|
|||||||
while (1) {
|
while (1) {
|
||||||
seclen = burn_sector_length_read(d, o);
|
seclen = burn_sector_length_read(d, o);
|
||||||
|
|
||||||
burn_print(12, "received %d blocks\n", page.sectors);
|
|
||||||
for (i = 0; i < page.sectors; i++) {
|
for (i = 0; i < page.sectors; i++) {
|
||||||
burn_packet_process(d, page.data + seclen * i, o);
|
burn_packet_process(d, page.data + seclen * i, o);
|
||||||
d->track_end--;
|
d->track_end--;
|
||||||
@ -123,7 +122,6 @@ drive, or only store a subset of the _opts structs in drives */
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((d->cancel) || (drive_lba == LAST_SESSION_END(d))) {
|
if ((d->cancel) || (drive_lba == LAST_SESSION_END(d))) {
|
||||||
burn_print(1, "finished or cancelled\n");
|
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
if (!d->cancel)
|
if (!d->cancel)
|
||||||
d->toc->complete = 1;
|
d->toc->complete = 1;
|
||||||
@ -137,16 +135,14 @@ drive, or only store a subset of the _opts structs in drives */
|
|||||||
if (d->currtrack >
|
if (d->currtrack >
|
||||||
d->toc->session[d->currsession].lasttrack) {
|
d->toc->session[d->currsession].lasttrack) {
|
||||||
d->currsession++;
|
d->currsession++;
|
||||||
burn_print(12, "session switch to %d\n",
|
/* session switch to d->currsession */
|
||||||
d->currsession);
|
/* skipping a lead out */
|
||||||
burn_print(12, "skipping a lead out\n");
|
|
||||||
drive_lba = CURRENT_SESSION_START(d);
|
drive_lba = CURRENT_SESSION_START(d);
|
||||||
burn_print(12, "new lba %d\n", drive_lba);
|
|
||||||
/* XXX more of the same
|
/* XXX more of the same
|
||||||
end = burn_track_end(d, d->currsession,
|
end = burn_track_end(d, d->currsession,
|
||||||
d->currtrack);
|
d->currtrack);
|
||||||
*/ }
|
*/
|
||||||
burn_print(12, "track switch to %d\n", d->currtrack);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
page.sectors = 0;
|
page.sectors = 0;
|
||||||
@ -201,23 +197,21 @@ static int bitcount(unsigned char *data, int n)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void burn_packet_process(struct burn_drive *d, unsigned char *data,
|
void burn_packet_process(struct burn_drive *d, unsigned char *data,
|
||||||
const struct burn_read_opts *o)
|
const struct burn_read_opts *o)
|
||||||
{
|
{
|
||||||
unsigned char sub[96];
|
unsigned char sub[96];
|
||||||
unsigned short crc;
|
|
||||||
int ptr = 2352, i, j, code, fb;
|
int ptr = 2352, i, j, code, fb;
|
||||||
int audio = 1;
|
int audio = 1;
|
||||||
|
#ifndef Libburn_no_crc_C
|
||||||
|
unsigned short crc;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (o->c2errors) {
|
if (o->c2errors) {
|
||||||
fb = bitcount(data + ptr, 294);
|
fb = bitcount(data + ptr, 294);
|
||||||
if (fb) {
|
if (fb) {
|
||||||
burn_print(1, "%d damaged bits\n",
|
/* bitcount(data + ptr, 294) damaged bits */;
|
||||||
bitcount(data + ptr, 294));
|
|
||||||
burn_print(1, "sending error on %s %s\n",
|
|
||||||
d->idata->vendor, d->idata->product);
|
|
||||||
/* XXX send a burn_message! burn_message_error(d,
|
|
||||||
something); */
|
|
||||||
}
|
}
|
||||||
ptr += 294;
|
ptr += 294;
|
||||||
}
|
}
|
||||||
@ -253,16 +247,17 @@ void burn_packet_process(struct burn_drive *d, unsigned char *data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
crc = (*(sub + 22) << 8) + *(sub + 23);
|
|
||||||
|
|
||||||
#ifndef Libburn_no_crc_C
|
#ifndef Libburn_no_crc_C
|
||||||
|
crc = (*(sub + 22) << 8) + *(sub + 23);
|
||||||
if (crc != crc_ccitt(sub + 12, 10)) {
|
if (crc != crc_ccitt(sub + 12, 10)) {
|
||||||
|
/*
|
||||||
burn_print(1, "sending error on %s %s\n",
|
burn_print(1, "sending error on %s %s\n",
|
||||||
d->idata->vendor, d->idata->product);
|
d->idata->vendor, d->idata->product);
|
||||||
/* e = burn_error();
|
e = burn_error();
|
||||||
e->drive = d;
|
e->drive = d;
|
||||||
*/
|
|
||||||
burn_print(1, "crc mismatch in Q\n");
|
burn_print(1, "crc mismatch in Q\n");
|
||||||
|
*/;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2009 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (c) 2009 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -44,6 +44,7 @@ Present implementation: default dummy which enables libburn only to work
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "toc.h"
|
#include "toc.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "init.h"
|
||||||
|
|
||||||
#include "libdax_msgs.h"
|
#include "libdax_msgs.h"
|
||||||
extern struct libdax_msgs *libdax_messenger;
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
@ -252,14 +253,12 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
char *testpath = NULL, *cpt;
|
char *testpath = NULL, *cpt;
|
||||||
long blocks;
|
|
||||||
off_t add_size = 0;
|
off_t add_size = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
BURN_ALLOC_MEM(testpath, char, 4096);
|
BURN_ALLOC_MEM(testpath, char, 4096);
|
||||||
|
|
||||||
testpath[0] = 0;
|
testpath[0] = 0;
|
||||||
blocks = *bytes / 512;
|
|
||||||
if (stat(path, &stbuf) == -1) {
|
if (stat(path, &stbuf) == -1) {
|
||||||
strcpy(testpath, path);
|
strcpy(testpath, path);
|
||||||
cpt = strrchr(testpath, '/');
|
cpt = strrchr(testpath, '/');
|
||||||
@ -275,6 +274,9 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
#ifdef Libburn_if_this_was_linuX
|
#ifdef Libburn_if_this_was_linuX
|
||||||
|
|
||||||
} else if(S_ISBLK(stbuf.st_mode)) {
|
} else if(S_ISBLK(stbuf.st_mode)) {
|
||||||
|
long blocks;
|
||||||
|
|
||||||
|
blocks = *bytes / 512;
|
||||||
fd = open(path, open_mode);
|
fd = open(path, open_mode);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
{ret = -2; goto ex;}
|
{ret = -2; goto ex;}
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* THIS CODE IS NOT FUNCTIONAL YET !!! */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
This is the main operating system dependent SCSI part of libburn. It implements
|
This is the main operating system dependent SCSI part of libburn. It implements
|
||||||
@ -490,10 +493,8 @@ int sg_grab(struct burn_drive *d)
|
|||||||
*/
|
*/
|
||||||
int sg_release(struct burn_drive *d)
|
int sg_release(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
if (d->cam == NULL) {
|
if (d->cam == NULL)
|
||||||
burn_print(1, "release an ungrabbed drive. die\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
sg_close_drive(d);
|
sg_close_drive(d);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -721,13 +722,11 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
struct statvfs vfsbuf;
|
struct statvfs vfsbuf;
|
||||||
char *testpath = NULL, *cpt;
|
char *testpath = NULL, *cpt;
|
||||||
long blocks;
|
|
||||||
off_t add_size = 0;
|
off_t add_size = 0;
|
||||||
int fd, ret;
|
int fd, ret;
|
||||||
|
|
||||||
BURN_ALLOC_MEM(testpath, char, 4096);
|
BURN_ALLOC_MEM(testpath, char, 4096);
|
||||||
testpath[0] = 0;
|
testpath[0] = 0;
|
||||||
blocks = *bytes / 512;
|
|
||||||
if (stat(path, &stbuf) == -1) {
|
if (stat(path, &stbuf) == -1) {
|
||||||
strcpy(testpath, path);
|
strcpy(testpath, path);
|
||||||
cpt = strrchr(testpath, '/');
|
cpt = strrchr(testpath, '/');
|
||||||
@ -744,7 +743,9 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
|
|
||||||
} else if(S_ISBLK(stbuf.st_mode)) {
|
} else if(S_ISBLK(stbuf.st_mode)) {
|
||||||
int open_mode = O_RDWR, fd, ret;
|
int open_mode = O_RDWR, fd, ret;
|
||||||
|
long blocks;
|
||||||
|
|
||||||
|
blocks = *bytes / 512;
|
||||||
if(burn_sg_open_o_excl)
|
if(burn_sg_open_o_excl)
|
||||||
open_mode |= O_EXCL;
|
open_mode |= O_EXCL;
|
||||||
fd = open(path, open_mode);
|
fd = open(path, open_mode);
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later
|
||||||
|
and under FreeBSD license revised, i.e. without advertising clause.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
@ -507,12 +508,9 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
|
|
||||||
/* try to get the drive info */
|
/* try to get the drive info */
|
||||||
if (t->grab(t)) {
|
if (t->grab(t)) {
|
||||||
burn_print(2, "getting drive info\n");
|
|
||||||
t->getcaps(t);
|
t->getcaps(t);
|
||||||
t->unlock(t);
|
t->unlock(t);
|
||||||
t->released = 1;
|
t->released = 1;
|
||||||
} else {
|
|
||||||
burn_print(2, "unable to grab new located drive\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts A60821
|
/* ts A60821
|
||||||
@ -750,10 +748,8 @@ int sg_release(struct burn_drive *d)
|
|||||||
if (mmc_function_spy(d, "sg_release") <= 0)
|
if (mmc_function_spy(d, "sg_release") <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (d->cam == NULL) {
|
if (d->cam == NULL)
|
||||||
burn_print(1, "release an ungrabbed drive. die\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
mmc_function_spy(NULL, "sg_release ----------- closing.");
|
mmc_function_spy(NULL, "sg_release ----------- closing.");
|
||||||
|
|
||||||
@ -764,7 +760,7 @@ int sg_release(struct burn_drive *d)
|
|||||||
|
|
||||||
int sg_issue_command(struct burn_drive *d, struct command *c)
|
int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
{
|
{
|
||||||
int done = 0, err, sense_len = 0, ret, ignore_error, no_retry = 0, i;
|
int done = 0, err, sense_len = 0, ret, ignore_error, i;
|
||||||
int cam_pass_err_recover = 0, key, asc, ascq, timeout_ms;
|
int cam_pass_err_recover = 0, key, asc, ascq, timeout_ms;
|
||||||
union ccb *ccb;
|
union ccb *ccb;
|
||||||
static FILE *fp = NULL;
|
static FILE *fp = NULL;
|
||||||
@ -957,7 +953,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
c->sense[2] = 0x02;
|
c->sense[2] = 0x02;
|
||||||
c->sense[12] = 0x04;
|
c->sense[12] = 0x04;
|
||||||
c->sense[13] = 0x00;
|
c->sense[13] = 0x00;
|
||||||
no_retry = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* >>> Need own duration time measurement.
|
/* >>> Need own duration time measurement.
|
||||||
@ -985,12 +981,13 @@ ex:;
|
|||||||
int burn_os_is_2k_seekrw(char *path, int flag)
|
int burn_os_is_2k_seekrw(char *path, int flag)
|
||||||
{
|
{
|
||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
|
#ifdef Libburn_DIOCGMEDIASIZE_ISBLK
|
||||||
|
int fd, ret;
|
||||||
|
off_t add_size;
|
||||||
|
#else
|
||||||
char *spt;
|
char *spt;
|
||||||
int i, e;
|
int i, e;
|
||||||
#ifdef Libburn_DIOCGMEDIASIZE_ISBLK
|
#endif /* ! Libburn_DIOCGMEDIASIZE_ISBLK */
|
||||||
int fd;
|
|
||||||
off_t add_size;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (stat(path, &stbuf) == -1)
|
if (stat(path, &stbuf) == -1)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1010,7 +1007,7 @@ int burn_os_is_2k_seekrw(char *path, int flag)
|
|||||||
ret = ioctl(fd, DIOCGMEDIASIZE, &add_size);
|
ret = ioctl(fd, DIOCGMEDIASIZE, &add_size);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
return 1;
|
return (ret != -1);
|
||||||
|
|
||||||
#else /* Libburn_DIOCGMEDIASIZE_ISBLK */
|
#else /* Libburn_DIOCGMEDIASIZE_ISBLK */
|
||||||
|
|
||||||
@ -1057,13 +1054,11 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
struct statvfs vfsbuf;
|
struct statvfs vfsbuf;
|
||||||
char *testpath = NULL, *cpt;
|
char *testpath = NULL, *cpt;
|
||||||
long blocks;
|
|
||||||
off_t add_size = 0;
|
off_t add_size = 0;
|
||||||
int fd, ret;
|
int fd, ret;
|
||||||
|
|
||||||
BURN_ALLOC_MEM(testpath, char, 4096);
|
BURN_ALLOC_MEM(testpath, char, 4096);
|
||||||
testpath[0] = 0;
|
testpath[0] = 0;
|
||||||
blocks = *bytes / 512;
|
|
||||||
if (stat(path, &stbuf) == -1) {
|
if (stat(path, &stbuf) == -1) {
|
||||||
strcpy(testpath, path);
|
strcpy(testpath, path);
|
||||||
cpt = strrchr(testpath, '/');
|
cpt = strrchr(testpath, '/');
|
||||||
@ -1080,7 +1075,9 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
|
|
||||||
} else if(S_ISBLK(stbuf.st_mode)) {
|
} else if(S_ISBLK(stbuf.st_mode)) {
|
||||||
int open_mode = O_RDWR, fd, ret;
|
int open_mode = O_RDWR, fd, ret;
|
||||||
|
long blocks;
|
||||||
|
|
||||||
|
blocks = *bytes / 512;
|
||||||
if(burn_sg_open_o_excl)
|
if(burn_sg_open_o_excl)
|
||||||
open_mode |= O_EXCL;
|
open_mode |= O_EXCL;
|
||||||
fd = open(path, open_mode);
|
fd = open(path, open_mode);
|
||||||
|
@ -142,6 +142,9 @@ Send feedback to libburn-hackers@pykix.org .
|
|||||||
#define Libburn_is_on_solariS 1
|
#define Libburn_is_on_solariS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Proposal by Rocky Bernstein to avoid macro clashes with cdio_config.h */
|
||||||
|
#define __CDIO_CONFIG_H__ 1
|
||||||
|
|
||||||
#include <cdio/cdio.h>
|
#include <cdio/cdio.h>
|
||||||
#include <cdio/logging.h>
|
#include <cdio/logging.h>
|
||||||
#include <cdio/mmc.h>
|
#include <cdio/mmc.h>
|
||||||
@ -259,7 +262,7 @@ try_next:;
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (strlen(*(idx->pos)) >= adr_size)
|
if ((ssize_t) strlen(*(idx->pos)) >= adr_size)
|
||||||
return -1;
|
return -1;
|
||||||
strcpy(adr, *(idx->pos));
|
strcpy(adr, *(idx->pos));
|
||||||
(idx->pos)++;
|
(idx->pos)++;
|
||||||
@ -440,7 +443,7 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
|||||||
ret = sg_give_next_adr_raw(idx, adr, adr_size, initialize);
|
ret = sg_give_next_adr_raw(idx, adr, adr_size, initialize);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
if (strlen(adr) >= path_size)
|
if ((ssize_t) strlen(adr) >= path_size)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
|
||||||
#ifdef Libburn_is_on_solariS
|
#ifdef Libburn_is_on_solariS
|
||||||
@ -453,8 +456,8 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
|||||||
#endif /* Libburn_is_on_solariS */
|
#endif /* Libburn_is_on_solariS */
|
||||||
|
|
||||||
ret = burn_drive_resolve_link(adr, path, &recursion_count, 2);
|
ret = burn_drive_resolve_link(adr, path, &recursion_count, 2);
|
||||||
if(ret > 0 && strlen(path) < adr_size)
|
if(ret > 0 && (ssize_t) strlen(path) < adr_size)
|
||||||
strcpy(path, adr);
|
strcpy(adr, path);
|
||||||
ret = (ret >= 0);
|
ret = (ret >= 0);
|
||||||
ex:
|
ex:
|
||||||
BURN_FREE_MEM(path);
|
BURN_FREE_MEM(path);
|
||||||
@ -594,10 +597,8 @@ ex:;
|
|||||||
*/
|
*/
|
||||||
int sg_release(struct burn_drive *d)
|
int sg_release(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
if (d->p_cdio == NULL) {
|
if (d->p_cdio == NULL)
|
||||||
burn_print(1, "release an ungrabbed drive. die\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
sg_close_drive(d);
|
sg_close_drive(d);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -614,7 +615,7 @@ int sg_release(struct burn_drive *d)
|
|||||||
*/
|
*/
|
||||||
int sg_issue_command(struct burn_drive *d, struct command *c)
|
int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
{
|
{
|
||||||
int sense_valid = 0, i, timeout_ms, no_retry = 0;
|
int sense_valid = 0, i, timeout_ms, sense_len;
|
||||||
int key = 0, asc = 0, ascq = 0, done = 0;
|
int key = 0, asc = 0, ascq = 0, done = 0;
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
driver_return_code_t i_status;
|
driver_return_code_t i_status;
|
||||||
@ -623,7 +624,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
mmc_cdb_t cdb = {{0, }};
|
mmc_cdb_t cdb = {{0, }};
|
||||||
cdio_mmc_direction_t e_direction;
|
cdio_mmc_direction_t e_direction;
|
||||||
CdIo_t *p_cdio;
|
CdIo_t *p_cdio;
|
||||||
unsigned char *sense_pt = NULL;
|
cdio_mmc_request_sense_t *sense_pt = NULL;
|
||||||
|
|
||||||
c->error = 0;
|
c->error = 0;
|
||||||
if (d->p_cdio == NULL) {
|
if (d->p_cdio == NULL) {
|
||||||
@ -666,9 +667,9 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
dxfer_len, c->page->data);
|
dxfer_len, c->page->data);
|
||||||
sense_valid = mmc_last_cmd_sense(p_cdio, &sense_pt);
|
sense_valid = mmc_last_cmd_sense(p_cdio, &sense_pt);
|
||||||
if (sense_valid >= 18) {
|
if (sense_valid >= 18) {
|
||||||
memcpy(c->sense, sense_pt,
|
memcpy(c->sense, (unsigned char *) sense_pt,
|
||||||
sense_valid >= sizeof(c->sense) ?
|
(size_t) sense_valid >= sizeof(c->sense) ?
|
||||||
sizeof(c->sense) : sense_valid );
|
sizeof(c->sense) : (size_t) sense_valid );
|
||||||
spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
|
spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
|
||||||
} else
|
} else
|
||||||
key = asc = ascq = 0;
|
key = asc = ascq = 0;
|
||||||
@ -701,14 +702,15 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
c->sense[0] = 0x70; /*Fixed format sense data*/
|
c->sense[0] = 0x70; /*Fixed format sense data*/
|
||||||
c->sense[2] = 0x02;
|
c->sense[2] = 0x02;
|
||||||
c->sense[12] = 0x04;
|
c->sense[12] = 0x04;
|
||||||
no_retry = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i_status != 0 || (key || asc || ascq)) {
|
if (key || asc || ascq)
|
||||||
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, 18,
|
sense_len = 18;
|
||||||
|
else
|
||||||
|
sense_len = 0;
|
||||||
|
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len,
|
||||||
0, start_time, timeout_ms, i, 2);
|
0, start_time, timeout_ms, i, 2);
|
||||||
} else
|
|
||||||
done = 1;
|
|
||||||
|
|
||||||
} /* end of retry-loop */
|
} /* end of retry-loop */
|
||||||
|
|
||||||
@ -860,13 +862,11 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
char *testpath = NULL, *cpt;
|
char *testpath = NULL, *cpt;
|
||||||
long blocks;
|
|
||||||
off_t add_size = 0;
|
off_t add_size = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
BURN_ALLOC_MEM(testpath, char, 4096);
|
BURN_ALLOC_MEM(testpath, char, 4096);
|
||||||
testpath[0] = 0;
|
testpath[0] = 0;
|
||||||
blocks = *bytes / 512;
|
|
||||||
if (stat(path, &stbuf) == -1) {
|
if (stat(path, &stbuf) == -1) {
|
||||||
strcpy(testpath, path);
|
strcpy(testpath, path);
|
||||||
cpt = strrchr(testpath, '/');
|
cpt = strrchr(testpath, '/');
|
||||||
@ -883,8 +883,10 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
|
|
||||||
/* GNU/Linux specific determination of block device size */
|
/* GNU/Linux specific determination of block device size */
|
||||||
} else if(S_ISBLK(stbuf.st_mode)) {
|
} else if(S_ISBLK(stbuf.st_mode)) {
|
||||||
int open_mode = O_RDONLY, fd, ret;
|
int open_mode = O_RDONLY, fd;
|
||||||
|
long blocks;
|
||||||
|
|
||||||
|
blocks = *bytes / 512;
|
||||||
fd = open(path, open_mode);
|
fd = open(path, open_mode);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
{ret = -2; goto ex;}
|
{ret = -2; goto ex;}
|
||||||
@ -899,7 +901,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
#ifdef Libburn_is_on_freebsD
|
#ifdef Libburn_is_on_freebsD
|
||||||
|
|
||||||
} else if(S_ISCHR(stbuf.st_mode)) {
|
} else if(S_ISCHR(stbuf.st_mode)) {
|
||||||
int fd, ret;
|
int fd;
|
||||||
|
|
||||||
fd = open(path, O_RDONLY);
|
fd = open(path, O_RDONLY);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
|
@ -185,6 +185,8 @@ static int linux_sg_enumerate_debug = 0;
|
|||||||
E.g.: "/dev/sg%d"
|
E.g.: "/dev/sg%d"
|
||||||
sr%d is supposed to map only CD-ROM style devices. Additionally a test
|
sr%d is supposed to map only CD-ROM style devices. Additionally a test
|
||||||
with ioctl(CDROM_DRIVE_STATUS) is made to assert that it is such a drive,
|
with ioctl(CDROM_DRIVE_STATUS) is made to assert that it is such a drive,
|
||||||
|
If no such assertion is made, then this adapter performs INQUIRE and
|
||||||
|
looks for first reply byte 0x05.
|
||||||
|
|
||||||
This initial setting may be overridden in sg_select_device_family() by
|
This initial setting may be overridden in sg_select_device_family() by
|
||||||
settings made via burn_preset_device_open().
|
settings made via burn_preset_device_open().
|
||||||
@ -252,9 +254,13 @@ int burn_drive_is_banned(char *device_address);
|
|||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
static void enumerate_common(char *fname, int bus_no, int host_no,
|
static void enumerate_common(char *fname, int fd_in, int bus_no, int host_no,
|
||||||
int channel_no, int target_no, int lun_no);
|
int channel_no, int target_no, int lun_no);
|
||||||
|
|
||||||
|
static int sg_obtain_scsi_adr_fd(char *path, int fd_in,
|
||||||
|
int *bus_no, int *host_no, int *channel_no,
|
||||||
|
int *target_no, int *lun_no);
|
||||||
|
|
||||||
|
|
||||||
/* ts A60813 : storage objects are in libburn/init.c
|
/* ts A60813 : storage objects are in libburn/init.c
|
||||||
whether to use O_EXCL with open(2) of devices
|
whether to use O_EXCL with open(2) of devices
|
||||||
@ -372,10 +378,48 @@ static int sg_exchange_scd_for_sr(char *fname, int flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11110 */
|
||||||
|
/* This is an early stage version of scsi_log_cmd.
|
||||||
|
>>> It will become obsolete when the /tmp file handler is moved into
|
||||||
|
>>> scsi_log_command().
|
||||||
|
*/
|
||||||
|
static int sgio_log_cmd(unsigned char *cmd, int cmd_len, FILE *fp_in, int flag)
|
||||||
|
{
|
||||||
|
FILE *fp = fp_in;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* >>> ts B11110 : move this into scsi_log_command() */
|
||||||
|
if (fp == NULL && (burn_sg_log_scsi & 1)) {
|
||||||
|
fp= fopen("/tmp/libburn_sg_command_log", "a");
|
||||||
|
fprintf(fp, "\n=========================================\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = scsi_log_command(cmd, cmd_len, NO_TRANSFER, NULL, 0, fp, flag);
|
||||||
|
if (fp_in == NULL && fp != NULL)
|
||||||
|
fclose(fp);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11110 */
|
||||||
|
static int sgio_log_reply(unsigned char *opcode, int data_dir,
|
||||||
|
unsigned char *data, int dxfer_len,
|
||||||
|
void *fp_in, unsigned char sense[18],
|
||||||
|
int sense_len, int duration, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = scsi_log_reply(opcode, data_dir, data, dxfer_len, fp_in,
|
||||||
|
sense, sense_len, duration, flag);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int sgio_test(int fd)
|
static int sgio_test(int fd)
|
||||||
{
|
{
|
||||||
unsigned char test_ops[] = { 0, 0, 0, 0, 0, 0 };
|
unsigned char test_ops[] = { 0, 0, 0, 0, 0, 0 };
|
||||||
sg_io_hdr_t s;
|
sg_io_hdr_t s;
|
||||||
|
int ret;
|
||||||
|
|
||||||
memset(&s, 0, sizeof(sg_io_hdr_t));
|
memset(&s, 0, sizeof(sg_io_hdr_t));
|
||||||
s.interface_id = 'S';
|
s.interface_id = 'S';
|
||||||
@ -383,7 +427,91 @@ static int sgio_test(int fd)
|
|||||||
s.cmd_len = 6;
|
s.cmd_len = 6;
|
||||||
s.cmdp = test_ops;
|
s.cmdp = test_ops;
|
||||||
s.timeout = 12345;
|
s.timeout = 12345;
|
||||||
return ioctl(fd, SG_IO, &s);
|
|
||||||
|
sgio_log_cmd(s.cmdp, s.cmd_len, NULL, 0);
|
||||||
|
|
||||||
|
ret= ioctl(fd, SG_IO, &s);
|
||||||
|
|
||||||
|
sgio_log_reply(s.cmdp, NO_TRANSFER, NULL, 0,
|
||||||
|
NULL, s.sbp, s.sb_len_wr, s.duration, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int sgio_inquiry_cd_drive(int fd, char *fname)
|
||||||
|
{
|
||||||
|
unsigned char test_ops[] = { 0x12, 0, 0, 0, 36, 0 };
|
||||||
|
sg_io_hdr_t s;
|
||||||
|
struct buffer *buf = NULL;
|
||||||
|
unsigned char *sense = NULL;
|
||||||
|
char *msg = NULL, *msg_pt;
|
||||||
|
int ret = 0, i;
|
||||||
|
|
||||||
|
BURN_ALLOC_MEM(buf, struct buffer, 1);
|
||||||
|
BURN_ALLOC_MEM(sense, unsigned char, 128);
|
||||||
|
BURN_ALLOC_MEM(msg, char, strlen(fname) + 1024);
|
||||||
|
|
||||||
|
memset(&s, 0, sizeof(sg_io_hdr_t));
|
||||||
|
s.interface_id = 'S';
|
||||||
|
s.dxfer_direction = SG_DXFER_FROM_DEV;
|
||||||
|
s.cmd_len = 6;
|
||||||
|
s.cmdp = test_ops;
|
||||||
|
s.mx_sb_len = 32;
|
||||||
|
s.sbp = sense;
|
||||||
|
s.timeout = 30000;
|
||||||
|
s.dxferp = buf;
|
||||||
|
s.dxfer_len = 36;
|
||||||
|
s.usr_ptr = NULL;
|
||||||
|
|
||||||
|
sgio_log_cmd(s.cmdp, s.cmd_len, NULL, 0);
|
||||||
|
|
||||||
|
ret = ioctl(fd, SG_IO, &s);
|
||||||
|
if (ret == -1) {
|
||||||
|
sprintf(msg,
|
||||||
|
"INQUIRY on '%s' : ioctl(SG_IO) failed , errno= %d",
|
||||||
|
fname, errno);
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
sgio_log_reply(s.cmdp, FROM_DRIVE, buf->data, s.dxfer_len,
|
||||||
|
NULL, s.sbp, s.sb_len_wr, s.duration, 0);
|
||||||
|
|
||||||
|
if (s.sb_len_wr > 0 || s.host_status != Libburn_sg_host_oK ||
|
||||||
|
s.driver_status != Libburn_sg_driver_oK) {
|
||||||
|
sprintf(msg, "INQUIRY failed on '%s' : host_status= %hd , driver_status= %hd", fname, s.host_status, s.driver_status);
|
||||||
|
if (s.sb_len_wr > 0) {
|
||||||
|
sprintf(msg + strlen(msg), " , sense data=");
|
||||||
|
msg_pt = msg + strlen(msg);
|
||||||
|
for (i = 0 ; i < s.sb_len_wr; i++)
|
||||||
|
sprintf(msg_pt + i * 3, " %2.2X", s.sbp[i]);
|
||||||
|
}
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
ret = -1;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
ret = 0;
|
||||||
|
if (buf->data[0] == 0x5) {
|
||||||
|
/* Peripheral qualifier 0, device type 0x5 = CD/DVD device.
|
||||||
|
SPC-3 tables 82 and 83 */
|
||||||
|
ret = 1;
|
||||||
|
} else {
|
||||||
|
sprintf(msg, "INQUIRY on '%s' : byte 0 = 0x%2.2X",
|
||||||
|
fname, buf->data[0]);
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ex:;
|
||||||
|
BURN_FREE_MEM(msg);
|
||||||
|
BURN_FREE_MEM(sense);
|
||||||
|
BURN_FREE_MEM(buf);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -576,6 +704,7 @@ static int sg_open_drive_fd(char *fname, int scan_mode)
|
|||||||
O_NONBLOCK was already hardcoded in ata_ but not in sg_.
|
O_NONBLOCK was already hardcoded in ata_ but not in sg_.
|
||||||
There must be some reason for this. So O_NONBLOCK is
|
There must be some reason for this. So O_NONBLOCK is
|
||||||
default mode for both now. Disable on own risk.
|
default mode for both now. Disable on own risk.
|
||||||
|
ts B10904: O_NONBLOCK is prescribed by <linux/cdrom.h>
|
||||||
ts A70411
|
ts A70411
|
||||||
Switched to O_NDELAY for LKML statement 2007/4/11/141 by Alan Cox:
|
Switched to O_NDELAY for LKML statement 2007/4/11/141 by Alan Cox:
|
||||||
"open() has side effects. The CD layer allows you to open
|
"open() has side effects. The CD layer allows you to open
|
||||||
@ -756,12 +885,15 @@ failed:;
|
|||||||
|
|
||||||
|
|
||||||
/* ts A80731 */
|
/* ts A80731 */
|
||||||
static int is_ata_drive(char *fname)
|
static int is_ata_drive(char *fname, int fd_in)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
struct hd_driveid tm;
|
struct hd_driveid tm;
|
||||||
|
|
||||||
fd = sg_open_drive_fd(fname, 1);
|
if (fd_in >= 0)
|
||||||
|
fd = fd_in;
|
||||||
|
else
|
||||||
|
fd = sg_open_drive_fd(fname, 1);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
if (linux_ata_enumerate_verbous)
|
if (linux_ata_enumerate_verbous)
|
||||||
fprintf(stderr,"open failed, errno=%d '%s'\n",
|
fprintf(stderr,"open failed, errno=%d '%s'\n",
|
||||||
@ -776,7 +908,8 @@ static int is_ata_drive(char *fname)
|
|||||||
if (!(tm.config & 0x8000) || (tm.config & 0x4000)) {
|
if (!(tm.config & 0x8000) || (tm.config & 0x4000)) {
|
||||||
if (linux_ata_enumerate_verbous)
|
if (linux_ata_enumerate_verbous)
|
||||||
fprintf(stderr, "not marked as ATAPI\n");
|
fprintf(stderr, "not marked as ATAPI\n");
|
||||||
sg_close_drive_fd(fname, -1, &fd, 0);
|
if (fd_in < 0)
|
||||||
|
sg_close_drive_fd(fname, -1, &fd, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -787,9 +920,12 @@ static int is_ata_drive(char *fname)
|
|||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"FATAL: sgio_test() failed: errno=%d '%s'\n",
|
"FATAL: sgio_test() failed: errno=%d '%s'\n",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
sg_close_drive_fd(fname, -1, &fd, 0);
|
if (fd_in < 0)
|
||||||
|
sg_close_drive_fd(fname, -1, &fd, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (fd_in >= 0)
|
||||||
|
return 1;
|
||||||
if (sg_close_drive_fd(fname, -1, &fd, 1) <= 0) {
|
if (sg_close_drive_fd(fname, -1, &fd, 1) <= 0) {
|
||||||
if (linux_ata_enumerate_verbous)
|
if (linux_ata_enumerate_verbous)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -801,10 +937,10 @@ static int is_ata_drive(char *fname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int is_scsi_drive(char *fname, int *bus_no, int *host_no,
|
static int is_scsi_drive(char *fname, int fd_in, int *bus_no, int *host_no,
|
||||||
int *channel_no, int *target_no, int *lun_no)
|
int *channel_no, int *target_no, int *lun_no)
|
||||||
{
|
{
|
||||||
int fd, sid_ret = 0, ret;
|
int fd = -1, sid_ret = 0, ret, fail_sev_sorry = 0;
|
||||||
struct sg_scsi_id sid;
|
struct sg_scsi_id sid;
|
||||||
int *sibling_fds = NULL, sibling_count= 0;
|
int *sibling_fds = NULL, sibling_count= 0;
|
||||||
typedef char burn_sg_sibling_fname[BURN_OS_SG_MAX_NAMELEN];
|
typedef char burn_sg_sibling_fname[BURN_OS_SG_MAX_NAMELEN];
|
||||||
@ -814,14 +950,16 @@ static int is_scsi_drive(char *fname, int *bus_no, int *host_no,
|
|||||||
BURN_ALLOC_MEM(sibling_fnames, burn_sg_sibling_fname,
|
BURN_ALLOC_MEM(sibling_fnames, burn_sg_sibling_fname,
|
||||||
BURN_OS_SG_MAX_SIBLINGS);
|
BURN_OS_SG_MAX_SIBLINGS);
|
||||||
|
|
||||||
fd = sg_open_drive_fd(fname, 1);
|
if (fd_in >= 0)
|
||||||
|
fd = fd_in;
|
||||||
|
else
|
||||||
|
fd = sg_open_drive_fd(fname, 1);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
if (linux_sg_enumerate_debug)
|
if (linux_sg_enumerate_debug)
|
||||||
fprintf(stderr, "open failed, errno=%d '%s'\n",
|
fprintf(stderr, "open failed, errno=%d '%s'\n",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
{ret = 0; goto ex;}
|
{ret = 0; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
sid_ret = ioctl(fd, SG_GET_SCSI_ID, &sid);
|
sid_ret = ioctl(fd, SG_GET_SCSI_ID, &sid);
|
||||||
if (sid_ret == -1) {
|
if (sid_ret == -1) {
|
||||||
sid.scsi_id = -1; /* mark SCSI address as invalid */
|
sid.scsi_id = -1; /* mark SCSI address as invalid */
|
||||||
@ -836,7 +974,6 @@ static int is_scsi_drive(char *fname, int *bus_no, int *host_no,
|
|||||||
"FATAL: sgio_test() failed: errno=%d '%s'",
|
"FATAL: sgio_test() failed: errno=%d '%s'",
|
||||||
errno, strerror(errno));
|
errno, strerror(errno));
|
||||||
|
|
||||||
sg_close_drive_fd(fname, -1, &fd, 0);
|
|
||||||
{ret = 0; goto ex;}
|
{ret = 0; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -856,20 +993,22 @@ static int is_scsi_drive(char *fname, int *bus_no, int *host_no,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sid_ret == -1) {
|
||||||
|
/* ts B11109 : Try device type from INQUIRY byte 0 */
|
||||||
|
if (sgio_inquiry_cd_drive(fd, fname) == 1) {
|
||||||
|
sid_ret = 0;
|
||||||
|
sid.scsi_type = TYPE_ROM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef SCSI_IOCTL_GET_BUS_NUMBER
|
#ifdef SCSI_IOCTL_GET_BUS_NUMBER
|
||||||
/* Hearsay A61005 */
|
/* Hearsay A61005 */
|
||||||
if (ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, bus_no) == -1)
|
if (ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, bus_no) == -1)
|
||||||
*bus_no = -1;
|
*bus_no = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (sg_close_drive_fd(fname, -1, &fd,
|
fail_sev_sorry = (sid.scsi_type == TYPE_ROM);
|
||||||
sid.scsi_type == TYPE_ROM ) <= 0) {
|
|
||||||
if (linux_sg_enumerate_debug)
|
|
||||||
fprintf(stderr,
|
|
||||||
"cannot close properly, errno=%d '%s'\n",
|
|
||||||
errno, strerror(errno));
|
|
||||||
{ret = 0; goto ex;}
|
|
||||||
}
|
|
||||||
if ( (sid_ret == -1 || sid.scsi_type != TYPE_ROM)
|
if ( (sid_ret == -1 || sid.scsi_type != TYPE_ROM)
|
||||||
&& !linux_sg_accept_any_type) {
|
&& !linux_sg_accept_any_type) {
|
||||||
if (linux_sg_enumerate_debug)
|
if (linux_sg_enumerate_debug)
|
||||||
@ -880,7 +1019,8 @@ static int is_scsi_drive(char *fname, int *bus_no, int *host_no,
|
|||||||
|
|
||||||
if (sid_ret == -1 || sid.scsi_id < 0) {
|
if (sid_ret == -1 || sid.scsi_id < 0) {
|
||||||
/* ts A61211 : employ a more general ioctl */
|
/* ts A61211 : employ a more general ioctl */
|
||||||
ret = sg_obtain_scsi_adr(fname, bus_no, host_no,
|
/* ts B11001 : re-use fd */
|
||||||
|
ret = sg_obtain_scsi_adr_fd(fname, fd, bus_no, host_no,
|
||||||
channel_no, target_no, lun_no);
|
channel_no, target_no, lun_no);
|
||||||
if (ret>0) {
|
if (ret>0) {
|
||||||
sid.host_no = *host_no;
|
sid.host_no = *host_no;
|
||||||
@ -890,7 +1030,7 @@ static int is_scsi_drive(char *fname, int *bus_no, int *host_no,
|
|||||||
} else {
|
} else {
|
||||||
if (linux_sg_enumerate_debug)
|
if (linux_sg_enumerate_debug)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"sg_obtain_scsi_adr() failed\n");
|
"sg_obtain_scsi_adr_fd() failed\n");
|
||||||
{ret = 0; goto ex;}
|
{ret = 0; goto ex;}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -924,18 +1064,42 @@ static int is_scsi_drive(char *fname, int *bus_no, int *host_no,
|
|||||||
*lun_no= sid.lun;
|
*lun_no= sid.lun;
|
||||||
ret = 1;
|
ret = 1;
|
||||||
ex:;
|
ex:;
|
||||||
|
if (fd_in < 0 && fd >= 0) {
|
||||||
|
if (sg_close_drive_fd(fname, -1, &fd, fail_sev_sorry) <= 0) {
|
||||||
|
if (linux_sg_enumerate_debug)
|
||||||
|
fprintf(stderr,
|
||||||
|
"cannot close properly, errno=%d '%s'\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
if (ret > 0)
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
BURN_FREE_MEM(sibling_fds);
|
BURN_FREE_MEM(sibling_fds);
|
||||||
BURN_FREE_MEM(sibling_fnames);
|
BURN_FREE_MEM(sibling_fnames);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int sg_open_for_enumeration(char *fname, int flag)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = sg_open_drive_fd(fname, 1);
|
||||||
|
if (fd < 0) {
|
||||||
|
if (linux_sg_enumerate_debug || linux_ata_enumerate_verbous)
|
||||||
|
fprintf(stderr, "open failed, errno=%d '%s'\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Speciality of GNU/Linux: detect non-SCSI ATAPI (EIDE) which will from
|
/** Speciality of GNU/Linux: detect non-SCSI ATAPI (EIDE) which will from
|
||||||
then on used used via generic SCSI as is done with (emulated) SCSI drives */
|
then on used used via generic SCSI as is done with (emulated) SCSI drives */
|
||||||
static void ata_enumerate(void)
|
static void ata_enumerate(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, i, fd = -1;
|
||||||
int i;
|
|
||||||
char fname[10];
|
char fname[10];
|
||||||
|
|
||||||
if (linux_ata_enumerate_verbous)
|
if (linux_ata_enumerate_verbous)
|
||||||
@ -956,14 +1120,17 @@ static void ata_enumerate(void)
|
|||||||
fprintf(stderr, "not in whitelist\n");
|
fprintf(stderr, "not in whitelist\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ret = is_ata_drive(fname);
|
fd = sg_open_for_enumeration(fname, 0);
|
||||||
|
if (fd < 0)
|
||||||
|
continue;
|
||||||
|
ret = is_ata_drive(fname, fd);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
break;
|
break;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
continue;
|
continue;
|
||||||
if (linux_ata_enumerate_verbous)
|
if (linux_ata_enumerate_verbous)
|
||||||
fprintf(stderr, "accepting as drive without SCSI address\n");
|
fprintf(stderr, "accepting as drive without SCSI address\n");
|
||||||
enumerate_common(fname, -1, -1, -1, -1, -1);
|
enumerate_common(fname, fd, -1, -1, -1, -1, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -971,7 +1138,7 @@ static void ata_enumerate(void)
|
|||||||
/** Detects (probably emulated) SCSI drives */
|
/** Detects (probably emulated) SCSI drives */
|
||||||
static void sg_enumerate(void)
|
static void sg_enumerate(void)
|
||||||
{
|
{
|
||||||
int i, ret;
|
int i, ret, fd = -1;
|
||||||
int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1;
|
int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1;
|
||||||
char fname[17];
|
char fname[17];
|
||||||
|
|
||||||
@ -999,8 +1166,11 @@ static void sg_enumerate(void)
|
|||||||
fprintf(stderr, "not in whitelist\n");
|
fprintf(stderr, "not in whitelist\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
fd = sg_open_for_enumeration(fname, 0);
|
||||||
|
if (fd < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
ret = is_scsi_drive(fname, &bus_no, &host_no, &channel_no,
|
ret = is_scsi_drive(fname, fd, &bus_no, &host_no, &channel_no,
|
||||||
&target_no, &lun_no);
|
&target_no, &lun_no);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
break;
|
break;
|
||||||
@ -1009,7 +1179,7 @@ static void sg_enumerate(void)
|
|||||||
if (linux_sg_enumerate_debug)
|
if (linux_sg_enumerate_debug)
|
||||||
fprintf(stderr, "accepting as SCSI %d,%d,%d,%d bus=%d\n",
|
fprintf(stderr, "accepting as SCSI %d,%d,%d,%d bus=%d\n",
|
||||||
host_no, channel_no, target_no, lun_no, bus_no);
|
host_no, channel_no, target_no, lun_no, bus_no);
|
||||||
enumerate_common(fname, bus_no, host_no, channel_no,
|
enumerate_common(fname, fd, bus_no, host_no, channel_no,
|
||||||
target_no, lun_no);
|
target_no, lun_no);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1058,7 +1228,7 @@ static int fname_drive_is_listed(char *fname, int flag)
|
|||||||
*/
|
*/
|
||||||
static int fname_enumerate(char *fname, int flag)
|
static int fname_enumerate(char *fname, int flag)
|
||||||
{
|
{
|
||||||
int is_ata= 0, is_scsi= 0, ret;
|
int is_ata= 0, is_scsi= 0, ret, fd = -1;
|
||||||
int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1;
|
int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1;
|
||||||
char *msg = NULL;
|
char *msg = NULL;
|
||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
@ -1076,13 +1246,16 @@ static int fname_enumerate(char *fname, int flag)
|
|||||||
msg, 0, 0);
|
msg, 0, 0);
|
||||||
{ret = -1; goto ex;}
|
{ret = -1; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
is_ata = is_ata_drive(fname);
|
fd = sg_open_for_enumeration(fname, 0);
|
||||||
|
if (fd < 0)
|
||||||
|
{ret = 0; goto ex;}
|
||||||
|
is_ata = is_ata_drive(fname, fd);
|
||||||
if (is_ata < 0)
|
if (is_ata < 0)
|
||||||
{ret = -1; goto ex;}
|
{ret = -1; goto ex;}
|
||||||
if (!is_ata)
|
if (!is_ata)
|
||||||
is_scsi = is_scsi_drive(fname, &bus_no, &host_no, &channel_no,
|
is_scsi = is_scsi_drive(fname, fd, &bus_no, &host_no,
|
||||||
&target_no, &lun_no);
|
&channel_no, &target_no, &lun_no);
|
||||||
if (is_scsi < 0)
|
if (is_scsi < 0)
|
||||||
{ret = -1; goto ex;}
|
{ret = -1; goto ex;}
|
||||||
if (is_ata == 0 && is_scsi == 0)
|
if (is_ata == 0 && is_scsi == 0)
|
||||||
@ -1092,7 +1265,8 @@ static int fname_enumerate(char *fname, int flag)
|
|||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"(single) accepting as SCSI %d,%d,%d,%d bus=%d\n",
|
"(single) accepting as SCSI %d,%d,%d,%d bus=%d\n",
|
||||||
host_no, channel_no, target_no, lun_no, bus_no);
|
host_no, channel_no, target_no, lun_no, bus_no);
|
||||||
enumerate_common(fname, bus_no, host_no, channel_no,
|
|
||||||
|
enumerate_common(fname, fd, bus_no, host_no, channel_no,
|
||||||
target_no, lun_no);
|
target_no, lun_no);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
ex:;
|
ex:;
|
||||||
@ -1216,6 +1390,9 @@ static int add_proc_info_drives(int flag)
|
|||||||
int ret, list_count, count = 0, i;
|
int ret, list_count, count = 0, i;
|
||||||
char **list= NULL;
|
char **list= NULL;
|
||||||
|
|
||||||
|
if (burn_sg_use_family != 0)
|
||||||
|
return(1); /* Looking only for sr resp. scd resp. sg */
|
||||||
|
|
||||||
ret = proc_sys_dev_cdrom_info(&list, &list_count, 0);
|
ret = proc_sys_dev_cdrom_info(&list, &list_count, 0);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -1245,7 +1422,7 @@ static int add_proc_info_drives(int flag)
|
|||||||
*/
|
*/
|
||||||
/* ts A60923 - A61005 : introduced new SCSI parameters */
|
/* ts A60923 - A61005 : introduced new SCSI parameters */
|
||||||
/* ts A61021 : moved non os-specific code to spc,sbc,mmc,drive */
|
/* ts A61021 : moved non os-specific code to spc,sbc,mmc,drive */
|
||||||
static void enumerate_common(char *fname, int bus_no, int host_no,
|
static void enumerate_common(char *fname, int fd_in, int bus_no, int host_no,
|
||||||
int channel_no, int target_no, int lun_no)
|
int channel_no, int target_no, int lun_no)
|
||||||
{
|
{
|
||||||
int ret, i;
|
int ret, i;
|
||||||
@ -1277,8 +1454,12 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
out.release = sg_release;
|
out.release = sg_release;
|
||||||
out.drive_is_open= sg_drive_is_open;
|
out.drive_is_open= sg_drive_is_open;
|
||||||
out.issue_command = sg_issue_command;
|
out.issue_command = sg_issue_command;
|
||||||
|
if (fd_in >= 0)
|
||||||
|
out.fd = fd_in;
|
||||||
|
|
||||||
/* Finally register drive and inquire drive information */
|
/* Finally register drive and inquire drive information.
|
||||||
|
out is an invalid copy afterwards. Do not use it for anything.
|
||||||
|
*/
|
||||||
burn_drive_finish_enum(&out);
|
burn_drive_finish_enum(&out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1530,6 +1711,39 @@ int sg_grab(struct burn_drive *d)
|
|||||||
relase of drive. Unclear why not the official error return
|
relase of drive. Unclear why not the official error return
|
||||||
value -1 of open(2) war used. */
|
value -1 of open(2) war used. */
|
||||||
if(! burn_drive_is_open(d)) {
|
if(! burn_drive_is_open(d)) {
|
||||||
|
char msg[120];
|
||||||
|
|
||||||
|
/* >>> SINGLE_OPEN : This case should be impossible now, since enumeration
|
||||||
|
transfers the fd from scanning to drive.
|
||||||
|
So if close-wait-open is desired, then it has to
|
||||||
|
be done unconditionally.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Libburn_udev_wait_useC
|
||||||
|
#define Libburn_udev_wait_useC 100000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Libburn_udev_extra_open_cyclE
|
||||||
|
|
||||||
|
if (Libburn_udev_wait_useC > 0) {
|
||||||
|
/* ts B10921 : workaround for udev which might get
|
||||||
|
a kernel event from open() and might
|
||||||
|
remove links if it cannot inspect the
|
||||||
|
drive. This waiting period shall allow udev
|
||||||
|
to act after it was woken up by the drive scan
|
||||||
|
activities.
|
||||||
|
*/
|
||||||
|
sprintf(msg,
|
||||||
|
"To avoid collision with udev: Waiting %lu usec before grabbing",
|
||||||
|
(unsigned long) Libburn_udev_wait_useC);
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
usleep(Libburn_udev_wait_useC);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Libburn_udev_extra_open_cyclE */
|
||||||
|
|
||||||
|
|
||||||
try_open:;
|
try_open:;
|
||||||
/* ts A60821
|
/* ts A60821
|
||||||
@ -1549,9 +1763,36 @@ try_open:;
|
|||||||
if(ret <= 0)
|
if(ret <= 0)
|
||||||
goto drive_is_in_use;
|
goto drive_is_in_use;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = open(d->devname, open_mode);
|
fd = open(d->devname, open_mode);
|
||||||
os_errno = errno;
|
os_errno = errno;
|
||||||
|
|
||||||
|
#ifdef Libburn_udev_extra_open_cyclE
|
||||||
|
|
||||||
|
/* ts B10920 : workaround for udev which might get
|
||||||
|
a kernel event from open() and might
|
||||||
|
remove links if it cannot inspect the
|
||||||
|
drive.
|
||||||
|
ts B10921 : this is more obtrusive than above waiting
|
||||||
|
before open(). The drive scan already has
|
||||||
|
opened and closed the drive several times.
|
||||||
|
So it seems to be merely about giving an
|
||||||
|
opportunity to udev, before long term grabbing
|
||||||
|
happens.
|
||||||
|
*/
|
||||||
|
if (fd >= 0 && Libburn_udev_wait_useC > 0) {
|
||||||
|
close(fd);
|
||||||
|
sprintf(msg,
|
||||||
|
"To avoid collision with udev: Waiting %lu usec before re-opening",
|
||||||
|
(unsigned long) Libburn_udev_wait_useC);
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
usleep(Libburn_udev_wait_useC);
|
||||||
|
fd = open(d->devname, open_mode);
|
||||||
|
os_errno = errno;
|
||||||
|
}
|
||||||
|
#endif /* Libburn_udev_extra_open_cyclE */
|
||||||
|
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
sg_fcntl_lock(&fd, d->devname, F_WRLCK, 1);
|
sg_fcntl_lock(&fd, d->devname, F_WRLCK, 1);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
@ -1575,6 +1816,10 @@ try_open:;
|
|||||||
drive_is_in_use:;
|
drive_is_in_use:;
|
||||||
tries++;
|
tries++;
|
||||||
if (tries < max_tries) {
|
if (tries < max_tries) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Drive is in use. Waiting 2 seconds before re-try",
|
||||||
|
0, 0);
|
||||||
usleep(2000000);
|
usleep(2000000);
|
||||||
goto try_open;
|
goto try_open;
|
||||||
}
|
}
|
||||||
@ -1601,10 +1846,8 @@ int sg_release(struct burn_drive *d)
|
|||||||
if (mmc_function_spy(d, "sg_release") <= 0)
|
if (mmc_function_spy(d, "sg_release") <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (d->fd < 1) {
|
if (d->fd < 1)
|
||||||
burn_print(1, "release an ungrabbed drive. die\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
/* ts A60821
|
/* ts A60821
|
||||||
<<< debug: for tracing calls which might use open drive fds */
|
<<< debug: for tracing calls which might use open drive fds */
|
||||||
@ -1640,6 +1883,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
d->fd, d->released);
|
d->fd, d->released);
|
||||||
mmc_function_spy(NULL, msg);
|
mmc_function_spy(NULL, msg);
|
||||||
|
|
||||||
|
/* >>> ts B11110 : move this into scsi_log_cmd() together with the
|
||||||
|
static fp */
|
||||||
/* ts A61030 */
|
/* ts A61030 */
|
||||||
if (burn_sg_log_scsi & 1) {
|
if (burn_sg_log_scsi & 1) {
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
@ -1760,12 +2005,13 @@ ex:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A60922 */
|
/* ts B11001 : outsourced from non-static sg_obtain_scsi_adr() */
|
||||||
/** Tries to obtain SCSI address parameters.
|
/** Tries to obtain SCSI address parameters.
|
||||||
@return 1 is success , 0 is failure
|
@return 1 is success , 0 is failure
|
||||||
*/
|
*/
|
||||||
int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
static int sg_obtain_scsi_adr_fd(char *path, int fd_in,
|
||||||
int *target_no, int *lun_no)
|
int *bus_no, int *host_no, int *channel_no,
|
||||||
|
int *target_no, int *lun_no)
|
||||||
{
|
{
|
||||||
int fd, ret, l, open_mode = O_RDONLY;
|
int fd, ret, l, open_mode = O_RDONLY;
|
||||||
struct my_scsi_idlun {
|
struct my_scsi_idlun {
|
||||||
@ -1775,7 +2021,8 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
|||||||
struct my_scsi_idlun idlun;
|
struct my_scsi_idlun idlun;
|
||||||
|
|
||||||
/* valgrind called idlun unitialized because it is blind for ioctl */
|
/* valgrind called idlun unitialized because it is blind for ioctl */
|
||||||
memset(&idlun, 0, sizeof(struct my_scsi_idlun));
|
idlun.x = 0;
|
||||||
|
idlun.host_unique_id = 0;
|
||||||
|
|
||||||
l = strlen(linux_ata_device_family) - 2;
|
l = strlen(linux_ata_device_family) - 2;
|
||||||
if (l > 0 && strncmp(path, linux_ata_device_family, l) == 0
|
if (l > 0 && strncmp(path, linux_ata_device_family, l) == 0
|
||||||
@ -1792,7 +2039,10 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
|||||||
SuSE 9.0 (kernel 2.4) and SuSE 9.3 (kernel 2.6) */
|
SuSE 9.0 (kernel 2.4) and SuSE 9.3 (kernel 2.6) */
|
||||||
/* so skip it for now */;
|
/* so skip it for now */;
|
||||||
}
|
}
|
||||||
fd = open(path, open_mode);
|
if (fd_in >= 0)
|
||||||
|
fd = fd_in;
|
||||||
|
else
|
||||||
|
fd = open(path, open_mode);
|
||||||
if(fd < 0)
|
if(fd < 0)
|
||||||
return 0;
|
return 0;
|
||||||
sg_fcntl_lock(&fd, path, F_RDLCK, 0);
|
sg_fcntl_lock(&fd, path, F_RDLCK, 0);
|
||||||
@ -1808,7 +2058,8 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
|||||||
/* http://www.tldp.org/HOWTO/SCSI-Generic-HOWTO/scsi_g_idlun.html */
|
/* http://www.tldp.org/HOWTO/SCSI-Generic-HOWTO/scsi_g_idlun.html */
|
||||||
ret = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &idlun);
|
ret = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &idlun);
|
||||||
|
|
||||||
sg_close_drive_fd(path, -1, &fd, 0);
|
if (fd_in < 0)
|
||||||
|
sg_close_drive_fd(path, -1, &fd, 0);
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
return(0);
|
return(0);
|
||||||
*host_no= (idlun.x>>24)&255;
|
*host_no= (idlun.x>>24)&255;
|
||||||
@ -1825,6 +2076,18 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A60922 */
|
||||||
|
/** Tries to obtain SCSI address parameters.
|
||||||
|
@return 1 is success , 0 is failure
|
||||||
|
*/
|
||||||
|
int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
||||||
|
int *target_no, int *lun_no)
|
||||||
|
{
|
||||||
|
return sg_obtain_scsi_adr_fd(path, -1, bus_no, host_no, channel_no,
|
||||||
|
target_no, lun_no);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A60922 ticket 33 : called from drive.c */
|
/* ts A60922 ticket 33 : called from drive.c */
|
||||||
/** Tells wether a text is a persistent address as listed by the enumeration
|
/** Tells wether a text is a persistent address as listed by the enumeration
|
||||||
functions.
|
functions.
|
||||||
@ -1928,6 +2191,19 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
|
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
|
||||||
(off_t) vfsbuf.f_bavail;
|
(off_t) vfsbuf.f_bavail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef NIX
|
||||||
|
/* <<< */
|
||||||
|
fprintf(stderr, "libburn_DEBUG: Faking 4.5 TB of disk space\n");
|
||||||
|
*bytes = ((off_t) 2415919104) * (off_t) 2048;
|
||||||
|
if (*bytes / (off_t) 2048 > (off_t) 0x7ffffff0) {
|
||||||
|
*bytes = ((off_t) 0x7ffffff0) * (off_t) 2048;
|
||||||
|
fprintf(stderr, "libburn_DEBUG: Reducing disk space to 4 TB - 2 kB\n");
|
||||||
|
}
|
||||||
|
/* <<< */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
ex:;
|
ex:;
|
||||||
BURN_FREE_MEM(testpath);
|
BURN_FREE_MEM(testpath);
|
||||||
|
@ -561,10 +561,8 @@ ex:;
|
|||||||
*/
|
*/
|
||||||
int sg_release(struct burn_drive *d)
|
int sg_release(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
if (d->fd < 0) {
|
if (d->fd < 0)
|
||||||
burn_print(1, "release an ungrabbed drive. die\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
sg_close_drive(d);
|
sg_close_drive(d);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -581,7 +579,7 @@ int sg_release(struct burn_drive *d)
|
|||||||
*/
|
*/
|
||||||
int sg_issue_command(struct burn_drive *d, struct command *c)
|
int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
{
|
{
|
||||||
int i, timeout_ms, ret, key, asc, ascq, done = 0;
|
int i, timeout_ms, ret, key, asc, ascq, done = 0, sense_len;
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
struct uscsi_cmd cgc;
|
struct uscsi_cmd cgc;
|
||||||
char msg[80];
|
char msg[80];
|
||||||
@ -662,11 +660,12 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
/* >>> valid sense: cgc.uscsi_rqlen - cgc.uscsi_rqresid */;
|
/* >>> valid sense: cgc.uscsi_rqlen - cgc.uscsi_rqresid */;
|
||||||
|
|
||||||
spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
|
spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
|
||||||
if (key || asc || ascq) {
|
if (key || asc || ascq)
|
||||||
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, 18, 0,
|
sense_len = 18;
|
||||||
|
else
|
||||||
|
sense_len = 0;
|
||||||
|
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len, 0,
|
||||||
start_time, timeout_ms, i, 2);
|
start_time, timeout_ms, i, 2);
|
||||||
} else
|
|
||||||
done = 1;
|
|
||||||
|
|
||||||
} /* end of retry-loop */
|
} /* end of retry-loop */
|
||||||
|
|
||||||
@ -785,13 +784,11 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
char *testpath = NULL, *cpt;
|
char *testpath = NULL, *cpt;
|
||||||
long blocks;
|
|
||||||
off_t add_size = 0;
|
off_t add_size = 0;
|
||||||
|
|
||||||
BURN_ALLOC_MEM(testpath, char, 4096);
|
BURN_ALLOC_MEM(testpath, char, 4096);
|
||||||
|
|
||||||
testpath[0] = 0;
|
testpath[0] = 0;
|
||||||
blocks = *bytes / 512;
|
|
||||||
if (stat(path, &stbuf) == -1) {
|
if (stat(path, &stbuf) == -1) {
|
||||||
strcpy(testpath, path);
|
strcpy(testpath, path);
|
||||||
cpt = strrchr(testpath, '/');
|
cpt = strrchr(testpath, '/');
|
||||||
|
12
libburn/sg.c
12
libburn/sg.c
@ -23,12 +23,20 @@
|
|||||||
#else
|
#else
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
|
|
||||||
|
#ifdef Libburn_use_sg_freebsd_porT
|
||||||
|
#include "sg-freebsd-port.c"
|
||||||
|
#else
|
||||||
#include "sg-freebsd.c"
|
#include "sg-freebsd.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#ifdef __FreeBSD_kernel__
|
#ifdef __FreeBSD_kernel__
|
||||||
|
|
||||||
|
#ifdef Libburn_use_sg_freebsd_porT
|
||||||
|
#include "sg-freebsd-port.c"
|
||||||
|
#else
|
||||||
#include "sg-freebsd.c"
|
#include "sg-freebsd.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#ifdef __linux
|
#ifdef __linux
|
||||||
@ -50,11 +58,11 @@
|
|||||||
static int intentional_compiler_warning(void)
|
static int intentional_compiler_warning(void)
|
||||||
{
|
{
|
||||||
int INTENTIONAL_COMPILER_WARNING_;
|
int INTENTIONAL_COMPILER_WARNING_;
|
||||||
int Cannot_recognize_GNU_Linux_nor_FreeBSD_;
|
int Cannot_recognize_GNU_Linux_nor_FreeBSD_nor_Solaris_;
|
||||||
int Have_to_use_dummy_MMC_transport_adapter_;
|
int Have_to_use_dummy_MMC_transport_adapter_;
|
||||||
int This_libburn_will_not_be_able_to_operate_on_real_CD_drives;
|
int This_libburn_will_not_be_able_to_operate_on_real_CD_drives;
|
||||||
int Have_to_use_dummy_MMC_transport_adapter;
|
int Have_to_use_dummy_MMC_transport_adapter;
|
||||||
int Cannot_recognize_GNU_Linux_nor_FreeBSD;
|
int Cannot_recognize_GNU_Linux_nor_FreeBSD_nor_Solaris;
|
||||||
int INTENTIONAL_COMPILER_WARNING;
|
int INTENTIONAL_COMPILER_WARNING;
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
|
255
libburn/spc.c
255
libburn/spc.c
@ -113,6 +113,7 @@ int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq)
|
|||||||
c->retry = 0;
|
c->retry = 0;
|
||||||
c->dir = NO_TRANSFER;
|
c->dir = NO_TRANSFER;
|
||||||
d->issue_command(d, c);
|
d->issue_command(d, c);
|
||||||
|
*key = *asc = *ascq = 0;
|
||||||
if (c->error) {
|
if (c->error) {
|
||||||
spc_decode_sense(c->sense, 0, key, asc, ascq);
|
spc_decode_sense(c->sense, 0, key, asc, ascq);
|
||||||
return (key == 0);
|
return (key == 0);
|
||||||
@ -138,15 +139,20 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
|
|||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
int i, ret = 1, key = 0, asc = 0, ascq = 0, clueless_start = 0;
|
int i, ret = 1, key = 0, asc = 0, ascq = 0, clueless_start = 0;
|
||||||
static int clueless_timeout = 5 * 10;
|
static double tests_per_second = 2.0;
|
||||||
|
int sleep_usecs, loop_limit, clueless_timeout;
|
||||||
char *msg = NULL;
|
char *msg = NULL;
|
||||||
unsigned char sense[14];
|
unsigned char sense[14];
|
||||||
enum response resp;
|
|
||||||
|
|
||||||
BURN_ALLOC_MEM(msg, char, 320);
|
BURN_ALLOC_MEM(msg, char, 320);
|
||||||
|
clueless_timeout = 5 * tests_per_second + 1;
|
||||||
|
loop_limit = max_sec * tests_per_second + 1;
|
||||||
|
sleep_usecs = 1000000 / tests_per_second;
|
||||||
|
|
||||||
if (!(flag & 1))
|
if (!(flag & 1))
|
||||||
usleep(100000);
|
usleep(sleep_usecs);
|
||||||
for(i = !(flag & 1); i < max_sec * 10; i++) {
|
|
||||||
|
for(i = !(flag & 1); i < loop_limit; i++) {
|
||||||
ret = spc_test_unit_ready_r(d, &key, &asc, &ascq);
|
ret = spc_test_unit_ready_r(d, &key, &asc, &ascq);
|
||||||
if (ret > 0) /* ready */
|
if (ret > 0) /* ready */
|
||||||
break;
|
break;
|
||||||
@ -177,7 +183,7 @@ handle_error:;
|
|||||||
sense[2] = key;
|
sense[2] = key;
|
||||||
sense[12] = asc;
|
sense[12] = asc;
|
||||||
sense[13] = ascq;
|
sense[13] = ascq;
|
||||||
resp = scsi_error_msg(d, sense, 14, msg + strlen(msg),
|
scsi_error_msg(d, sense, 14, msg + strlen(msg),
|
||||||
&key, &asc, &ascq);
|
&key, &asc, &ascq);
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x0002014d,
|
0x0002014d,
|
||||||
@ -203,7 +209,7 @@ handle_error:;
|
|||||||
goto handle_error;
|
goto handle_error;
|
||||||
|
|
||||||
slumber:;
|
slumber:;
|
||||||
usleep(100000);
|
usleep(sleep_usecs);
|
||||||
}
|
}
|
||||||
if (ret <= 0 || !(flag & 2)) {
|
if (ret <= 0 || !(flag & 2)) {
|
||||||
sprintf(msg, "Async %s %s after %d.%d seconds",
|
sprintf(msg, "Async %s %s after %d.%d seconds",
|
||||||
@ -268,13 +274,12 @@ void spc_inquiry(struct burn_drive *d)
|
|||||||
struct buffer *buf = NULL;
|
struct buffer *buf = NULL;
|
||||||
struct burn_scsi_inquiry_data *id;
|
struct burn_scsi_inquiry_data *id;
|
||||||
struct command *c = NULL;
|
struct command *c = NULL;
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (mmc_function_spy(d, "inquiry") <= 0)
|
if (mmc_function_spy(d, "inquiry") <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BURN_ALLOC_MEM(buf, struct buffer, 1);
|
BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
|
||||||
BURN_ALLOC_MEM(c, struct command, 1);
|
BURN_ALLOC_MEM_VOID(c, struct command, 1);
|
||||||
scsi_init_command(c, SPC_INQUIRY, sizeof(SPC_INQUIRY));
|
scsi_init_command(c, SPC_INQUIRY, sizeof(SPC_INQUIRY));
|
||||||
c->dxfer_len = (c->opcode[3] << 8) | c->opcode[4];
|
c->dxfer_len = (c->opcode[3] << 8) | c->opcode[4];
|
||||||
c->retry = 1;
|
c->retry = 1;
|
||||||
@ -342,8 +347,8 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
|||||||
{
|
{
|
||||||
struct buffer *buf = NULL;
|
struct buffer *buf = NULL;
|
||||||
struct scsi_mode_data *m;
|
struct scsi_mode_data *m;
|
||||||
int size, page_length, num_write_speeds = 0, i, speed, ret;
|
int page_length, num_write_speeds = 0, i, speed, ret;
|
||||||
int old_alloc_len, was_error = 0;
|
int old_alloc_len, was_error = 0, block_descr_len;
|
||||||
unsigned char *page;
|
unsigned char *page;
|
||||||
struct command *c = NULL;
|
struct command *c = NULL;
|
||||||
struct burn_speed_descriptor *sd;
|
struct burn_speed_descriptor *sd;
|
||||||
@ -366,10 +371,6 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
|||||||
|
|
||||||
memset(buf, 0, sizeof(struct buffer));
|
memset(buf, 0, sizeof(struct buffer));
|
||||||
scsi_init_command(c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
|
scsi_init_command(c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
|
||||||
/*
|
|
||||||
memcpy(c->opcode, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
|
|
||||||
c->oplen = sizeof(SPC_MODE_SENSE);
|
|
||||||
*/
|
|
||||||
c->dxfer_len = *alloc_len;
|
c->dxfer_len = *alloc_len;
|
||||||
c->opcode[7] = (c->dxfer_len >> 8) & 0xff;
|
c->opcode[7] = (c->dxfer_len >> 8) & 0xff;
|
||||||
c->opcode[8] = c->dxfer_len & 0xff;
|
c->opcode[8] = c->dxfer_len & 0xff;
|
||||||
@ -386,14 +387,22 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
|||||||
was_error = 1;
|
was_error = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = c->page->data[0] * 256 + c->page->data[1] + 2;
|
/* ts B11103 : qemu SCSI CD-ROM has Block Descriptor Length > 0.
|
||||||
page = c->page->data + 8;
|
The descriptors come between header and page.
|
||||||
|
*/
|
||||||
|
block_descr_len = c->page->data[6] * 256 + c->page->data[7];
|
||||||
|
|
||||||
|
/* Skip over Mode Data Header and block descriptors */
|
||||||
|
page = c->page->data + 8 + block_descr_len;
|
||||||
|
|
||||||
/* ts A61225 :
|
/* ts A61225 :
|
||||||
Although MODE SENSE indeed belongs to SPC, the returned code page
|
Although MODE SENSE indeed belongs to SPC, the returned code page
|
||||||
2Ah is part of MMC-1 to MMC-3. In MMC-1 5.2.3.4. it has 22 bytes,
|
2Ah is part of MMC-1 to MMC-3. In MMC-1 5.2.3.4. it has 22 bytes,
|
||||||
in MMC-3 6.3.11 there are at least 28 bytes plus a variable length
|
in MMC-3 6.3.11 there are at least 28 bytes plus a variable length
|
||||||
set of speed descriptors. In MMC-5 E.11 it is declared "legacy".
|
set of speed descriptors. In MMC-5 E.11 it is declared "legacy".
|
||||||
|
ts B11031 :
|
||||||
|
qemu emulates an ATAPI DVD-ROM, which delivers only a page length
|
||||||
|
of 18. This is now tolerated.
|
||||||
*/
|
*/
|
||||||
/* ts A90603 :
|
/* ts A90603 :
|
||||||
SPC-1 8.3.3 enumerates mode page format bytes from 0 to n and
|
SPC-1 8.3.3 enumerates mode page format bytes from 0 to n and
|
||||||
@ -407,8 +416,9 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
|||||||
if (page_length + 10 > old_alloc_len)
|
if (page_length + 10 > old_alloc_len)
|
||||||
page_length = old_alloc_len - 10;
|
page_length = old_alloc_len - 10;
|
||||||
|
|
||||||
/* ts A90602 : 20 asserts page[21]. (see SPC-1 8.3.3) */
|
/* ts A90602 : page_length N asserts page[N+1]. (see SPC-1 8.3.3) */
|
||||||
if (page_length < 20) {
|
/* ts B11031 : qemu drive has a page_length of 18 */
|
||||||
|
if (page_length < 18) {
|
||||||
m->valid = -1;
|
m->valid = -1;
|
||||||
sprintf(msg, "MODE SENSE page 2A too short: %s : %d",
|
sprintf(msg, "MODE SENSE page 2A too short: %s : %d",
|
||||||
d->devname, page_length);
|
d->devname, page_length);
|
||||||
@ -437,8 +447,11 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
|||||||
m->max_read_speed = page[8] * 256 + page[9];
|
m->max_read_speed = page[8] * 256 + page[9];
|
||||||
m->cur_read_speed = page[14] * 256 + page[15];
|
m->cur_read_speed = page[14] * 256 + page[15];
|
||||||
|
|
||||||
m->max_write_speed = page[18] * 256 + page[19];
|
m->max_write_speed = m->cur_write_speed = 0;
|
||||||
m->cur_write_speed = page[20] * 256 + page[21];
|
if (page_length >= 18) /* note: page length is page size - 2 */
|
||||||
|
m->max_write_speed = page[18] * 256 + page[19];
|
||||||
|
if (page_length >= 20)
|
||||||
|
m->cur_write_speed = page[20] * 256 + page[21];
|
||||||
|
|
||||||
/* ts A61021 : New field to be set by atip (or following MMC-3 info) */
|
/* ts A61021 : New field to be set by atip (or following MMC-3 info) */
|
||||||
m->min_write_speed = m->max_write_speed;
|
m->min_write_speed = m->max_write_speed;
|
||||||
@ -538,7 +551,7 @@ ex:
|
|||||||
|
|
||||||
void spc_sense_caps(struct burn_drive *d)
|
void spc_sense_caps(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
int alloc_len, start_len = 30, ret;
|
int alloc_len, start_len = 30, minimum_len = 28, ret;
|
||||||
|
|
||||||
mmc_start_if_needed(d, 1);
|
mmc_start_if_needed(d, 1);
|
||||||
if (mmc_function_spy(d, "sense_caps") <= 0)
|
if (mmc_function_spy(d, "sense_caps") <= 0)
|
||||||
@ -551,7 +564,12 @@ void spc_sense_caps(struct burn_drive *d)
|
|||||||
fprintf(stderr,"LIBBURN_DEBUG: 5Ah alloc_len = %d , ret = %d\n",
|
fprintf(stderr,"LIBBURN_DEBUG: 5Ah alloc_len = %d , ret = %d\n",
|
||||||
alloc_len, ret);
|
alloc_len, ret);
|
||||||
*/
|
*/
|
||||||
if (alloc_len >= start_len && ret > 0)
|
/* ts B11103:
|
||||||
|
qemu ATAPI DVD-ROM delivers only 28.
|
||||||
|
SanDisk Cruzer U3 memory stick throws error on alloc_len < 30.
|
||||||
|
MMC-1 prescribes that 30 are available. qemu tolerates 30.
|
||||||
|
*/
|
||||||
|
if (alloc_len >= minimum_len && ret > 0)
|
||||||
/* second execution with announced length */
|
/* second execution with announced length */
|
||||||
spc_sense_caps_al(d, &alloc_len, 0);
|
spc_sense_caps_al(d, &alloc_len, 0);
|
||||||
}
|
}
|
||||||
@ -561,17 +579,16 @@ void spc_sense_error_params(struct burn_drive *d)
|
|||||||
{
|
{
|
||||||
struct buffer *buf = NULL;
|
struct buffer *buf = NULL;
|
||||||
struct scsi_mode_data *m;
|
struct scsi_mode_data *m;
|
||||||
int size, alloc_len = 12 ;
|
int alloc_len = 12 ;
|
||||||
unsigned char *page;
|
unsigned char *page;
|
||||||
struct command *c = NULL;
|
struct command *c = NULL;
|
||||||
int ret;
|
|
||||||
|
|
||||||
mmc_start_if_needed(d, 1);
|
mmc_start_if_needed(d, 1);
|
||||||
if (mmc_function_spy(d, "sense_error_params") <= 0)
|
if (mmc_function_spy(d, "sense_error_params") <= 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
|
||||||
BURN_ALLOC_MEM(buf, struct buffer, 1);
|
BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
|
||||||
BURN_ALLOC_MEM(c, struct command, 1);
|
BURN_ALLOC_MEM_VOID(c, struct command, 1);
|
||||||
|
|
||||||
scsi_init_command(c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
|
scsi_init_command(c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
|
||||||
c->dxfer_len = alloc_len;
|
c->dxfer_len = alloc_len;
|
||||||
@ -585,7 +602,6 @@ void spc_sense_error_params(struct burn_drive *d)
|
|||||||
c->dir = FROM_DRIVE;
|
c->dir = FROM_DRIVE;
|
||||||
d->issue_command(d, c);
|
d->issue_command(d, c);
|
||||||
|
|
||||||
size = c->page->data[0] * 256 + c->page->data[1] + 2;
|
|
||||||
m = d->mdata;
|
m = d->mdata;
|
||||||
page = c->page->data + 8;
|
page = c->page->data + 8;
|
||||||
d->params.retries = page[3];
|
d->params.retries = page[3];
|
||||||
@ -601,14 +617,13 @@ void spc_select_error_params(struct burn_drive *d,
|
|||||||
{
|
{
|
||||||
struct buffer *buf = NULL;
|
struct buffer *buf = NULL;
|
||||||
struct command *c = NULL;
|
struct command *c = NULL;
|
||||||
int ret;
|
|
||||||
|
|
||||||
mmc_start_if_needed(d, 1);
|
mmc_start_if_needed(d, 1);
|
||||||
if (mmc_function_spy(d, "select_error_params") <= 0)
|
if (mmc_function_spy(d, "select_error_params") <= 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
|
||||||
BURN_ALLOC_MEM(buf, struct buffer, 1);
|
BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
|
||||||
BURN_ALLOC_MEM(c, struct command, 1);
|
BURN_ALLOC_MEM_VOID(c, struct command, 1);
|
||||||
|
|
||||||
scsi_init_command(c, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
|
scsi_init_command(c, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
|
||||||
c->retry = 1;
|
c->retry = 1;
|
||||||
@ -627,7 +642,6 @@ void spc_select_error_params(struct burn_drive *d,
|
|||||||
c->page->data[10] |= 4;
|
c->page->data[10] |= 4;
|
||||||
if (!o->hardware_error_recovery)
|
if (!o->hardware_error_recovery)
|
||||||
c->page->data[10] |= 1;
|
c->page->data[10] |= 1;
|
||||||
/*burn_print(1, "error parameter 0x%x\n", c->page->data[10]);*/
|
|
||||||
c->page->data[11] = d->params.retries;
|
c->page->data[11] = d->params.retries;
|
||||||
c->dir = TO_DRIVE;
|
c->dir = TO_DRIVE;
|
||||||
d->issue_command(d, c);
|
d->issue_command(d, c);
|
||||||
@ -640,7 +654,7 @@ void spc_sense_write_params(struct burn_drive *d)
|
|||||||
{
|
{
|
||||||
struct buffer *buf = NULL;
|
struct buffer *buf = NULL;
|
||||||
struct scsi_mode_data *m;
|
struct scsi_mode_data *m;
|
||||||
int size, dummy, alloc_len = 10, ret;
|
int dummy1, dummy2, alloc_len = 10;
|
||||||
unsigned char *page;
|
unsigned char *page;
|
||||||
struct command *c = NULL;
|
struct command *c = NULL;
|
||||||
|
|
||||||
@ -648,8 +662,8 @@ void spc_sense_write_params(struct burn_drive *d)
|
|||||||
if (mmc_function_spy(d, "sense_write_params") <= 0)
|
if (mmc_function_spy(d, "sense_write_params") <= 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
|
||||||
BURN_ALLOC_MEM(buf, struct buffer, 1);
|
BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
|
||||||
BURN_ALLOC_MEM(c, struct command, 1);
|
BURN_ALLOC_MEM_VOID(c, struct command, 1);
|
||||||
|
|
||||||
/* ts A61007 : Done in soft at only caller burn_drive_grab() */
|
/* ts A61007 : Done in soft at only caller burn_drive_grab() */
|
||||||
/* a ssert(d->mdata->cdr_write || d->mdata->cdrw_write ||
|
/* a ssert(d->mdata->cdr_write || d->mdata->cdrw_write ||
|
||||||
@ -670,9 +684,7 @@ void spc_sense_write_params(struct burn_drive *d)
|
|||||||
/* ts A71128 : do not interpret reply if error */
|
/* ts A71128 : do not interpret reply if error */
|
||||||
m = d->mdata;
|
m = d->mdata;
|
||||||
if (!c->error) {
|
if (!c->error) {
|
||||||
size = c->page->data[0] * 256 + c->page->data[1] + 2;
|
|
||||||
page = c->page->data + 8;
|
page = c->page->data + 8;
|
||||||
burn_print(1, "write page length 0x%x\n", page[1]);
|
|
||||||
m->write_page_length = page[1];
|
m->write_page_length = page[1];
|
||||||
m->write_page_valid = 1;
|
m->write_page_valid = 1;
|
||||||
} else
|
} else
|
||||||
@ -685,7 +697,8 @@ void spc_sense_write_params(struct burn_drive *d)
|
|||||||
d->read_format_capacities(d, -1);
|
d->read_format_capacities(d, -1);
|
||||||
else if (d->status == BURN_DISC_BLANK ||
|
else if (d->status == BURN_DISC_BLANK ||
|
||||||
(d->current_is_cd_profile && d->status == BURN_DISC_APPENDABLE)) {
|
(d->current_is_cd_profile && d->status == BURN_DISC_APPENDABLE)) {
|
||||||
d->get_nwa(d, -1, &dummy, &dummy);
|
burn_drive_send_default_page_05(d, 0);
|
||||||
|
d->get_nwa(d, -1, &dummy1, &dummy2);
|
||||||
}
|
}
|
||||||
/* others are hopefully up to date from mmc_read_disc_info() */
|
/* others are hopefully up to date from mmc_read_disc_info() */
|
||||||
|
|
||||||
@ -710,14 +723,14 @@ void spc_select_write_params(struct burn_drive *d,
|
|||||||
{
|
{
|
||||||
struct buffer *buf = NULL;
|
struct buffer *buf = NULL;
|
||||||
struct command *c = NULL;
|
struct command *c = NULL;
|
||||||
int alloc_len, ret;
|
int alloc_len;
|
||||||
|
|
||||||
mmc_start_if_needed(d, 1);
|
mmc_start_if_needed(d, 1);
|
||||||
if (mmc_function_spy(d, "select_write_params") <= 0)
|
if (mmc_function_spy(d, "select_write_params") <= 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
|
||||||
BURN_ALLOC_MEM(buf, struct buffer, 1);
|
BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
|
||||||
BURN_ALLOC_MEM(c, struct command, 1);
|
BURN_ALLOC_MEM_VOID(c, struct command, 1);
|
||||||
|
|
||||||
/* ts A61007 : All current callers are safe. */
|
/* ts A61007 : All current callers are safe. */
|
||||||
/* a ssert(o->drive == d); */
|
/* a ssert(o->drive == d); */
|
||||||
@ -762,9 +775,6 @@ void spc_select_write_params(struct burn_drive *d,
|
|||||||
|
|
||||||
c->page->bytes = alloc_len;
|
c->page->bytes = alloc_len;
|
||||||
|
|
||||||
burn_print(12, "using write page length %d (valid %d)\n",
|
|
||||||
d->mdata->write_page_length, d->mdata->write_page_valid);
|
|
||||||
|
|
||||||
/* ts A61229 */
|
/* ts A61229 */
|
||||||
if (mmc_compose_mode_page_5(d, o, c->page->data + 8) <= 0)
|
if (mmc_compose_mode_page_5(d, o, c->page->data + 8) <= 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
@ -781,6 +791,7 @@ void spc_getcaps(struct burn_drive *d)
|
|||||||
if (mmc_function_spy(d, "getcaps") <= 0)
|
if (mmc_function_spy(d, "getcaps") <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
burn_speed_descriptor_destroy(&(d->mdata->speed_descriptors), 1);
|
||||||
spc_inquiry(d);
|
spc_inquiry(d);
|
||||||
spc_sense_caps(d);
|
spc_sense_caps(d);
|
||||||
spc_sense_error_params(d);
|
spc_sense_error_params(d);
|
||||||
@ -797,21 +808,18 @@ void spc_probe_write_modes(struct burn_drive *d)
|
|||||||
int try_write_type = 1;
|
int try_write_type = 1;
|
||||||
int try_block_type = 0;
|
int try_block_type = 0;
|
||||||
int key, asc, ascq, useable_write_type = -1, useable_block_type = -1;
|
int key, asc, ascq, useable_write_type = -1, useable_block_type = -1;
|
||||||
int last_try = 0, ret;
|
int last_try = 0;
|
||||||
struct command *c = NULL;
|
struct command *c = NULL;
|
||||||
|
|
||||||
mmc_start_if_needed(d, 1);
|
mmc_start_if_needed(d, 1);
|
||||||
if (mmc_function_spy(d, "spc_probe_write_modes") <= 0)
|
if (mmc_function_spy(d, "spc_probe_write_modes") <= 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
|
||||||
BURN_ALLOC_MEM(buf, struct buffer, 1);
|
BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
|
||||||
BURN_ALLOC_MEM(c, struct command, 1);
|
BURN_ALLOC_MEM_VOID(c, struct command, 1);
|
||||||
|
|
||||||
/* ts A70213 : added pseudo try_write_type 4 to set a suitable mode */
|
/* ts A70213 : added pseudo try_write_type 4 to set a suitable mode */
|
||||||
while (try_write_type != 5) {
|
while (try_write_type != 5) {
|
||||||
burn_print(9, "trying %d, %d\n", try_write_type,
|
|
||||||
try_block_type);
|
|
||||||
|
|
||||||
/* ts A70213 */
|
/* ts A70213 */
|
||||||
if (try_write_type == 4) {
|
if (try_write_type == 4) {
|
||||||
/* Pseudo write type NONE . Set a useable write mode */
|
/* Pseudo write type NONE . Set a useable write mode */
|
||||||
@ -850,10 +858,9 @@ void spc_probe_write_modes(struct burn_drive *d)
|
|||||||
|
|
||||||
spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
|
spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
|
||||||
if (key)
|
if (key)
|
||||||
burn_print(7, "%d not supported\n", try_block_type);
|
/* try_block_type not supported */;
|
||||||
else {
|
else {
|
||||||
burn_print(7, "%d:%d SUPPORTED MODE!\n",
|
/* try_write_type, try_block_type is supported mode */
|
||||||
try_write_type, try_block_type);
|
|
||||||
if (try_write_type == 2) /* sao */
|
if (try_write_type == 2) /* sao */
|
||||||
d->block_types[try_write_type] =
|
d->block_types[try_write_type] =
|
||||||
BURN_BLOCK_SAO;
|
BURN_BLOCK_SAO;
|
||||||
@ -1034,9 +1041,6 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
|
|||||||
sprintf(msg, "[%X %2.2X %2.2X] ", *key, *asc, *ascq);
|
sprintf(msg, "[%X %2.2X %2.2X] ", *key, *asc, *ascq);
|
||||||
msg= msg + strlen(msg);
|
msg= msg + strlen(msg);
|
||||||
|
|
||||||
burn_print(12, "CONDITION: 0x%x 0x%x 0x%x on %s %s\n",
|
|
||||||
*key, *asc, *ascq, d->idata->vendor, d->idata->product);
|
|
||||||
|
|
||||||
switch (*asc) {
|
switch (*asc) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
if (*key > 0 || *ascq > 0)
|
if (*key > 0 || *ascq > 0)
|
||||||
@ -1332,10 +1336,6 @@ enum response scsi_error(struct burn_drive *d, unsigned char *sense,
|
|||||||
|
|
||||||
BURN_ALLOC_MEM(msg, char, 160);
|
BURN_ALLOC_MEM(msg, char, 160);
|
||||||
resp = scsi_error_msg(d, sense, senselen, msg, &key, &asc, &ascq);
|
resp = scsi_error_msg(d, sense, senselen, msg, &key, &asc, &ascq);
|
||||||
if (asc == 0 || asc == 0x3A)
|
|
||||||
burn_print(12, "%s\n", msg);
|
|
||||||
else
|
|
||||||
burn_print(1, "%s\n", msg);
|
|
||||||
ex:;
|
ex:;
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
resp = FAIL;
|
resp = FAIL;
|
||||||
@ -1408,7 +1408,7 @@ static char *scsi_command_name(unsigned int c, int flag)
|
|||||||
case 0xbe:
|
case 0xbe:
|
||||||
return "READ CD";
|
return "READ CD";
|
||||||
}
|
}
|
||||||
return "(NOT IN COMMAND LIST)";
|
return "(NOT IN LIBBURN COMMAND LIST)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1456,38 +1456,39 @@ ex:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A91106 */
|
/* ts B11110 */
|
||||||
/* @param flag bit0= do not show eventual data payload sent to the drive
|
/* @param flag bit0= do not show eventual data payload sent to the drive
|
||||||
(never with WRITE commands)
|
(never with WRITE commands)
|
||||||
bit1= show write length and target LBA in decimal
|
|
||||||
*/
|
*/
|
||||||
int scsi_show_cmd_text(struct command *c, void *fp_in, int flag)
|
int scsi_show_command(unsigned char *opcode, int oplen, int dir,
|
||||||
|
unsigned char *data, int bytes,
|
||||||
|
void *fp_in, int flag)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
FILE *fp = fp_in;
|
FILE *fp = fp_in;
|
||||||
|
|
||||||
fprintf(fp, "\n%s\n",
|
fprintf(fp, "\n%s\n",
|
||||||
scsi_command_name((unsigned int) c->opcode[0], 0));
|
scsi_command_name((unsigned int) opcode[0], 0));
|
||||||
for(i = 0; i < 16 && i < c->oplen; i++)
|
for(i = 0; i < 16 && i < oplen; i++)
|
||||||
fprintf(fp, "%2.2x ", c->opcode[i]);
|
fprintf(fp, "%2.2x ", opcode[i]);
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
fprintf(fp, "\n");
|
fprintf(fp, "\n");
|
||||||
if (flag & 1)
|
if (flag & 1)
|
||||||
return 1;
|
return 1;
|
||||||
if (c->opcode[0] == 0x2A) { /* WRITE 10 */
|
if (opcode[0] == 0x2A) { /* WRITE 10 */
|
||||||
if (flag & 2)
|
if (flag & 2)
|
||||||
fprintf(fp, "%d -> %d\n",
|
fprintf(fp, "%d -> %d\n",
|
||||||
(c->opcode[7] << 8) | c->opcode[8],
|
(opcode[7] << 8) | opcode[8],
|
||||||
mmc_four_char_to_int(c->opcode + 2));
|
mmc_four_char_to_int(opcode + 2));
|
||||||
} else if (c->opcode[0] == 0xAA) { /* WRITE 12 */
|
} else if (opcode[0] == 0xAA) { /* WRITE 12 */
|
||||||
if (flag & 2)
|
if (flag & 2)
|
||||||
fprintf(fp, "%d -> %d\n",
|
fprintf(fp, "%d -> %d\n",
|
||||||
mmc_four_char_to_int(c->opcode + 6),
|
mmc_four_char_to_int(opcode + 6),
|
||||||
mmc_four_char_to_int(c->opcode + 2));
|
mmc_four_char_to_int(opcode + 2));
|
||||||
} else if (c->dir == TO_DRIVE) {
|
} else if (dir == TO_DRIVE && !(flag & 1)) {
|
||||||
fprintf(fp, "To drive: %db\n", c->page->bytes);
|
fprintf(fp, "To drive: %db\n", bytes);
|
||||||
for (i = 0; i < c->page->bytes; i++)
|
for (i = 0; i < bytes; i++)
|
||||||
fprintf(fp, "%2.2x%c", c->page->data[i],
|
fprintf(fp, "%2.2x%c", data[i],
|
||||||
((i % 20) == 19 ? '\n' : ' '));
|
((i % 20) == 19 ? '\n' : ' '));
|
||||||
if (i % 20)
|
if (i % 20)
|
||||||
fprintf(fp, "\n");
|
fprintf(fp, "\n");
|
||||||
@ -1495,24 +1496,39 @@ int scsi_show_cmd_text(struct command *c, void *fp_in, int flag)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A91106 */
|
/* ts A91106 */
|
||||||
int scsi_show_cmd_reply(struct command *c, void *fp_in, int flag)
|
/* @param flag bit0= do not show eventual data payload sent to the drive
|
||||||
|
(never with WRITE commands)
|
||||||
|
*/
|
||||||
|
int scsi_show_cmd_text(struct command *c, void *fp_in, int flag)
|
||||||
|
{
|
||||||
|
return scsi_show_command(c->opcode, c->oplen, c->dir, c->page->data,
|
||||||
|
c->page->bytes, fp_in, flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91106 */ /* ts B11110 */
|
||||||
|
int scsi_show_command_reply(unsigned char *opcode, int data_dir,
|
||||||
|
unsigned char *data, int dxfer_len,
|
||||||
|
void *fp_in, int flag)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
FILE *fp = fp_in;
|
FILE *fp = fp_in;
|
||||||
|
|
||||||
if (c->dir != FROM_DRIVE)
|
if (data_dir != FROM_DRIVE)
|
||||||
return 2;
|
return 2;
|
||||||
if (c->opcode[0] == 0x28 || c->opcode[0] == 0x3C ||
|
if (opcode[0] == 0x28 || opcode[0] == 0x3C ||
|
||||||
c->opcode[0] == 0xA8 || c->opcode[0] == 0xBE) {
|
opcode[0] == 0xA8 || opcode[0] == 0xBE) {
|
||||||
/* READ commands */
|
/* READ commands */
|
||||||
/* >>> report amount of data */;
|
/* >>> report amount of data */;
|
||||||
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
fprintf(fp, "From drive: %db\n", c->dxfer_len);
|
fprintf(fp, "From drive: %db\n", dxfer_len);
|
||||||
for (i = 0; i < c->dxfer_len; i++)
|
for (i = 0; i < dxfer_len; i++)
|
||||||
fprintf(fp, "%2.2x%c", c->page->data[i],
|
fprintf(fp, "%2.2x%c", data[i],
|
||||||
((i % 20) == 19 ? '\n' : ' '));
|
((i % 20) == 19 ? '\n' : ' '));
|
||||||
if (i % 20)
|
if (i % 20)
|
||||||
fprintf(fp, "\n");
|
fprintf(fp, "\n");
|
||||||
@ -1520,31 +1536,51 @@ int scsi_show_cmd_reply(struct command *c, void *fp_in, int flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts B11110 */
|
||||||
|
/** Logs command (before execution) */
|
||||||
|
int scsi_log_command(unsigned char *opcode, int oplen, int data_dir,
|
||||||
|
unsigned char *data, int bytes,
|
||||||
|
void *fp_in, int flag)
|
||||||
|
{
|
||||||
|
FILE *fp = fp_in;
|
||||||
|
|
||||||
|
if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
|
||||||
|
scsi_show_command(opcode, oplen, data_dir, data, bytes, fp, 0);
|
||||||
|
if (burn_sg_log_scsi & 4)
|
||||||
|
fflush(fp);
|
||||||
|
}
|
||||||
|
if (fp == stderr || !(burn_sg_log_scsi & 2))
|
||||||
|
return 1;
|
||||||
|
scsi_log_command(opcode, oplen, data_dir, data, bytes, stderr, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A91218 (former sg_log_cmd ts A70518) */
|
/* ts A91218 (former sg_log_cmd ts A70518) */
|
||||||
/** Logs command (before execution) */
|
/** Logs command (before execution) */
|
||||||
int scsi_log_cmd(struct command *c, void *fp_in, int flag)
|
int scsi_log_cmd(struct command *c, void *fp_in, int flag)
|
||||||
{
|
{
|
||||||
FILE *fp = fp_in;
|
int ret, bytes = 0;
|
||||||
|
unsigned char *data = NULL;
|
||||||
|
|
||||||
if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
|
if (c->page != NULL) {
|
||||||
scsi_show_cmd_text(c, fp, 0);
|
data = c->page->data;
|
||||||
if (burn_sg_log_scsi & 4)
|
bytes = c->page->bytes;
|
||||||
fflush(fp);
|
|
||||||
}
|
}
|
||||||
if (fp == stderr || !(burn_sg_log_scsi & 2))
|
ret = scsi_log_command(c->opcode, c->oplen, c->dir, data, bytes,
|
||||||
return 1;
|
fp_in, flag);
|
||||||
scsi_log_cmd(c, stderr, flag);
|
return ret;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A91221 (former sg_log_err ts A91108) */
|
/* ts B11110 */
|
||||||
/** Logs outcome of a sg command.
|
/** Logs outcome of a sg command.
|
||||||
@param flag bit0 causes an error message
|
@param flag bit0 causes an error message
|
||||||
bit1 do not print duration
|
bit1 do not print duration
|
||||||
*/
|
*/
|
||||||
int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18],
|
int scsi_log_reply(unsigned char *opcode, int data_dir, unsigned char *data,
|
||||||
int sense_len, int duration, int flag)
|
int dxfer_len, void *fp_in, unsigned char sense[18],
|
||||||
|
int sense_len, int duration, int flag)
|
||||||
{
|
{
|
||||||
char durtxt[20];
|
char durtxt[20];
|
||||||
FILE *fp = fp_in;
|
FILE *fp = fp_in;
|
||||||
@ -1570,7 +1606,9 @@ int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18],
|
|||||||
(unsigned int) key, (unsigned int) asc,
|
(unsigned int) key, (unsigned int) asc,
|
||||||
(unsigned int) ascq, durtxt);
|
(unsigned int) ascq, durtxt);
|
||||||
} else {
|
} else {
|
||||||
scsi_show_cmd_reply(c, fp, 0);
|
scsi_show_command_reply(opcode, data_dir, data,
|
||||||
|
dxfer_len, fp, 0);
|
||||||
|
|
||||||
if (!(flag & 2))
|
if (!(flag & 2))
|
||||||
fprintf(fp,"%6d ms\n", duration);
|
fprintf(fp,"%6d ms\n", duration);
|
||||||
}
|
}
|
||||||
@ -1579,11 +1617,32 @@ int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18],
|
|||||||
}
|
}
|
||||||
if (fp == stderr || !(burn_sg_log_scsi & 2))
|
if (fp == stderr || !(burn_sg_log_scsi & 2))
|
||||||
return 1;
|
return 1;
|
||||||
scsi_log_err(c, stderr, sense, sense_len, duration, flag);
|
scsi_log_reply(opcode, data_dir, data, dxfer_len,
|
||||||
|
stderr, sense, sense_len, duration, flag);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91221 (former sg_log_err ts A91108) */
|
||||||
|
/** Legacy frontend to scsi_log_reply().
|
||||||
|
@param flag bit0 causes an error message
|
||||||
|
bit1 do not print duration
|
||||||
|
*/
|
||||||
|
int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18],
|
||||||
|
int sense_len, int duration, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
unsigned char *data = NULL;
|
||||||
|
|
||||||
|
if (c->page != NULL)
|
||||||
|
data = c->page->data;
|
||||||
|
ret= scsi_log_reply(c->opcode, c->dir, data, c->dxfer_len ,
|
||||||
|
fp_in, sense, sense_len, duration, flag);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts B00808 */
|
/* ts B00808 */
|
||||||
/*
|
/*
|
||||||
@param flag bit0 = do not retry
|
@param flag bit0 = do not retry
|
||||||
|
@ -68,15 +68,30 @@ int scsi_init_command(struct command *c, unsigned char *opcode, int oplen);
|
|||||||
/* ts A91106 */
|
/* ts A91106 */
|
||||||
int scsi_show_cmd_text(struct command *c, void *fp, int flag);
|
int scsi_show_cmd_text(struct command *c, void *fp, int flag);
|
||||||
|
|
||||||
/* ts A91106 */
|
/* ts B11110 */
|
||||||
int scsi_show_cmd_reply(struct command *c, void *fp, int flag);
|
/** Logs command (before execution). */
|
||||||
|
int scsi_log_command(unsigned char *opcode, int oplen, int data_dir,
|
||||||
|
unsigned char *data, int bytes,
|
||||||
|
void *fp_in, int flag);
|
||||||
|
|
||||||
/* ts A91218 (former sg_log_cmd ts A70518) */
|
/* ts A91218 (former sg_log_cmd ts A70518) */
|
||||||
/** Logs command (before execution) */
|
/** Legacy frontend to scsi_log_command() */
|
||||||
int scsi_log_cmd(struct command *c, void *fp, int flag);
|
int scsi_log_cmd(struct command *c, void *fp, int flag);
|
||||||
|
|
||||||
|
/* ts B11110 */
|
||||||
|
/** Logs outcome of a sg command.
|
||||||
|
@param flag bit0 causes an error message
|
||||||
|
bit1 do not print duration
|
||||||
|
*/
|
||||||
|
int scsi_log_reply(unsigned char *opcode, int data_dir, unsigned char *data,
|
||||||
|
int dxfer_len, void *fp_in, unsigned char sense[18],
|
||||||
|
int sense_len, int duration, int flag);
|
||||||
|
|
||||||
/* ts A91221 (former sg_log_err ts A91108) */
|
/* ts A91221 (former sg_log_err ts A91108) */
|
||||||
/** Logs outcome of a sg command. */
|
/** Legacy frontend to scsi_log_reply().
|
||||||
|
@param flag bit0 causes an error message
|
||||||
|
bit1 do not print duration
|
||||||
|
*/
|
||||||
int scsi_log_err(struct command *c, void *fp, unsigned char sense[18],
|
int scsi_log_err(struct command *c, void *fp, unsigned char sense[18],
|
||||||
int sense_len, int duration, int flag);
|
int sense_len, int duration, int flag);
|
||||||
|
|
||||||
|
@ -242,8 +242,12 @@ int burn_session_remove_track(struct burn_session *s, struct burn_track *t)
|
|||||||
void burn_structure_print_disc(struct burn_disc *d)
|
void burn_structure_print_disc(struct burn_disc *d)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
char msg[40];
|
||||||
|
|
||||||
burn_print(12, "This disc has %d sessions\n", d->sessions);
|
sprintf(msg, "This disc has %d sessions", d->sessions);
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
for (i = 0; i < d->sessions; i++) {
|
for (i = 0; i < d->sessions; i++) {
|
||||||
burn_structure_print_session(d->session[i]);
|
burn_structure_print_session(d->session[i]);
|
||||||
}
|
}
|
||||||
@ -251,16 +255,25 @@ void burn_structure_print_disc(struct burn_disc *d)
|
|||||||
void burn_structure_print_session(struct burn_session *s)
|
void burn_structure_print_session(struct burn_session *s)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
char msg[40];
|
||||||
|
|
||||||
burn_print(12, " Session has %d tracks\n", s->tracks);
|
sprintf(msg, " Session has %d tracks", s->tracks);
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
for (i = 0; i < s->tracks; i++) {
|
for (i = 0; i < s->tracks; i++) {
|
||||||
burn_structure_print_track(s->track[i]);
|
burn_structure_print_track(s->track[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void burn_structure_print_track(struct burn_track *t)
|
void burn_structure_print_track(struct burn_track *t)
|
||||||
{
|
{
|
||||||
burn_print(12, "(%p) track size %d sectors\n", t,
|
char msg[80];
|
||||||
burn_track_get_sectors(t));
|
|
||||||
|
sprintf(msg, " track size %d sectors",
|
||||||
|
burn_track_get_sectors(t));
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void burn_track_define_data(struct burn_track *t, int offset, int tail,
|
void burn_track_define_data(struct burn_track *t, int offset, int tail,
|
||||||
@ -398,7 +411,6 @@ int burn_track_get_sectors(struct burn_track *t)
|
|||||||
sectors = size / seclen;
|
sectors = size / seclen;
|
||||||
if (size % seclen)
|
if (size % seclen)
|
||||||
sectors++;
|
sectors++;
|
||||||
burn_print(1, "%d sectors of %d length\n", sectors, seclen);
|
|
||||||
return sectors;
|
return sectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,16 +105,14 @@ static void write_clonecd2(volatile struct toc *toc, int f)
|
|||||||
|
|
||||||
void toc_find_modes(struct burn_drive *d)
|
void toc_find_modes(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
struct burn_read_opts o;
|
int i, j;
|
||||||
int lba;
|
|
||||||
int i, j, ret;
|
|
||||||
struct buffer *mem = NULL;
|
struct buffer *mem = NULL;
|
||||||
struct burn_toc_entry *e;
|
struct burn_toc_entry *e;
|
||||||
|
|
||||||
BURN_ALLOC_MEM(mem, struct buffer, 1);
|
/* ts A70519 : the code which needs this does not work with GNU/Linux 2.4 USB
|
||||||
|
int lba;
|
||||||
|
struct burn_read_opts o;
|
||||||
|
|
||||||
mem->bytes = 0;
|
|
||||||
mem->sectors = 1;
|
|
||||||
o.raw = 1;
|
o.raw = 1;
|
||||||
o.c2errors = 0;
|
o.c2errors = 0;
|
||||||
o.subcodes_audio = 1;
|
o.subcodes_audio = 1;
|
||||||
@ -123,17 +121,18 @@ void toc_find_modes(struct burn_drive *d)
|
|||||||
o.report_recovered_errors = 0;
|
o.report_recovered_errors = 0;
|
||||||
o.transfer_damaged_blocks = 1;
|
o.transfer_damaged_blocks = 1;
|
||||||
o.hardware_error_retries = 1;
|
o.hardware_error_retries = 1;
|
||||||
|
*/
|
||||||
|
|
||||||
|
BURN_ALLOC_MEM_VOID(mem, struct buffer, 1);
|
||||||
|
|
||||||
|
mem->bytes = 0;
|
||||||
|
mem->sectors = 1;
|
||||||
|
|
||||||
for (i = 0; i < d->disc->sessions; i++)
|
for (i = 0; i < d->disc->sessions; i++)
|
||||||
for (j = 0; j < d->disc->session[i]->tracks; j++) {
|
for (j = 0; j < d->disc->session[i]->tracks; j++) {
|
||||||
struct burn_track *t = d->disc->session[i]->track[j];
|
struct burn_track *t = d->disc->session[i]->track[j];
|
||||||
|
|
||||||
e = t->entry;
|
e = t->entry;
|
||||||
if (!e)
|
|
||||||
lba = 0;
|
|
||||||
else
|
|
||||||
lba = burn_msf_to_lba(e->pmin, e->psec,
|
|
||||||
e->pframe);
|
|
||||||
/* XXX | in the subcodes if appropriate! */
|
/* XXX | in the subcodes if appropriate! */
|
||||||
if (e && !(e->control & 4)) {
|
if (e && !(e->control & 4)) {
|
||||||
t->mode = BURN_AUDIO;
|
t->mode = BURN_AUDIO;
|
||||||
@ -142,6 +141,11 @@ void toc_find_modes(struct burn_drive *d)
|
|||||||
t->mode = BURN_MODE1;
|
t->mode = BURN_MODE1;
|
||||||
/* ts A70519 : this does not work with GNU/Linux 2.4 USB because one cannot
|
/* ts A70519 : this does not work with GNU/Linux 2.4 USB because one cannot
|
||||||
predict the exact dxfer_size without knowing the sector type.
|
predict the exact dxfer_size without knowing the sector type.
|
||||||
|
if (!e)
|
||||||
|
lba = 0;
|
||||||
|
else
|
||||||
|
lba = burn_msf_to_lba(e->pmin, e->psec,
|
||||||
|
e->pframe);
|
||||||
mem->sectors = 1;
|
mem->sectors = 1;
|
||||||
d->read_sectors(d, lba, mem.sectors, &o, mem);
|
d->read_sectors(d, lba, mem.sectors, &o, mem);
|
||||||
t->mode = sector_identify(mem->data);
|
t->mode = sector_identify(mem->data);
|
||||||
|
@ -279,6 +279,10 @@ struct burn_drive
|
|||||||
/* ts A70129 :
|
/* ts A70129 :
|
||||||
from 51h READ DISC INFORMATION Last Track Number in Last Session */
|
from 51h READ DISC INFORMATION Last Track Number in Last Session */
|
||||||
int last_track_no;
|
int last_track_no;
|
||||||
|
|
||||||
|
/* ts B10730 : whether a default mode page 05 was already sent.
|
||||||
|
*/
|
||||||
|
int sent_default_page_05;
|
||||||
/* ts A70212 : from various sources : free space on media (in bytes)
|
/* ts A70212 : from various sources : free space on media (in bytes)
|
||||||
With CD this might change after particular write
|
With CD this might change after particular write
|
||||||
parameters have been set and nwa has been inquired.
|
parameters have been set and nwa has been inquired.
|
||||||
@ -289,7 +293,9 @@ struct burn_drive
|
|||||||
int media_lba_limit;
|
int media_lba_limit;
|
||||||
|
|
||||||
/* ts A81210 : Upper limit of readable data size,
|
/* ts A81210 : Upper limit of readable data size,
|
||||||
0x7fffffff = unknown */
|
0x7fffffff = unknown
|
||||||
|
0x7ffffff0 = 32 bit overflow, or unknown stdio size
|
||||||
|
*/
|
||||||
int media_read_capacity;
|
int media_read_capacity;
|
||||||
|
|
||||||
/* ts B10314 : Next Writeable Adress for drive_role == 5 */
|
/* ts B10314 : Next Writeable Adress for drive_role == 5 */
|
||||||
|
180
libburn/util.c
180
libburn/util.c
@ -74,9 +74,6 @@ struct cd_mid_record {
|
|||||||
int m_li;
|
int m_li;
|
||||||
int s_li;
|
int s_li;
|
||||||
int f_li;
|
int f_li;
|
||||||
int m_lo;
|
|
||||||
int s_lo;
|
|
||||||
int f_lo;
|
|
||||||
char *other_brands;
|
char *other_brands;
|
||||||
};
|
};
|
||||||
typedef struct cd_mid_record cd_mid_record_t;
|
typedef struct cd_mid_record cd_mid_record_t;
|
||||||
@ -91,51 +88,51 @@ char *burn_guess_cd_manufacturer(int m_li, int s_li, int f_li,
|
|||||||
int m_lo, int s_lo, int f_lo, int flag)
|
int m_lo, int s_lo, int f_lo, int flag)
|
||||||
{
|
{
|
||||||
static cd_mid_record_t mid_list[]= {
|
static cd_mid_record_t mid_list[]= {
|
||||||
{"SKC", 96, 40, 0, 0, 0, 0, ""},
|
{"SKC", 96, 40, 0, ""},
|
||||||
{"Ritek Corp" , 96, 43, 30, 0, 0, 0, ""},
|
{"Ritek Corp" , 96, 43, 30, ""},
|
||||||
{"TDK / Ritek" , 97, 10, 0, 0, 0, 0, "TRAXDATA"},
|
{"TDK / Ritek" , 97, 10, 0, "TRAXDATA"},
|
||||||
{"TDK Corporation" , 97, 15, 0, 0, 0, 0, ""},
|
{"TDK Corporation" , 97, 15, 0, ""},
|
||||||
{"Ritek Corp" , 97, 15, 10, 0, 0, 0, "7-plus, Aopen, PONY, Power Source, TDK, TRAXDATA, HiCO, PHILIPS, Primdisc, Victor.JVC, OPTI STORAGE, Samsung"},
|
{"Ritek Corp" , 97, 15, 10, "7-plus, Aopen, PONY, Power Source, TDK, TRAXDATA, HiCO, PHILIPS, Primdisc, Victor.JVC, OPTI STORAGE, Samsung"},
|
||||||
{"Mitsubishi Chemical Corporation" , 97, 15, 20, 0, 0, 0, ""},
|
{"Mitsubishi Chemical Corporation" , 97, 15, 20, ""},
|
||||||
{"Nan-Ya Plastics Corporation" , 97, 15, 30, 0, 0, 0, "Hatron, MMore, Acer, LITEON"},
|
{"Nan-Ya Plastics Corporation" , 97, 15, 30, "Hatron, MMore, Acer, LITEON"},
|
||||||
{"Delphi" , 97, 15, 50, 0, 0, 0, ""},
|
{"Delphi" , 97, 15, 50, ""},
|
||||||
{"Shenzhen SG&SAST" , 97, 16, 20, 0, 0, 0, ""},
|
{"Shenzhen SG&SAST" , 97, 16, 20, ""},
|
||||||
{"Moser Baer India Limited" , 97, 17, 0, 0, 0, 0, "EMTEC, Intenso, YAKUMO, PLATINUM, Silver Circle"},
|
{"Moser Baer India Limited" , 97, 17, 0, "EMTEC, Intenso, YAKUMO, PLATINUM, Silver Circle"},
|
||||||
{"SKY media Manufacturing SA" , 97, 17, 10, 0, 0, 0, ""},
|
{"SKY media Manufacturing SA" , 97, 17, 10, ""},
|
||||||
{"Wing" , 97, 18, 10, 0, 0, 0, ""},
|
{"Wing" , 97, 18, 10, ""},
|
||||||
{"DDT" , 97, 18, 20, 0, 0, 0, ""},
|
{"DDT" , 97, 18, 20, ""},
|
||||||
{"Daxon Technology Inc. / Acer" , 97, 22, 60, 0, 0, 0, "Maxmax, Diamond Data, BenQ, gold, SONY"},
|
{"Daxon Technology Inc. / Acer" , 97, 22, 60, "Maxmax, Diamond Data, BenQ, gold, SONY"},
|
||||||
{"Taiyo Yuden Company Limited" , 97, 24, 0, 0, 0, 0, "Maxell, FUJIFILM, SONY"},
|
{"Taiyo Yuden Company Limited" , 97, 24, 0, "Maxell, FUJIFILM, SONY"},
|
||||||
{"Sony Corporation" , 97, 24, 10, 0, 0, 0, "LeadData, Imation"},
|
{"Sony Corporation" , 97, 24, 10, "LeadData, Imation"},
|
||||||
{"Computer Support Italcard s.r.l" , 97, 24, 20, 0, 0, 0, ""},
|
{"Computer Support Italcard s.r.l" , 97, 24, 20, ""},
|
||||||
{"Unitech Japan Inc." , 97, 24, 30, 0, 0, 0, ""},
|
{"Unitech Japan Inc." , 97, 24, 30, ""},
|
||||||
{"MPO, France" , 97, 25, 0, 0, 0, 0, "TDK"},
|
{"MPO, France" , 97, 25, 0, "TDK"},
|
||||||
{"Hitachi Maxell Ltd." , 97, 25, 20, 0, 0, 0, ""},
|
{"Hitachi Maxell Ltd." , 97, 25, 20, ""},
|
||||||
{"Infodisc Technology Co,Ltd." , 97, 25, 30, 0, 0, 0, "MEMOREX, SPEEDA, Lead data"},
|
{"Infodisc Technology Co,Ltd." , 97, 25, 30, "MEMOREX, SPEEDA, Lead data"},
|
||||||
{"Xcitec" , 97, 25, 60, 0, 0, 0, ""},
|
{"Xcitec" , 97, 25, 60, ""},
|
||||||
{"Fornet International Pte Ltd" , 97, 26, 0, 0, 0, 0, "COMPUSA, Cdhouse"},
|
{"Fornet International Pte Ltd" , 97, 26, 0, "COMPUSA, Cdhouse"},
|
||||||
{"Postech Corporation" , 97, 26, 10, 0, 0, 0, "Mr.Platinum"},
|
{"Postech Corporation" , 97, 26, 10, "Mr.Platinum"},
|
||||||
{"SKC Co Ltd." , 97, 26, 20, 0, 0, 0, "Infinite"},
|
{"SKC Co Ltd." , 97, 26, 20, "Infinite"},
|
||||||
{"Fuji Photo Film Co,Ltd." , 97, 26, 40, 0, 0, 0, ""},
|
{"Fuji Photo Film Co,Ltd." , 97, 26, 40, ""},
|
||||||
{"Lead Data Inc." , 97, 26, 50, 0, 0, 0, "SONY, Gigastorage, MIRAGE"},
|
{"Lead Data Inc." , 97, 26, 50, "SONY, Gigastorage, MIRAGE"},
|
||||||
{"CMC Magnetics Corporation" , 97, 26, 60, 0, 0, 0, "Daxon, Verbatim, Memorex, Bi-Winner, PLEXTOR, YAMAHA, Melody, Office DEPOT, Philips, eMARK, imation, HyperMedia, Samsung, Shintaro, Techworks"},
|
{"CMC Magnetics Corporation" , 97, 26, 60, "Daxon, Verbatim, Memorex, Bi-Winner, PLEXTOR, YAMAHA, Melody, Office DEPOT, Philips, eMARK, imation, HyperMedia, Samsung, Shintaro, Techworks"},
|
||||||
{"Ricoh Company Limited" , 97, 27, 0, 0, 0, 0, "Sony, Digital Storage, Csita"},
|
{"Ricoh Company Limited" , 97, 27, 0, "Sony, Digital Storage, Csita"},
|
||||||
{"Plasmon Data Systems Ltd" , 97, 27, 10, 0, 0, 0, "Ritek, TDK, EMTEC, ALPHAPET, MANIA"},
|
{"Plasmon Data Systems Ltd" , 97, 27, 10, "Ritek, TDK, EMTEC, ALPHAPET, MANIA"},
|
||||||
{"Princo Corporation" , 97, 27, 20, 0, 0, 0, ""},
|
{"Princo Corporation" , 97, 27, 20, ""},
|
||||||
{"Pioneer" , 97, 27, 30, 0, 0, 0, ""},
|
{"Pioneer" , 97, 27, 30, ""},
|
||||||
{"Eastman Kodak Company" , 97, 27, 40, 0, 0, 0, ""},
|
{"Eastman Kodak Company" , 97, 27, 40, ""},
|
||||||
{"Mitsui Chemicals Inc." , 97, 27, 50, 0, 0, 0, "MAM-A, TDK"},
|
{"Mitsui Chemicals Inc." , 97, 27, 50, "MAM-A, TDK"},
|
||||||
{"Ricoh Company Limited" , 97, 27, 60, 0, 0, 0, "Ritek"},
|
{"Ricoh Company Limited" , 97, 27, 60, "Ritek"},
|
||||||
{"Gigastorage Corporation" , 97, 28, 10, 0, 0, 0, "MaxMax, Nan-Ya"},
|
{"Gigastorage Corporation" , 97, 28, 10, "MaxMax, Nan-Ya"},
|
||||||
{"Multi Media Masters&Machinary SA" , 97, 28, 20, 0, 0, 0, "King, Mmirex"},
|
{"Multi Media Masters&Machinary SA" , 97, 28, 20, "King, Mmirex"},
|
||||||
{"Ritek Corp" , 97, 31, 0, 0, 0, 0, "TDK"},
|
{"Ritek Corp" , 97, 31, 0, "TDK"},
|
||||||
{"Grand Advance Technology Sdn. Bhd." , 97, 31, 30, 0, 0, 0, ""},
|
{"Grand Advance Technology Sdn. Bhd." , 97, 31, 30, ""},
|
||||||
{"TDK Corporation" , 97, 32, 00, 0, 0, 0, ""},
|
{"TDK Corporation" , 97, 32, 00, ""},
|
||||||
{"Prodisc Technology Inc." , 97, 32, 10, 0, 0, 0, "Smartbuy, Mitsubishi, Digmaster, LG, Media Market"},
|
{"Prodisc Technology Inc." , 97, 32, 10, "Smartbuy, Mitsubishi, Digmaster, LG, Media Market"},
|
||||||
{"Mitsubishi Chemical Corporation" , 97, 34, 20, 0, 0, 0, "YAMAHA, Verbatim"},
|
{"Mitsubishi Chemical Corporation" , 97, 34, 20, "YAMAHA, Verbatim"},
|
||||||
{"Mitsui Chemicals Inc." , 97, 48, 50, 0, 0, 0, ""},
|
{"Mitsui Chemicals Inc." , 97, 48, 50, ""},
|
||||||
{"TDK Corporation" , 97, 49, 0, 0, 0, 0, ""},
|
{"TDK Corporation" , 97, 49, 0, ""},
|
||||||
{"", 0, 0, 0, 0, 0, 0, ""}
|
{"", 0, 0, 0, ""}
|
||||||
};
|
};
|
||||||
|
|
||||||
int i, f_li_0;
|
int i, f_li_0;
|
||||||
@ -173,7 +170,6 @@ char *burn_guess_cd_manufacturer(int m_li, int s_li, int f_li,
|
|||||||
/* ts A90904 */
|
/* ts A90904 */
|
||||||
struct dvd_mid_record {
|
struct dvd_mid_record {
|
||||||
char *mc1;
|
char *mc1;
|
||||||
char *mc2;
|
|
||||||
int mc1_sig_len;
|
int mc1_sig_len;
|
||||||
char *manufacturer;
|
char *manufacturer;
|
||||||
};
|
};
|
||||||
@ -192,49 +188,49 @@ char *burn_guess_manufacturer(int prf,
|
|||||||
Especially: ' ' -> '_' , {"_%/" unprintables -> %XY)
|
Especially: ' ' -> '_' , {"_%/" unprintables -> %XY)
|
||||||
*/
|
*/
|
||||||
static dvd_mid_record_t mid_list[]= {
|
static dvd_mid_record_t mid_list[]= {
|
||||||
{"AML", "", 8, "UML"},
|
{"AML", 8, "UML"},
|
||||||
{"BeAll", "", 5, "BeAll Developers, Inc."},
|
{"BeAll", 5, "BeAll Developers, Inc."},
|
||||||
{"CMC", "", 3, "CMC Magnetics Corporation"},
|
{"CMC", 3, "CMC Magnetics Corporation"},
|
||||||
{"DAXON", "", 5, "Daxon Technology Inc. / Acer"},
|
{"DAXON", 5, "Daxon Technology Inc. / Acer"},
|
||||||
{"Daxon", "", 5, "Daxon Technology Inc. / Acer"},
|
{"Daxon", 5, "Daxon Technology Inc. / Acer"},
|
||||||
{"FUJI", "", 4, "Fujifilm Holdings Corporation"},
|
{"FUJI", 4, "Fujifilm Holdings Corporation"},
|
||||||
{"INFODISC", "", 8, "New Star Digital Co., Ltd."},
|
{"INFODISC", 8, "New Star Digital Co., Ltd."},
|
||||||
{"INFOME", "", 6, "InfoMedia Inc."},
|
{"INFOME", 6, "InfoMedia Inc."},
|
||||||
{"ISMMBD", "", 6, "Info Source Multi Media Ltd."},
|
{"ISMMBD", 6, "Info Source Multi Media Ltd."},
|
||||||
{"JVC", "", 3, "JVC Limited"},
|
{"JVC", 3, "JVC Limited"},
|
||||||
{"KIC01RG", "", 7, "AMC"},
|
{"KIC01RG", 7, "AMC"},
|
||||||
{"LD", "", 8, "Lead Data Inc."},
|
{"LD", 8, "Lead Data Inc."},
|
||||||
{"LGE", "", 3, "LG Electronics"},
|
{"LGE", 3, "LG Electronics"},
|
||||||
{"MAM", "", 8, "Mitsui Advanced Media, Inc. Europe"},
|
{"MAM", 8, "Mitsui Advanced Media, Inc. Europe"},
|
||||||
{"MAXELL", "", 6, "Hitachi Maxell Ltd."},
|
{"MAXELL", 6, "Hitachi Maxell Ltd."},
|
||||||
{"MBI", "", 3, "Moser Baer India Limited"},
|
{"MBI", 3, "Moser Baer India Limited"},
|
||||||
{"MCC", "", 8, "Mitsubishi Chemical Corporation"},
|
{"MCC", 8, "Mitsubishi Chemical Corporation"},
|
||||||
{"MCI", "", 8, "Mitsui Chemicals Inc."},
|
{"MCI", 8, "Mitsui Chemicals Inc."},
|
||||||
{"MEI", "", 3, "Panasonic Corporation"},
|
{"MEI", 3, "Panasonic Corporation"},
|
||||||
{"MKM", "", 3, "Mitsubishi Kagaku Media Co."},
|
{"MKM", 3, "Mitsubishi Kagaku Media Co."},
|
||||||
{"MMC", "", 8, "Mitsubishi Kagaku Media Co."},
|
{"MMC", 8, "Mitsubishi Kagaku Media Co."},
|
||||||
{"MXL", "", 8, "Hitachi Maxell Ltd."},
|
{"MXL", 8, "Hitachi Maxell Ltd."},
|
||||||
{"NANYA", "", 5, "Nan-Ya Plastics Corporation"},
|
{"NANYA", 5, "Nan-Ya Plastics Corporation"},
|
||||||
{"NSD", "", 8, "NESA International Inc."},
|
{"NSD", 8, "NESA International Inc."},
|
||||||
{"OPTODISC", "", 8, "Optodisc Technology Corporation"},
|
{"OPTODISC", 8, "Optodisc Technology Corporation"},
|
||||||
{"OTCBDR", "", 8, "Optodisc Technology Corporation"},
|
{"OTCBDR", 8, "Optodisc Technology Corporation"},
|
||||||
{"PHILIP", "", 8, "Moser Baer India Limited"},
|
{"PHILIP", 8, "Moser Baer India Limited"},
|
||||||
{"PHILIPS", "", 8, "Philips"},
|
{"PHILIPS", 8, "Philips"},
|
||||||
{"PRINCO", "", 6, "Princo Corporation"},
|
{"PRINCO", 6, "Princo Corporation"},
|
||||||
{"PRODISC", "", 7, "Prodisc Technology Inc."},
|
{"PRODISC", 7, "Prodisc Technology Inc."},
|
||||||
{"Prodisc", "", 7, "Prodisc Technology Inc."},
|
{"Prodisc", 7, "Prodisc Technology Inc."},
|
||||||
{"PVC", "", 3, "Pioneer"},
|
{"PVC", 3, "Pioneer"},
|
||||||
{"RICOHJPN", "", 8, "Ricoh Company Limited"},
|
{"RICOHJPN", 8, "Ricoh Company Limited"},
|
||||||
{"RITEK", "", 5, "Ritek Corp"},
|
{"RITEK", 5, "Ritek Corp"},
|
||||||
{"SONY", "", 4, "Sony Corporation"},
|
{"SONY", 4, "Sony Corporation"},
|
||||||
{"TDK", "", 3, "TDK Corporation"},
|
{"TDK", 3, "TDK Corporation"},
|
||||||
{"TT", "", 8, "TDK Corporation"},
|
{"TT", 8, "TDK Corporation"},
|
||||||
{"TY", "", 8, "Taiyo Yuden Company Limited"},
|
{"TY", 8, "Taiyo Yuden Company Limited"},
|
||||||
{"TYG", "", 3, "Taiyo Yuden Company Limited"},
|
{"TYG", 3, "Taiyo Yuden Company Limited"},
|
||||||
{"UTJR001", "", 7, "Unifino Inc."},
|
{"UTJR001", 7, "Unifino Inc."},
|
||||||
{"VERBAT", "", 5, "Mitsubishi Kagaku Media Co."},
|
{"VERBAT", 5, "Mitsubishi Kagaku Media Co."},
|
||||||
{"YUDEN", "", 5, "Taiyo Yuden Company Limited"},
|
{"YUDEN", 5, "Taiyo Yuden Company Limited"},
|
||||||
{"", "", 0, ""}
|
{"", 0, ""}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (media_code2 != NULL &&
|
if (media_code2 != NULL &&
|
||||||
|
@ -244,7 +244,6 @@ int burn_write_close_track(struct burn_write_opts *o, struct burn_session *s,
|
|||||||
{
|
{
|
||||||
char msg[81];
|
char msg[81];
|
||||||
struct burn_drive *d;
|
struct burn_drive *d;
|
||||||
struct burn_track *t;
|
|
||||||
|
|
||||||
/* ts A61106 */
|
/* ts A61106 */
|
||||||
#ifdef Libburn_experimental_no_close_tracK
|
#ifdef Libburn_experimental_no_close_tracK
|
||||||
@ -252,7 +251,6 @@ int burn_write_close_track(struct burn_write_opts *o, struct burn_session *s,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
d = o->drive;
|
d = o->drive;
|
||||||
t = s->track[tnum];
|
|
||||||
|
|
||||||
d->busy = BURN_DRIVE_CLOSING_TRACK;
|
d->busy = BURN_DRIVE_CLOSING_TRACK;
|
||||||
|
|
||||||
@ -414,7 +412,6 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
|
|||||||
goto failed;
|
goto failed;
|
||||||
runtime += 150;
|
runtime += 150;
|
||||||
|
|
||||||
burn_print(1, "toc for %d tracks:\n", ntr);
|
|
||||||
d->toc_entries = ntr + 3;
|
d->toc_entries = ntr + 3;
|
||||||
|
|
||||||
/* ts A61009 */
|
/* ts A61009 */
|
||||||
@ -515,8 +512,6 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
|
|||||||
e[3 + i].pframe = f;
|
e[3 + i].pframe = f;
|
||||||
e[3 + i].adr = 1;
|
e[3 + i].adr = 1;
|
||||||
e[3 + i].control = type_to_ctrl(tar[i]->mode);
|
e[3 + i].control = type_to_ctrl(tar[i]->mode);
|
||||||
burn_print(1, "track %d control %d\n", tar[i]->mode,
|
|
||||||
e[3 + i].control);
|
|
||||||
|
|
||||||
ret = add_cue(sheet, ctladr | 1, i + 1, 1, form, 0, runtime);
|
ret = add_cue(sheet, ctladr | 1, i + 1, 1, form, 0, runtime);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
@ -568,11 +563,6 @@ XXX this is untested :)
|
|||||||
e[2].pmin = m;
|
e[2].pmin = m;
|
||||||
e[2].psec = s;
|
e[2].psec = s;
|
||||||
e[2].pframe = f;
|
e[2].pframe = f;
|
||||||
burn_print(1, "run time is %d (%d:%d:%d)\n", runtime, m, s, f);
|
|
||||||
for (i = 0; i < d->toc_entries; i++)
|
|
||||||
burn_print(1, "point %d (%02d:%02d:%02d)\n",
|
|
||||||
d->toc_entry[i].point, d->toc_entry[i].pmin,
|
|
||||||
d->toc_entry[i].psec, d->toc_entry[i].pframe);
|
|
||||||
ret = add_cue(sheet, ctladr | 1, 0xAA, 1, 1, 0, runtime);
|
ret = add_cue(sheet, ctladr | 1, 0xAA, 1, 1, 0, runtime);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
goto failed;
|
goto failed;
|
||||||
@ -614,8 +604,6 @@ int burn_write_leadin(struct burn_write_opts *o,
|
|||||||
|
|
||||||
d->busy = BURN_DRIVE_WRITING_LEADIN;
|
d->busy = BURN_DRIVE_WRITING_LEADIN;
|
||||||
|
|
||||||
burn_print(5, first ? " first leadin\n" : " leadin\n");
|
|
||||||
|
|
||||||
if (first)
|
if (first)
|
||||||
count = 0 - d->alba - 150;
|
count = 0 - d->alba - 150;
|
||||||
else
|
else
|
||||||
@ -644,7 +632,6 @@ int burn_write_leadout(struct burn_write_opts *o,
|
|||||||
d->busy = BURN_DRIVE_WRITING_LEADOUT;
|
d->busy = BURN_DRIVE_WRITING_LEADOUT;
|
||||||
|
|
||||||
d->rlba = -150;
|
d->rlba = -150;
|
||||||
burn_print(5, first ? " first leadout\n" : " leadout\n");
|
|
||||||
if (first)
|
if (first)
|
||||||
count = 6750;
|
count = 6750;
|
||||||
else
|
else
|
||||||
@ -666,19 +653,10 @@ int burn_write_leadout(struct burn_write_opts *o,
|
|||||||
int burn_write_session(struct burn_write_opts *o, struct burn_session *s)
|
int burn_write_session(struct burn_write_opts *o, struct burn_session *s)
|
||||||
{
|
{
|
||||||
struct burn_drive *d = o->drive;
|
struct burn_drive *d = o->drive;
|
||||||
struct burn_track *prev = NULL, *next = NULL;
|
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
d->rlba = 0;
|
d->rlba = 0;
|
||||||
burn_print(1, " writing a session\n");
|
|
||||||
for (i = 0; i < s->tracks; i++) {
|
for (i = 0; i < s->tracks; i++) {
|
||||||
if (i > 0)
|
|
||||||
prev = s->track[i - 1];
|
|
||||||
if (i + 1 < s->tracks)
|
|
||||||
next = s->track[i + 1];
|
|
||||||
else
|
|
||||||
next = NULL;
|
|
||||||
|
|
||||||
if (!burn_write_track(o, s, i))
|
if (!burn_write_track(o, s, i))
|
||||||
{ ret = 0; goto ex; }
|
{ ret = 0; goto ex; }
|
||||||
}
|
}
|
||||||
@ -808,8 +786,6 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
|
|||||||
|
|
||||||
burn_disc_init_track_status(o, s, tnum, sectors);
|
burn_disc_init_track_status(o, s, tnum, sectors);
|
||||||
|
|
||||||
burn_print(12, "track %d is %d sectors long\n", tnum, sectors);
|
|
||||||
|
|
||||||
/* ts A61030 : this cannot happen. tnum is always < s->tracks */
|
/* ts A61030 : this cannot happen. tnum is always < s->tracks */
|
||||||
if (tnum == s->tracks)
|
if (tnum == s->tracks)
|
||||||
tmp = sectors > 150 ? 150 : sectors;
|
tmp = sectors > 150 ? 150 : sectors;
|
||||||
@ -840,8 +816,6 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
|
|||||||
fprintf(stderr,"LIBBURN_DEBUG: TNUM=%d TRACKS=%d TMP=%d\n",
|
fprintf(stderr,"LIBBURN_DEBUG: TNUM=%d TRACKS=%d TMP=%d\n",
|
||||||
tnum, s->tracks, tmp);
|
tnum, s->tracks, tmp);
|
||||||
|
|
||||||
burn_print(1, "last track, leadout prep\n");
|
|
||||||
|
|
||||||
/* ts A61023 */
|
/* ts A61023 */
|
||||||
if ((i%64)==0)
|
if ((i%64)==0)
|
||||||
d->read_buffer_capacity(d);
|
d->read_buffer_capacity(d);
|
||||||
@ -1158,7 +1132,7 @@ int burn_disc_open_track_dvd_plus_r(struct burn_write_opts *o,
|
|||||||
struct burn_session *s, int tnum)
|
struct burn_session *s, int tnum)
|
||||||
{
|
{
|
||||||
struct burn_drive *d = o->drive;
|
struct burn_drive *d = o->drive;
|
||||||
char *msg;
|
char *msg = NULL;
|
||||||
int ret, lba, nwa;
|
int ret, lba, nwa;
|
||||||
off_t size;
|
off_t size;
|
||||||
|
|
||||||
@ -2010,7 +1984,7 @@ ex:;
|
|||||||
/* >>> eventual emergency finalization measures */
|
/* >>> eventual emergency finalization measures */
|
||||||
|
|
||||||
/* update media state records */
|
/* update media state records */
|
||||||
burn_drive_mark_unready(d);
|
burn_drive_mark_unready(d, 0);
|
||||||
burn_drive_inquire_media(d);
|
burn_drive_inquire_media(d);
|
||||||
|
|
||||||
if (d->current_profile == 0x41 && d->complete_sessions >= 300) {
|
if (d->current_profile == 0x41 && d->complete_sessions >= 300) {
|
||||||
@ -2115,6 +2089,9 @@ int burn_stdio_read_source(struct burn_source *source, char *buf, int bufsize,
|
|||||||
int burn_stdio_write(int fd, char *buf, int count, struct burn_drive *d,
|
int burn_stdio_write(int fd, char *buf, int count, struct burn_drive *d,
|
||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
char *msg = NULL;
|
||||||
|
|
||||||
if (d->cancel)
|
if (d->cancel)
|
||||||
return 0;
|
return 0;
|
||||||
/*
|
/*
|
||||||
@ -2122,15 +2099,23 @@ fprintf(stderr, "libburn_DEBUG: write(%d, %lX, %d)\n",
|
|||||||
fd, (unsigned long) buf, count);
|
fd, (unsigned long) buf, count);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (write(fd, buf, count) != count) {
|
ret = write(fd, buf, count);
|
||||||
|
if (ret != count) {
|
||||||
|
BURN_ALLOC_MEM(msg, char, 160);
|
||||||
|
|
||||||
|
sprintf(msg,
|
||||||
|
"Cannot write desired amount of data. write(2) returned %d.",
|
||||||
|
ret);
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x00020148,
|
0x00020148,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Cannot write desired amount of data", errno, 0);
|
msg, errno, 0);
|
||||||
d->cancel = 1;
|
d->cancel = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return count;
|
ex:;
|
||||||
|
BURN_FREE_MEM(msg);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2194,6 +2179,9 @@ int burn_stdio_mmc_dummy_write(struct burn_drive *d, int start,
|
|||||||
*/
|
*/
|
||||||
int burn_stdio_sync_cache(int fd, struct burn_drive *d, int flag)
|
int burn_stdio_sync_cache(int fd, struct burn_drive *d, int flag)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
char *msg = NULL;
|
||||||
|
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x0002017d,
|
0x0002017d,
|
||||||
@ -2208,17 +2196,24 @@ int burn_stdio_sync_cache(int fd, struct burn_drive *d, int flag)
|
|||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||||
"syncing cache (stdio fsync)", 0, 0);
|
"syncing cache (stdio fsync)", 0, 0);
|
||||||
if (fsync(fd) != 0) {
|
ret = fsync(fd);
|
||||||
if (errno == EINVAL) /* E.g. /dev/null cannot fsync */
|
if (ret != 0 && errno == EIO) {
|
||||||
return 1;
|
BURN_ALLOC_MEM(msg, char, 160);
|
||||||
|
|
||||||
|
sprintf(msg,
|
||||||
|
"Cannot write desired amount of data. fsync(2) returned %d.",
|
||||||
|
ret);
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x00020148,
|
0x00020148,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Cannot write desired amount of data", errno, 0);
|
msg, errno, 0);
|
||||||
d->cancel = 1;
|
d->cancel = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
ret = 1;
|
||||||
|
ex:;
|
||||||
|
BURN_FREE_MEM(msg);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2263,7 +2258,7 @@ int burn_stdio_slowdown(struct burn_drive *d, struct timeval *prev_time,
|
|||||||
int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
|
int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
|
||||||
int tnum, int flag)
|
int tnum, int flag)
|
||||||
{
|
{
|
||||||
int open_ended, bufsize = 16 * 2048, ret, sectors, fd;
|
int open_ended, bufsize = 16 * 2048, ret, sectors;
|
||||||
struct burn_track *t = s->track[tnum];
|
struct burn_track *t = s->track[tnum];
|
||||||
struct burn_drive *d = o->drive;
|
struct burn_drive *d = o->drive;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
@ -2272,7 +2267,6 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
|
|||||||
struct timeval prev_time;
|
struct timeval prev_time;
|
||||||
|
|
||||||
BURN_ALLOC_MEM(buf, char, bufsize);
|
BURN_ALLOC_MEM(buf, char, bufsize);
|
||||||
fd = d->stdio_fd;
|
|
||||||
|
|
||||||
sectors = burn_track_get_sectors(t);
|
sectors = burn_track_get_sectors(t);
|
||||||
burn_disc_init_track_status(o, s, tnum, sectors);
|
burn_disc_init_track_status(o, s, tnum, sectors);
|
||||||
@ -2349,6 +2343,9 @@ int burn_stdio_write_sync(struct burn_write_opts *o,
|
|||||||
d->progress.tracks = 1;
|
d->progress.tracks = 1;
|
||||||
|
|
||||||
/* >>> adjust sector size (2048) to eventual audio or even raw */
|
/* >>> adjust sector size (2048) to eventual audio or even raw */
|
||||||
|
|
||||||
|
/* >>> ??? ts B11004 : Why this eagerness to close and open ? */
|
||||||
|
|
||||||
/* open target file */
|
/* open target file */
|
||||||
if (d->stdio_fd >= 0)
|
if (d->stdio_fd >= 0)
|
||||||
close(d->stdio_fd);
|
close(d->stdio_fd);
|
||||||
@ -2369,12 +2366,15 @@ int burn_stdio_write_sync(struct burn_write_opts *o,
|
|||||||
d->progress.sectors = 0;
|
d->progress.sectors = 0;
|
||||||
ret = 1;
|
ret = 1;
|
||||||
ex:;
|
ex:;
|
||||||
|
|
||||||
|
/* >>> ??? ts B11004 : Why this eagerness to close ? */
|
||||||
|
|
||||||
if (d->stdio_fd >= 0)
|
if (d->stdio_fd >= 0)
|
||||||
close(d->stdio_fd);
|
close(d->stdio_fd);
|
||||||
d->stdio_fd = -1;
|
d->stdio_fd = -1;
|
||||||
|
|
||||||
/* update media state records */
|
/* update media state records */
|
||||||
burn_drive_mark_unready(d);
|
burn_drive_mark_unready(d, 8);
|
||||||
|
|
||||||
/* <<< d->busy = BURN_DRIVE_IDLE; */
|
/* <<< d->busy = BURN_DRIVE_IDLE; */
|
||||||
return ret;
|
return ret;
|
||||||
@ -2488,8 +2488,6 @@ calloc() seems not to have the desired effect. valgrind warns:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
burn_print(1, "sync write of %d CD sessions\n", disc->sessions);
|
|
||||||
|
|
||||||
/* Apparently some drives require this command to be sent, and a few drives
|
/* Apparently some drives require this command to be sent, and a few drives
|
||||||
return crap. so we send the command, then ignore the result.
|
return crap. so we send the command, then ignore the result.
|
||||||
*/
|
*/
|
||||||
@ -2619,12 +2617,9 @@ return crap. so we send the command, then ignore the result.
|
|||||||
sleep(1);
|
sleep(1);
|
||||||
|
|
||||||
/* ts A61125 : update media state records */
|
/* ts A61125 : update media state records */
|
||||||
burn_drive_mark_unready(d);
|
burn_drive_mark_unready(d, 0);
|
||||||
burn_drive_inquire_media(d);
|
burn_drive_inquire_media(d);
|
||||||
|
|
||||||
burn_print(1, "done\n");
|
|
||||||
/* <<< d->busy = BURN_DRIVE_IDLE; */
|
|
||||||
|
|
||||||
/* ts A61012 : This return was traditionally missing. I suspect this
|
/* ts A61012 : This return was traditionally missing. I suspect this
|
||||||
to have caused Cdrskin_eject() failures */
|
to have caused Cdrskin_eject() failures */
|
||||||
goto ex;
|
goto ex;
|
||||||
@ -2633,7 +2628,6 @@ fail:
|
|||||||
d->sync_cache(d);
|
d->sync_cache(d);
|
||||||
fail_wo_sync:;
|
fail_wo_sync:;
|
||||||
usleep(500001); /* ts A61222: to avoid a warning from remove_worker()*/
|
usleep(500001); /* ts A61222: to avoid a warning from remove_worker()*/
|
||||||
burn_print(1, "done - failed\n");
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010b,
|
libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010b,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Burn run failed", 0, 0);
|
"Burn run failed", 0, 0);
|
||||||
|
41
releng/releng_build_os
Executable file
41
releng/releng_build_os
Executable file
@ -0,0 +1,41 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
if [ ! -x configure ]; then
|
||||||
|
printf "\n*** please run ./bootstrap first.\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
build()
|
||||||
|
{
|
||||||
|
for F in ${1}
|
||||||
|
do
|
||||||
|
make clean
|
||||||
|
clear
|
||||||
|
printf "\n *** building with: %s\n" CPPFLAGS=-D${F}
|
||||||
|
sleep 1
|
||||||
|
# libcdio is not autodetected by default; should be available everywhere
|
||||||
|
CPPFLAGS=-D${F} ./configure --enable-libcdio; make 2> releng/libburn.${F}.log
|
||||||
|
make clean
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
OS=`uname -o`
|
||||||
|
|
||||||
|
case ${OS} in
|
||||||
|
GNU/Linux)
|
||||||
|
printf "OS: %s\n" ${OS}
|
||||||
|
sleep 1
|
||||||
|
build "__linux Libburn_use_sg_dummY Libburn_use_libcdiO"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
printf "Unknown OS: %s\n" ${OS}
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# just in case
|
||||||
|
unset CPPFLAGS
|
@ -20,8 +20,6 @@ static void catch_int ()
|
|||||||
|
|
||||||
static void poll_drive(int d)
|
static void poll_drive(int d)
|
||||||
{
|
{
|
||||||
enum burn_disc_status s;
|
|
||||||
|
|
||||||
fprintf(stderr, "polling disc in %s - %s:\n",
|
fprintf(stderr, "polling disc in %s - %s:\n",
|
||||||
drives[d].vendor, drives[d].product);
|
drives[d].vendor, drives[d].product);
|
||||||
|
|
||||||
@ -33,8 +31,7 @@ static void poll_drive(int d)
|
|||||||
while (burn_drive_get_status(drives[d].drive, NULL))
|
while (burn_drive_get_status(drives[d].drive, NULL))
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
|
|
||||||
while ((s = burn_disc_get_status(drives[d].drive))
|
while (burn_disc_get_status(drives[d].drive) == BURN_DISC_UNREADY)
|
||||||
== BURN_DISC_UNREADY)
|
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
|
|
||||||
while (NEXT == 0) {
|
while (NEXT == 0) {
|
||||||
|
@ -12,6 +12,9 @@ int main(int argc, char **argv)
|
|||||||
struct burn_session *session;
|
struct burn_session *session;
|
||||||
struct burn_source *src;
|
struct burn_source *src;
|
||||||
|
|
||||||
|
burn_initialize();
|
||||||
|
burn_msgs_set_severities("NEVER", "ALL", "structest: ");
|
||||||
|
|
||||||
disc = burn_disc_create();
|
disc = burn_disc_create();
|
||||||
session = burn_session_create();
|
session = burn_session_create();
|
||||||
burn_disc_add_session(disc, session, BURN_POS_END);
|
burn_disc_add_session(disc, session, BURN_POS_END);
|
||||||
|
Reference in New Issue
Block a user