+ Finished up cdrom session module

+ Fixed volume name bug in iso9660 module
+ Added licenses


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2458 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Tyler Dauwalder 2003-01-16 08:26:22 +00:00
parent 319b1b3085
commit e3e6d2db88
9 changed files with 458 additions and 192 deletions

View File

@ -1,4 +1,34 @@
// disk_scanner.h
//------------------------------------------------------------------------------
// Copyright (c) 2001-2002, OpenBeOS
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: disk_scanner.h
// Author: Ingo Weinhold (bonefish@users.sf.net)
// Description: hook function declarations for disk_scanner module
//------------------------------------------------------------------------------
/*!
\file disk_scanner.h
hook function declarations for disk_scanner module
*/
#ifndef _DISKSCANNER_H
#define _DISKSCANNER_H

View File

@ -1,4 +1,33 @@
// fs.h
//------------------------------------------------------------------------------
// Copyright (c) 2001-2002, OpenBeOS
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: filesystem.h
// Author: Ingo Weinhold (bonefish@users.sf.net)
// Description: hook function declarations for disk_scanner filesystem modules
//------------------------------------------------------------------------------
/*!
\file filesystem.h
hook function declarations for disk_scanner filesystem modules
*/
#ifndef _PARTSCAN_FS_H
#define _PARTSCAN_FS_H

View File

@ -1,4 +1,34 @@
// partition.h
//------------------------------------------------------------------------------
// Copyright (c) 2001-2002, OpenBeOS
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: partition.h
// Author: Ingo Weinhold (bonefish@users.sf.net)
// Description: hook function declarations for disk_scanner partition modules
//------------------------------------------------------------------------------
/*!
\file partition.h
hook function declarations for disk_scanner partition modules
*/
#ifndef _PARTSCAN_PARTITION_H
#define _PARTSCAN_PARTITION_H

View File

@ -1,4 +1,33 @@
// session.h
//------------------------------------------------------------------------------
// Copyright (c) 2001-2002, OpenBeOS
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: session.h
// Author: Ingo Weinhold (bonefish@users.sf.net)
// Description: hook function declarations for disk_scanner session modules
//------------------------------------------------------------------------------
/*!
\file session.h
hook function declarations for disk_scanner session modules
*/
#ifndef _PARTSCAN_SESSION_H
#define _PARTSCAN_SESSION_H

View File

@ -1,4 +1,33 @@
// disk_scanner.c
//------------------------------------------------------------------------------
// Copyright (c) 2001-2003, OpenBeOS
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: disk_scanner.c
// Author: Ingo Weinhold (bonefish@users.sf.net)
// Description: disk_scanner kernel module
//------------------------------------------------------------------------------
/*!
\file disk_scanner.c
disk_scanner kernel module
*/
#include <errno.h>
#include <stdlib.h>

View File

@ -1,4 +1,33 @@
// bfs.c
//------------------------------------------------------------------------------
// Copyright (c) 2001-2003, OpenBeOS
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: bfs.c
// Author: Tyler Dauwalder (tyler@dauwalder.net)
// Description: disk_scanner filesystem module for BFS filesystems
//------------------------------------------------------------------------------
/*!
\file bfs.c
disk_scanner filesystem module for BFS filesystems
*/
#include <errno.h>
#include <stdlib.h>
@ -12,8 +41,8 @@
#define BFS_FS_MODULE_NAME "disk_scanner/fs/bfs/v1"
const char *kModuleDebugName = "fs/bfs";
//#define TRACE(x)
#define TRACE(x) dprintf x
#define TRACE(x)
//#define TRACE(x) dprintf x
// prototypes
static status_t read_block(int fd, off_t offset, size_t size, uchar **block);

View File

@ -1,4 +1,34 @@
// iso9660.c
//------------------------------------------------------------------------------
// Copyright (c) 2001-2003, OpenBeOS
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: iso9660.c
// Author: Tyler Dauwalder (tyler@dauwalder.net)
// Description: disk_scanner filesystem module for iso9660 CD-ROM filesystems
//------------------------------------------------------------------------------
/*!
\file iso9660.c
disk_scanner filesystem module for iso9660 CD-ROM filesystems
*/
#include <errno.h>
#include <stdlib.h>
@ -199,8 +229,10 @@ iso9660_fs_identify(int deviceFD, struct extended_partition_info *partitionInfo,
if (primary->volume_identifier[i] != 0x20)
break;
}
if (partitionInfo->volume_name)
if (partitionInfo->volume_name) {
strncpy(partitionInfo->volume_name, primary->volume_identifier, i+1);
partitionInfo->volume_name[i+1] = 0;
}
if (priority)
*priority = 0;

