2006-10-30 05:32:33 +00:00
|
|
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
|
|
|
|
|
|
|
/* scsi block commands */
|
|
|
|
|
|
|
|
#include <string.h>
|
2007-03-15 19:50:57 +00:00
|
|
|
#include <unistd.h>
|
2006-10-30 05:32:33 +00:00
|
|
|
|
|
|
|
#include "transport.h"
|
|
|
|
#include "sbc.h"
|
2007-03-15 19:50:57 +00:00
|
|
|
#include "spc.h"
|
2006-10-30 05:32:33 +00:00
|
|
|
#include "options.h"
|
|
|
|
|
2007-09-12 10:45:34 +00:00
|
|
|
|
|
|
|
/* ts A70910
|
|
|
|
debug: for tracing calls which might use open drive fds
|
|
|
|
or for catching SCSI usage of emulated drives. */
|
|
|
|
int mmc_function_spy(struct burn_drive *d, char * text);
|
|
|
|
|
|
|
|
|
2006-10-30 05:32:33 +00:00
|
|
|
/* spc command set */
|
2007-05-21 18:57:09 +00:00
|
|
|
static unsigned char SBC_LOAD[] = { 0x1b, 0, 0, 0, 3, 0 };
|
|
|
|
static unsigned char SBC_UNLOAD[] = { 0x1b, 0, 0, 0, 2, 0 };
|
|
|
|
static unsigned char SBC_START_UNIT[] = { 0x1b, 0, 0, 0, 1, 0 };
|
2006-10-30 05:32:33 +00:00
|
|
|
|
|
|
|
void sbc_load(struct burn_drive *d)
|
|
|
|
{
|
|
|
|
struct command c;
|
|
|
|
|
2007-09-12 10:45:34 +00:00
|
|
|
if (mmc_function_spy(d, "load") <= 0)
|
|
|
|
return;
|
|
|
|
|
2007-05-21 18:57:09 +00:00
|
|
|
scsi_init_command(&c, SBC_LOAD, sizeof(SBC_LOAD));
|
|
|
|
/*
|
2006-10-30 05:32:33 +00:00
|
|
|
memcpy(c.opcode, SBC_LOAD, sizeof(SBC_LOAD));
|
|
|
|
c.oplen = sizeof(SBC_LOAD);
|
|
|
|
c.page = NULL;
|
2007-05-21 18:57:09 +00:00
|
|
|
*/
|
|
|
|
c.retry = 1;
|
|
|
|
c.dir = NO_TRANSFER;
|
2006-10-30 05:32:33 +00:00
|
|
|
d->issue_command(d, &c);
|
2007-03-15 19:50:57 +00:00
|
|
|
spc_wait_unit_attention(d, 60);
|
2006-10-30 05:32:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void sbc_eject(struct burn_drive *d)
|
|
|
|
{
|
|
|
|
struct command c;
|
|
|
|
|
2007-09-12 10:45:34 +00:00
|
|
|
if (mmc_function_spy(d, "eject") <= 0)
|
|
|
|
return;
|
|
|
|
|
2007-05-21 18:57:09 +00:00
|
|
|
scsi_init_command(&c, SBC_UNLOAD, sizeof(SBC_UNLOAD));
|
|
|
|
/*
|
2006-10-30 05:32:33 +00:00
|
|
|
memcpy(c.opcode, SBC_UNLOAD, sizeof(SBC_UNLOAD));
|
|
|
|
c.oplen = sizeof(SBC_UNLOAD);
|
|
|
|
c.page = NULL;
|
2007-05-21 18:57:09 +00:00
|
|
|
*/
|
|
|
|
c.page = NULL;
|
2006-10-30 05:32:33 +00:00
|
|
|
c.dir = NO_TRANSFER;
|
|
|
|
d->issue_command(d, &c);
|
|
|
|
}
|
|
|
|
|
2006-11-18 19:49:18 +00:00
|
|
|
/* ts A61118 : is it necessary to tell the drive to get ready for use ? */
|
|
|
|
int sbc_start_unit(struct burn_drive *d)
|
|
|
|
{
|
|
|
|
struct command c;
|
|
|
|
|
2007-09-12 10:45:34 +00:00
|
|
|
if (mmc_function_spy(d, "start_unit") <= 0)
|
|
|
|
return 0;
|
|
|
|
|
2007-05-21 18:57:09 +00:00
|
|
|
scsi_init_command(&c, SBC_START_UNIT, sizeof(SBC_START_UNIT));
|
|
|
|
/*
|
2006-11-18 19:49:18 +00:00
|
|
|
memcpy(c.opcode, SBC_START_UNIT, sizeof(SBC_START_UNIT));
|
|
|
|
c.oplen = sizeof(SBC_START_UNIT);
|
|
|
|
c.page = NULL;
|
2007-05-21 18:57:09 +00:00
|
|
|
*/
|
|
|
|
c.retry = 1;
|
|
|
|
c.dir = NO_TRANSFER;
|
2006-11-18 19:49:18 +00:00
|
|
|
d->issue_command(d, &c);
|
|
|
|
return (c.error==0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-30 05:32:33 +00:00
|
|
|
/* 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;
|
2006-11-18 19:49:18 +00:00
|
|
|
d->start_unit = sbc_start_unit;
|
2006-10-30 05:32:33 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|