From e3e6d2db882430c0f63945f0bff584da39f0f8f2 Mon Sep 17 00:00:00 2001 From: Tyler Dauwalder Date: Thu, 16 Jan 2003 08:26:22 +0000 Subject: [PATCH] + 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 --- headers/private/disk_scanner/disk_scanner.h | 32 +- headers/private/disk_scanner/fs.h | 31 +- headers/private/disk_scanner/partition.h | 32 +- headers/private/disk_scanner/session.h | 31 +- .../kernel/disk_scanner/disk_scanner.c | 31 +- src/add-ons/kernel/disk_scanner/fs/bfs.c | 35 +- src/add-ons/kernel/disk_scanner/fs/iso9660.c | 36 +- .../kernel/disk_scanner/partition/intel.c | 31 +- .../kernel/disk_scanner/session/cdrom.c | 391 ++++++++++-------- 9 files changed, 458 insertions(+), 192 deletions(-) diff --git a/headers/private/disk_scanner/disk_scanner.h b/headers/private/disk_scanner/disk_scanner.h index 63d02244fe..1d8b51c68a 100644 --- a/headers/private/disk_scanner/disk_scanner.h +++ b/headers/private/disk_scanner/disk_scanner.h @@ -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 diff --git a/headers/private/disk_scanner/fs.h b/headers/private/disk_scanner/fs.h index 7b87fb55a8..daa5d42254 100644 --- a/headers/private/disk_scanner/fs.h +++ b/headers/private/disk_scanner/fs.h @@ -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 diff --git a/headers/private/disk_scanner/partition.h b/headers/private/disk_scanner/partition.h index 56473e34c2..ee096dfbc7 100644 --- a/headers/private/disk_scanner/partition.h +++ b/headers/private/disk_scanner/partition.h @@ -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 diff --git a/headers/private/disk_scanner/session.h b/headers/private/disk_scanner/session.h index faff7e9501..1657e4f968 100644 --- a/headers/private/disk_scanner/session.h +++ b/headers/private/disk_scanner/session.h @@ -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 diff --git a/src/add-ons/kernel/disk_scanner/disk_scanner.c b/src/add-ons/kernel/disk_scanner/disk_scanner.c index 7092435706..2c44ad3345 100644 --- a/src/add-ons/kernel/disk_scanner/disk_scanner.c +++ b/src/add-ons/kernel/disk_scanner/disk_scanner.c @@ -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 #include diff --git a/src/add-ons/kernel/disk_scanner/fs/bfs.c b/src/add-ons/kernel/disk_scanner/fs/bfs.c index fc8417967e..9dc1b0ff83 100644 --- a/src/add-ons/kernel/disk_scanner/fs/bfs.c +++ b/src/add-ons/kernel/disk_scanner/fs/bfs.c @@ -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 #include @@ -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); diff --git a/src/add-ons/kernel/disk_scanner/fs/iso9660.c b/src/add-ons/kernel/disk_scanner/fs/iso9660.c index 7869fc4b76..23afd64e74 100644 --- a/src/add-ons/kernel/disk_scanner/fs/iso9660.c +++ b/src/add-ons/kernel/disk_scanner/fs/iso9660.c @@ -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 #include @@ -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; diff --git a/src/add-ons/kernel/disk_scanner/partition/intel.c b/src/add-ons/kernel/disk_scanner/partition/intel.c index bf8365ff15..5035e2c502 100644 --- a/src/add-ons/kernel/disk_scanner/partition/intel.c +++ b/src/add-ons/kernel/disk_scanner/partition/intel.c @@ -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 #include diff --git a/src/add-ons/kernel/disk_scanner/session/cdrom.c b/src/add-ons/kernel/disk_scanner/session/cdrom.c index 8cb35b3ce5..59406c43ee 100644 --- a/src/add-ons/kernel/disk_scanner/session/cdrom.c +++ b/src/add-ons/kernel/disk_scanner/session/cdrom.c @@ -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 #include @@ -11,11 +43,12 @@ #include #include -#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 },