Split enumerate_common() into logic-layer, command-layer, transport-layer
This commit is contained in:
parent
6f0643b7cf
commit
e5ed5f1856
@ -1 +1 @@
|
|||||||
#define Cdrskin_timestamP "2006.10.21.103653"
|
#define Cdrskin_timestamP "2006.10.21.185102"
|
||||||
|
@ -33,6 +33,16 @@ extern struct libdax_msgs *libdax_messenger;
|
|||||||
static struct burn_drive drive_array[255];
|
static struct burn_drive drive_array[255];
|
||||||
static int drivetop = -1;
|
static int drivetop = -1;
|
||||||
|
|
||||||
|
/* ts A61021 : the unspecific part of sg.c:enumerate_common()
|
||||||
|
*/
|
||||||
|
int burn_setup_drive(struct burn_drive *d, char *fname)
|
||||||
|
{
|
||||||
|
d->devname = burn_strdup(fname);
|
||||||
|
memset(&d->params, 0, sizeof(struct params));
|
||||||
|
d->released = 1;
|
||||||
|
d->status = BURN_DISC_UNREADY;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* ts A60904 : ticket 62, contribution by elmom */
|
/* ts A60904 : ticket 62, contribution by elmom */
|
||||||
/* splitting former burn_drive_free() (which freed all, into two calls) */
|
/* splitting former burn_drive_free() (which freed all, into two calls) */
|
||||||
@ -65,21 +75,8 @@ void burn_drive_free_all(void)
|
|||||||
/* ts A60822 */
|
/* ts A60822 */
|
||||||
int burn_drive_is_open(struct burn_drive *d)
|
int burn_drive_is_open(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
#if defined(__FreeBSD__)
|
/* ts A61021 : moved decision to sg.c */
|
||||||
|
return d->drive_is_open(d);
|
||||||
if (d->cam == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#else /* __FreeBSD__ */
|
|
||||||
|
|
||||||
/* a bit more detailed case distinction than needed */
|
|
||||||
if (d->fd == -1337)
|
|
||||||
return 0;
|
|
||||||
if (d->fd < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#endif /* ! __FreeBSD__ */
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -280,6 +277,39 @@ int burn_drive_unregister(struct burn_drive *d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A61021 : after-setup activities from sg.c:enumerate_common()
|
||||||
|
*/
|
||||||
|
struct burn_drive *burn_drive_finish_enum(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
struct burn_drive *t;
|
||||||
|
/* ts A60821
|
||||||
|
<<< debug: for tracing calls which might use open drive fds */
|
||||||
|
int mmc_function_spy(char * text);
|
||||||
|
|
||||||
|
t = burn_drive_register(d);
|
||||||
|
|
||||||
|
/* ts A60821 */
|
||||||
|
mmc_function_spy("enumerate_common : -------- doing grab");
|
||||||
|
|
||||||
|
/* try to get the drive info */
|
||||||
|
if (t->grab(t)) {
|
||||||
|
burn_print(2, "getting drive info\n");
|
||||||
|
t->getcaps(t);
|
||||||
|
t->unlock(t);
|
||||||
|
t->released = 1;
|
||||||
|
} else {
|
||||||
|
burn_print(2, "unable to grab new located drive\n");
|
||||||
|
burn_drive_unregister(t);
|
||||||
|
t = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A60821 */
|
||||||
|
mmc_function_spy("enumerate_common : ----- would release ");
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void burn_drive_release(struct burn_drive *d, int le)
|
void burn_drive_release(struct burn_drive *d, int le)
|
||||||
{
|
{
|
||||||
if (d->released) {
|
if (d->released) {
|
||||||
|
@ -61,4 +61,13 @@ int burn_drive_is_occupied(struct burn_drive *d);
|
|||||||
int burn_drive_forget(struct burn_drive *d, int force);
|
int burn_drive_forget(struct burn_drive *d, int force);
|
||||||
int burn_drive_convert_fs_adr_sub(char *path, char adr[], int *rec_count);
|
int burn_drive_convert_fs_adr_sub(char *path, char adr[], int *rec_count);
|
||||||
|
|
||||||
|
/* ts A61021 : the unspecific part of sg.c:enumerate_common()
|
||||||
|
*/
|
||||||
|
int burn_setup_drive(struct burn_drive *d, char *fname);
|
||||||
|
|
||||||
|
/* ts A61021 : after-setup activities from sg.c:enumerate_common()
|
||||||
|
*/
|
||||||
|
struct burn_drive *burn_drive_finish_enum(struct burn_drive *d);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __DRIVE */
|
#endif /* __DRIVE */
|
||||||
|
@ -757,3 +757,27 @@ void mmc_sync_cache(struct burn_drive *d)
|
|||||||
c.dir = NO_TRANSFER;
|
c.dir = NO_TRANSFER;
|
||||||
d->issue_command(d, &c);
|
d->issue_command(d, &c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ts A61021 : the mmc specific part of sg.c:enumerate_common()
|
||||||
|
*/
|
||||||
|
int mmc_setup_drive(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
d->read_atip = mmc_read_atip;
|
||||||
|
d->read_toc = mmc_read_toc;
|
||||||
|
d->write = mmc_write;
|
||||||
|
d->erase = mmc_erase;
|
||||||
|
d->read_sectors = mmc_read_sectors;
|
||||||
|
d->perform_opc = mmc_perform_opc;
|
||||||
|
d->set_speed = mmc_set_speed;
|
||||||
|
d->send_cue_sheet = mmc_send_cue_sheet;
|
||||||
|
d->sync_cache = mmc_sync_cache;
|
||||||
|
d->get_nwa = mmc_get_nwa;
|
||||||
|
d->close_disc = mmc_close_disc;
|
||||||
|
d->close_session = mmc_close_session;
|
||||||
|
|
||||||
|
/* ts A61020 */
|
||||||
|
d->start_lba= -2000000000;
|
||||||
|
d->end_lba= -2000000000;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@ -39,4 +39,9 @@ void mmc_perform_opc(struct burn_drive *);
|
|||||||
void mmc_get_configuration(struct burn_drive *);
|
void mmc_get_configuration(struct burn_drive *);
|
||||||
int mmc_get_nwa(struct burn_drive *);
|
int mmc_get_nwa(struct burn_drive *);
|
||||||
void mmc_send_cue_sheet(struct burn_drive *, struct cue_sheet *);
|
void mmc_send_cue_sheet(struct burn_drive *, struct cue_sheet *);
|
||||||
|
|
||||||
|
/* ts A61021 : the mmc specific part of sg.c:enumerate_common()
|
||||||
|
*/
|
||||||
|
int mmc_setup_drive(struct burn_drive *d);
|
||||||
|
|
||||||
#endif /*__MMC*/
|
#endif /*__MMC*/
|
||||||
|
@ -36,3 +36,13 @@ void sbc_eject(struct burn_drive *d)
|
|||||||
c.dir = NO_TRANSFER;
|
c.dir = NO_TRANSFER;
|
||||||
d->issue_command(d, &c);
|
d->issue_command(d, &c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ts A61021 : the sbc specific part of sg.c:enumerate_common()
|
||||||
|
*/
|
||||||
|
int sbc_setup_drive(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
d->eject = sbc_eject;
|
||||||
|
d->load = sbc_load;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -8,4 +8,8 @@ struct burn_drive;
|
|||||||
void sbc_load(struct burn_drive *);
|
void sbc_load(struct burn_drive *);
|
||||||
void sbc_eject(struct burn_drive *);
|
void sbc_eject(struct burn_drive *);
|
||||||
|
|
||||||
|
/* ts A61021 : the sbc specific part of sg.c:enumerate_common()
|
||||||
|
*/
|
||||||
|
int sbc_setup_drive(struct burn_drive *d);
|
||||||
|
|
||||||
#endif /* __SBC */
|
#endif /* __SBC */
|
||||||
|
@ -1,5 +1,21 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
|
||||||
|
/* >>> ts A61021 : for testing the new arrangement of code
|
||||||
|
please outcomment these defines : */
|
||||||
|
|
||||||
|
/* Keeps alive old enumerate_common(). New version delegates much work
|
||||||
|
to methods in drive, mmc, spc, and sbc .
|
||||||
|
*/
|
||||||
|
#define Scsi_freebsd_make_own_enumeratE 1
|
||||||
|
|
||||||
|
|
||||||
|
/* Keeps alive old sg_enumerate(). New version delegates most work to
|
||||||
|
sg_give_next_adr().
|
||||||
|
*/
|
||||||
|
#define Scsi_freebsd_old_sg_enumeratE 1
|
||||||
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -37,33 +53,17 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
/* ts A51221 */
|
/* ts A51221 */
|
||||||
int burn_drive_is_banned(char *device_address);
|
int burn_drive_is_banned(char *device_address);
|
||||||
|
|
||||||
/* ts A60813 : storage objects are in libburn/init.c
|
|
||||||
wether to use O_EXCL
|
|
||||||
wether to use O_NOBLOCK with open(2) on devices
|
|
||||||
wether to take O_EXCL rejection as fatal error */
|
|
||||||
extern int burn_sg_open_o_excl;
|
|
||||||
extern int burn_sg_open_o_nonblock;
|
|
||||||
extern int burn_sg_open_abort_busy;
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A60821
|
/* ts A60821
|
||||||
<<< debug: for tracing calls which might use open drive fds */
|
<<< debug: for tracing calls which might use open drive fds */
|
||||||
int mmc_function_spy(char * text);
|
int mmc_function_spy(char * text);
|
||||||
|
|
||||||
/** Returns the next index number and the next enumerated drive address.
|
|
||||||
@param idx An opaque handle. Make no own theories about it.
|
#ifdef Scsi_freebsd_old_sg_enumeratE
|
||||||
@param adr Takes the reply
|
|
||||||
@param adr_size Gives maximum size of reply including final 0
|
|
||||||
@param initialize 1 = start new,
|
|
||||||
0 = continue, use no other values for now
|
|
||||||
-1 = finish
|
|
||||||
@return 1 = reply is a valid address , 0 = no further address available
|
|
||||||
-1 = severe error (e.g. adr_size too small)
|
|
||||||
*/
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,6 +78,208 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else /* Scsi_freebsd_old_sg_enumeratE */
|
||||||
|
|
||||||
|
/* ts A61021 : Moved most code from sg_enumerate under sg_give_next_adr() */
|
||||||
|
/* Some helper functions for sg_give_next_adr() */
|
||||||
|
|
||||||
|
static int sg_init_enumerator(burn_drive_enumerator_t *idx)
|
||||||
|
{
|
||||||
|
idx->skip_device = 0;
|
||||||
|
|
||||||
|
if ((idx->fd = open(XPT_DEVICE, O_RDWR)) == -1) {
|
||||||
|
warn("couldn't open %s", XPT_DEVICE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bzero(&(idx->ccb), sizeof(union ccb));
|
||||||
|
|
||||||
|
idx->ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
|
||||||
|
idx->ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
|
||||||
|
idx->ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
|
||||||
|
|
||||||
|
idx->ccb.ccb_h.func_code = XPT_DEV_MATCH;
|
||||||
|
idx->bufsize = sizeof(struct dev_match_result) * 100;
|
||||||
|
idx->ccb.cdm.match_buf_len = idx->bufsize;
|
||||||
|
idx->ccb.cdm.matches = (struct dev_match_result *)malloc(idx->bufsize);
|
||||||
|
if (idx->ccb.cdm.matches == NULL) {
|
||||||
|
warnx("can't malloc memory for matches");
|
||||||
|
close(idx->fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
idx->ccb.cdm.num_matches = 0;
|
||||||
|
idx->i = idx->ccb.cdm.num_matches; /* to trigger buffer load */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We fetch all nodes, since we display most of them in the default
|
||||||
|
* case, and all in the verbose case.
|
||||||
|
*/
|
||||||
|
idx->ccb.cdm.num_patterns = 0;
|
||||||
|
idx->ccb.cdm.pattern_buf_len = 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int sg_next_enumeration_buffer(burn_drive_enumerator_t *idx)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We do the ioctl multiple times if necessary, in case there are
|
||||||
|
* more than 100 nodes in the EDT.
|
||||||
|
*/
|
||||||
|
if (ioctl(idx->fd, CAMIOCOMMAND, &(idx->ccb)) == -1) {
|
||||||
|
warn("error sending CAMIOCOMMAND ioctl");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((idx->ccb.ccb_h.status != CAM_REQ_CMP)
|
||||||
|
|| ((idx->ccb.cdm.status != CAM_DEV_MATCH_LAST)
|
||||||
|
&& (idx->ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
|
||||||
|
warnx("got CAM error %#x, CDM error %d\n",
|
||||||
|
idx->ccb.ccb_h.status, idx->ccb.cdm.status);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns the next index number and the next enumerated drive address.
|
||||||
|
@param idx An opaque handle. Make no own theories about it.
|
||||||
|
@param adr Takes the reply
|
||||||
|
@param adr_size Gives maximum size of reply including final 0
|
||||||
|
@param initialize 1 = start new,
|
||||||
|
0 = continue, use no other values for now
|
||||||
|
-1 = finish
|
||||||
|
@return 1 = reply is a valid address , 0 = no further address available
|
||||||
|
-1 = severe error (e.g. adr_size too small)
|
||||||
|
*/
|
||||||
|
int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
||||||
|
char adr[], int adr_size, int initialize)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (initialize == 1) {
|
||||||
|
ret = sg_init_enumerator(idx);
|
||||||
|
if (ret<=0)
|
||||||
|
return ret;
|
||||||
|
} else if (initialize == -1) {
|
||||||
|
if(idx->fd != -1)
|
||||||
|
close(idx->fd);
|
||||||
|
idx->fd = -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try_item:; /* This spaghetti loop keeps the number of tabs small */
|
||||||
|
|
||||||
|
/* Loop content from old sg_enumerate() */
|
||||||
|
|
||||||
|
while (idx->i >= idx->ccb.cdm.num_matches) {
|
||||||
|
ret = sg_next_enumeration_buffer(idx);
|
||||||
|
if (ret<=0)
|
||||||
|
return -1;
|
||||||
|
if (!((idx->ccb.ccb_h.status == CAM_REQ_CMP)
|
||||||
|
&& (idx->ccb.cdm.status == CAM_DEV_MATCH_MORE)) )
|
||||||
|
return 0;
|
||||||
|
idx->i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (idx->ccb.cdm.matches[idx->i].type) {
|
||||||
|
case DEV_MATCH_BUS:
|
||||||
|
break;
|
||||||
|
case DEV_MATCH_DEVICE: {
|
||||||
|
struct device_match_result* result;
|
||||||
|
|
||||||
|
result = &(idx->ccb.cdm.matches[i].result.device_result);
|
||||||
|
if (result->flags & DEV_RESULT_UNCONFIGURED)
|
||||||
|
idx->skip_device = 1;
|
||||||
|
else
|
||||||
|
idx->skip_device = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DEV_MATCH_PERIPH: {
|
||||||
|
struct periph_match_result* result;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
result = &(idx->ccb.cdm.matches[i].result.periph_result);
|
||||||
|
if (idx->skip_device ||
|
||||||
|
strcmp(result->periph_name, "pass") == 0)
|
||||||
|
break;
|
||||||
|
snprintf(buf, sizeof (buf), "/dev/%s%d",
|
||||||
|
result->periph_name, result->unit_number);
|
||||||
|
if(adr_size <= strlen(buf)
|
||||||
|
return -1;
|
||||||
|
strcpy(adr, buf);
|
||||||
|
|
||||||
|
/* Found next enumerable address */
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
/* printf(stderr, "unknown match type\n"); */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
(idx->i)++;
|
||||||
|
goto try_item; /* Regular function exit is return 1 above */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int sg_is_enumerable_adr(char* adr)
|
||||||
|
{
|
||||||
|
burn_drive_enumerator_t idx;
|
||||||
|
int initialize = 1;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
|
||||||
|
initialize = 0;
|
||||||
|
if (ret <= 0)
|
||||||
|
break;
|
||||||
|
if (strcmp(adr, buf) == 0) {
|
||||||
|
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Try 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)
|
||||||
|
{
|
||||||
|
burn_drive_enumerator_t idx;
|
||||||
|
int initialize = 1;
|
||||||
|
char buf[64];
|
||||||
|
struct periph_match_result* result;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
|
||||||
|
initialize = 0;
|
||||||
|
if (ret <= 0)
|
||||||
|
break;
|
||||||
|
if (strcmp(adr, buf) != 0)
|
||||||
|
continue;
|
||||||
|
result = &(idx->ccb.cdm.matches[i].result.periph_result);
|
||||||
|
*bus_no = result->path_id;
|
||||||
|
*host_no = result->path_id;
|
||||||
|
*channel_no = 0;
|
||||||
|
*target_no = result->target_id
|
||||||
|
*lun_no = result->target_lun;
|
||||||
|
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ! Scsi_freebsd_old_sg_enumeratE */
|
||||||
|
|
||||||
|
|
||||||
int sg_close_drive(struct burn_drive * d)
|
int sg_close_drive(struct burn_drive * d)
|
||||||
{
|
{
|
||||||
if (d->cam != NULL) {
|
if (d->cam != NULL) {
|
||||||
@ -87,13 +289,26 @@ int sg_close_drive(struct burn_drive * d)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sg_drive_is_open(struct burn_drive * d)
|
||||||
|
{
|
||||||
|
return (d->cam != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ata_enumerate(void)
|
void ata_enumerate(void)
|
||||||
{
|
{
|
||||||
/* Do not supported */
|
/* ts A61021: Only a dummy function is needed in FreeBSD */
|
||||||
|
/* The difference between sg and ata should be encapsulated
|
||||||
|
in sg-linux.c */
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void sg_enumerate(void)
|
void sg_enumerate(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifdef Scsi_freebsd_old_sg_enumeratE
|
||||||
|
|
||||||
union ccb ccb;
|
union ccb ccb;
|
||||||
int bufsize, fd;
|
int bufsize, fd;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@ -188,8 +403,35 @@ void sg_enumerate(void)
|
|||||||
&& (ccb.cdm.status == CAM_DEV_MATCH_MORE));
|
&& (ccb.cdm.status == CAM_DEV_MATCH_MORE));
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
#else /* Scsi_freebsd_old_sg_enumeratE */
|
||||||
|
|
||||||
|
burn_drive_enumerator_t idx;
|
||||||
|
int initialize = 1;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
|
||||||
|
initialize = 0;
|
||||||
|
if (ret <= 0)
|
||||||
|
break;
|
||||||
|
if (burn_drive_is_banned(buf))
|
||||||
|
continue;
|
||||||
|
enumerate_common(buf, idx.result->path_id, idx.result->path_id,
|
||||||
|
0, idx.result->target_id,
|
||||||
|
idx.result->target_lun);
|
||||||
|
}
|
||||||
|
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||||
|
|
||||||
|
#endif /* ! Scsi_freebsd_old_sg_enumeratE */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Scsi_freebsd_make_own_enumeratE
|
||||||
|
|
||||||
|
/* ts A61021: The old version which mixes SCSI and operating system adapter
|
||||||
|
*/
|
||||||
static void enumerate_common(char *fname, int bus_no, int host_no,
|
static void enumerate_common(char *fname, int bus_no, int host_no,
|
||||||
int channel_no, int target_no, int lun_no)
|
int channel_no, int target_no, int lun_no)
|
||||||
{
|
{
|
||||||
@ -212,6 +454,7 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
|
|
||||||
out.grab = sg_grab;
|
out.grab = sg_grab;
|
||||||
out.release = sg_release;
|
out.release = sg_release;
|
||||||
|
out.drive_is_open= sg_drive_is_open;
|
||||||
out.issue_command = sg_issue_command;
|
out.issue_command = sg_issue_command;
|
||||||
out.getcaps = spc_getcaps;
|
out.getcaps = spc_getcaps;
|
||||||
out.released = 1;
|
out.released = 1;
|
||||||
@ -271,7 +514,41 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
#else /* Scsi_freebsd_make_own_enumeratE */
|
||||||
|
|
||||||
|
/* The new, more concise version of enumerate_common */
|
||||||
|
static void enumerate_common(char *fname, int bus_no, int host_no,
|
||||||
|
int channel_no, int target_no, int lun_no)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct burn_drive out;
|
||||||
|
|
||||||
|
/* General libburn drive setup */
|
||||||
|
burn_setup_drive(&out, fname);
|
||||||
|
|
||||||
|
/* This transport adapter uses SCSI-family commands and models
|
||||||
|
(seems the adapter would know better than its boss, if ever) */
|
||||||
|
ret = burn_scsi_setup_drive(&out, bus_no, host_no, channel_no,
|
||||||
|
target_no, lun_no, 0);
|
||||||
|
if (ret<=0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Operating system adapter is CAM */
|
||||||
|
/* Adapter specific handles and data */
|
||||||
|
out.cam = NULL;
|
||||||
|
/* Adapter specific functions */
|
||||||
|
out.grab = sg_grab;
|
||||||
|
out.release = sg_release;
|
||||||
|
out.drive_is_open = sg_drive_is_open;
|
||||||
|
out.issue_command = sg_issue_command;
|
||||||
|
|
||||||
|
/* Finally register drive and inquire drive information */
|
||||||
|
burn_drive_finish_enum(&out);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ! Scsi_freebsd_make_own_enumeratE */
|
||||||
|
|
||||||
|
/* ts A61021: do not believe this:
|
||||||
we use the sg reference count to decide whether we can use the
|
we use the sg reference count to decide whether we can use the
|
||||||
drive or not.
|
drive or not.
|
||||||
if refcount is not one, drive is open somewhere else.
|
if refcount is not one, drive is open somewhere else.
|
||||||
@ -305,6 +582,7 @@ int sg_grab(struct burn_drive *d)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
non zero return means you still have the drive and it's not
|
non zero return means you still have the drive and it's not
|
||||||
in a state to be released? (is that even possible?)
|
in a state to be released? (is that even possible?)
|
||||||
|
@ -100,6 +100,15 @@ int sg_close_drive_fd(char *fname, int driveno, int *fd, int sorry)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sg_drive_is_open(struct burn_drive * d)
|
||||||
|
{
|
||||||
|
/* a bit more detailed case distinction than needed */
|
||||||
|
if (d->fd == -1337)
|
||||||
|
return 0;
|
||||||
|
if (d->fd < 0)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* ts A60924 */
|
/* ts A60924 */
|
||||||
int sg_handle_busy_device(char *fname, int os_errno)
|
int sg_handle_busy_device(char *fname, int os_errno)
|
||||||
@ -420,94 +429,37 @@ void sg_enumerate(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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 */
|
||||||
static void enumerate_common(char *fname, int bus_no, int host_no,
|
static void enumerate_common(char *fname, 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 i;
|
int ret, i;
|
||||||
struct burn_drive *t;
|
|
||||||
struct burn_drive out;
|
struct burn_drive out;
|
||||||
|
|
||||||
/* ts A60923 */
|
/* General libburn drive setup */
|
||||||
out.bus_no = bus_no;
|
burn_setup_drive(&out, fname);
|
||||||
out.host = host_no;
|
|
||||||
out.id = target_no;
|
|
||||||
out.channel = channel_no;
|
|
||||||
out.lun = lun_no;
|
|
||||||
|
|
||||||
out.devname = burn_strdup(fname);
|
/* This transport adapter uses SCSI-family commands and models
|
||||||
|
(seems the adapter would know better than its boss, if ever) */
|
||||||
|
ret = burn_scsi_setup_drive(&out, bus_no, host_no, channel_no,
|
||||||
|
target_no, lun_no, 0);
|
||||||
|
if (ret<=0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Operating system adapter is Linux Generic SCSI (sg) */
|
||||||
|
/* Adapter specific handles and data */
|
||||||
out.fd = -1337;
|
out.fd = -1337;
|
||||||
out.sibling_count = 0;
|
out.sibling_count = 0;
|
||||||
for(i= 0; i<LIBBURN_SG_MAX_SIBLINGS; i++)
|
for(i= 0; i<LIBBURN_SG_MAX_SIBLINGS; i++)
|
||||||
out.sibling_fds[i] = -1337;
|
out.sibling_fds[i] = -1337;
|
||||||
|
/* Adapter specific functions */
|
||||||
/* ts A61020 */
|
|
||||||
out.start_lba= -2000000000;
|
|
||||||
out.end_lba= -2000000000;
|
|
||||||
out.read_atip = mmc_read_atip;
|
|
||||||
|
|
||||||
out.grab = sg_grab;
|
out.grab = sg_grab;
|
||||||
out.release = sg_release;
|
out.release = sg_release;
|
||||||
|
out.drive_is_open= sg_drive_is_open;
|
||||||
out.issue_command = sg_issue_command;
|
out.issue_command = sg_issue_command;
|
||||||
out.getcaps = spc_getcaps;
|
|
||||||
out.released = 1;
|
|
||||||
out.status = BURN_DISC_UNREADY;
|
|
||||||
|
|
||||||
out.eject = sbc_eject;
|
|
||||||
out.load = sbc_load;
|
|
||||||
out.lock = spc_prevent;
|
|
||||||
out.unlock = spc_allow;
|
|
||||||
out.read_disc_info = spc_sense_write_params;
|
|
||||||
out.get_erase_progress = spc_get_erase_progress;
|
|
||||||
out.test_unit_ready = spc_test_unit_ready;
|
|
||||||
out.probe_write_modes = spc_probe_write_modes;
|
|
||||||
out.read_toc = mmc_read_toc;
|
|
||||||
out.write = mmc_write;
|
|
||||||
out.erase = mmc_erase;
|
|
||||||
out.read_sectors = mmc_read_sectors;
|
|
||||||
out.perform_opc = mmc_perform_opc;
|
|
||||||
out.set_speed = mmc_set_speed;
|
|
||||||
out.send_parameters = spc_select_error_params;
|
|
||||||
out.send_write_parameters = spc_select_write_params;
|
|
||||||
out.send_cue_sheet = mmc_send_cue_sheet;
|
|
||||||
out.sync_cache = mmc_sync_cache;
|
|
||||||
out.get_nwa = mmc_get_nwa;
|
|
||||||
out.close_disc = mmc_close_disc;
|
|
||||||
out.close_session = mmc_close_session;
|
|
||||||
out.idata = malloc(sizeof(struct burn_scsi_inquiry_data));
|
|
||||||
out.idata->valid = 0;
|
|
||||||
out.mdata = malloc(sizeof(struct scsi_mode_data));
|
|
||||||
out.mdata->valid = 0;
|
|
||||||
|
|
||||||
/* ts A61007 : obsolete Assert in drive_getcaps() */
|
|
||||||
if(out.idata == NULL || out.mdata == NULL) {
|
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020108,
|
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Could not allocate new drive object", 0, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&out.params, 0, sizeof(struct params));
|
|
||||||
t = burn_drive_register(&out);
|
|
||||||
|
|
||||||
/* ts A60821
|
|
||||||
<<< debug: for tracing calls which might use open drive fds */
|
|
||||||
mmc_function_spy("enumerate_common : -------- doing grab");
|
|
||||||
|
|
||||||
/* try to get the drive info */
|
|
||||||
if (sg_grab(t)) {
|
|
||||||
burn_print(2, "getting drive info\n");
|
|
||||||
t->getcaps(t);
|
|
||||||
t->unlock(t);
|
|
||||||
t->released = 1;
|
|
||||||
} else {
|
|
||||||
burn_print(2, "unable to grab new located drive\n");
|
|
||||||
burn_drive_unregister(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ts A60821
|
|
||||||
<<< debug: for tracing calls which might use open drive fds */
|
|
||||||
mmc_function_spy("enumerate_common : ----- would release ");
|
|
||||||
|
|
||||||
|
/* Finally register drive and inquire drive information */
|
||||||
|
burn_drive_finish_enum(&out);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -9,7 +9,16 @@
|
|||||||
which are now local in sg_enumerate() . So that sg_give_next_adr()
|
which are now local in sg_enumerate() . So that sg_give_next_adr()
|
||||||
can work in BSD and sg_enumerate() can use it. */
|
can work in BSD and sg_enumerate() can use it. */
|
||||||
struct burn_drive_enumeration_state {
|
struct burn_drive_enumeration_state {
|
||||||
|
|
||||||
|
#ifdef Scsi_freebsd_old_sg_enumeratE
|
||||||
int dummy;
|
int dummy;
|
||||||
|
#else
|
||||||
|
union ccb ccb;
|
||||||
|
int bufsize, fd;
|
||||||
|
unsigned int i;
|
||||||
|
int skip_device;
|
||||||
|
#endif /* ! Scsi_freebsd_old_sg_enumeratE */
|
||||||
|
|
||||||
};
|
};
|
||||||
typedef struct burn_drive_enumeration_state burn_drive_enumerator_t;
|
typedef struct burn_drive_enumeration_state burn_drive_enumerator_t;
|
||||||
|
|
||||||
|
@ -23,6 +23,10 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
|
||||||
|
#include "libdax_msgs.h"
|
||||||
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
|
||||||
|
|
||||||
/* spc command set */
|
/* spc command set */
|
||||||
static unsigned char SPC_INQUIRY[] = { 0x12, 0, 0, 0, 255, 0 };
|
static unsigned char SPC_INQUIRY[] = { 0x12, 0, 0, 0, 255, 0 };
|
||||||
|
|
||||||
@ -433,3 +437,61 @@ int spc_block_type(enum burn_block_types b)
|
|||||||
/* ts A61007 : already prevented in burn_write_opts_set_write_type() */
|
/* ts A61007 : already prevented in burn_write_opts_set_write_type() */
|
||||||
/* a ssert(0); */;
|
/* a ssert(0); */;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ts A61021 : the spc specific part of sg.c:enumerate_common()
|
||||||
|
*/
|
||||||
|
int spc_setup_drive(struct burn_drive *d)
|
||||||
|
{
|
||||||
|
d->getcaps = spc_getcaps;
|
||||||
|
d->lock = spc_prevent;
|
||||||
|
d->unlock = spc_allow;
|
||||||
|
d->read_disc_info = spc_sense_write_params;
|
||||||
|
d->get_erase_progress = spc_get_erase_progress;
|
||||||
|
d->test_unit_ready = spc_test_unit_ready;
|
||||||
|
d->probe_write_modes = spc_probe_write_modes;
|
||||||
|
d->send_parameters = spc_select_error_params;
|
||||||
|
d->send_write_parameters = spc_select_write_params;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A61021 : the general SCSI specific part of sg.c:enumerate_common()
|
||||||
|
@param flag Bitfiled for control purposes
|
||||||
|
bit0= do not setup spc/sbc/mmc
|
||||||
|
*/
|
||||||
|
int burn_scsi_setup_drive(struct burn_drive *d, int bus_no, int host_no,
|
||||||
|
int channel_no, int target_no, int lun_no, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* ts A60923 */
|
||||||
|
d->bus_no = bus_no;
|
||||||
|
d->host = host_no;
|
||||||
|
d->id = target_no;
|
||||||
|
d->channel = channel_no;
|
||||||
|
d->lun = lun_no;
|
||||||
|
|
||||||
|
d->idata = malloc(sizeof(struct burn_scsi_inquiry_data));
|
||||||
|
d->idata->valid = 0;
|
||||||
|
d->mdata = malloc(sizeof(struct scsi_mode_data));
|
||||||
|
d->mdata->valid = 0;
|
||||||
|
|
||||||
|
/* ts A61007 : obsolete Assert in drive_getcaps() */
|
||||||
|
if(d->idata == NULL || d->mdata == NULL) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020108,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Could not allocate new drive object", 0, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(!(flag & 1)) {
|
||||||
|
ret = spc_setup_drive(d);
|
||||||
|
if (ret<=0)
|
||||||
|
return ret;
|
||||||
|
ret = sbc_setup_drive(d);
|
||||||
|
if (ret<=0)
|
||||||
|
return ret;
|
||||||
|
ret = mmc_setup_drive(d);
|
||||||
|
if (ret<=0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@ -22,4 +22,16 @@ int spc_block_type(enum burn_block_types b);
|
|||||||
int spc_get_erase_progress(struct burn_drive *d);
|
int spc_get_erase_progress(struct burn_drive *d);
|
||||||
int spc_test_unit_ready(struct burn_drive *d);
|
int spc_test_unit_ready(struct burn_drive *d);
|
||||||
|
|
||||||
|
/* ts A61021 : the spc specific part of sg.c:enumerate_common()
|
||||||
|
*/
|
||||||
|
int spc_setup_drive(struct burn_drive *d);
|
||||||
|
|
||||||
|
/* ts A61021 : the general SCSI specific part of sg.c:enumerate_common()
|
||||||
|
@param flag Bitfield for control purposes
|
||||||
|
bit0= do not setup spc/sbc/mmc
|
||||||
|
*/
|
||||||
|
int burn_scsi_setup_drive(struct burn_drive *d, int bus_no, int host_no,
|
||||||
|
int channel_no, int target_no, int lun_no, int flag);
|
||||||
|
|
||||||
|
|
||||||
#endif /*__SPC*/
|
#endif /*__SPC*/
|
||||||
|
@ -145,6 +145,10 @@ struct burn_drive
|
|||||||
/* transport functions */
|
/* transport functions */
|
||||||
int (*grab) (struct burn_drive *);
|
int (*grab) (struct burn_drive *);
|
||||||
int (*release) (struct burn_drive *);
|
int (*release) (struct burn_drive *);
|
||||||
|
|
||||||
|
/* ts A61021 */
|
||||||
|
int (*drive_is_open) (struct burn_drive *);
|
||||||
|
|
||||||
int (*issue_command) (struct burn_drive *, struct command *);
|
int (*issue_command) (struct burn_drive *, struct command *);
|
||||||
|
|
||||||
/* lower level functions */
|
/* lower level functions */
|
||||||
|
Loading…
Reference in New Issue
Block a user