Replaced some large local variables by other means in libburn/spc.c

This commit is contained in:
Thomas Schmitt 2011-06-06 17:31:36 +00:00
parent 27997067c9
commit 5f743b8030
2 changed files with 281 additions and 233 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2011.06.06.105052" #define Cdrskin_timestamP "2011.06.06.173021"

View File

@ -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.
*/ */
@ -32,6 +32,7 @@
#include "drive.h" #include "drive.h"
#include "debug.h" #include "debug.h"
#include "options.h" #include "options.h"
#include "init.h"
#include "libdax_msgs.h" #include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger; extern struct libdax_msgs *libdax_messenger;
@ -101,26 +102,25 @@ int spc_decode_sense(unsigned char *sense, int senselen,
int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq) int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq)
{ {
struct command c; struct command *c = NULL;
int ret;
if (mmc_function_spy(d, "test_unit_ready") <= 0) if (mmc_function_spy(d, "test_unit_ready") <= 0)
return 0; {ret = 0; goto ex;}
scsi_init_command(&c, SPC_TEST_UNIT_READY,sizeof(SPC_TEST_UNIT_READY)); BURN_ALLOC_MEM(c, struct command, 1);
c.retry = 0; scsi_init_command(c, SPC_TEST_UNIT_READY,sizeof(SPC_TEST_UNIT_READY));
c.dir = NO_TRANSFER; c->retry = 0;
d->issue_command(d, &c); c->dir = NO_TRANSFER;
if (c.error) { d->issue_command(d, c);
if (c->error) {
/* spc_decode_sense(c->sense, 0, key, asc, ascq);
fprintf(stderr, "sense[0 - 2] = %2.2X %2.2X %2.2X", {ret = (key == 0); goto ex;}
c.sense[0], c.sense[1], c.sense[2]);
*/
spc_decode_sense(c.sense, 0, key, asc, ascq);
return (key == 0);
} }
return 1; ret = 1;
ex:;
BURN_FREE_MEM(c);
return ret;
} }
@ -142,10 +142,11 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
{ {
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 int clueless_timeout = 5 * 10;
char msg[320]; char *msg = NULL;
unsigned char sense[14]; unsigned char sense[14];
enum response resp; enum response resp;
BURN_ALLOC_MEM(msg, char, 320);
if (!(flag & 1)) if (!(flag & 1))
usleep(100000); usleep(100000);
for(i = !(flag & 1); i < max_sec * 10; i++) { for(i = !(flag & 1); i < max_sec * 10; i++) {
@ -217,119 +218,133 @@ slumber:;
} }
if (i < max_sec * 10) if (i < max_sec * 10)
return (ret > 0); {ret = (ret > 0); goto ex;}
sprintf(msg, "Timeout (%d s) with asynchronous SCSI command %s\n", sprintf(msg, "Timeout (%d s) with asynchronous SCSI command %s\n",
max_sec, cmd_text); max_sec, cmd_text);
libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002014f, libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002014f,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
return 0; ret = 0;
ex:;
BURN_FREE_MEM(msg);
return ret;
} }
void spc_request_sense(struct burn_drive *d, struct buffer *buf) void spc_request_sense(struct burn_drive *d, struct buffer *buf)
{ {
struct command c; struct command *c = NULL;
int ret;
if (mmc_function_spy(d, "request_sense") <= 0) if (mmc_function_spy(d, "request_sense") <= 0)
return; goto ex;
scsi_init_command(&c, SPC_REQUEST_SENSE, sizeof(SPC_REQUEST_SENSE)); BURN_ALLOC_MEM(c, struct command, 1);
c.retry = 0; scsi_init_command(c, SPC_REQUEST_SENSE, sizeof(SPC_REQUEST_SENSE));
/* c->retry = 0;
c.oplen = sizeof(SPC_REQUEST_SENSE); c->dxfer_len= c->opcode[4];
memcpy(c.opcode, SPC_REQUEST_SENSE, sizeof(SPC_REQUEST_SENSE)); c->retry = 0;
*/ c->page = buf;
c.dxfer_len= c.opcode[4]; c->page->sectors = 0;
c.retry = 0; c->page->bytes = 0;
c.page = buf; c->dir = FROM_DRIVE;
c.page->sectors = 0; d->issue_command(d, c);
c.page->bytes = 0; ex:;
c.dir = FROM_DRIVE; BURN_FREE_MEM(c);
d->issue_command(d, &c);
} }
int spc_get_erase_progress(struct burn_drive *d) int spc_get_erase_progress(struct burn_drive *d)
{ {
struct buffer b; struct buffer *b = NULL;
int ret;
if (mmc_function_spy(d, "get_erase_progress") <= 0) if (mmc_function_spy(d, "get_erase_progress") <= 0)
return 0; {ret = 0; goto ex;}
spc_request_sense(d, &b); BURN_ALLOC_MEM(b, struct buffer, 1);
return (b.data[16] << 8) | b.data[17]; spc_request_sense(d, b);
ret = (b->data[16] << 8) | b->data[17];
ex:;
BURN_FREE_MEM(b);
return ret;
} }
void spc_inquiry(struct burn_drive *d) void spc_inquiry(struct burn_drive *d)
{ {
struct buffer buf; struct buffer *buf = NULL;
struct burn_scsi_inquiry_data *id; struct burn_scsi_inquiry_data *id;
struct command c; struct command *c = NULL;
int ret;
if (mmc_function_spy(d, "inquiry") <= 0) if (mmc_function_spy(d, "inquiry") <= 0)
return; return;
scsi_init_command(&c, SPC_INQUIRY, sizeof(SPC_INQUIRY)); BURN_ALLOC_MEM(buf, struct buffer, 1);
/* BURN_ALLOC_MEM(c, struct command, 1);
memcpy(c.opcode, SPC_INQUIRY, sizeof(SPC_INQUIRY)); scsi_init_command(c, SPC_INQUIRY, sizeof(SPC_INQUIRY));
c.oplen = sizeof(SPC_INQUIRY); c->dxfer_len = (c->opcode[3] << 8) | c->opcode[4];
*/ c->retry = 1;
c.dxfer_len = (c.opcode[3] << 8) | c.opcode[4]; c->page = buf;
c.retry = 1; c->page->bytes = 0;
c.page = &buf; c->page->sectors = 0;
c.page->bytes = 0; c->dir = FROM_DRIVE;
c.page->sectors = 0; d->issue_command(d, c);
c.dir = FROM_DRIVE;
d->issue_command(d, &c);
id = (struct burn_scsi_inquiry_data *)d->idata; id = (struct burn_scsi_inquiry_data *)d->idata;
memset(id->vendor, 0, 9); memset(id->vendor, 0, 9);
memset(id->product, 0, 17); memset(id->product, 0, 17);
memset(id->revision, 0, 5); memset(id->revision, 0, 5);
if (c.error) { if (c->error) {
id->valid = -1; id->valid = -1;
return; goto ex;
} }
memcpy(id->vendor, c.page->data + 8, 8); memcpy(id->vendor, c->page->data + 8, 8);
memcpy(id->product, c.page->data + 16, 16); memcpy(id->product, c->page->data + 16, 16);
memcpy(id->revision, c.page->data + 32, 4); memcpy(id->revision, c->page->data + 32, 4);
id->valid = 1; id->valid = 1;
ex:;
BURN_FREE_MEM(buf);
BURN_FREE_MEM(c);
return; return;
} }
void spc_prevent(struct burn_drive *d) void spc_prevent(struct burn_drive *d)
{ {
struct command c; struct command *c = NULL;
int ret;
if (mmc_function_spy(d, "prevent") <= 0) if (mmc_function_spy(d, "prevent") <= 0)
return; return;
BURN_ALLOC_MEM(c, struct command, 1);
scsi_init_command(c, SPC_PREVENT, sizeof(SPC_PREVENT));
c->retry = 1;
c->dir = NO_TRANSFER;
d->issue_command(d, c);
scsi_init_command(&c, SPC_PREVENT, sizeof(SPC_PREVENT));
c.retry = 1;
c.dir = NO_TRANSFER;
d->issue_command(d, &c);
#ifdef Libburn_pioneer_dvr_216d_get_evenT #ifdef Libburn_pioneer_dvr_216d_get_evenT
mmc_get_event(d); mmc_get_event(d);
#endif #endif
ex:;
BURN_FREE_MEM(c);
} }
void spc_allow(struct burn_drive *d) void spc_allow(struct burn_drive *d)
{ {
struct command c; struct command *c = NULL;
int ret;
if (mmc_function_spy(d, "allow") <= 0) if (mmc_function_spy(d, "allow") <= 0)
return; goto ex;
scsi_init_command(&c, SPC_ALLOW, sizeof(SPC_ALLOW)); BURN_ALLOC_MEM(c, struct command, 1);
/* scsi_init_command(c, SPC_ALLOW, sizeof(SPC_ALLOW));
memcpy(c.opcode, SPC_ALLOW, sizeof(SPC_ALLOW)); c->retry = 1;
c.oplen = sizeof(SPC_ALLOW); c->dir = NO_TRANSFER;
c.page = NULL; d->issue_command(d, c);
*/ ex:;
c.retry = 1; BURN_FREE_MEM(c);
c.dir = NO_TRANSFER;
d->issue_command(d, &c);
} }
/* /*
@ -338,50 +353,54 @@ ts A70518 - A90603 : Do not call with *alloc_len < 10
/** flag&1= do only inquire alloc_len */ /** flag&1= do only inquire alloc_len */
static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag) static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
{ {
struct buffer buf; 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 size, page_length, num_write_speeds = 0, i, speed, ret;
int old_alloc_len, was_error = 0; int old_alloc_len, was_error = 0;
unsigned char *page; unsigned char *page;
struct command c; struct command *c = NULL;
struct burn_speed_descriptor *sd; struct burn_speed_descriptor *sd;
char msg[BURN_DRIVE_ADR_LEN + 160]; char *msg = NULL;
/* ts A61225 : 1 = report about post-MMC-1 speed descriptors */ /* ts A61225 : 1 = report about post-MMC-1 speed descriptors */
static int speed_debug = 0; static int speed_debug = 0;
if (*alloc_len < 10) if (*alloc_len < 10)
return 0; {ret = 0; goto ex;}
BURN_ALLOC_MEM(msg, char, BURN_DRIVE_ADR_LEN + 160);
BURN_ALLOC_MEM(buf, struct buffer, 1);
BURN_ALLOC_MEM(c, struct command, 1);
/* ts A90602 : Clearing mdata before command execution */ /* ts A90602 : Clearing mdata before command execution */
m = d->mdata; m = d->mdata;
m->valid = 0; m->valid = 0;
burn_mdata_free_subs(m); burn_mdata_free_subs(m);
memset(&buf, 0, sizeof(buf)); 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)); memcpy(c->opcode, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
c.oplen = 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;
c.retry = 1; c->retry = 1;
c.opcode[2] = 0x2A; c->opcode[2] = 0x2A;
c.page = &buf; c->page = buf;
c.page->bytes = 0; c->page->bytes = 0;
c.page->sectors = 0; c->page->sectors = 0;
c.dir = FROM_DRIVE; c->dir = FROM_DRIVE;
d->issue_command(d, &c); d->issue_command(d, c);
if (c.error) { if (c->error) {
memset(&buf, 0, sizeof(buf)); memset(buf, 0, sizeof(struct buffer));
m->valid = -1; m->valid = -1;
was_error = 1; was_error = 1;
} }
size = c.page->data[0] * 256 + c.page->data[1] + 2; size = c->page->data[0] * 256 + c->page->data[1] + 2;
page = c.page->data + 8; page = c->page->data + 8;
/* 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
@ -397,7 +416,7 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
old_alloc_len = *alloc_len; old_alloc_len = *alloc_len;
*alloc_len = page_length + 10; *alloc_len = page_length + 10;
if (flag & 1) if (flag & 1)
return !was_error; {ret = !was_error; goto ex;}
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;
@ -409,7 +428,7 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
libdax_msgs_submit(libdax_messenger, d->global_index, libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002016e, LIBDAX_MSGS_SEV_DEBUG, 0x0002016e, LIBDAX_MSGS_SEV_DEBUG,
LIBDAX_MSGS_PRIO_LOW, msg, 0, 0); LIBDAX_MSGS_PRIO_LOW, msg, 0, 0);
return 0; {ret = 0; goto ex;}
} }
m->buffer_size = page[12] * 256 + page[13]; m->buffer_size = page[12] * 256 + page[13];
@ -460,14 +479,12 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
m->max_write_speed = m->min_write_speed = m->cur_write_speed; m->max_write_speed = m->min_write_speed = m->cur_write_speed;
if (32 + 4 * num_write_speeds > page_length + 2) { if (32 + 4 * num_write_speeds > page_length + 2) {
char msg[161];
sprintf(msg, "Malformed capabilities page 2Ah received (len=%d, #speeds=%d)", page_length, num_write_speeds); sprintf(msg, "Malformed capabilities page 2Ah received (len=%d, #speeds=%d)", page_length, num_write_speeds);
libdax_msgs_submit(libdax_messenger, d->global_index, libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002013c, 0x0002013c,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0); msg, 0, 0);
return 0; {ret = 0; goto ex;}
} }
for (i = 0; i < num_write_speeds; i++) { for (i = 0; i < num_write_speeds; i++) {
@ -523,7 +540,12 @@ try_mmc_get_performance:;
m->min_write_speed, m->max_write_speed); m->min_write_speed, m->max_write_speed);
} }
return !was_error; ret = !was_error;
ex:
BURN_FREE_MEM(msg);
BURN_FREE_MEM(buf);
BURN_FREE_MEM(c);
return ret;
} }
@ -550,117 +572,119 @@ void spc_sense_caps(struct burn_drive *d)
void spc_sense_error_params(struct burn_drive *d) void spc_sense_error_params(struct burn_drive *d)
{ {
struct buffer buf; struct buffer *buf = NULL;
struct scsi_mode_data *m; struct scsi_mode_data *m;
int size, alloc_len = 12 ; int size, alloc_len = 12 ;
unsigned char *page; unsigned char *page;
struct command c; 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)
return; goto ex;
scsi_init_command(&c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE)); BURN_ALLOC_MEM(buf, struct buffer, 1);
/* BURN_ALLOC_MEM(c, struct command, 1);
memcpy(c.opcode, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
c.oplen = sizeof(SPC_MODE_SENSE);
*/
c.dxfer_len = alloc_len;
c.opcode[7] = (c.dxfer_len >> 8) & 0xff;
c.opcode[8] = c.dxfer_len & 0xff;
c.retry = 1;
c.opcode[2] = 0x01;
c.page = &buf;
c.page->bytes = 0;
c.page->sectors = 0;
c.dir = FROM_DRIVE;
d->issue_command(d, &c);
size = c.page->data[0] * 256 + c.page->data[1] + 2; scsi_init_command(c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
c->dxfer_len = alloc_len;
c->opcode[7] = (c->dxfer_len >> 8) & 0xff;
c->opcode[8] = c->dxfer_len & 0xff;
c->retry = 1;
c->opcode[2] = 0x01;
c->page = buf;
c->page->bytes = 0;
c->page->sectors = 0;
c->dir = FROM_DRIVE;
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];
m->retry_page_length = page[1]; m->retry_page_length = page[1];
m->retry_page_valid = 1; m->retry_page_valid = 1;
ex:;
BURN_FREE_MEM(buf);
BURN_FREE_MEM(c);
} }
void spc_select_error_params(struct burn_drive *d, void spc_select_error_params(struct burn_drive *d,
const struct burn_read_opts *o) const struct burn_read_opts *o)
{ {
struct buffer buf; struct buffer *buf = NULL;
struct command c; 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)
return; goto ex;
scsi_init_command(&c, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT)); BURN_ALLOC_MEM(buf, struct buffer, 1);
/* BURN_ALLOC_MEM(c, struct command, 1);
memcpy(c.opcode, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
c.oplen = sizeof(SPC_MODE_SELECT);
*/
c.retry = 1;
c.opcode[8] = 8 + 2 + d->mdata->retry_page_length;
c.page = &buf;
c.page->bytes = 0;
c.page->sectors = 0;
/* ts A61007 : moved up to only caller burn_disc_read() */ scsi_init_command(c, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
/* a ssert(d->mdata->valid); */ c->retry = 1;
c->opcode[8] = 8 + 2 + d->mdata->retry_page_length;
c->page = buf;
c->page->bytes = 0;
c->page->sectors = 0;
memset(c.page->data, 0, 8 + 2 + d->mdata->retry_page_length); memset(c->page->data, 0, 8 + 2 + d->mdata->retry_page_length);
c.page->bytes = 8 + 2 + d->mdata->retry_page_length; c->page->bytes = 8 + 2 + d->mdata->retry_page_length;
c.page->data[8] = 1; c->page->data[8] = 1;
c.page->data[9] = d->mdata->retry_page_length; c->page->data[9] = d->mdata->retry_page_length;
if (o->transfer_damaged_blocks) if (o->transfer_damaged_blocks)
c.page->data[10] |= 32; c->page->data[10] |= 32;
if (o->report_recovered_errors) if (o->report_recovered_errors)
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]);*/ /*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);
ex:;
BURN_FREE_MEM(buf);
BURN_FREE_MEM(c);
} }
void spc_sense_write_params(struct burn_drive *d) void spc_sense_write_params(struct burn_drive *d)
{ {
struct buffer buf; struct buffer *buf = NULL;
struct scsi_mode_data *m; struct scsi_mode_data *m;
int size, dummy, alloc_len = 10; int size, dummy, alloc_len = 10, ret;
unsigned char *page; unsigned char *page;
struct command c; struct command *c = NULL;
mmc_start_if_needed(d, 1); mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "sense_write_params") <= 0) if (mmc_function_spy(d, "sense_write_params") <= 0)
return; goto ex;
BURN_ALLOC_MEM(buf, struct buffer, 1);
BURN_ALLOC_MEM(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 ||
d->mdata->dvdr_write || d->mdata->dvdram_write); */ d->mdata->dvdr_write || d->mdata->dvdram_write); */
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;
memcpy(c.opcode, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE)); c->opcode[7] = (c->dxfer_len >> 8) & 0xff;
c.oplen = sizeof(SPC_MODE_SENSE); c->opcode[8] = c->dxfer_len & 0xff;
*/ c->retry = 1;
c.dxfer_len = alloc_len; c->opcode[2] = 0x05;
c.opcode[7] = (c.dxfer_len >> 8) & 0xff; c->page = buf;
c.opcode[8] = c.dxfer_len & 0xff; c->page->bytes = 0;
c.retry = 1; c->page->sectors = 0;
c.opcode[2] = 0x05; c->dir = FROM_DRIVE;
c.page = &buf; d->issue_command(d, c);
c.page->bytes = 0;
c.page->sectors = 0;
c.dir = FROM_DRIVE;
d->issue_command(d, &c);
/* 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; 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]); 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;
@ -683,6 +707,9 @@ void spc_sense_write_params(struct burn_drive *d)
(double) d->media_capacity_remaining); (double) d->media_capacity_remaining);
*/ */
ex:;
BURN_FREE_MEM(buf);
BURN_FREE_MEM(c);
} }
@ -694,13 +721,16 @@ Thus the filling of the mode page is done by mmc_compose_mode_page_5().
void spc_select_write_params(struct burn_drive *d, void spc_select_write_params(struct burn_drive *d,
const struct burn_write_opts *o) const struct burn_write_opts *o)
{ {
struct buffer buf; struct buffer *buf = NULL;
struct command c; struct command *c = NULL;
int alloc_len; int alloc_len, ret;
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)
return; goto ex;
BURN_ALLOC_MEM(buf, struct buffer, 1);
BURN_ALLOC_MEM(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); */
@ -713,50 +743,50 @@ void spc_select_write_params(struct burn_drive *d,
*/ */
alloc_len = 8 + 2 + d->mdata->write_page_length; alloc_len = 8 + 2 + d->mdata->write_page_length;
memset(&(buf.data), 0, alloc_len); memset(&(buf->data), 0, alloc_len);
#ifdef Libburn_pioneer_dvr_216d_load_mode5 #ifdef Libburn_pioneer_dvr_216d_load_mode5
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;
c.opcode[7] = (alloc_len >> 8) & 0xff; c->opcode[7] = (alloc_len >> 8) & 0xff;
c.opcode[8] = alloc_len & 0xff; c->opcode[8] = alloc_len & 0xff;
c.retry = 1; c->retry = 1;
c.opcode[2] = 0x05; c->opcode[2] = 0x05;
c.page = &buf; c->page = buf;
c.page->bytes = 0; c->page->bytes = 0;
c.page->sectors = 0; c->page->sectors = 0;
c.dir = FROM_DRIVE; c->dir = FROM_DRIVE;
d->issue_command(d, &c); d->issue_command(d, c);
if (c.error) if (c->error)
memset(&(buf.data), 0, memset(&(buf->data), 0,
8 + 2 + d->mdata->write_page_length); 8 + 2 + d->mdata->write_page_length);
#endif /* Libburn_pioneer_dvr_216d_load_mode5 */ #endif /* Libburn_pioneer_dvr_216d_load_mode5 */
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;
c.opcode[7] = (alloc_len >> 8) & 0xff; c->opcode[7] = (alloc_len >> 8) & 0xff;
c.opcode[8] = alloc_len & 0xff; c->opcode[8] = alloc_len & 0xff;
c.page = &buf; c->page = buf;
c.page->bytes = 0; c->page->bytes = 0;
c.page->sectors = 0; c->page->sectors = 0;
/* ts A61007 : moved up to burn_disc_write() */ c->page->bytes = alloc_len;
/* a ssert(d->mdata->valid); */
c.page->bytes = alloc_len;
burn_print(12, "using write page length %d (valid %d)\n", burn_print(12, "using write page length %d (valid %d)\n",
d->mdata->write_page_length, d->mdata->write_page_valid); 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)
return; goto ex;
c.dir = TO_DRIVE; c->dir = TO_DRIVE;
d->issue_command(d, &c); d->issue_command(d, c);
ex:;
BURN_FREE_MEM(buf);
BURN_FREE_MEM(c);
} }
void spc_getcaps(struct burn_drive *d) void spc_getcaps(struct burn_drive *d)
@ -776,16 +806,19 @@ some drives say they're ok, and they're not.
void spc_probe_write_modes(struct burn_drive *d) void spc_probe_write_modes(struct burn_drive *d)
{ {
struct buffer buf; struct buffer *buf = NULL;
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; int last_try = 0, ret;
struct command c; 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)
return; goto ex;
BURN_ALLOC_MEM(buf, struct buffer, 1);
BURN_ALLOC_MEM(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) {
@ -802,33 +835,33 @@ void spc_probe_write_modes(struct burn_drive *d)
last_try= 1; last_try= 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;
c.opcode[8] = 8 + 2 + 0x32; c->opcode[8] = 8 + 2 + 0x32;
c.page = &buf; c->page = buf;
memset(c.page->data, 0, 8 + 2 + 0x32); memset(c->page->data, 0, 8 + 2 + 0x32);
c.page->bytes = 8 + 2 + 0x32; c->page->bytes = 8 + 2 + 0x32;
c.page->data[8] = 5; c->page->data[8] = 5;
c.page->data[9] = 0x32; c->page->data[9] = 0x32;
c.page->data[10] = try_write_type; c->page->data[10] = try_write_type;
if (try_block_type > 4) if (try_block_type > 4)
c.page->data[11] = 4; c->page->data[11] = 4;
else else
c.page->data[11] = 0; c->page->data[11] = 0;
c.page->data[12] = try_block_type; c->page->data[12] = try_block_type;
c.page->data[23] = 150; c->page->data[23] = 150;
c.dir = TO_DRIVE; c->dir = TO_DRIVE;
d->silent_on_scsi_error = 1; d->silent_on_scsi_error = 1;
d->issue_command(d, &c); d->issue_command(d, c);
d->silent_on_scsi_error = 0; d->silent_on_scsi_error = 0;
if (last_try) if (last_try)
break; break;
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); burn_print(7, "%d not supported\n", try_block_type);
else { else {
@ -871,10 +904,12 @@ void spc_probe_write_modes(struct burn_drive *d)
try_write_type++; try_write_type++;
break; break;
default: default:
return; goto ex;
} }
} }
ex:;
BURN_FREE_MEM(buf);
BURN_FREE_MEM(c);
} }
/* ( ts A61229 : shouldn't this go to mmc.c too ?) */ /* ( ts A61229 : shouldn't this go to mmc.c too ?) */
@ -1232,6 +1267,10 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
else if (*ascq == 2) else if (*ascq == 2)
sprintf(msg, "Timeout on logical unit"); sprintf(msg, "Timeout on logical unit");
return FAIL; return FAIL;
case 0x44:
if (*ascq == 0)
sprintf(msg, "Internal target failure");
return FAIL;
case 0x57: case 0x57:
if (*key != 3 || *ascq != 0) if (*key != 3 || *ascq != 0)
break; break;
@ -1300,15 +1339,20 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
enum response scsi_error(struct burn_drive *d, unsigned char *sense, enum response scsi_error(struct burn_drive *d, unsigned char *sense,
int senselen) int senselen)
{ {
int key, asc, ascq; int key, asc, ascq, ret = 0;
char msg[160]; char *msg = NULL;
enum response resp; enum response resp;
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) if (asc == 0 || asc == 0x3A)
burn_print(12, "%s\n", msg); burn_print(12, "%s\n", msg);
else else
burn_print(1, "%s\n", msg); burn_print(1, "%s\n", msg);
ex:;
if (ret == -1)
resp = FAIL;
BURN_FREE_MEM(msg);
return resp; return resp;
} }
@ -1387,22 +1431,24 @@ int scsi_notify_error(struct burn_drive *d, struct command *c,
unsigned char *sense, int senselen, int flag) unsigned char *sense, int senselen, int flag)
{ {
int key= -1, asc= -1, ascq= -1, ret; int key= -1, asc= -1, ascq= -1, ret;
char msg[320],scsi_msg[160]; char *msg = NULL, *scsi_msg = NULL;
if (d->silent_on_scsi_error) if (d->silent_on_scsi_error)
return 1; {ret = 1; goto ex;}
BURN_ALLOC_MEM(msg, char, 320);
BURN_ALLOC_MEM(scsi_msg, char, 160);
scsi_error_msg(d, sense, senselen, scsi_msg, &key, &asc, &ascq); scsi_error_msg(d, sense, senselen, scsi_msg, &key, &asc, &ascq);
if (!(flag & 1)) { if (!(flag & 1)) {
/* SPC : TEST UNIT READY command */ /* SPC : TEST UNIT READY command */
if (c->opcode[0] == 0) if (c->opcode[0] == 0)
return 1; {ret = 1; goto ex;}
/* MMC : READ DISC INFORMATION command */ /* MMC : READ DISC INFORMATION command */
if (c->opcode[0] == 0x51) if (c->opcode[0] == 0x51)
if (key == 0x2 && asc == 0x3A && if (key == 0x2 && asc == 0x3A &&
ascq>=0 && ascq <= 0x02) /* MEDIUM NOT PRESENT */ ascq>=0 && ascq <= 0x02) /* MEDIUM NOT PRESENT */
return 1; {ret = 1; goto ex;}
} }
sprintf(msg, "SCSI error condition on command %2.2Xh %s: ", sprintf(msg, "SCSI error condition on command %2.2Xh %s: ",
@ -1411,7 +1457,9 @@ int scsi_notify_error(struct burn_drive *d, struct command *c,
strcat(msg, scsi_msg); strcat(msg, scsi_msg);
ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f, ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0); LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0);
ex:;
BURN_FREE_MEM(msg);
BURN_FREE_MEM(scsi_msg);
return ret; return ret;
} }