1
/***************************************************************************
4
* Wed Oct 18 14:39:28 2006
5
* Copyright 2006 Rouquier Philippe
6
* <Rouquier Philippe@localhost.localdomain>
7
****************************************************************************/
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU Library General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA
32
#include <sys/types.h>
36
#include <sys/ioctl.h>
38
#include <scsi/scsi.h>
41
#include "scsi-command.h"
42
#include "burn-debug.h"
43
#include "scsi-utils.h"
44
#include "scsi-error.h"
45
#include "scsi-sense-data.h"
47
struct _BraseroDeviceHandle {
51
struct _BraseroScsiCmd {
52
uchar cmd [BRASERO_SCSI_CMD_MAX_LEN];
53
BraseroDeviceHandle *handle;
55
const BraseroScsiCmdInfo *info;
57
typedef struct _BraseroScsiCmd BraseroScsiCmd;
59
#define BRASERO_SCSI_CMD_OPCODE_OFF 0
60
#define BRASERO_SCSI_CMD_SET_OPCODE(command) (command->cmd [BRASERO_SCSI_CMD_OPCODE_OFF] = command->info->opcode)
62
#define OPEN_FLAGS O_RDONLY /*|O_EXCL */|O_NONBLOCK
65
* This is to send a command
69
brasero_sg_command_setup (struct sg_io_hdr *transport,
75
memset (sense_data, 0, BRASERO_SENSE_DATA_SIZE);
76
memset (transport, 0, sizeof (struct sg_io_hdr));
78
transport->interface_id = 'S'; /* mandatory */
79
// transport->flags = SG_FLAG_LUN_INHIBIT|SG_FLAG_DIRECT_IO;
80
transport->cmdp = cmd->cmd;
81
transport->cmd_len = cmd->info->size;
82
transport->dxferp = buffer;
83
transport->dxfer_len = size;
85
/* where to output the scsi sense buffer */
86
transport->sbp = sense_data;
87
transport->mx_sb_len = BRASERO_SENSE_DATA_SIZE;
89
if (cmd->info->direction & BRASERO_SCSI_READ)
90
transport->dxfer_direction = SG_DXFER_FROM_DEV;
91
else if (cmd->info->direction & BRASERO_SCSI_WRITE)
92
transport->dxfer_direction = SG_DXFER_TO_DEV;
96
brasero_scsi_command_issue_sync (gpointer command,
99
BraseroScsiErrCode *error)
101
uchar sense_buffer [BRASERO_SENSE_DATA_SIZE];
102
struct sg_io_hdr transport;
103
BraseroScsiResult res;
107
brasero_sg_command_setup (&transport,
113
/* NOTE on SG_IO: only for TEST UNIT READY, REQUEST/MODE SENSE, INQUIRY,
114
* READ CAPACITY, READ BUFFER, READ and LOG SENSE are allowed with it */
115
res = ioctl (cmd->handle->fd, SG_IO, &transport);
117
BRASERO_SCSI_SET_ERRCODE (error, BRASERO_SCSI_ERRNO);
118
return BRASERO_SCSI_FAILURE;
121
if ((transport.info & SG_INFO_OK_MASK) == SG_INFO_OK)
122
return BRASERO_SCSI_OK;
124
if ((transport.masked_status & CHECK_CONDITION) && transport.sb_len_wr)
125
return brasero_sense_data_process (sense_buffer, error);
127
return BRASERO_SCSI_FAILURE;
131
brasero_scsi_command_new (const BraseroScsiCmdInfo *info,
132
BraseroDeviceHandle *handle)
136
/* make sure we can set the flags of the descriptor */
138
/* allocate the command */
139
cmd = g_new0 (BraseroScsiCmd, 1);
141
cmd->handle = handle;
143
BRASERO_SCSI_CMD_SET_OPCODE (cmd);
148
brasero_scsi_command_free (gpointer cmd)
151
return BRASERO_SCSI_OK;
155
* This is to open a device
158
BraseroDeviceHandle *
159
brasero_device_handle_open (const gchar *path,
160
BraseroScsiErrCode *code)
163
BraseroDeviceHandle *handle;
165
fd = open (path, OPEN_FLAGS);
168
|| errno == EWOULDBLOCK
170
*code = BRASERO_SCSI_NOT_READY;
172
*code = BRASERO_SCSI_ERRNO;
177
handle = g_new (BraseroDeviceHandle, 1);
184
brasero_device_handle_close (BraseroDeviceHandle *handle)