Bus,Target,Lun for dev=ATA and dev=ATAPI, real SCSI addressing by default

trunk@386
Thomas Schmitt 16 years ago
parent eadef2c51d
commit 187fc90edf
  1. 48
      cdrskin/README
  2. 154
      cdrskin/cdrskin.c
  3. 2
      cdrskin/cdrskin_timestamp.h

@ -143,6 +143,16 @@ It is not checked for the necessary degree of hacker safety.
Get an overview of cdrecord style addresses of available devices
cdrskin -scanbus
cdrskin dev=ATA -scanbus
Note: Adresses reported with dev=ATA are to be used with prefix "ATA:".
Like "ATA:2,2,0" . Their numbers are not cdrecord compatible. See
"Pseudo-SCSI Adresses". It is well possible to use IDE device file
paths like "/dev/hdc" rather than "ATA:2,2,0".
With SCSI devices it is possible to use "/dev/sg1" or "/dev/scd0".
Note: Address numbers have changed since cdrskin-0.2.2. To get the old number
scheme, use option --old_pseudo_scsi_adr . Sorry for any inconvenience.
Obtain some info about the drive
cdrskin dev=1,1,0 -checkdrive
@ -233,18 +243,21 @@ the meaning of the components. A cdrecord-style address for cdrskin
[prefix:]scsibus,target,lun
can be interpreted in two different modes.
Mode --no_pseudo_scsi_adr uses scsibus,target,lun as given by the operating
system. On (old) real SCSI burners and on emulated SCSI it is compatible to
cdrecord even in quite old versions.
On plain ATAPI this mode offers no scsibus,target,lun addressing at all
but refers directly to the device file names /dev/hdX. Modern versions of
cdrecord on kernel 2.6 do accept these addresses too, but the advised method
is rather ATA:scsibus,target,lun which is not supported by cdrskin, yet.
In standard mode there is a scsibus,target,lun representation for any visible
device. The price for this is that the numbering has nothing to do with SCSI
and thus is not compatible to cdrecord. Each number triple corresponds either
to a device file address or to a libburn drive number.
Standard mode uses scsibus,target,lun as given by the operating system. On
(old) real SCSI burners and on emulated SCSI it is compatible to cdrecord.
On plain IDE this mode offers no compatible scsibus,target,lun addressing,
but the cdrecord-ly advised methods ATA:scsibus,target,lun and ATAPI:...
are supported by cdrskin via an own incompatible address enumeration.
In this mode, option -scanbus will list only SCSI devices unless option
dev=ATA or dev=ATAPI are given, which will suppress SCSI devices and only
show IDE drives (i.e. /dev/hdX without ide-scsi emulation).
In mode --old_pseudo_scsi_adr there is a scsibus,target,lun representation
which has nothing to do with SCSI and thus is not compatible to cdrecord.
Each number triple corresponds either to a device file address or to a
libburn drive number.
Component "scsibus" indicates the translation method. Defined busses are:
0 target is the libburn drivenumber as listed with --devices
1 associated to device file /dev/sgN , target chooses N
@ -263,10 +276,13 @@ a meaning. To stay upward compatible, use addresses as printed by -scanbus.
Some programs or users have their own ideas about the address of their burner.
K3b 0.10 for example derives cdrecord addresses by own examination of the
devices and not by calling cdrecord -scanbus.
On systems where the burners are attached via (emulated) SCSI it is worth
a try to use cdrskin with optio --no_pseudo_scsi_adr . If ATAPI devices are
used directly then this will work well only if the frontend uses /dev/hdX as
address and does not insist in ATA:scsibus,target,lun .
On systems where the burners are attached via (emulated) SCSI, standard mode
will hopefully be fully compatible. If IDE devices are used, then hope that
the frontend uses directly /dev/hdX or asks its "cdrecord:" via
dev=ATA -scanbus for drive addresses and drive descriptions.
Old frontends which do not know dev=ATA or dev=ATAPI and which do ask their
"cdrecord" via -scanbus may be well served with option --old_pseudo_scsi_adr .
To direct any stubborn callers to the appropriate drives, cdrskin allows to
define device address aliases. Like