View File

@ -1,4 +1,33 @@
// intel.c
//------------------------------------------------------------------------------
// Copyright (c) 2001-2003, OpenBeOS
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: intel.c
// Author: Ingo Weinhold (bonefish@users.sf.net)
// Description: disk_scanner partition module for "intel" style partitions
//------------------------------------------------------------------------------
/*!
\file intel.c
disk_scanner partition module for "intel" style partitions
*/
#include <errno.h>
#include <stdlib.h>

View File

@ -1,4 +1,36 @@
// cdrom.c
//------------------------------------------------------------------------------
// Copyright (c) 2001-2003, OpenBeOS
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: cdrom.c
// Author: Tyler Dauwalder (tyler@dauwalder.net)
// Description: disk_scanner session module for SCSI/ATAPI cdrom drives
//------------------------------------------------------------------------------
/*!
\file cdrom.c
disk_scanner session module for SCSI/ATAPI cdrom drives
The protocols used in this module are based on information taken
from the "SCSI-3 Multimedia Commands" draft, revision 10A.
*/
#include <errno.h>
#include <stdlib.h>
@ -11,11 +43,12 @@
#include <scsi.h>
#include <disk_scanner/session.h>
#define TRACE(x)
//#define TRACE(x) dprintf x
static void dump_full_table_of_contents(uchar *data, uint16 data_length);
#define ISO9660_SESSION_MODULE_NAME "disk_scanner/session/cdrom/v1"
//#define DBG(y) (y)
#define DBG(y)
#define TRACE(x) DBG(dprintf x)
#define CDROM_SESSION_MODULE_NAME "disk_scanner/session/cdrom/v1"
static const char *kModuleDebugName = "session/cdrom";
/*! \brief raw_device_command flags
@ -27,6 +60,10 @@ const uint8 kScsiFlags = B_RAW_DEVICE_DATA_IN
| B_RAW_DEVICE_SHORT_READ_VALID;
/*! \brief Timeout value used when making scsi commands
I'm honestly not sure what value to use here. It's currently
1 second because I got sick of waiting for the timeout while
figuring out how to get the commands to work.
*/
const uint32 kScsiTimeout = 1000000;
@ -37,7 +74,7 @@ typedef struct {
msf:1, //!< addressing format: 0 == LBA, 1 == MSF; try lba first, then msf if that fails
reserved1:3,
reserved0:3;
uint8 format:4, //!< sub-command: 0x0 == "TOC", 0x1 == "Session Info", 0x2 == "Full TOC"
uint8 format:4, //!< sub-command: 0x0 == "TOC", 0x1 == "Session Info", 0x2 == "Full TOC", ...
reserved3:4;
uint8 reserved4;
uint8 reserved5;
@ -47,12 +84,17 @@ typedef struct {
uint8 control; //!< control codes; 0x0 should be fine
} __attribute__((packed)) scsi_table_of_contents_command;
// formats of interest
// Some of the possible "READ TOC/PMA/ATIP" formats
const uint8 kTableOfContentsFormat = 0x00;
const uint8 kSessionFormat = 0x01;
const uint8 kFullTableOfContentsFormat = 0x10;
const uint8 kFullTableOfContentsFormat = 0x10; //!< "READ TOC/PMA/ATIP" format of interest
/*! \brief Minutes:Seconds:Frames format address
- Each msf frame corresponds to one logical block.
- Each msf second corresponds to 75 msf frames
- Each msf minute corresponds to 60 msf seconds
- Logical block 0 is at msf address 00:02:00
*/
typedef struct {
uint8 reserved;
@ -64,6 +106,8 @@ typedef struct {
#define CDROM_FRAMES_PER_SECOND (75)
#define CDROM_FRAMES_PER_MINUTE (CDROM_FRAMES_PER_SECOND*60)
/*! \brief Returns an initialized \c msf_address struct
*/
static
inline
msf_address
@ -77,6 +121,8 @@ make_msf_address(uint8 minutes, uint8 seconds, uint8 frames)
return result;
}
/*! \brief Converts the given msf address to lba format
*/
static
inline
uint32
@ -126,7 +172,6 @@ typedef struct {
uint8 pframes;
} cdrom_full_table_of_contents_entry;
// std_ops
static
status_t
@ -141,33 +186,12 @@ std_ops(int32 op, ...)
return B_ERROR;
}
// read_block
static
status_t
read_block(int fd, off_t offset, size_t size, uchar **block)
{
status_t error = (block && size > 0 ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
*block = malloc(size);
if (*block) {
if (read_pos(fd, offset, *block, size) != (ssize_t)size) {
error = errno;
if (error == B_OK)
error = B_ERROR;
free(*block);
*block = NULL;
}
} else
error = B_NO_MEMORY;
}
return error;
}
/*
static
void
dump_scsi_command(raw_device_command *cmd) {
int i;
int j;
uint j;
scsi_table_of_contents_command *scsi_command = (scsi_table_of_contents_command*)(&(cmd->command));
for (i = 0; i < cmd->command_length; i++)
@ -182,15 +206,15 @@ dump_scsi_command(raw_device_command *cmd) {
TRACE((" number = %d\n", scsi_command->number));
TRACE((" length = %d\n", B_BENDIAN_TO_HOST_INT16(scsi_command->length)));
TRACE((" control = %d\n", scsi_command->control));
TRACE((" command_length = %ld\n", cmd->command_length));
TRACE((" flags = %ld\n", cmd->flags));
TRACE((" scsi_status = 0x%lx\n", cmd->scsi_status));
TRACE((" cam_status = 0x%lx\n", cmd->cam_status));
TRACE((" command_length = %d\n", cmd->command_length));
TRACE((" flags = %d\n", cmd->flags));
TRACE((" scsi_status = 0x%x\n", cmd->scsi_status));
TRACE((" cam_status = 0x%x\n", cmd->cam_status));
TRACE((" data = %p\n", cmd->data));
TRACE((" data_length = %ld\n", cmd->data_length));
TRACE((" sense_data = %p\n", cmd->sense_data));
TRACE((" sense_data_length = %ld\n", cmd->sense_data_length));
TRACE((" timeout = %ld\n", cmd->timeout));
TRACE((" timeout = %lld\n", cmd->timeout));
TRACE(("data dump:\n"));
for (j = 0; j < 2048; j++) {//cmd->data_length; j++) {
uchar c = ((uchar*)cmd->data)[j];
@ -213,8 +237,122 @@ dump_scsi_command(raw_device_command *cmd) {
}
TRACE(("\n"));
}
*/
// cdrom_identify
static
void
dump_full_table_of_contents(uchar *data, uint16 data_length)
{
cdrom_table_of_contents_header *header;
cdrom_full_table_of_contents_entry *entries;
int i, count;
int header_length;
header = (cdrom_table_of_contents_header*)data;
entries = (cdrom_full_table_of_contents_entry*)(data+4);
header_length = B_BENDIAN_TO_HOST_INT16(header->length);
if (data_length < header_length) {
TRACE(("dump_full_table_of_contents: warning, data buffer not large enough (%d < %d)\n",
data_length, header_length));
header_length = data_length;
}
TRACE(("%s: table of contents dump:\n", kModuleDebugName));
TRACE(("--------------------------------------------------\n"));
TRACE(("header:\n"));
TRACE((" length = %d\n", header_length));
TRACE((" first = %d\n", header->first));
TRACE((" last = %d\n", header->last));
count = (header_length-2) / sizeof(cdrom_full_table_of_contents_entry);
TRACE(("\n"));
TRACE(("entry count = %d\n", count));
for (i = 0; i < count; i++) {
TRACE(("\n"));
TRACE(("entry #%d:\n", i));
TRACE((" session = %d\n", entries[i].session));
TRACE((" adr = %d\n", entries[i].adr));
TRACE((" control = %d\n", entries[i].control));
TRACE((" tno = %d\n", entries[i].tno));
TRACE((" point = %d (0x%.2x)\n", entries[i].point, entries[i].point));
TRACE((" minutes = %d\n", entries[i].minutes));
TRACE((" frames = %d\n", entries[i].seconds));
TRACE((" seconds = %d\n", entries[i].frames));
TRACE((" zero = %d\n", entries[i].zero));
TRACE((" pminutes = %d\n", entries[i].pminutes));
TRACE((" pseconds = %d\n", entries[i].pseconds));
TRACE((" pframes = %d\n", entries[i].pframes));
TRACE((" lba = %ld\n", msf_to_lba(make_msf_address(entries[i].pminutes,
entries[i].pseconds, entries[i].pframes))));
}
TRACE(("--------------------------------------------------\n"));
}
// read_table_of_contents
static
status_t
read_table_of_contents(int deviceFD, uint32 first_session, uchar *buffer,
uint16 buffer_length, bool msf)
{
scsi_table_of_contents_command scsi_command;
raw_device_command raw_command;
const uint32 sense_data_length = 1024;
uchar sense_data[sense_data_length];
status_t error = buffer ? B_OK : B_BAD_VALUE;
TRACE(("%s: read_table_of_contents: (%d, %p, %d)\n", kModuleDebugName,
deviceFD, buffer, buffer_length));
if (error)
return error;
// Init the scsi command and copy it into the BeOS "raw scsi command" ioctl struct
memset(raw_command.command, 0, 16);
scsi_command.command = 0x43;
scsi_command.msf = 0;
scsi_command.format = 2;
scsi_command.number = first_session;
scsi_command.length = B_HOST_TO_BENDIAN_INT16(buffer_length);
scsi_command.control = 0;
scsi_command.reserved0 = scsi_command.reserved1 = scsi_command.reserved2
= scsi_command.reserved3 = scsi_command.reserved4
= scsi_command.reserved5 = scsi_command.reserved6 = 0;
memcpy(raw_command.command, &scsi_command, sizeof(scsi_command));
// Init the rest of the raw command
raw_command.command_length = 10;
raw_command.flags = kScsiFlags;
raw_command.scsi_status = 0;
raw_command.cam_status = 0;
raw_command.data = buffer;
raw_command.data_length = buffer_length;
memset(raw_command.data, 0, raw_command.data_length);
raw_command.sense_data = sense_data;
raw_command.sense_data_length = sense_data_length;
memset(raw_command.sense_data, 0, raw_command.sense_data_length);
raw_command.timeout = kScsiTimeout;
if (ioctl(deviceFD, B_RAW_DEVICE_COMMAND, &raw_command) == 0) {
if (raw_command.scsi_status == 0 && raw_command.cam_status == 1) {
// SUCCESS!!!
DBG(dump_full_table_of_contents(buffer, buffer_length));
} else {
error = B_FILE_ERROR;
TRACE(("%s: scsi ioctl succeeded, but scsi command failed\n",
kModuleDebugName));
}
} else {
error = errno;
TRACE(("%s: scsi command failed with error 0x%lx\n", kModuleDebugName,
error));
}
return error;
}
// cdrom_session_identify
static
bool
cdrom_session_identify(int deviceFD, off_t deviceSize, int32 blockSize)
@ -231,154 +369,37 @@ cdrom_session_identify(int deviceFD, off_t deviceSize, int32 blockSize)
// cdrom_session_get_nth_info
static
status_t
read_table_of_contents(int deviceFD, uint32 first_session, uchar *buffer,
uint16 buffer_length, bool msf)
{
raw_device_command raw_command;
scsi_table_of_contents_command *scsi_command = NULL;
const uint32 sense_data_length = 1024;
uchar sense_data[sense_data_length];
status_t error = buffer ? B_OK : B_BAD_VALUE;
scsi_table_of_contents_command cmdo;
TRACE(("%s: read_table_of_contents: (%d, %p, %ld)\n", kModuleDebugName,
deviceFD, buffer, buffer_length));
if (error)
return error;
memset(raw_command.command, 0, 16);
scsi_command = (scsi_table_of_contents_command*)(raw_command.command);
cmdo.command = 0x43;
cmdo.msf = 0;
cmdo.format = 2;
cmdo.number = first_session;
cmdo.length = B_HOST_TO_BENDIAN_INT16(buffer_length);
cmdo.control = 0;
cmdo.reserved0 = cmdo.reserved1 = cmdo.reserved2 = cmdo.reserved3 = cmdo.reserved4
= cmdo.reserved5 = cmdo.reserved6 = 0;
/* scsi_command->command = 0x43;
scsi_command->msf = msf;
dprintf("format == 0x%lx\n", scsi_command->format);
scsi_command->format = 0x10;//kFullTableOfContentsFormat;
dprintf("format == 0x%lx\n", scsi_command->format);
scsi_command->number = 0;
scsi_command->length = B_HOST_TO_BENDIAN_INT16(buffer_length);
scsi_command->control = 0;
scsi_command->reserved0 = scsi_command->reserved1 = scsi_command->reserved2
= scsi_command->reserved3 = scsi_command->reserved4
= scsi_command->reserved5 = scsi_command->reserved6 = 0;
*/
memcpy(raw_command.command, &cmdo, sizeof(cmdo));
raw_command.command_length = 10;
raw_command.flags = kScsiFlags;
raw_command.scsi_status = 0;
raw_command.cam_status = 0;
raw_command.data = buffer;
raw_command.data_length = buffer_length;
memset(raw_command.data, 0, raw_command.data_length);
raw_command.sense_data = sense_data;
raw_command.sense_data_length = sense_data_length;
memset(raw_command.sense_data, 0, raw_command.sense_data_length);
raw_command.timeout = kScsiTimeout;
dump_scsi_command((uchar*)&raw_command);
if (ioctl(deviceFD, B_RAW_DEVICE_COMMAND, &raw_command) == 0) {
dump_scsi_command((uchar*)&raw_command);
if (raw_command.scsi_status == 0 && raw_command.cam_status == 1) {
// SUCCESS!!!
// dump_full_table_of_contents(buffer, buffer_length);
} else {
error = B_FILE_ERROR;
TRACE(("%s: scsi ioctl succeeded, but scsi command failed\n",
kModuleDebugName));
}
} else {
error = errno;
TRACE(("%s: scsi command failed with error 0x%lx\n", kModuleDebugName,
error));
}
return error;
}
static
void
dump_full_table_of_contents(uchar *data, uint16 data_length)
{
cdrom_table_of_contents_header *header;
cdrom_full_table_of_contents_entry *entries;
int i, count;
header = (cdrom_table_of_contents_header*)data;
entries = (cdrom_full_table_of_contents_entry*)(data+4);
header->length = B_BENDIAN_TO_HOST_INT16(header->length);
if (data_length < header->length) {
TRACE(("dump_full_table_of_contents: warning, data buffer not large enough (%ld < %ld)\n",
data_length, header->length));
header->length = data_length;
}
TRACE(("header:\n"));
TRACE((" length = %d\n", header->length));
TRACE((" first = %d\n", header->first));
TRACE((" last = %d\n", header->last));
count = (header->length-2) / sizeof(cdrom_full_table_of_contents_entry);
TRACE(("\n"));
TRACE(("entry count = %d\n", count));
TRACE(("\n"));
for (i = 0; i < count; i++) {
TRACE(("entry #%d:\n", i));
TRACE((" session = %d\n", entries[i].session));
TRACE((" adr = %d\n", entries[i].adr));
TRACE((" control = %d\n", entries[i].control));
TRACE((" tno = %d\n", entries[i].tno));
TRACE((" point = %d (0x%.2x)\n", entries[i].point, entries[i].point));
TRACE((" minutes = %d\n", entries[i].minutes));
TRACE((" frames = %d\n", entries[i].seconds));
TRACE((" seconds = %d\n", entries[i].frames));
TRACE((" zero = %d\n", entries[i].zero));
TRACE((" pminutes = %d\n", entries[i].pminutes));
TRACE((" pseconds = %d\n", entries[i].pseconds));
TRACE((" pframes = %d\n", entries[i].pframes));
TRACE((" lba = %ld\n", msf_to_lba(make_msf_address(entries[i].pminutes,
entries[i].pseconds, entries[i].pframes))));
TRACE(("\n"));
}
}
// cdrom_get_nth_info
static
status_t
cdrom_session_get_nth_info(int deviceFD, int32 index, off_t deviceSize,
int32 blockSize, struct session_info *sessionInfo)
{
status_t error = sessionInfo && index >= 0 ? B_OK : B_BAD_VALUE;
uchar data[2048];
int32 session = index+1;
bool found_track = false;
bool found_start = false;
bool found_end = false;
off_t start_lba = 0;
off_t end_lba = 0;
off_t end_lba = 0;
TRACE(("%s: get_nth_info(%d, %ld, %lld, %ld, %p)\n", kModuleDebugName,
deviceFD, index, deviceSize, blockSize, sessionInfo));
// As with identify(), this is just a bogus function that
// treats the whole device as a single session.
// Attempt to read the table of contents, first in lba mode, then in msf mode
if (!error) {
error = read_table_of_contents(deviceFD, index+1, data, 2048,
false);
error = read_table_of_contents(deviceFD, index+1, data, 2048, false);
}
if (error) {
TRACE(("%s: lba read_toc failed, trying msf instead\n", kModuleDebugName));
error = read_table_of_contents(deviceFD, index+1, data, 2048, true);
}
// Interpret the data returned, if successful
if (!error) {
cdrom_table_of_contents_header *header;
cdrom_full_table_of_contents_entry *entries;
int i, count;
int trace = 0;
int first_track = session;
header = (cdrom_table_of_contents_header*)data;
@ -391,44 +412,53 @@ cdrom_session_get_nth_info(int deviceFD, int32 index, off_t deviceSize,
if (session < header->first || session > header->last)
error = B_ENTRY_NOT_FOUND;
// Extract the data of interest
if (!error) {
for (i = 0; i < count; i++) {
switch (entries[i].point) {
case 0xa0:
// PMin holds first track in session
if (entries[i].session == session)
first_track = entries[i].pminutes;
// PMin holds first track in session
if (entries[i].session == session) {
first_track = entries[i].pminutes;
found_track = true;
}
break;
case 0xa2:
// PMSF holds end of session
if (entries[i].session == session) {
end_lba = msf_to_lba(make_msf_address(entries[i].pminutes,
entries[i].pseconds, entries[i].pframes));
trace++;
found_end = true;
}
break;
default:
if (entries[i].session == session && entries[i].point == first_track) {
if (!found_track) {
TRACE(("WARNING: %s: No \"first track in session\" info found; "
"using session as first track number\n", kModuleDebugName));
}
// PMSF holds start of session
start_lba = msf_to_lba(make_msf_address(entries[i].pminutes,
entries[i].pseconds, entries[i].pframes));
trace++;
found_start = true;
}
break;
}
}
}
if (trace == 2) {
if (found_start && found_end) {
TRACE(("%s: found session #%ld info\n", kModuleDebugName, session));
sessionInfo->offset = start_lba * blockSize;
sessionInfo->size = (end_lba - start_lba) * blockSize;
sessionInfo->logical_block_size = blockSize;
sessionInfo->index = index;
sessionInfo->flags = B_DATA_SESSION; // possibly B_AUDIO_SESSION for audio tracks?
// dump_full_table_of_contents(data);
} else {
dprintf("%s: bad trace: %d\n", kModuleDebugName, trace);
TRACE(("%s: error in table of contents data: %s\n", kModuleDebugName,
(found_start ? (found_end ? "(can't happen)" : "session end not found")
: (found_end ? "session start not found"
: "no session info found"))));
error = B_ENTRY_NOT_FOUND;
}
}
@ -437,7 +467,6 @@ cdrom_session_get_nth_info(int deviceFD, int32 index, off_t deviceSize,
if (error)
dprintf("%s: get_nth error 0x%lx\n", kModuleDebugName, error);
return error;
}
@ -445,7 +474,7 @@ static session_module_info cdrom_session_module =
{
// module_info
{
ISO9660_SESSION_MODULE_NAME,
CDROM_SESSION_MODULE_NAME,
0, // better B_KEEP_LOADED?
std_ops
},