1 /***************************************************************************
4 * Saturday February 16, 2008
5 * Copyright 2008 Joe Marcus Clarke
7 ****************************************************************************/
10 * Copyright (C) Joe Marcus Clarke 2008 <marcus@FreeBSD.org>
12 * Libbrasero-media is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * The Libbrasero-media authors hereby grant permission for non-GPL compatible
18 * GStreamer plugins to be used and distributed together with GStreamer
19 * and Libbrasero-media. This permission is above and beyond the permissions granted
20 * by the GPL license by which Libbrasero-media is covered. If you modify this code
21 * you may extend this exception to your version of the code, but you are not
22 * obligated to do so. If you do not wish to do so, delete this exception
23 * statement from your version.
25 * Libbrasero-media is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU Library General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to:
32 * The Free Software Foundation, Inc.,
33 * 51 Franklin Street, Fifth Floor
34 * Boston, MA 02110-1301, USA.
44 #include <sys/types.h>
48 #include <sys/ioctl.h>
52 #include "brasero-media-private.h"
53 #include "scsi-command.h"
54 #include "scsi-utils.h"
55 #include "scsi-error.h"
56 #include "scsi-sense-data.h"
58 /* FreeBSD's SCSI CAM interface */
61 #include <cam/scsi/scsi_message.h>
63 struct _BraseroDeviceHandle
{
64 struct cam_device
*cam
;
68 struct _BraseroScsiCmd
{
69 uchar cmd
[BRASERO_SCSI_CMD_MAX_LEN
];
70 BraseroDeviceHandle
*handle
;
72 const BraseroScsiCmdInfo
*info
;
74 typedef struct _BraseroScsiCmd BraseroScsiCmd
;
76 #define BRASERO_SCSI_CMD_OPCODE_OFF 0
77 #define BRASERO_SCSI_CMD_SET_OPCODE(command) (command->cmd [BRASERO_SCSI_CMD_OPCODE_OFF] = command->info->opcode)
79 #define OPEN_FLAGS O_RDONLY /*|O_EXCL */|O_NONBLOCK
82 brasero_scsi_command_issue_sync (gpointer command
,
85 BraseroScsiErrCode
*error
)
94 memset (&cam_ccb
, 0, sizeof(cam_ccb
));
97 cam_ccb
.ccb_h
.path_id
= cmd
->handle
->cam
->path_id
;
98 cam_ccb
.ccb_h
.target_id
= cmd
->handle
->cam
->target_id
;
99 cam_ccb
.ccb_h
.target_lun
= cmd
->handle
->cam
->target_lun
;
101 if (cmd
->info
->direction
& BRASERO_SCSI_READ
)
102 direction
= CAM_DIR_IN
;
103 else if (cmd
->info
->direction
& BRASERO_SCSI_WRITE
)
104 direction
= CAM_DIR_OUT
;
106 g_assert (direction
> -1);
108 cam_fill_csio(&cam_ccb
.csio
,
115 sizeof(cam_ccb
.csio
.sense_data
),
119 memcpy (cam_ccb
.csio
.cdb_io
.cdb_bytes
, cmd
->cmd
,
120 BRASERO_SCSI_CMD_MAX_LEN
);
122 if (cam_send_ccb (cmd
->handle
->cam
, &cam_ccb
) == -1) {
123 BRASERO_SCSI_SET_ERRCODE (error
, BRASERO_SCSI_ERRNO
);
124 return BRASERO_SCSI_FAILURE
;
127 if ((cam_ccb
.ccb_h
.status
& CAM_STATUS_MASK
) != CAM_REQ_CMP
) {
128 BRASERO_SCSI_SET_ERRCODE (error
, BRASERO_SCSI_ERRNO
);
129 return BRASERO_SCSI_FAILURE
;
132 return BRASERO_SCSI_OK
;
136 brasero_scsi_command_new (const BraseroScsiCmdInfo
*info
,
137 BraseroDeviceHandle
*handle
)
141 /* make sure we can set the flags of the descriptor */
143 /* allocate the command */
144 cmd
= g_new0 (BraseroScsiCmd
, 1);
146 cmd
->handle
= handle
;
148 BRASERO_SCSI_CMD_SET_OPCODE (cmd
);
153 brasero_scsi_command_free (gpointer cmd
)
156 return BRASERO_SCSI_OK
;
160 * This is to open a device
163 BraseroDeviceHandle
*
164 brasero_device_handle_open (const gchar
*path
,
166 BraseroScsiErrCode
*code
)
169 int flags
= OPEN_FLAGS
;
170 BraseroDeviceHandle
*handle
;
171 struct cam_device
*cam
;
173 g_assert (path
!= NULL
);
178 /* cam_open_device() fails unless we use O_RDWR */
179 cam
= cam_open_device (path
, O_RDWR
);
180 fd
= open (path
, flags
);
181 if (cam
&& fd
> -1) {
182 handle
= g_new0 (BraseroDeviceHandle
, 1);
191 || errno
== EWOULDBLOCK
193 *code
= BRASERO_SCSI_NOT_READY
;
195 *code
= BRASERO_SCSI_ERRNO
;
203 cam_close_device (cam
);
214 brasero_device_handle_close (BraseroDeviceHandle
*handle
)
216 g_assert (handle
!= NULL
);
219 cam_close_device (handle
->cam
);
227 brasero_device_get_bus_target_lun (const gchar
*device
)
229 struct cam_device
*cam_dev
;
232 cam_dev
= cam_open_device (device
, O_RDWR
);
234 if (cam_dev
== NULL
) {
235 BRASERO_MEDIA_LOG ("CAM: Failed to open %s: %s", device
, g_strerror (errno
));
239 addr
= g_strdup_printf ("%i,%i,%i", cam_dev
->path_id
, cam_dev
->target_id
, cam_dev
->target_lun
);
241 cam_close_device (cam_dev
);