From Ian MacIntosh:

Modifications that it doesn't use the uscsi commands anymore and so
all IDE and SCSI drives go through the same code path - a major
simplification.

This works with all the CD drives that work with Solaris (IDE or SCSI)
as the ioctl's for CDROMCDXA in Solaris just end up doing uscsi calls
anyway, but directly from the kernel. The added advantage of not using
uscsi is that the user doesn't need to be root - which is important in
Sunray environments.
This commit is contained in:
rocky
2004-03-16 12:18:32 +00:00
parent b6e8f0ab6f
commit 6d6fbfcfa6

View File

@@ -1,5 +1,5 @@
/* /*
$Id: _cdio_sunos.c,v 1.24 2004/03/06 18:22:07 rocky Exp $ $Id: _cdio_sunos.c,v 1.25 2004/03/16 12:18:32 rocky Exp $
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org> Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com> Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -41,7 +41,7 @@
#ifdef HAVE_SOLARIS_CDROM #ifdef HAVE_SOLARIS_CDROM
static const char _rcsid[] = "$Id: _cdio_sunos.c,v 1.24 2004/03/06 18:22:07 rocky Exp $"; static const char _rcsid[] = "$Id: _cdio_sunos.c,v 1.25 2004/03/16 12:18:32 rocky Exp $";
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -97,22 +97,9 @@ static bool
_cdio_init (_img_private_t *_obj) _cdio_init (_img_private_t *_obj)
{ {
struct dk_cinfo cinfo;
if (!cdio_generic_init(_obj)) return false; if (!cdio_generic_init(_obj)) return false;
/*
* CDROMCDXA/CDROMREADMODE2 are broken on IDE/ATAPI devices.
* Try to send MMC3 SCSI commands via the uscsi interface on
* ATAPI devices.
*/
if ( ioctl(_obj->gen.fd, DKIOCINFO, &cinfo) == 0
&& ((strcmp(cinfo.dki_cname, "ide") == 0)
|| (strncmp(cinfo.dki_cname, "pci", 3) == 0)) ) {
_obj->access_mode = _AM_SUN_CTRL_ATAPI;
} else {
_obj->access_mode = _AM_SUN_CTRL_SCSI; _obj->access_mode = _AM_SUN_CTRL_SCSI;
}
return true; return true;
} }
@@ -132,6 +119,7 @@ _cdio_read_audio_sectors (void *env, void *data, lsn_t lsn,
char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, }; char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };
struct cdrom_msf *msf = (struct cdrom_msf *) &buf; struct cdrom_msf *msf = (struct cdrom_msf *) &buf;
msf_t _msf; msf_t _msf;
struct cdrom_cdda cdda;
_img_private_t *_obj = env; _img_private_t *_obj = env;
@@ -154,16 +142,6 @@ _cdio_read_audio_sectors (void *env, void *data, lsn_t lsn,
_obj->gen.ioctls_debugged++; _obj->gen.ioctls_debugged++;
switch (_obj->access_mode)
{
case _AM_NONE:
cdio_error ("No way to read CD audio");
return 1;
break;
case _AM_SUN_CTRL_SCSI:
{
struct cdrom_cdda cdda;
cdda.cdda_addr = lsn; cdda.cdda_addr = lsn;
cdda.cdda_length = nblocks; cdda.cdda_length = nblocks;
cdda.cdda_data = (caddr_t) data; cdda.cdda_data = (caddr_t) data;
@@ -172,52 +150,6 @@ _cdio_read_audio_sectors (void *env, void *data, lsn_t lsn,
return 1; return 1;
/* exit (EXIT_FAILURE); */ /* exit (EXIT_FAILURE); */
} }
}
break;
case _AM_SUN_CTRL_ATAPI:
{
struct uscsi_cmd sc;
union scsi_cdb cdb;
int sector_type = 1; /* CD-DA */
int sync = 0;
int header_code = 2;
int user_data = 1;
int edc_ecc = 0;
int error_field = 0;
int sub_channel = 0;
memset(&cdb, 0, sizeof(cdb));
memset(&sc, 0, sizeof(sc));
cdb.scc_cmd = CDIO_MMC_GPCMD_READ_CD;
CDIO_MMC_SET_READ_TYPE(cdb.cdb_opaque, sector_type);
CDIO_MMC_SET_READ_LBA(cdb.cdb_opaque, lsn);
CDIO_MMC_SET_READ_LENGTH(cdb.cdb_opaque, nblocks);
cdb.cdb_opaque[9] = (sync << 7) |
(header_code << 5) |
(user_data << 4) |
(edc_ecc << 3) |
(error_field << 1);
cdb.cdb_opaque[10] = sub_channel;
sc.uscsi_cdb = (caddr_t)&cdb;
sc.uscsi_cdblen = 12;
sc.uscsi_bufaddr = (caddr_t) buf;
sc.uscsi_buflen = CDIO_CD_FRAMESIZE_RAW;
sc.uscsi_flags = USCSI_ISOLATE | USCSI_READ;
sc.uscsi_timeout = 20;
if (ioctl(_obj->gen.fd, USCSICMD, &sc)) {
perror("USCSICMD: READ CD");
return 1;
}
if (sc.uscsi_status) {
cdio_error("SCSI command failed with status %d\n",
sc.uscsi_status);
return 1;
}
break;
}
}
memcpy (data, buf, CDIO_CD_FRAMESIZE_RAW); memcpy (data, buf, CDIO_CD_FRAMESIZE_RAW);
return 0; return 0;
@@ -276,9 +208,11 @@ static int
_cdio_read_mode2_sector (void *env, void *data, lsn_t lsn, _cdio_read_mode2_sector (void *env, void *data, lsn_t lsn,
bool b_form2) bool b_form2)
{ {
char buf[M2RAW_SECTOR_SIZE] = { 0, }; char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };
struct cdrom_msf *msf = (struct cdrom_msf *) &buf; struct cdrom_msf *msf = (struct cdrom_msf *) &buf;
msf_t _msf; msf_t _msf;
int offset = 0;
struct cdrom_cdxa cd_read;
_img_private_t *_obj = env; _img_private_t *_obj = env;
@@ -302,70 +236,24 @@ _cdio_read_mode2_sector (void *env, void *data, lsn_t lsn,
_obj->gen.ioctls_debugged++; _obj->gen.ioctls_debugged++;
switch (_obj->access_mode) /* Using CDROMXA ioctl will actually use the same uscsi command
{ * as ATAPI, except we don't need to be root
case _AM_NONE: */
cdio_error ("No way to read CD mode2."); offset = CDIO_CD_XA_SYNC_HEADER;
return 1; cd_read.cdxa_addr = lsn;
break; cd_read.cdxa_data = buf;
cd_read.cdxa_length = 1;
case _AM_SUN_CTRL_SCSI: cd_read.cdxa_format = CDROM_XA_SECTOR_DATA;
if (ioctl (_obj->gen.fd, CDROMREADMODE2, &buf) == -1) { if (ioctl (_obj->gen.fd, CDROMCDXA, &cd_read) == -1) {
perror ("ioctl(..,CDROMREADMODE2,..)"); perror ("ioctl(..,CDROMCDXA,..)");
return 1; return 1;
/* exit (EXIT_FAILURE); */ /* exit (EXIT_FAILURE); */
} }
break;
case _AM_SUN_CTRL_ATAPI:
{
struct uscsi_cmd sc;
union scsi_cdb cdb;
int nblocks = 1;
int sector_type = 0; /* all types */
int sync = 0;
int header_code = 2;
int sub_channel = 0;
int user_data = 1;
int edc_ecc = 0;
int error_field = 0;
memset(&cdb, 0, sizeof(cdb));
memset(&sc, 0, sizeof(sc));
cdb.scc_cmd = CDIO_MMC_GPCMD_READ_CD;
CDIO_MMC_SET_READ_TYPE(cdb.cdb_opaque, sector_type);
CDIO_MMC_SET_READ_LBA(cdb.cdb_opaque, lsn);
CDIO_MMC_SET_READ_LENGTH(cdb.cdb_opaque, nblocks);
cdb.cdb_opaque[9] = (sync << 7) |
(header_code << 5) |
(user_data << 4) |
(edc_ecc << 3) |
(error_field << 1);
cdb.cdb_opaque[10] = sub_channel;
sc.uscsi_cdb = (caddr_t)&cdb;
sc.uscsi_cdblen = 12;
sc.uscsi_bufaddr = (caddr_t) buf;
sc.uscsi_buflen = M2RAW_SECTOR_SIZE;
sc.uscsi_flags = USCSI_ISOLATE | USCSI_READ;
sc.uscsi_timeout = 20;
if (ioctl(_obj->gen.fd, USCSICMD, &sc)) {
perror("USCSICMD: READ CD");
return 1;
}
if (sc.uscsi_status) {
cdio_error("SCSI command failed with status %d\n",
sc.uscsi_status);
return 1;
}
break;
}
}
if (b_form2) if (b_form2)
memcpy (data, buf, M2RAW_SECTOR_SIZE); memcpy (data, buf + (offset-CDIO_CD_SUBHEADER_SIZE), M2RAW_SECTOR_SIZE);
else else
memcpy (((char *)data), buf + CDIO_CD_SUBHEADER_SIZE, CDIO_CD_FRAMESIZE); memcpy (((char *)data), buf + offset, CDIO_CD_FRAMESIZE);
return 0; return 0;
} }
@@ -443,7 +331,7 @@ _cdio_set_arg (void *env, const char key[], const char value[])
else if (!strcmp (key, "access-mode")) else if (!strcmp (key, "access-mode"))
{ {
if (!strcmp(value, "ATAPI")) if (!strcmp(value, "ATAPI"))
_obj->access_mode = _AM_SUN_CTRL_ATAPI; _obj->access_mode = _AM_SUN_CTRL_SCSI; /* force ATAPI to be SCSI */
else if (!strcmp(value, "SCSI")) else if (!strcmp(value, "SCSI"))
_obj->access_mode = _AM_SUN_CTRL_SCSI; _obj->access_mode = _AM_SUN_CTRL_SCSI;
else else