@ -1159,10 +1159,11 @@ struct CdrpreskiN {
clones and SCSI addresses */
int no_convert_fs_adr;
/** Wether Bus,Target,Lun addresses shall not be converted literally as
Pseudo SCSI-Adresses but as (possibly system emulated) real SCSI addresses
via burn_drive_convert_scsi_adr() */
int no_pseudo_scsi_adr;
/** Wether Bus,Target,Lun addresses shall be converted literally as old
Pseudo SCSI-Adresses. New default is to use (possibly system emulated)
real SCSI addresses via burn_drive_convert_scsi_adr() and literally
emulated and cdrecord-incompatible ATA: addresses. */
int old_pseudo_scsi_adr;
/** Wether bus scans shall exit!=0 if no drive was found */
int scan_demands_drive;
@ -1218,7 +1219,11 @@ int Cdrpreskin_new(struct CdrpreskiN **preskin, int flag)
o->allow_fd_source= 0;
o->no_whitelist= 0;
o->no_convert_fs_adr= 0;
o->no_pseudo_scsi_adr= 0;
#ifdef Cdrskin_libburn_has_convert_scsi_adR
o->old_pseudo_scsi_adr= 0;
#else
o->old_pseudo_scsi_adr= 1;
#endif
o->scan_demands_drive= 0;
o->abort_on_busy_drive= 0;
o->drive_exclusive= 1;
@ -1269,7 +1274,7 @@ int Cdrpreskin_destroy(struct CdrpreskiN **preskin, int flag)
bus=0 : drive number , bus=1 : /dev/sgN , bus=2 : /dev/hdX
(This call intentionally has no CdrpreskiN argument)
@param flag Bitfield for control purposes:
bit0= no_pseudo_scsi_adr
bit0= old_pseudo_scsi_adr
@return <=0 error, 1 success
*/
int Cdrpreskin__cdrecord_to_dev(char *adr, char device_adr[Cdrskin_adrleN],
@ -1316,28 +1321,32 @@ int Cdrpreskin__cdrecord_to_dev(char *adr, char device_adr[Cdrskin_adrleN],
if(digit_seen) {
sscanf(adr+k+1,"%d",&busno);
if(flag&1) {
if(busno==1) {
sprintf(device_adr,"/dev/sg%d",*driveno);
} else if(busno==2) {
sprintf(device_adr,"/dev/hd%c",'a'+(*driveno));
} else if(busno!=0) {
fprintf(stderr,
"cdrskin: FATAL : dev=[Prefix:]Bus,Target,Lun expects Bus out of {0,1,2}\n");
return(0);
}
} else {
if(busno<0 || busno>255) {
fprintf(stderr,
"cdrskin: FATAL : dev=[Prefix:]Bus,Target,Lun expects Bus out of {0..255}\n");
return(0);
}
if((strncmp(adr,"ATA",3)==0 && (adr[3]==0 || adr[3]==':')) ||
(strncmp(adr,"ATAPI",5)==0 && (adr[5]==0 || adr[5]==':'))) {
/* >>> eventually check for non SCSI prefixes */
/* >>> in future expect busno to have a meaning */
sprintf(device_adr,"/dev/hd%c",'a'+(*driveno));
#ifdef Cdrskin_libburn_has_convert_scsi_adR
ret= burn_drive_convert_scsi_adr(busno,-1,*driveno,lun_no,device_adr);
return(ret);
} else {
ret= burn_drive_convert_scsi_adr(busno,-1,*driveno,lun_no,device_adr);
return(ret);
#endif
} else {
if(busno==1) {
sprintf(device_adr,"/dev/sg%d",*driveno);
} else if(busno==2) {
sprintf(device_adr,"/dev/hd%c",'a'+(*driveno));
} else if(busno!=0) {
fprintf(stderr,
"cdrskin: FATAL : dev=[Prefix:]Bus,Target,Lun expects Bus out of {0,1,2}\n");
return(0);
}
}
}
@ -1597,12 +1606,8 @@ set_dev:;
" --ignore_signals try to ignore any signals rather than to abort\n");
printf(" --no_abort_handler exit even if the drive is in busy state\n");
printf(" --no_blank_appendable refuse to blank appendable CD-RW\n");
#ifdef Cdrskin_libburn_has_convert_scsi_adR
printf(" --no_pseudo_scsi_adr use and report real Bus,Target,Lun\n");
printf(" (not yet with \"ATA:\", \"ATAPI:\" ...)\n");
#endif
printf(" --old_pseudo_scsi_adr use and report literal Bus,Target,Lun\n");
printf(" rather than real SCSI and pseudo ATA.\n");
printf(" --no_convert_fs_adr only literal translations of dev=\n");
printf(
" --no_rc as first argument: do not read startup files\n");
@ -1713,10 +1718,8 @@ see_cdrskin_eng_html:;
} else if(strcmp(argv[i],"--no_convert_fs_adr")==0) {
o->no_convert_fs_adr= 1;
#ifdef Cdrskin_libburn_has_convert_scsi_adR
} else if(strcmp(argv[i],"--no_pseudo_scsi_adr")==0) {
o->no_pseudo_scsi_adr= 1;
#endif
} else if(strcmp(argv[i],"--old_pseudo_scsi_adr")==0) {
o->old_pseudo_scsi_adr= 1;
} else if(strcmp(argv[i],"--no_rc")==0) {
if(i!=1)
@ -1790,7 +1793,7 @@ dev_too_long:;
strcpy(o->device_adr,adr);
} else {
ret= Cdrpreskin__cdrecord_to_dev(adr,o->device_adr,&driveno,
!!o->no_pseudo_scsi_adr);
!!o->old_pseudo_scsi_adr);
if(ret<=0) {
fprintf(stderr,
"cdrskin: FATAL : dev= expects /dev/xyz, Bus,Target,0 or a number\n");
@ -2664,7 +2667,7 @@ location_not_found:;
return(1);
}
ret= Cdrpreskin__cdrecord_to_dev(adr,synthetic_adr,driveno,
!!skin->preskin->no_pseudo_scsi_adr);
!!skin->preskin->old_pseudo_scsi_adr);
if(ret<=0) {
wrong_devno:;
if(skin->n_drives<=0) {
@ -2703,8 +2706,12 @@ wrong_devno:;
represents a device address if possible and the drive number else.
@param flag Bitfield for control purposes:
bit0= do not apply user defined address translation
@return <0 error, 0 drive number, 1 /dev/sgN, 2 /dev/hdX,
1000+busno = non-pseudo SCSI bus
@return <0 error,
pseudo transport groups:
0 volatile drive number,
1 /dev/sgN, 2 /dev/hdX,
1000+busno = non-pseudo SCSI bus
2000+busno = pseudo-ATA|ATAPI SCSI bus (currently busno==2)
*/
int Cdrskin_driveno_to_btldev(struct CdrskiN *skin, int driveno,
char btldev[Cdrskin_adrleN], int flag)
@ -2728,16 +2735,24 @@ int Cdrskin_driveno_to_btldev(struct CdrskiN *skin, int driveno,
#endif
#ifdef Cdrskin_libburn_has_convert_scsi_adR
if(skin->preskin->no_pseudo_scsi_adr) {
if(!skin->preskin->old_pseudo_scsi_adr) {
int host_no= -1,channel_no= -1,target_no= -1,lun_no= -1;
ret= burn_drive_obtain_scsi_adr(loc,&host_no,&channel_no,&target_no,
&lun_no);
if(ret<=0)
if(ret<=0) {
if(strncmp(loc,"/dev/hd",7)==0)
if(loc[7]>='a' && loc[7]<='z')
if(loc[8]==0) {
sprintf(btldev,"2,%d,0",loc[7]-'a');
{ret= 2002; goto adr_translation;}
}
goto fallback;
sprintf(btldev,"%d,%d,%d",host_no,target_no,lun_no);
ret= 1000+host_no;
goto adr_translation;
} else {
sprintf(btldev,"%d,%d,%d",host_no,target_no,lun_no);
ret= 1000+host_no;
goto adr_translation;
}
}
#endif
@ -2757,13 +2772,14 @@ int Cdrskin_driveno_to_btldev(struct CdrskiN *skin, int driveno,
{ret= 2; goto adr_translation;}
}
fallback:;
if(skin->preskin->no_pseudo_scsi_adr) {
if(skin->preskin->old_pseudo_scsi_adr) {
sprintf(btldev,"0,%d,0",driveno);
} else {
if(loc!=NULL)
strcpy(btldev,loc);
else
sprintf(btldev,"%d",driveno);
} else
sprintf(btldev,"0,%d,0",driveno);
}
ret= 0;
adr_translation:;
@ -2816,9 +2832,9 @@ int Cdrskin_report_disc_status(struct CdrskiN *skin, enum burn_disc_status s,
*/
int Cdrskin_scanbus(struct CdrskiN *skin, int flag)
{
int ret,i,busno,first_on_bus;
int ret,i,busno,first_on_bus,pseudo_transport_group= 0,skipped_devices= 0;
char shellsafe[5*Cdrskin_strleN+2],perms[40],btldev[Cdrskin_adrleN];
char adr[Cdrskin_adrleN];
char adr[Cdrskin_adrleN],*raw_dev;
struct stat stbuf;
if(flag&1) {
@ -2857,23 +2873,57 @@ int Cdrskin_scanbus(struct CdrskiN *skin, int flag)
}
printf("-----------------------------------------------------------------------------\n");
} else {
printf("Using libburn version '%s'.\n",Cdrskin_libburn_versioN);
if(!skin->preskin->old_pseudo_scsi_adr) {
pseudo_transport_group= 1000;
raw_dev= skin->preskin->raw_device_adr;
if(strncmp(raw_dev,"ATA",3)==0 && (raw_dev[3]==0 || raw_dev[3]==':'))
pseudo_transport_group= 2000;
if(strncmp(raw_dev,"ATAPI",5)==0 && (raw_dev[5]==0 || raw_dev[5]==':'))
pseudo_transport_group= 2000;
if(pseudo_transport_group==2000) {
fprintf(stderr,"scsidev: 'ATA'\ndevname: 'ATA'\n");
fprintf(stderr,"scsibus: -2 target: -2 lun: -2\n");
}
}
/* >>> fprintf(stderr,"Linux sg driver version: 3.1.25\n"); */
printf("Using libburn version '%s'.\n", Cdrskin_libburn_versioN);
if(pseudo_transport_group!=1000)
printf(
"cdrskin: NOTE : The printed addresses are not cdrecord compatible !\n");
for(busno= 0;busno<16;busno++) {
first_on_bus= 1;
for(i=0;i<skin->n_drives;i++) {
ret= Cdrskin_driveno_to_btldev(skin,i,btldev,1);
if(ret==1000+busno)
if(ret==pseudo_transport_group + busno)
ret= busno;
if(ret!=busno)
if(ret!=busno) {
if((ret%1000)==busno) {
skipped_devices++;
if(skin->verbosity>=Cdrskin_verbose_debuG)
ClN(fprintf(stderr,"cdrskin_debug: skipping drive '%s'\n",
btldev));
}
continue;
}
if(first_on_bus)
printf("scsibus%d:\n",busno);
first_on_bus= 0;
printf("\t%s\t %d) '%s' '%s' '%s' Removable CD-ROM\n",
btldev,i,skin->drives[i].vendor,skin->drives[i].product,"?");
printf("\t%s\t %d) '%-8s' '%-16s' '%-4s' Removable CD-ROM\n",
btldev,i,skin->drives[i].vendor,skin->drives[i].product,"?..?");
}
}
}
if(skipped_devices>0) {
if(skipped_devices>1)
printf("cdrskin: NOTE : There were %d drives not shown.\n",
skipped_devices);
else
printf("cdrskin: NOTE : There was 1 drives not shown.\n");
printf("cdrskin: HINT : To surely see all drives try option: --devices\n");
if(pseudo_transport_group!=2000)
printf("cdrskin: HINT : or try options: dev=ATA -scanbus\n");
}
return(1);
}
@ -3708,8 +3758,12 @@ int Cdrskin_eject(struct CdrskiN *skin, int flag)
if(!skin->do_eject)
return(1);
/* A60923 :
Still not in libburn-0.2.2 : prevent SIGSEV on non-existent drive */
if(skin->n_drives<=skin->driveno || skin->driveno < 0)
return(2);
for(i= 0;i<max_try;i++) {
ret= Cdrskin_grab_drive(skin,2|((i<max_try-1)<<2));
if(ret>0 || i>=max_try-1)
@ -4129,10 +4183,8 @@ gracetime_equals:;
} else if(strcmp(argv[i],"--no_convert_fs_adr")==0) {
/* is handled in Cdrpreskin_setup() */;
#ifdef Cdrskin_libburn_has_convert_scsi_adR
} else if(strcmp(argv[i],"--no_pseudo_scsi_adr")==0) {
} else if(strcmp(argv[i],"--old_pseudo_scsi_adr")==0) {
/* is handled in Cdrpreskin_setup() */;
#endif
} else if(strcmp(argv[i],"--no_rc")==0) {
/* is handled in Cdrpreskin_setup() */;

@ -1 +1 @@
#define Cdrskin_timestamP "2006.09.23.132755"
#define Cdrskin_timestamP "2006.09.23.182444"

Loading…
Cancel
Save