--- cd-drive.c.orig Mon Sep 8 15:24:07 2003
+++ cd-drive.c Sun Dec 21 02:40:36 2003
@@ -693,28 +693,133 @@
#endif /* __linux__ */
#ifdef __FreeBSD__
+static void
+get_cd_properties (char *id, int *max_rd_speed, int *max_wr_speed,
+ CDDriveType *type)
+{
+ int i;
+ const char *argv[20];
+ char *dev_str, *stdout_data, *rd_speed, *wr_speed, *drive_cap;
+
+ *max_rd_speed = -1;
+ *max_wr_speed = -1;
+ *type = 0;
+
+ i = 0;
+ argv[i++] = "cdrecord";
+ argv[i++] = "-prcap";
+ dev_str = g_strdup_printf ("dev=%s", id);
+ argv[i++] = dev_str;
+ argv[i++] = NULL;
+
+ if (g_spawn_sync (NULL,
+ (char **)argv,
+ NULL,
+ G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL,
+ NULL, NULL,
+ &stdout_data,
+ NULL,
+ NULL,
+ NULL)) {
+ rd_speed = strstr (stdout_data, "Maximum read speed:");
+ if (rd_speed != NULL) {
+ char *tok;
+ rd_speed += strlen ("Maximum read speed:");
+ for (tok = strtok (rd_speed, " (),\t\n");
+ tok && strcmp (tok, "CD");
+ tok = strtok (NULL, " (),\t\n")) {}
+ tok = strtok (NULL, " (),\t\n"); /* Get the CD speed. */
+ *max_rd_speed = atol (tok);
+ }
+ else {
+ rd_speed = strstr (stdout_data, "Maximum read speed in kB/s:");
+ if (rd_speed != NULL) {
+ char *tok;
+ rd_speed += strlen ("Maximum read speed in kB/s:");
+ for (tok = strtok (rd_speed, " (),\t\n");
+ tok && strcmp (tok, "CD");
+ tok = strtok (NULL, " (),\t\n")) {}
+ tok = strtok (NULL, " (),\t\n"); /* Get the CD speed. */
+ *max_rd_speed = atol (tok);
+ }
+ }
+
+ wr_speed = strstr (stdout_data, "Maximum write speed:");
+ if (wr_speed != NULL) {
+ char *tok;
+ wr_speed += strlen ("Maximum write speed:");
+ for (tok = strtok (wr_speed, " (),\t\n");
+ tok && strcmp (tok, "CD");
+ tok = strtok (NULL, " (),\t\n")) {}
+ tok = strtok (NULL, " (),\t\n"); /* Get the CD speed. */
+ *max_wr_speed = atol (tok);
+ }
+ else {
+ wr_speed = strstr (stdout_data, "Maximum write speed in kB/s:");
+ if (wr_speed != NULL) {
+ char *tok;
+ wr_speed += strlen ("Maximum write speed in kB/s:");
+ for (tok = strtok (wr_speed, " (),\t\n");
+ tok && strcmp (tok, "CD");
+ tok = strtok (NULL, " (),\t\n")) {}
+ tok = strtok (NULL, " (),\t\n"); /* Get the CD speed. */
+ *max_wr_speed = atol (tok);
+ }
+ }
+ drive_cap = strstr (stdout_data, "Does write DVD-RAM media");
+ if (drive_cap != NULL) {
+ *type |= CDDRIVE_TYPE_DVD_RAM_RECORDER;
+ }
+ drive_cap = strstr (stdout_data, "Does read DVD-R media");
+ if (drive_cap != NULL) {
+ *type |= CDDRIVE_TYPE_DVD_RW_RECORDER;
+ }
+ drive_cap = strstr (stdout_data, "Does read DVD-ROM media");
+ if (drive_cap != NULL) {
+ *type |= CDDRIVE_TYPE_DVD_DRIVE;
+ }
+ drive_cap = strstr (stdout_data, "Does write CD-RW media");
+ if (drive_cap != NULL) {
+ *type |= CDDRIVE_TYPE_CDRW_RECORDER;
+ }
+ drive_cap = strstr (stdout_data, "Does write CD-R media");
+ if (drive_cap != NULL) {
+ *type |= CDDRIVE_TYPE_CD_RECORDER;
+ }
+ drive_cap = strstr (stdout_data, "Does read CD-R media");
+ if (drive_cap != NULL) {
+ *type |= CDDRIVE_TYPE_CD_DRIVE;
+ }
+ g_free (stdout_data);
+ }
+
+ g_free (dev_str);
+}
+
static GList *
freebsd_scan (gboolean recorder_only)
{
GList *cdroms_list = NULL;
const char *dev_type = "cd";
- int fd;
int speed = 16; /* XXX Hardcode the write speed for now. */
- int max_speed = CDR_MAX_SPEED;
int i = 0;
+ int cnode = 1; /* Use the CD device's 'c' node. */
while (1) {
- CDDriveType type;
CDDrive *cdrom;
- gchar *cam_path, *dev;
+ gchar *cam_path;
struct cam_device *cam_dev;
- type = 0;
cam_path = g_strdup_printf ("/dev/%s%dc", dev_type, i);
if (!g_file_test (cam_path, G_FILE_TEST_EXISTS)) {
g_free (cam_path);
- break;
+ cam_path = g_strdup_printf ("/dev/%s%d", dev_type, i);
+ cnode = 0;
+ if (!g_file_test (cam_path, G_FILE_TEST_EXISTS)) {
+ g_free (cam_path);
+ break;
+ }
}
if ((cam_dev = cam_open_spec_device (dev_type, i, O_RDWR, NULL)) == NULL) {
@@ -723,47 +828,41 @@
continue;
}
- /* XXX Other controllers might need to be added. */
- if ((strncmp (cam_dev->sim_name, "ata", 3)) == 0) {
- dev = g_strdup_printf ("/dev/a%s%dc", dev_type, i);
- } else {
- dev = g_strdup (cam_path);
- }
-
- g_free (cam_path);
-
- if ((fd = open (dev, O_RDWR, 0)) < 0) {
- g_free (dev);
- free (cam_dev);
- i++;
- continue;
- }
-
- type |= CDDRIVE_TYPE_CD_DRIVE;
- if (ioctl (fd, CDRIOCWRITESPEED, &max_speed) >= 0) {
- /* XXX is it CD-R or CD-RW ? */
- type |= CDDRIVE_TYPE_CD_RECORDER;
- }
-
- close (fd);
-
- if (type & CDDRIVE_TYPE_CD_RECORDER
- || type & CDDRIVE_TYPE_CDRW_RECORDER
- || recorder_only == FALSE) {
- cdrom = g_new0 (CDDrive, 1);
- cdrom->display_name = g_strdup_printf ("%s %s", cam_dev->inq_data.vendor, cam_dev->inq_data.revision);
- cdrom->device = g_strdup (dev);
- cdrom->max_speed_read = speed;
- cdrom->max_speed_write = speed;
- cdrom->cdrecord_id = g_strdup_printf ("%d,%d,%d", cam_dev->path_id, cam_dev->target_id, cam_dev->target_lun);
- cdrom->type = type;
-
- add_dvd_plus (cdrom);
+ cdrom = g_new0 (CDDrive, 1);
+ cdrom->display_name = g_strdup_printf ("%s %s", cam_dev->inq_data.vendor, cam_dev->inq_data.revision);
+ cdrom->device = g_strdup (cam_path);
+ cdrom->cdrecord_id = g_strdup_printf ("%d,%d,%d", cam_dev->path_id, cam_dev->target_id, cam_dev->target_lun);
+ /* Attempt to get more specific information from
+ * this drive by using cdrecord.
+ */
+ get_cd_properties (cdrom->cdrecord_id,
+ &(cdrom->max_speed_read),
+ &(cdrom->max_speed_write),
+ &(cdrom->type));
+ if (cdrom->type & CDDRIVE_TYPE_CD_RECORDER
+ || cdrom->type & CDDRIVE_TYPE_CDRW_RECORDER
+ || cdrom->type & CDDRIVE_TYPE_DVD_RAM_RECORDER
+ || cdrom->type & CDDRIVE_TYPE_DVD_RW_RECORDER
+ || !recorder_only) {
+
+ if (cdrom->max_speed_read == -1) {
+ cdrom->max_speed_read = speed;
+ }
+ if (cdrom->max_speed_write == -1) {
+ cdrom->max_speed_write = speed;
+ }
+
+ if (cdrom->type & CDDRIVE_TYPE_DVD_DRIVE) {
+ add_dvd_plus (cdrom);
+ }
cdroms_list = g_list_append (cdroms_list, cdrom);
}
+ else {
+ cd_drive_free (cdrom);
+ }
- g_free (dev);
+ g_free (cam_path);
free (cam_dev);
i++;