Adjusted libcdio system adapter to FreeBSD peculiarities

This commit is contained in:
Thomas Schmitt 2010-03-29 10:33:05 +00:00
parent e6029ae238
commit fafc190fd4
5 changed files with 65 additions and 22 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2010.03.27.172644" #define Cdrskin_timestamP "2010.03.29.103141"

View File

@ -755,7 +755,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; int done = 0, err, sense_len = 0, ret, ignore_error, no_retry = 0;
int cam_pass_err_recover = 0; int cam_pass_err_recover = 0;
union ccb *ccb; union ccb *ccb;
char buf[161]; char buf[161];
@ -874,9 +874,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
fprintf(stderr, "libburn_EXPERIMENTAL: errno = %d . cam_errbuf = '%s'\n", errno, cam_errbuf); fprintf(stderr, "libburn_EXPERIMENTAL: errno = %d . cam_errbuf = '%s'\n", errno, cam_errbuf);
#endif #endif
if (errno == ENXIO) { if (errno == ENXIO && c->opcode[0] != 0) {
/* Operations on empty or ejected tray */ /* Operations on empty or ejected tray */
/* Inquiries while tray is being loaded */
/* MEDIUM NOT PRESENT */ /* MEDIUM NOT PRESENT */
#ifdef Libburn_ahci_verbouS #ifdef Libburn_ahci_verbouS
@ -888,8 +887,10 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
c->sense[13] = 0x00; c->sense[13] = 0x00;
sense_len = 14; sense_len = 14;
ignore_error = 1; ignore_error = 1;
} else if (c->opcode[0] == 0 && errno == EBUSY) { } else if (c->opcode[0] == 0 &&
(errno == EBUSY || errno == ENXIO)) {
/* Timeout of TEST UNIT READY loop */ /* Timeout of TEST UNIT READY loop */
/* Inquiries while tray is being loaded */
/*LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE*/ /*LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE*/
#ifdef Libburn_ahci_verbouS #ifdef Libburn_ahci_verbouS
@ -942,14 +943,22 @@ 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;
} }
if (!c->retry) { if (no_retry || ignore_error || !c->retry) {
c->error = 1; c->error = 1;
{ret = 1; goto ex;} {ret = 1; goto ex;}
} }
switch (scsi_error(d, c->sense, 0)) { switch (scsi_error(d, c->sense, 0)) {
case RETRY: case RETRY:
done = 0; done = 0;
if (burn_sg_log_scsi & 3) {
/* >>> Need own duration time
measurement. Then remove bit1 */
scsi_log_err(c, fp, c->sense, 0,
(c->error != 0) | 2);
scsi_log_cmd(c,fp,0);
}
break; break;
case FAIL: case FAIL:
done = 1; done = 1;

View File

@ -553,7 +553,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, usleep_time, timeout_ms; int sense_valid = 0, i, usleep_time, timeout_ms, no_retry = 0;
time_t start_time; time_t start_time;
driver_return_code_t i_status; driver_return_code_t i_status;
unsigned int dxfer_len; unsigned int dxfer_len;
@ -568,15 +568,15 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
return 0; return 0;
} }
p_cdio = (CdIo_t *) d->p_cdio; p_cdio = (CdIo_t *) d->p_cdio;
if (burn_sg_log_scsi & 1) { if (burn_sg_log_scsi & 1) {
if (fp == NULL) { if (fp == NULL) {
fp= fopen("/tmp/libburn_sg_command_log", "a"); fp= fopen("/tmp/libburn_sg_command_log", "a");
fprintf(fp, fprintf(fp,
"\n-----------------------------------------\n"); "\n-----------------------------------------\n");
} }
} }
if (burn_sg_log_scsi & 3) if (burn_sg_log_scsi & 3)
scsi_log_cmd(c,fp,0); scsi_log_cmd(c,fp,0);
memcpy(cdb.field, c->opcode, c->oplen); memcpy(cdb.field, c->opcode, c->oplen);
if (c->dir == TO_DRIVE) { if (c->dir == TO_DRIVE) {
@ -628,24 +628,35 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
} }
*/ */
if (!sense_valid) { if ((!sense_valid) ||
((c->sense[2] & 0x0f) == 0 && c->sense[12] == 0 &&
c->sense[13] == 0)) {
memset(c->sense, 0, sizeof(c->sense)); memset(c->sense, 0, sizeof(c->sense));
if (i_status != 0) { /* set dummy sense */ if (i_status != 0) { /* set dummy sense */
/*LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE*/ /*LOGICAL UNIT NOT READY,
CAUSE NOT REPORTABLE*/
c->sense[2] = 0x02; c->sense[2] = 0x02;
c->sense[12] = 0x04; c->sense[12] = 0x04;
no_retry = 1;
} }
} else } else
c->sense[2] &= 15; c->sense[2] &= 15;
if (i_status != 0 || if (i_status != 0 ||
(c->sense[2] || c->sense[12] || c->sense[13])) { (c->sense[2] || c->sense[12] || c->sense[13])) {
if (!c->retry) { if (no_retry || !c->retry) {
c->error = 1; c->error = 1;
goto ex; goto ex;
} }
switch (scsi_error(d, c->sense, 18)) { switch (scsi_error(d, c->sense, 18)) {
case RETRY: case RETRY:
if (burn_sg_log_scsi & 3) {
/* >>> Need own duration time
measurement. Then remove bit1 */
scsi_log_err(c, fp, c->sense, 0,
(c->error != 0) | 2);
scsi_log_cmd(c,fp,0);
}
break; break;
case FAIL: case FAIL:
c->error = 1; c->error = 1;

View File

@ -1928,6 +1928,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
switch (scsi_error(d, s.sbp, s.sb_len_wr)) { switch (scsi_error(d, s.sbp, s.sb_len_wr)) {
case RETRY: case RETRY:
done = 0; done = 0;
if (burn_sg_log_scsi & 3)
scsi_log_cmd(c,fp,0);
break; break;
case FAIL: case FAIL:
done = 1; done = 1;

View File

@ -113,7 +113,8 @@ int spc_test_unit_ready(struct burn_drive *d)
int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text, 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; int i, ret = 1, key = 0, asc = 0, ascq = 0, clueless_start = 0;
static int clueless_timeout = 5 * 10;
char msg[320]; char msg[320];
unsigned char sense[14]; unsigned char sense[14];
enum response resp; enum response resp;
@ -143,6 +144,7 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
/* media change notice = try again */ /* media change notice = try again */
goto slumber; goto slumber;
handle_error:;
/* ts A90213 */ /* ts A90213 */
sprintf(msg, sprintf(msg,
"Asynchronous SCSI error on %s: ", cmd_text); "Asynchronous SCSI error on %s: ", cmd_text);
@ -157,7 +159,23 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
msg, 0, 0); msg, 0, 0);
d->cancel = 1; d->cancel = 1;
break; break;
} } else if (ascq == 0x00) { /* CAUSE NOT REPORTABLE */
/* Might be a clueless system adapter */
if (clueless_start == 0)
clueless_start = i;
if (i - clueless_start > clueless_timeout) {
libdax_msgs_submit(libdax_messenger,
d->global_index,
0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
"Ended clueless NOT READY cycle",
0, 0);
ret = 1; /* medium not present = ok */
break;
}
} else if (ascq == 0x02 || ascq == 0x03)
goto handle_error;
slumber:; slumber:;
usleep(100000); usleep(100000);
} }
@ -982,8 +1000,11 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
sprintf(msg, "Not ready"); sprintf(msg, "Not ready");
return RETRY; return RETRY;
case 0x04: case 0x04:
sprintf(msg, if (*ascq == 1)
sprintf(msg,
"Logical unit is in the process of becoming ready"); "Logical unit is in the process of becoming ready");
else
sprintf(msg, "Logical unit is not ready");
return RETRY; return RETRY;
case 0x08: case 0x08:
if (*key != 4) if (*key != 4)