Prepared experiments for new Linux SCSI adventures
This commit is contained in:
parent
7bbbeca905
commit
b025c6a255
@ -1 +1 @@
|
|||||||
#define Cdrskin_timestamP "2006.12.11.095230"
|
#define Cdrskin_timestamP "2006.12.11.100021"
|
||||||
|
@ -75,6 +75,50 @@ Hint: You should also look into sg-freebsd-port.c, which is a younger and
|
|||||||
#include <scsi/scsi.h>
|
#include <scsi/scsi.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61211 : preparing for exploration of recent Linux ATA adventures */
|
||||||
|
/** PORTING : Device file families for bus scanning and drive access.
|
||||||
|
Both device families must support the following ioctls:
|
||||||
|
SG_IO,
|
||||||
|
SG_GET_SCSI_ID
|
||||||
|
SCSI_IOCTL_GET_BUS_NUMBER
|
||||||
|
SCSI_IOCTL_GET_IDLUN
|
||||||
|
as well as mutual exclusively locking with open(O_EXCL).
|
||||||
|
If a device family is left empty, then it will not be used.
|
||||||
|
|
||||||
|
To avoid misunderstandings: both families are used via identical
|
||||||
|
transport methods as soon as a device file is accepted as CD drive
|
||||||
|
by the family specific function <family>_enumerate().
|
||||||
|
One difference remains throughout usage: Host,Channel,Id,Lun and Bus
|
||||||
|
address parameters of ATA devices are considered invalid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Set this to 1 in order to get on stderr messages from sg_enumerate() */
|
||||||
|
static int linux_sg_enumerate_debug = 0;
|
||||||
|
|
||||||
|
/* The device file family to use for (emulated) generic SCSI transport.
|
||||||
|
This must be a printf formatter with one single placeholder for int
|
||||||
|
in the range of 0 to 31 . The resulting addresses must provide SCSI
|
||||||
|
address parameters Host, Channel, Id, Lun and also Bus.
|
||||||
|
E.g.: "/dev/sg%d"
|
||||||
|
*/
|
||||||
|
static char linux_sg_device_family[80] = {"/dev/sg%d"};
|
||||||
|
|
||||||
|
|
||||||
|
/* The device file family to use for SCSI transport over ATA.
|
||||||
|
This must be a printf formatter with one single placeholder for a
|
||||||
|
_single_ char in the range of 'a' to 'z'. This placeholder _must_ be
|
||||||
|
at the end of the formatter string.
|
||||||
|
E.g. "/dev/hd%c"
|
||||||
|
*/
|
||||||
|
static char linux_ata_device_family[80] = {"/dev/hd%c"};
|
||||||
|
|
||||||
|
/* >>> Not implemented yet:
|
||||||
|
Set this to 1 in order to get on stderr messages from ata_enumerate() */
|
||||||
|
static int linux_ata_enumerate_verbous = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** PORTING : ------ libburn portable headers and definitions ----- */
|
/** PORTING : ------ libburn portable headers and definitions ----- */
|
||||||
|
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
@ -285,7 +329,11 @@ static int sg_open_scsi_siblings(char *path, int driveno,
|
|||||||
int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1;
|
int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1;
|
||||||
char msg[161], fname[81];
|
char msg[161], fname[81];
|
||||||
|
|
||||||
static char tldev[][81]= {"/dev/sr%d", "/dev/scd%d", "/dev/st%d", ""};
|
static char tldev[][81]= {"/dev/sr%d", "/dev/scd%d", "/dev/st%d",
|
||||||
|
"/dev/sg%d", ""};
|
||||||
|
|
||||||
|
if (linux_sg_device_family[0] == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
if(host_no < 0 || id_no < 0 || channel_no < 0 || lun_no < 0)
|
if(host_no < 0 || id_no < 0 || channel_no < 0 || lun_no < 0)
|
||||||
return(2);
|
return(2);
|
||||||
@ -293,6 +341,8 @@ static int sg_open_scsi_siblings(char *path, int driveno,
|
|||||||
sg_release_siblings(sibling_fds, sibling_count);
|
sg_release_siblings(sibling_fds, sibling_count);
|
||||||
|
|
||||||
for (tld = 0; tldev[tld][0] != 0; tld++) {
|
for (tld = 0; tldev[tld][0] != 0; tld++) {
|
||||||
|
if (strcmp(tldev[tld], linux_sg_device_family)==0)
|
||||||
|
continue;
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
sprintf(fname, tldev[tld], i);
|
sprintf(fname, tldev[tld], i);
|
||||||
ret = sg_obtain_scsi_adr(fname, &i_bus_no, &i_host_no,
|
ret = sg_obtain_scsi_adr(fname, &i_bus_no, &i_host_no,
|
||||||
@ -327,7 +377,7 @@ static int sg_open_scsi_siblings(char *path, int driveno,
|
|||||||
(*sibling_count)++;
|
(*sibling_count)++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(1);
|
return 1;
|
||||||
failed:;
|
failed:;
|
||||||
sg_release_siblings(sibling_fds, sibling_count);
|
sg_release_siblings(sibling_fds, sibling_count);
|
||||||
return 0;
|
return 0;
|
||||||
@ -342,8 +392,11 @@ static void ata_enumerate(void)
|
|||||||
int i, fd;
|
int i, fd;
|
||||||
char fname[10];
|
char fname[10];
|
||||||
|
|
||||||
|
if (linux_ata_device_family[0] == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
for (i = 0; i < 26; i++) {
|
for (i = 0; i < 26; i++) {
|
||||||
sprintf(fname, "/dev/hd%c", 'a' + i);
|
sprintf(fname, linux_ata_device_family, 'a' + i);
|
||||||
/* ts A51221 */
|
/* ts A51221 */
|
||||||
if (burn_drive_is_banned(fname))
|
if (burn_drive_is_banned(fname))
|
||||||
continue;
|
continue;
|
||||||
@ -381,15 +434,34 @@ static void sg_enumerate(void)
|
|||||||
int bus_no = -1;
|
int bus_no = -1;
|
||||||
char fname[10];
|
char fname[10];
|
||||||
|
|
||||||
|
if (linux_sg_enumerate_debug)
|
||||||
|
fprintf(stderr, "libburn_debug: linux_sg_device_family = %s\n",
|
||||||
|
linux_sg_device_family);
|
||||||
|
|
||||||
|
if (linux_sg_device_family[0] == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
sprintf(fname, "/dev/sg%d", i);
|
sprintf(fname, linux_sg_device_family, i);
|
||||||
|
|
||||||
|
if (linux_sg_enumerate_debug)
|
||||||
|
fprintf(stderr, "libburn_debug: %s : ", fname);
|
||||||
|
|
||||||
/* ts A51221 */
|
/* ts A51221 */
|
||||||
if (burn_drive_is_banned(fname))
|
if (burn_drive_is_banned(fname)) {
|
||||||
|
if (linux_sg_enumerate_debug)
|
||||||
|
fprintf(stderr, "not in whitelist\n");
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* ts A60927 */
|
/* ts A60927 */
|
||||||
fd = sg_open_drive_fd(fname, 1);
|
fd = sg_open_drive_fd(fname, 1);
|
||||||
if (fd == -1)
|
if (fd == -1) {
|
||||||
|
if (linux_sg_enumerate_debug)
|
||||||
|
fprintf(stderr, "open failed, errno=%d '%s'\n",
|
||||||
|
errno, strerror(errno));
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* found a drive */
|
/* found a drive */
|
||||||
ioctl(fd, SG_GET_SCSI_ID, &sid);
|
ioctl(fd, SG_GET_SCSI_ID, &sid);
|
||||||
@ -401,10 +473,18 @@ static void sg_enumerate(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (sg_close_drive_fd(fname, -1, &fd,
|
if (sg_close_drive_fd(fname, -1, &fd,
|
||||||
sid.scsi_type == TYPE_ROM ) <= 0)
|
sid.scsi_type == TYPE_ROM ) <= 0) {
|
||||||
|
if (linux_sg_enumerate_debug)
|
||||||
|
fprintf(stderr,
|
||||||
|
"cannot close properly, errno=%d '%s'\n",
|
||||||
|
errno, strerror(errno));
|
||||||
continue;
|
continue;
|
||||||
if (sid.scsi_type != TYPE_ROM)
|
}
|
||||||
|
if (sid.scsi_type != TYPE_ROM) {
|
||||||
|
if (linux_sg_enumerate_debug)
|
||||||
|
fprintf(stderr, "sid.scsi_type != TYPE_ROM\n");
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* ts A60927 : trying to do locking with growisofs */
|
/* ts A60927 : trying to do locking with growisofs */
|
||||||
if(burn_sg_open_o_excl>1) {
|
if(burn_sg_open_o_excl>1) {
|
||||||
@ -413,6 +493,8 @@ static void sg_enumerate(void)
|
|||||||
sid.host_no, sid.channel,
|
sid.host_no, sid.channel,
|
||||||
sid.scsi_id, sid.lun);
|
sid.scsi_id, sid.lun);
|
||||||
if (ret<=0) {
|
if (ret<=0) {
|
||||||
|
if (linux_sg_enumerate_debug)
|
||||||
|
fprintf(stderr, "cannot lock siblings\n");
|
||||||
sg_handle_busy_device(fname, 0);
|
sg_handle_busy_device(fname, 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -425,6 +507,10 @@ static void sg_enumerate(void)
|
|||||||
#else
|
#else
|
||||||
bus_no = sid.host_no;
|
bus_no = sid.host_no;
|
||||||
#endif
|
#endif
|
||||||
|
if (linux_sg_enumerate_debug)
|
||||||
|
fprintf(stderr, "accepting as SCSI %d,%d,%d,%d bus=%d\n",
|
||||||
|
sid.host_no, sid.channel, sid.scsi_id, sid.lun,
|
||||||
|
bus_no);
|
||||||
enumerate_common(fname, bus_no, sid.host_no, sid.channel,
|
enumerate_common(fname, bus_no, sid.host_no, sid.channel,
|
||||||
sid.scsi_id, sid.lun);
|
sid.scsi_id, sid.lun);
|
||||||
}
|
}
|
||||||
@ -513,13 +599,18 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
||||||
char adr[], int adr_size, int initialize)
|
char adr[], int adr_size, int initialize)
|
||||||
{
|
{
|
||||||
/* sg.h : typedef int burn_drive_enumerator_t; */
|
/* os-linux.h : typedef int burn_drive_enumerator_t; */
|
||||||
static int sg_limit = 32, ata_limit = 26;
|
static int sg_limit = 32, ata_limit = 26;
|
||||||
int baseno = 0;
|
int baseno = 0;
|
||||||
|
|
||||||
if (initialize == -1)
|
if (initialize == -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (linux_sg_device_family[0] == 0)
|
||||||
|
sg_limit = 0;
|
||||||
|
if (linux_ata_device_family[0] == 0)
|
||||||
|
ata_limit = 0;
|
||||||
|
|
||||||
if (initialize == 1)
|
if (initialize == 1)
|
||||||
*idx = -1;
|
*idx = -1;
|
||||||
(*idx)++;
|
(*idx)++;
|
||||||
@ -527,7 +618,7 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
|||||||
goto next_ata;
|
goto next_ata;
|
||||||
if (adr_size < 10)
|
if (adr_size < 10)
|
||||||
return -1;
|
return -1;
|
||||||
sprintf(adr, "/dev/sg%d", *idx);
|
sprintf(adr, linux_sg_device_family, *idx);
|
||||||
return 1;
|
return 1;
|
||||||
next_ata:;
|
next_ata:;
|
||||||
baseno += sg_limit;
|
baseno += sg_limit;
|
||||||
@ -535,7 +626,7 @@ next_ata:;
|
|||||||
goto next_nothing;
|
goto next_nothing;
|
||||||
if (adr_size < 9)
|
if (adr_size < 9)
|
||||||
return -1;
|
return -1;
|
||||||
sprintf(adr, "/dev/hd%c", 'a' + (*idx - baseno));
|
sprintf(adr, linux_ata_device_family, 'a' + (*idx - baseno));
|
||||||
return 1;
|
return 1;
|
||||||
next_nothing:;
|
next_nothing:;
|
||||||
baseno += ata_limit;
|
baseno += ata_limit;
|
||||||
@ -851,14 +942,15 @@ ex:;
|
|||||||
int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
||||||
int *target_no, int *lun_no)
|
int *target_no, int *lun_no)
|
||||||
{
|
{
|
||||||
int fd, ret;
|
int fd, ret, l;
|
||||||
struct my_scsi_idlun {
|
struct my_scsi_idlun {
|
||||||
int x;
|
int x;
|
||||||
int host_unique_id;
|
int host_unique_id;
|
||||||
};
|
};
|
||||||
struct my_scsi_idlun idlun;
|
struct my_scsi_idlun idlun;
|
||||||
|
|
||||||
if (strncmp(path, "/dev/hd", 7) == 0
|
l = strlen(linux_ata_device_family) - 2;
|
||||||
|
if (l > 0 && strncmp(path, linux_ata_device_family, l) == 0
|
||||||
&& path[7] >= 'a' && path[7] <= 'z' && path[8] == 0)
|
&& path[7] >= 'a' && path[7] <= 'z' && path[8] == 0)
|
||||||
return 0; /* on RIP 14 all hdx return SCSI adr 0,0,0,0 */
|
return 0; /* on RIP 14 all hdx return SCSI adr 0,0,0,0 */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user