device.c revision 4becbc5b6d8bf411bcf87e2aa73dd99f22fccac8
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <fcntl.h>
#include <volmgt.h>
#include <errno.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <libintl.h>
#include <limits.h>
#include "transport.h"
#include "mmc.h"
#include "device.h"
#include "util.h"
#include "msgs.h"
#include "misc_scsi.h"
#include "toshiba.h"
#include "main.h"
/*
* Also they use a different method for extracting audio.
* We have the device inquiry strings at this time. This is used to enable
* us to use older sun drives to extract audio.
*/
static int
{
/*
* If we have a SONY CDU 561, CDU 8012, or TOSHIBA model with XMa we
* need to handle these drives a bit differently.
*/
return (1);
return (1);
}
char product_id[17];
/* Changing speed is not allowed for 32X TOSHIBA drives */
product_id[16] = 0;
return (1);
}
return (0);
}
/*
* returns a cd_device handle for a node returned by lookup_device()
* also takes the user supplied name and stores it inside the node
*/
{
int fd;
int size;
int use_cd_speed = 0;
/*
* we need to resolve any link paths to avoid fake files
*/
return (NULL);
/* resolvepath may not return a null terminated string */
return (NULL);
/*
* Since we are currently running with the user euid it is
* safe to try to open the file without checking access.
*/
if (fd < 0) {
return (NULL);
}
if (debug) {
(void) printf("USCSI ioctl failed %d\n",
}
return (NULL);
}
if (debug) {
(void) printf("Checking device type\n");
(void) printf("DVD-R read support\n");
(void) printf("DVD-R write support\n");
(void) printf("R-W supported\n");
(void) printf("DVD-RAM read supported\n");
(void) printf("DVD-RAM write supported\n");
} else {
(void) printf("Could not read mode page 2A! \n");
}
}
/* Detect if it's a Lite-ON drive with a streaming CD problem */
use_cd_speed = 1;
}
/*
* a workaround for the firmware problem in LITE-ON COMBO drives.
* streaming for these drives sets it only to max speed regardless
* of requested speed. cd_speed_ctrl allow speeds less than max
* to be set but not max thus the code below. (x48 is max speed
* for these drives).
*/
(strncmp("COMBO SOHC-4836VS",
if (requested_speed < 48)
use_cd_speed = 1;
if (is_old_sun_drive(dev)) {
} else if (use_cd_speed) {
/*
* Work around for Lite-on FW bug in which rt_speed_ctrl
* doesn't work correctly.
*/
} else {
/*
* If feature 8 (see GET CONF MMC command) is supported,
* READ CD will work and will return jitter free audio data.
* Otherwise look at page code 2A for this info.
*/
}
}
/*
* If feature 0x0107 is suported then Real-time streaming
* commands can be used for speed control. Otherwise try
* SET CD SPEED.
*/
if (debug)
(void) printf("using rt speed ctrl\n");
} else {
if (debug)
(void) printf("using cd speed ctrl\n");
}
}
/*
* Find the block size of the device so we can translate
*/
/*
* If DKIOCGMEDIAINFO fails we'll try to get
* the blocksize from the device itself.
*/
if (debug)
(void) printf("DKIOCGMEDIAINFO failed\n");
} else {
}
if (debug) {
(void) printf("read_format_capacity = %d \n",
}
/*
* Some devices will return invalid blocksizes. ie. Toshiba
* drives will return 2352 when an audio CD is inserted.
* Older Sun drives will use 512 byte block sizes. All newer
* drives should have 2k blocksizes.
*/
if (is_old_sun_drive(dev)) {
} else {
}
if (debug)
}
if (user_supplied) {
}
return (dev);
}
void
{
}
static int
{
char *p1;
int i;
return (0);
if (vol_running)
(void) volmgt_check(vname);
return (0);
return (0);
}
for (i = 0; i < 16; i++) {
break;
}
if (i == 16) {
return (0);
}
} else {
}
return (1);
}
/*
* Searches for volume manager's equivalent char device for the
*/
static int
{
int i, ret;
return (0);
for (i = 0; i < 16; i++) {
break;
}
if (p == NULL)
return (0);
}
free(p);
return (ret);
}
/*
* Builds an open()able device path from a user supplied node which can be
* cdrom[n]
* returns the path found in 'found' and returns 1. Otherwise returns 0.
*/
int
{
int fd;
/* If everything is fine and proper, no need to analyze */
return (1);
}
return (1);
}
else
return (0);
}
supplied);
}
return (1);
}
}
}
/*
* Opens the device node name passed and returns 1 (true) if the
* device is a CD.
*/
static int
{
int fd;
int ret = 1;
if (fd < 0) {
ret = 0;
ret = 0;
ret = 0;
}
if (fd >= 0) {
}
return (ret);
}
static void
print_header(void)
{
/* l10n_NOTE : Column spacing should be kept same */
/* l10n_NOTE : Column spacing should be kept same */
(void) printf(
"----------------------+--------------------------------");
(void) printf("+-----------------\n");
}
/*
* the first device found depending on the mode argument.
* possible mode values are:
* SCAN_WRITERS Scan all CD-RW devices. Return first one found.
* SCAN_LISTDEVS List all devices found.
*/
int
{
int writers_found = 0;
int header_printed = 0;
int is_writer;
int retry = 0;
int total_devices_found;
int total_devices_found_last_time = 0;
int defer = 0;
#define MAX_RETRIES_FOR_SCANNING 5
if (mode) {
if (vol_running)
defer = 1;
}
return (0);
writers_found = 0;
total_devices_found = 0;
continue;
continue;
continue;
continue;
continue;
}
if (is_writer) {
}
/* We found a CD-ROM or DVD-ROM */
}
char *sn;
if (!header_printed) {
print_header();
header_printed = 1;
}
/* show vendor, model, firmware rev and device type */
(void) printf(" %-21.21s| %.8s %.16s %.4s | %s%s\n",
gettext("CD Reader"),
if (sn)
}
}
/*
* If volume manager is running we'll do a retry in case the
* user has just inserted media, This should allow vold
* enough time to create the device links. If we cannot
* find any devices, or we find any new devices we'll retry
* again up to MAX_RETRIES_FOR_SCANNING
*/
retry++;
(writers_found == 0))) {
if ((total_devices_found == 0) ||
/* before we rescan remove the device found */
if (total_devices_found != 0 && t_dev) {
}
(void) sleep(2);
goto try_again;
} else {
/* Do the printing this time */
defer = 0;
goto try_again;
}
}
}
return (writers_found);
else
return (total_devices_found);
}
/*
* Check device for various conditions/capabilities
* If EXIT_IF_CHECK_FAILED set in cond then it will also exit after
* printing a message.
*/
int
{
errmsg =
gettext("Specified device does not appear to be a CDROM");
}
}
/* Look at the capabilities page for this information */
}
}
/* medium not present */
}
}
/* Issue READ DISC INFORMATION mmc command */
(cond & CHECK_MEDIA_IS_NOT_WRITABLE) ||
(cond & CHECK_MEDIA_IS_NOT_ERASABLE))) {
} else {
}
"Media in the device is not erasable");
else if ((disc_status != 0) &&
"Media in the device is not blank");
else if ((disc_status == 2) &&
(cond & CHECK_MEDIA_IS_NOT_WRITABLE) &&
((device_type != DVD_PLUS_W) &&
(device_type != DVD_PLUS)))
"Media in the device is not writable");
}
}
if (errmsg) {
if (cond & EXIT_IF_CHECK_FAILED) {
exit(1);
}
return (1);
}
return (0);
}
/*
* Generic routine for writing whatever the next track is and taking
* care of the progress bar. Mode tells the track type (audio or data).
* Data from track is taken from the byte stream h
*/
void
{
struct track_info *ti;
struct trackio_error *te;
DVD_PLUS_W)) {
} else {
"Cannot get writable address for the media.\n"));
exit(1);
}
}
"Media state is not suitable for this write mode.\n"));
exit(1);
}
if (mode == TRACK_MODE_DATA) {
/* Write track depends upon this bit */
}
}
size = 0;
h->bstr_rewind(h);
} else {
if (device_type != DVD_PLUS_W) {
/* l10n_NOTE : 'failed' as in Writing Track...failed */
}
}
}
/* l10n_NOTE : 'done' as in "Writing track 1...done" */
}
void
list(void)
{
if (vol_running) {
"No CD writers found or no media in the drive.\n"));
} else {
if (cur_uid != 0) {
"Volume manager is not running.\n"));
"Please start volume manager or run cdrw as root to access all devices.\n"));
} else {
}
}
}
exit(0);
}
void
get_media_type(int fd)
{
uint_t i;
(void) printf("\nprofile = ");
for (i = 7; i < 0x20; i += 4)
(void) printf("\n");
}
switch (cap[7]) {
case 0x8: /* CD-ROM */
if (debug)
(void) printf("CD-ROM found\n");
/*
* To avoid regression issues, treat as
* A cdrw, we will check the writable
* mode page to see if the media is
* actually writable.
*/
device_type = CD_RW;
break;
case 0x9: /* CD-R */
if (debug)
(void) printf("CD-R found\n");
device_type = CD_RW;
break;
case 0x10: /* DVD-ROM */
/*
* Have seen drives return DVD+RW media
* DVD-ROM, so try treating it as a DVD+RW
* profile. checking for writable media
* is done through mode page 5.
*/
if (debug)
(void) printf("DVD-ROM found\n");
break;
case 0xA: /* CD-RW */
if (debug)
(void) printf("CD-RW found\n");
device_type = CD_RW;
break;
case 0x11: /* DVD-R */
if (debug)
(void) printf("DVD-R found\n");
break;
case 0x12: /* DVD-RAM */
if (debug)
(void) printf("DVD-RAM found\n");
/* treat as CD-RW, may be a legacy drive */
device_type = CD_RW;
break;
case 0x13: /* DVD-RW restricted overwrite */
case 0x14: /* DVD-RW sequencial */
if (debug)
(void) printf("DVD-RW found\n");
break;
case 0x1A: /* DVD+RW */
if (debug)
(void) printf("DVD+RW found\n");
break;
case 0x1B: /* DVD+R */
if (debug)
(void) printf("DVD+R found\n");
break;
default:
if (debug)
(void) printf(
"unknown drive found\n type = 0x%x",
cap[7]);
/*
* Treat as CD_RW to avoid regression, may
* be a legacy drive.
*/
device_type = CD_RW;
}
}
}