1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
4 * Copyright (C) Philippe Rouquier 2005-2009 <bonfire-app@wanadoo.fr>
6 * Libbrasero-media is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * The Libbrasero-media authors hereby grant permission for non-GPL compatible
12 * GStreamer plugins to be used and distributed together with GStreamer
13 * and Libbrasero-media. This permission is above and beyond the permissions granted
14 * by the GPL license by which Libbrasero-media is covered. If you modify this code
15 * you may extend this exception to your version of the code, but you are not
16 * obligated to do so. If you do not wish to do so, delete this exception
17 * statement from your version.
19 * Libbrasero-media is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to:
26 * The Free Software Foundation, Inc.,
27 * 51 Franklin Street, Fifth Floor
28 * Boston, MA 02110-1301, USA.
38 #include <sys/types.h>
42 #include <sys/ioctl.h>
44 #include <scsi/scsi.h>
47 #include "brasero-media-private.h"
49 #include "scsi-command.h"
50 #include "scsi-utils.h"
51 #include "scsi-error.h"
52 #include "scsi-sense-data.h"
54 struct _BraseroDeviceHandle
{
58 struct _BraseroScsiCmd
{
59 uchar cmd
[BRASERO_SCSI_CMD_MAX_LEN
];
60 BraseroDeviceHandle
*handle
;
62 const BraseroScsiCmdInfo
*info
;
64 typedef struct _BraseroScsiCmd BraseroScsiCmd
;
66 #define BRASERO_SCSI_CMD_OPCODE_OFF 0
67 #define BRASERO_SCSI_CMD_SET_OPCODE(command) (command->cmd [BRASERO_SCSI_CMD_OPCODE_OFF] = command->info->opcode)
69 #define OPEN_FLAGS O_RDWR /*|O_EXCL */|O_NONBLOCK
72 * This is to send a command
76 brasero_sg_command_setup (struct sg_io_hdr
*transport
,
82 memset (sense_data
, 0, BRASERO_SENSE_DATA_SIZE
);
83 memset (transport
, 0, sizeof (struct sg_io_hdr
));
85 transport
->interface_id
= 'S'; /* mandatory */
86 // transport->flags = SG_FLAG_LUN_INHIBIT|SG_FLAG_DIRECT_IO;
87 transport
->cmdp
= cmd
->cmd
;
88 transport
->cmd_len
= cmd
->info
->size
;
89 transport
->dxferp
= buffer
;
90 transport
->dxfer_len
= size
;
92 /* where to output the scsi sense buffer */
93 transport
->sbp
= sense_data
;
94 transport
->mx_sb_len
= BRASERO_SENSE_DATA_SIZE
;
96 if (cmd
->info
->direction
& BRASERO_SCSI_READ
)
97 transport
->dxfer_direction
= SG_DXFER_FROM_DEV
;
98 else if (cmd
->info
->direction
& BRASERO_SCSI_WRITE
)
99 transport
->dxfer_direction
= SG_DXFER_TO_DEV
;
103 brasero_scsi_command_issue_sync (gpointer command
,
106 BraseroScsiErrCode
*error
)
108 uchar sense_buffer
[BRASERO_SENSE_DATA_SIZE
];
109 struct sg_io_hdr transport
;
110 BraseroScsiResult res
;
113 g_return_val_if_fail (command
!= NULL
, BRASERO_SCSI_FAILURE
);
116 brasero_sg_command_setup (&transport
,
122 /* NOTE on SG_IO: only for TEST UNIT READY, REQUEST/MODE SENSE, INQUIRY,
123 * READ CAPACITY, READ BUFFER, READ and LOG SENSE are allowed with it */
124 res
= ioctl (cmd
->handle
->fd
, SG_IO
, &transport
);
126 BRASERO_SCSI_SET_ERRCODE (error
, BRASERO_SCSI_ERRNO
);
127 return BRASERO_SCSI_FAILURE
;
130 if ((transport
.info
& SG_INFO_OK_MASK
) == SG_INFO_OK
)
131 return BRASERO_SCSI_OK
;
133 if ((transport
.masked_status
& CHECK_CONDITION
) && transport
.sb_len_wr
)
134 return brasero_sense_data_process (sense_buffer
, error
);
136 return BRASERO_SCSI_FAILURE
;
140 brasero_scsi_command_new (const BraseroScsiCmdInfo
*info
,
141 BraseroDeviceHandle
*handle
)
145 g_return_val_if_fail (handle
!= NULL
, NULL
);
147 /* make sure we can set the flags of the descriptor */
149 /* allocate the command */
150 cmd
= g_new0 (BraseroScsiCmd
, 1);
152 cmd
->handle
= handle
;
154 BRASERO_SCSI_CMD_SET_OPCODE (cmd
);
159 brasero_scsi_command_free (gpointer cmd
)
162 return BRASERO_SCSI_OK
;
166 * This is to open a device
169 BraseroDeviceHandle
*
170 brasero_device_handle_open (const gchar
*path
,
172 BraseroScsiErrCode
*code
)
175 int flags
= OPEN_FLAGS
;
176 BraseroDeviceHandle
*handle
;
181 BRASERO_MEDIA_LOG ("Getting handle");
182 fd
= open (path
, flags
);
184 BRASERO_MEDIA_LOG ("No handle: %s", strerror (errno
));
187 || errno
== EWOULDBLOCK
189 *code
= BRASERO_SCSI_NOT_READY
;
191 *code
= BRASERO_SCSI_ERRNO
;
197 handle
= g_new (BraseroDeviceHandle
, 1);
200 BRASERO_MEDIA_LOG ("Handle ready");
205 brasero_device_handle_close (BraseroDeviceHandle
*handle
)
212 brasero_device_get_bus_target_lun (const gchar
*device
)
214 return strdup (device
);