[brasero] Reworked and hopefully enhanced drive and medium probing code.
- From: Philippe Rouquier <philippr src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [brasero] Reworked and hopefully enhanced drive and medium probing code.
- Date: Wed, 9 Sep 2009 20:20:40 +0000 (UTC)
commit ad3f8527ec926706f0d03247579895aec119bf18
Author: Philippe Rouquier <bonfire-app wanadoo fr>
Date: Wed Sep 9 16:08:26 2009 +0200
Reworked and hopefully enhanced drive and medium probing code.
Use a mutex when probing drive
Don't rely any more on GIO when checking whether a medium is inside
libbrasero-media/brasero-drive.c | 464 +++++++++++++++++++----------
libbrasero-media/brasero-medium.c | 16 +-
libbrasero-media/scsi-error.c | 4 +
libbrasero-media/scsi-error.h | 1 +
libbrasero-media/scsi-get-configuration.h | 1 +
libbrasero-media/scsi-sense-data.c | 6 +
6 files changed, 339 insertions(+), 153 deletions(-)
---
diff --git a/libbrasero-media/brasero-drive.c b/libbrasero-media/brasero-drive.c
index 4a6a37d..08ab4e7 100644
--- a/libbrasero-media/brasero-drive.c
+++ b/libbrasero-media/brasero-drive.c
@@ -70,6 +70,8 @@ struct _BraseroDrivePrivate
GDrive *gdrive;
GThread *probe;
+ GMutex *mutex;
+ GCond *cond;
gint probe_id;
BraseroMedium *medium;
@@ -85,6 +87,7 @@ struct _BraseroDrivePrivate
GCancellable *cancel;
guint probed:1;
+ guint has_medium:1;
guint probe_cancelled:1;
};
@@ -225,7 +228,7 @@ brasero_drive_eject (BraseroDrive *drive,
return TRUE;
}
else
- BRASERO_BURN_LOG ("No GDrive");
+ BRASERO_MEDIA_LOG ("No GDrive");
if (!priv->medium)
return FALSE;
@@ -712,15 +715,6 @@ brasero_drive_can_write (BraseroDrive *drive)
}
static void
-brasero_drive_init (BraseroDrive *object)
-{
- BraseroDrivePrivate *priv;
-
- priv = BRASERO_DRIVE_PRIVATE (object);
- priv->cancel = g_cancellable_new ();
-}
-
-static void
brasero_drive_medium_probed (BraseroMedium *medium,
BraseroDrive *self)
{
@@ -731,6 +725,13 @@ brasero_drive_medium_probed (BraseroMedium *medium,
/* only when it is probed */
/* NOTE: BraseroMedium calls GDK_THREADS_ENTER/LEAVE() around g_signal_emit () */
priv->probed = TRUE;
+
+ if (brasero_medium_get_status (priv->medium) == BRASERO_MEDIUM_NONE) {
+ g_object_unref (priv->medium);
+ priv->medium = NULL;
+ return;
+ }
+
g_signal_emit (self,
drive_signals [MEDIUM_INSERTED],
0,
@@ -752,75 +753,25 @@ brasero_drive_probing (BraseroDrive *drive)
return priv->probed != TRUE;
}
-/**
- * brasero_drive_reprobe:
- * @drive: a #BraseroDrive
- *
- * Reprobes the drive contents. Useful when an operation has just been performed
- * (blanking, burning, ...) and medium status should be updated.
- *
- * NOTE: This operation does not block.
- *
- **/
-
-void
-brasero_drive_reprobe (BraseroDrive *drive)
-{
- BraseroDrivePrivate *priv;
- BraseroMedium *medium;
-
- g_return_if_fail (drive != NULL);
- g_return_if_fail (BRASERO_IS_DRIVE (drive));
-
- priv = BRASERO_DRIVE_PRIVATE (drive);
-
- if (priv->gdrive) {
- /* reprobe the contents of the drive system wide */
- g_drive_poll_for_media (priv->gdrive, NULL, NULL, NULL);
- }
-
- if (!priv->medium)
- return;
-
- BRASERO_MEDIA_LOG ("Reprobing inserted medium");
-
- /* remove current medium */
- medium = priv->medium;
- priv->medium = NULL;
-
- g_signal_emit (drive,
- drive_signals [MEDIUM_REMOVED],
- 0,
- medium);
- g_object_unref (medium);
- priv->probed = FALSE;
-
- /* try to get a new one */
- priv->medium = g_object_new (BRASERO_TYPE_VOLUME,
- "drive", drive,
- NULL);
- g_signal_connect (priv->medium,
- "probed",
- G_CALLBACK (brasero_drive_medium_probed),
- drive);
-}
-
-static void
-brasero_drive_check_medium_inside_gdrive (BraseroDrive *self)
+static gboolean
+brasero_drive_probed_inside (gpointer data)
{
+ BraseroDrive *self;
BraseroDrivePrivate *priv;
+ self = BRASERO_DRIVE (data);
priv = BRASERO_DRIVE_PRIVATE (self);
- BRASERO_MEDIA_LOG ("Contents changed %i", g_drive_has_media (priv->gdrive));
+ g_mutex_lock (priv->mutex);
+ priv->probe_id = 0;
+ g_mutex_unlock (priv->mutex);
- if (g_drive_has_media (priv->gdrive)) {
+ if (priv->has_medium) {
if (priv->medium)
- return;
+ return FALSE;
BRASERO_MEDIA_LOG ("Medium inserted");
- priv->probed = FALSE;
priv->medium = g_object_new (BRASERO_TYPE_VOLUME,
"drive", self,
NULL);
@@ -842,35 +793,211 @@ brasero_drive_check_medium_inside_gdrive (BraseroDrive *self)
drive_signals [MEDIUM_REMOVED],
0,
medium);
+
g_object_unref (medium);
priv->probed = TRUE;
}
else
priv->probed = TRUE;
+
+ return FALSE;
+}
+
+static gpointer
+brasero_drive_probe_inside_thread (gpointer data)
+{
+ gint counter = 0;
+ const gchar *device;
+ BraseroScsiErrCode code;
+ BraseroDrivePrivate *priv;
+ BraseroDeviceHandle *handle;
+ BraseroDrive *drive = BRASERO_DRIVE (data);
+
+ priv = BRASERO_DRIVE_PRIVATE (drive);
+
+ /* the drive might be busy (a burning is going on) so we don't block
+ * but we re-try to open it every second */
+ device = brasero_drive_get_device (drive);
+ BRASERO_MEDIA_LOG ("Trying to open device %s", device);
+
+ handle = brasero_device_handle_open (device, FALSE, &code);
+ while (!handle && counter <= BRASERO_DRIVE_OPEN_ATTEMPTS) {
+ sleep (1);
+
+ if (priv->probe_cancelled) {
+ BRASERO_MEDIA_LOG ("Open () cancelled");
+ goto end;
+ }
+
+ counter ++;
+ handle = brasero_device_handle_open (device, FALSE, &code);
+ }
+
+ if (priv->probe_cancelled) {
+ BRASERO_MEDIA_LOG ("Open () cancelled");
+ goto end;
+ }
+
+ if (!handle) {
+ BRASERO_MEDIA_LOG ("Open () failed: medium busy");
+ goto end;
+ }
+
+ while (brasero_spc1_test_unit_ready (handle, &code) != BRASERO_SCSI_OK) {
+ if (code == BRASERO_SCSI_NO_MEDIUM) {
+ BRASERO_MEDIA_LOG ("No medium inserted");
+
+ priv->has_medium = FALSE;
+ goto end;
+ }
+
+ if (code != BRASERO_SCSI_NOT_READY) {
+ brasero_device_handle_close (handle);
+ BRASERO_MEDIA_LOG ("Device does not respond");
+ goto end;
+ }
+
+ sleep (2);
+
+ if (priv->probe_cancelled) {
+ brasero_device_handle_close (handle);
+ BRASERO_MEDIA_LOG ("Device probing cancelled");
+ goto end;
+ }
+ }
+
+ BRASERO_MEDIA_LOG ("Medium inserted");
+ brasero_device_handle_close (handle);
+
+ priv->has_medium = TRUE;
+
+end:
+
+ g_mutex_lock (priv->mutex);
+
+ if (!priv->probe_cancelled)
+ priv->probe_id = g_idle_add (brasero_drive_probed_inside, drive);
+
+ priv->probe = NULL;
+ g_cond_broadcast (priv->cond);
+ g_mutex_unlock (priv->mutex);
+
+ g_thread_exit (0);
+
+ return NULL;
+}
+
+static void
+brasero_drive_probe_inside (BraseroDrive *drive)
+{
+ BraseroDrivePrivate *priv;
+
+ priv = BRASERO_DRIVE_PRIVATE (drive);
+
+ priv->probed = FALSE;
+
+ /* Check that a probe is not already being performed */
+ g_mutex_lock (priv->mutex);
+ if (!priv->probe) {
+ BRASERO_MEDIA_LOG ("Setting new probe");
+
+ if (priv->probe_id) {
+ /* Remove the result reporting as
+ * the status seem to have changed */
+ g_source_remove (priv->probe_id);
+ priv->probe_id = 0;
+ }
+
+ priv->probe = g_thread_create (brasero_drive_probe_inside_thread,
+ drive,
+ FALSE,
+ NULL);
+ }
+ else
+ BRASERO_MEDIA_LOG ("Ongoing probe");
+ g_mutex_unlock (priv->mutex);
}
static void
brasero_drive_medium_gdrive_changed_cb (BraseroDrive *gdrive,
BraseroDrive *drive)
{
- brasero_drive_check_medium_inside_gdrive (drive);
+ brasero_drive_probe_inside (drive);
}
static void
-brasero_drive_update_gdrive (BraseroDrive *drive)
+brasero_drive_update_gdrive (BraseroDrive *drive,
+ GDrive *gdrive)
{
BraseroDrivePrivate *priv;
priv = BRASERO_DRIVE_PRIVATE (drive);
+ if (priv->gdrive) {
+ g_signal_handlers_disconnect_by_func (priv->gdrive,
+ brasero_drive_medium_gdrive_changed_cb,
+ drive);
+ g_object_unref (priv->gdrive);
+ }
- /* If it's not a fake drive then connect to signal for any
- * change and check medium inside */
- g_signal_connect (priv->gdrive,
- "changed",
- G_CALLBACK (brasero_drive_medium_gdrive_changed_cb),
- drive);
+ BRASERO_MEDIA_LOG ("Setting GDrive %p", gdrive);
- brasero_drive_check_medium_inside_gdrive (drive);
+ if (gdrive) {
+ priv->gdrive = g_object_ref (gdrive);
+
+ /* If it's not a fake drive then connect to signal for any
+ * change and check medium inside */
+ g_signal_connect (priv->gdrive,
+ "changed",
+ G_CALLBACK (brasero_drive_medium_gdrive_changed_cb),
+ drive);
+ }
+
+ brasero_drive_probe_inside (drive);
+}
+
+/**
+ * brasero_drive_reprobe:
+ * @drive: a #BraseroDrive
+ *
+ * Reprobes the drive contents. Useful when an operation has just been performed
+ * (blanking, burning, ...) and medium status should be updated.
+ *
+ * NOTE: This operation does not block.
+ *
+ **/
+
+void
+brasero_drive_reprobe (BraseroDrive *drive)
+{
+ BraseroDrivePrivate *priv;
+ BraseroMedium *medium;
+
+ g_return_if_fail (drive != NULL);
+ g_return_if_fail (BRASERO_IS_DRIVE (drive));
+
+ priv = BRASERO_DRIVE_PRIVATE (drive);
+
+ if (priv->gdrive) {
+ /* reprobe the contents of the drive system wide */
+ g_drive_poll_for_media (priv->gdrive, NULL, NULL, NULL);
+ }
+
+ if (!priv->medium)
+ return;
+
+ BRASERO_MEDIA_LOG ("Reprobing inserted medium");
+
+ /* remove current medium */
+ medium = priv->medium;
+ priv->medium = NULL;
+
+ g_signal_emit (drive,
+ drive_signals [MEDIUM_REMOVED],
+ 0,
+ medium);
+ g_object_unref (medium);
+
+ brasero_drive_probe_inside (drive);
}
static gboolean
@@ -880,9 +1007,11 @@ brasero_drive_probed (gpointer data)
priv = BRASERO_DRIVE_PRIVATE (data);
- g_thread_join (priv->probe);
- priv->probe = NULL;
+ g_mutex_lock (priv->mutex);
priv->probe_id = 0;
+ g_mutex_unlock (priv->mutex);
+
+ brasero_drive_probe_inside (BRASERO_DRIVE (data));
return FALSE;
}
@@ -1015,6 +1144,8 @@ brasero_drive_probe_thread (gpointer data)
{
gint counter = 0;
const gchar *device;
+ BraseroScsiResult res;
+ BraseroScsiInquiry hdr;
BraseroScsiErrCode code;
BraseroDrivePrivate *priv;
BraseroDeviceHandle *handle;
@@ -1033,8 +1164,7 @@ brasero_drive_probe_thread (gpointer data)
if (priv->probe_cancelled) {
BRASERO_MEDIA_LOG ("Open () cancelled");
- priv->probe = NULL;
- return NULL;
+ goto end;
}
counter ++;
@@ -1043,56 +1173,86 @@ brasero_drive_probe_thread (gpointer data)
if (priv->probe_cancelled) {
BRASERO_MEDIA_LOG ("Open () cancelled");
- priv->probe = NULL;
- return NULL;
+ goto end;
}
- if (handle) {
- BraseroScsiInquiry hdr;
- BraseroScsiResult res;
-
- BRASERO_MEDIA_LOG ("Open () succeeded");
-
- /* get additional information like the name */
- res = brasero_spc1_inquiry (handle, &hdr, NULL);
- if (res == BRASERO_SCSI_OK) {
- gchar *name_utf8;
- gchar *vendor;
- gchar *model;
- gchar *name;
-
- vendor = g_strndup ((gchar *) hdr.vendor, sizeof (hdr.vendor));
- model = g_strndup ((gchar *) hdr.name, sizeof (hdr.name));
- name = g_strdup_printf ("%s %s", g_strstrip (vendor), g_strstrip (model));
- g_free (vendor);
- g_free (model);
-
- /* make sure that's proper UTF-8 */
- name_utf8 = g_convert_with_fallback (name,
- -1,
- "ASCII",
- "UTF-8",
- "_",
- NULL,
- NULL,
- NULL);
- g_free (name);
-
- priv->name = name_utf8;
+ if (!handle) {
+ BRASERO_MEDIA_LOG ("Open () failed: medium busy");
+ goto end;
+ }
+
+ while (brasero_spc1_test_unit_ready (handle, &code) != BRASERO_SCSI_OK) {
+ if (code == BRASERO_SCSI_NO_MEDIUM) {
+ BRASERO_MEDIA_LOG ("No medium inserted");
+ break;
}
- /* Get supported medium types */
- if (!brasero_drive_get_caps_profiles (drive, handle, &code))
- brasero_drive_get_caps_2A (drive, handle, &code);
+ if (code != BRASERO_SCSI_NOT_READY) {
+ brasero_device_handle_close (handle);
+ BRASERO_MEDIA_LOG ("Device does not respond");
+ goto end;
+ }
- brasero_device_handle_close (handle);
+ sleep (2);
- BRASERO_MEDIA_LOG ("Drive caps are %d", priv->caps);
+ if (priv->probe_cancelled) {
+ brasero_device_handle_close (handle);
+ BRASERO_MEDIA_LOG ("Device probing cancelled");
+ goto end;
+ }
}
- else
- BRASERO_MEDIA_LOG ("Open () failed: medium busy");
- priv->probe_id = g_idle_add (brasero_drive_probed, drive);
+ BRASERO_MEDIA_LOG ("Device ready");
+
+ /* get additional information like the name */
+ res = brasero_spc1_inquiry (handle, &hdr, NULL);
+ if (res == BRASERO_SCSI_OK) {
+ gchar *name_utf8;
+ gchar *vendor;
+ gchar *model;
+ gchar *name;
+
+ vendor = g_strndup ((gchar *) hdr.vendor, sizeof (hdr.vendor));
+ model = g_strndup ((gchar *) hdr.name, sizeof (hdr.name));
+ name = g_strdup_printf ("%s %s", g_strstrip (vendor), g_strstrip (model));
+ g_free (vendor);
+ g_free (model);
+
+ /* make sure that's proper UTF-8 */
+ name_utf8 = g_convert_with_fallback (name,
+ -1,
+ "ASCII",
+ "UTF-8",
+ "_",
+ NULL,
+ NULL,
+ NULL);
+ g_free (name);
+
+ priv->name = name_utf8;
+ }
+
+ /* Get supported medium types */
+ if (!brasero_drive_get_caps_profiles (drive, handle, &code))
+ brasero_drive_get_caps_2A (drive, handle, &code);
+
+ brasero_device_handle_close (handle);
+
+ BRASERO_MEDIA_LOG ("Drive caps are %d", priv->caps);
+
+end:
+
+ g_mutex_lock (priv->mutex);
+
+ if (!priv->probe_cancelled)
+ priv->probe_id = g_idle_add (brasero_drive_probed, drive);
+
+ priv->probe = NULL;
+ g_cond_broadcast (priv->cond);
+ g_mutex_unlock (priv->mutex);
+
+ g_thread_exit (0);
+
return NULL;
}
@@ -1121,10 +1281,12 @@ brasero_drive_init_real_device (BraseroDrive *drive,
* thread then our whole UI blocks. This medium won't be exported by the
* BraseroDrive that exported until it returns PROBED signal.
* One (good) side effect is that it also improves start time. */
+ g_mutex_lock (priv->mutex);
priv->probe = g_thread_create (brasero_drive_probe_thread,
drive,
- TRUE,
+ FALSE,
NULL);
+ g_mutex_unlock (priv->mutex);
}
static void
@@ -1149,30 +1311,7 @@ brasero_drive_set_property (GObject *object,
break;
gdrive = g_value_get_object (value);
- if (priv->gdrive) {
- g_signal_handlers_disconnect_by_func (priv->gdrive,
- brasero_drive_medium_gdrive_changed_cb,
- object);
- g_object_unref (priv->gdrive);
- }
-
- BRASERO_MEDIA_LOG ("Setting GDrive %p", gdrive);
-
- if (gdrive) {
- priv->gdrive = g_object_ref (gdrive);
- brasero_drive_update_gdrive (BRASERO_DRIVE (object));
- }
- else if (!priv->medium) {
- priv->probed = FALSE;
- priv->medium = g_object_new (BRASERO_TYPE_VOLUME,
- "drive", object,
- NULL);
-
- g_signal_connect (priv->medium,
- "probed",
- G_CALLBACK (brasero_drive_medium_probed),
- object);
- }
+ brasero_drive_update_gdrive (BRASERO_DRIVE (object), gdrive);
break;
case PROP_DEVICE:
if (!g_value_get_string (value)) {
@@ -1219,6 +1358,18 @@ brasero_drive_get_property (GObject *object,
}
static void
+brasero_drive_init (BraseroDrive *object)
+{
+ BraseroDrivePrivate *priv;
+
+ priv = BRASERO_DRIVE_PRIVATE (object);
+ priv->cancel = g_cancellable_new ();
+
+ priv->mutex = g_mutex_new ();
+ priv->cond = g_cond_new ();
+}
+
+static void
brasero_drive_finalize (GObject *object)
{
BraseroDrivePrivate *priv;
@@ -1227,17 +1378,28 @@ brasero_drive_finalize (GObject *object)
BRASERO_MEDIA_LOG ("Finalizing BraseroDrive");
+ g_mutex_lock (priv->mutex);
if (priv->probe) {
priv->probe_cancelled = TRUE;
- g_thread_join (priv->probe);
- priv->probe = 0;
+ g_cond_wait (priv->cond, priv->mutex);
}
+ g_mutex_unlock (priv->mutex);
if (priv->probe_id) {
g_source_remove (priv->probe_id);
priv->probe_id = 0;
}
+ if (priv->mutex) {
+ g_mutex_free (priv->mutex);
+ priv->mutex = NULL;
+ }
+
+ if (priv->cond) {
+ g_cond_free (priv->cond);
+ priv->cond = NULL;
+ }
+
if (priv->medium) {
g_signal_emit (object,
drive_signals [MEDIUM_REMOVED],
diff --git a/libbrasero-media/brasero-medium.c b/libbrasero-media/brasero-medium.c
index 65eabc1..46762d4 100644
--- a/libbrasero-media/brasero-medium.c
+++ b/libbrasero-media/brasero-medium.c
@@ -2325,8 +2325,10 @@ brasero_medium_get_medium_type (BraseroMedium *self,
/* If this fails it means that this drive is probably older than
* MMC1 spec or does not conform to it. */
- if (result != TRUE)
+ if (result != TRUE) {
+ priv->info = BRASERO_MEDIUM_NONE;
return FALSE;
+ }
/* The only thing here left to determine is if that's a WRITABLE
* or a REWRITABLE. To determine that information, we need to
@@ -2370,6 +2372,10 @@ brasero_medium_get_medium_type (BraseroMedium *self,
}
switch (profile) {
+ case BRASERO_SCSI_PROF_EMPTY:
+ priv->info = BRASERO_MEDIUM_NONE;
+ return FALSE;
+
case BRASERO_SCSI_PROF_CDROM:
priv->info = BRASERO_MEDIUM_CDROM;
priv->type = types [1];
@@ -2981,7 +2987,13 @@ brasero_medium_probe_thread (gpointer self)
/* NOTE: if we wanted to know the status we'd need to read the
* error code variable which is currently NULL */
while (brasero_spc1_test_unit_ready (handle, &code) != BRASERO_SCSI_OK) {
- if (code != BRASERO_SCSI_NOT_READY) {
+ if (code == BRASERO_SCSI_NO_MEDIUM) {
+ brasero_device_handle_close (handle);
+ BRASERO_MEDIA_LOG ("No medium inserted");
+ priv->info = BRASERO_MEDIUM_NONE;
+ goto end;
+ }
+ else if (code != BRASERO_SCSI_NOT_READY) {
brasero_device_handle_close (handle);
BRASERO_MEDIA_LOG ("Device does not respond");
goto end;
diff --git a/libbrasero-media/scsi-error.c b/libbrasero-media/scsi-error.c
index 7edae5f..3358544 100644
--- a/libbrasero-media/scsi-error.c
+++ b/libbrasero-media/scsi-error.c
@@ -61,6 +61,10 @@ brasero_scsi_strerror (BraseroScsiErrCode code)
if (code > BRASERO_SCSI_ERROR_LAST || code < 0)
return NULL;
+ /* FIXME: this is for errors that don't have any message yet */
+ if (code > BRASERO_SCSI_ERRNO)
+ return NULL;
+
if (code == BRASERO_SCSI_ERRNO)
return g_strerror (errno);
diff --git a/libbrasero-media/scsi-error.h b/libbrasero-media/scsi-error.h
index 61d744a..73b768b 100644
--- a/libbrasero-media/scsi-error.h
+++ b/libbrasero-media/scsi-error.h
@@ -59,6 +59,7 @@ typedef enum {
BRASERO_SCSI_KEY_NOT_ESTABLISHED,
BRASERO_SCSI_INVALID_TRACK_MODE,
BRASERO_SCSI_ERRNO,
+ BRASERO_SCSI_NO_MEDIUM,
BRASERO_SCSI_ERROR_LAST
} BraseroScsiErrCode;
diff --git a/libbrasero-media/scsi-get-configuration.h b/libbrasero-media/scsi-get-configuration.h
index 3cf1f89..b7fe7b1 100644
--- a/libbrasero-media/scsi-get-configuration.h
+++ b/libbrasero-media/scsi-get-configuration.h
@@ -38,6 +38,7 @@
G_BEGIN_DECLS
typedef enum {
+BRASERO_SCSI_PROF_EMPTY = 0x0000,
BRASERO_SCSI_PROF_NON_REMOVABLE = 0x0001,
BRASERO_SCSI_PROF_REMOVABLE = 0x0002,
BRASERO_SCSI_PROF_MO_ERASABLE = 0x0003,
diff --git a/libbrasero-media/scsi-sense-data.c b/libbrasero-media/scsi-sense-data.c
index e88e89d..633e91d 100644
--- a/libbrasero-media/scsi-sense-data.c
+++ b/libbrasero-media/scsi-sense-data.c
@@ -57,6 +57,7 @@
#define SENSE_CODE_UNIT_ATTENTION 0x06
#define ASC_CODE_NOT_READY 0x04
+#define ASC_CODE_NO_MEDIUM 0x3A
#define ASC_CODE_PARAMETER 0x26
#define ASC_CODE_PROTECTION_KEY 0x6F
@@ -110,6 +111,11 @@ brasero_sense_data_not_ready (uchar *sense_data, BraseroScsiErrCode *err)
BraseroScsiResult res = BRASERO_SCSI_FAILURE;
switch (SENSE_DATA_ASC (sense_data)) {
+ case ASC_CODE_NO_MEDIUM:
+ /* No need to use BRASERO_SCSI_SET_ERRCODE
+ * as this is not necessarily an error */
+ *err = BRASERO_SCSI_NO_MEDIUM;
+ break;
case ASC_CODE_NOT_READY:
BRASERO_SCSI_SET_ERRCODE (err, BRASERO_SCSI_NOT_READY);
break;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]