^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* -*-linux-c-*-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * vendor-specific code for SCSI CD-ROM's goes here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This is needed becauce most of the new features (multisession and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * the like) are too new to be included into the SCSI-II standard (to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * be exact: there is'nt anything in my draft copy).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Aug 1997: Ha! Got a SCSI-3 cdrom spec across my fingers. SCSI-3 does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * multisession using the READ TOC command (like SONY).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Rearranged stuff here: SCSI-3 is included allways, support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * for NEC/TOSHIBA/HP commands is optional.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Gerd Knorr <kraxel@cs.tu-berlin.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * --------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * support for XA/multisession-CD's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * - NEC: Detection and support of multisession CD's.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * - TOSHIBA: Detection and support of multisession CD's.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * Some XA-Sector tweaking, required for older drives.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * - SONY: Detection and support of multisession CD's.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * added by Thomas Quinot <thomas@cuivre.freenix.fr>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * - PIONEER, HITACHI, PLEXTOR, MATSHITA, TEAC, PHILIPS: known to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * work with SONY (SCSI3 now) code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * - HP: Much like SONY, but a little different... (Thomas)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * HP-Writers only ??? Maybe other CD-Writers work with this too ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * HP 6020 writers now supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/cdrom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/bcd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <scsi/scsi_ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include "sr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* here are some constants to sort the vendors into groups */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define VENDOR_SCSI3 1 /* default: scsi-3 mmc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define VENDOR_NEC 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define VENDOR_TOSHIBA 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define VENDOR_WRITER 4 /* pre-scsi3 writers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define VENDOR_CYGNAL_85ED 5 /* CD-on-a-chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define VENDOR_TIMEOUT 30*HZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) void sr_vendor_init(Scsi_CD *cd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) const char *vendor = cd->device->vendor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) const char *model = cd->device->model;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /* default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) cd->vendor = VENDOR_SCSI3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (cd->readcd_known)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* this is true for scsi3/mmc drives - no more checks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (cd->device->type == TYPE_WORM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) cd->vendor = VENDOR_WRITER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) } else if (!strncmp(vendor, "NEC", 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) cd->vendor = VENDOR_NEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (!strncmp(model, "CD-ROM DRIVE:25", 15) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) !strncmp(model, "CD-ROM DRIVE:36", 15) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) !strncmp(model, "CD-ROM DRIVE:83", 15) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) !strncmp(model, "CD-ROM DRIVE:84 ", 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* my NEC 3x returns the read-raw data if a read-raw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) is followed by a read for the same sector - aeb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) || !strncmp(model, "CD-ROM DRIVE:500", 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* these can't handle multisession, may hang */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) cd->cdi.mask |= CDC_MULTI_SESSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) } else if (!strncmp(vendor, "TOSHIBA", 7)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) cd->vendor = VENDOR_TOSHIBA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) } else if (!strncmp(vendor, "Beurer", 6) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) !strncmp(model, "Gluco Memory", 12)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* The Beurer GL50 evo uses a Cygnal-manufactured CD-on-a-chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) that only accepts a subset of SCSI commands. Most of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) not-implemented commands are fine to fail, but a few,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) particularly around the MMC or Audio commands, will put the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) device into an unrecoverable state, so they need to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) avoided at all costs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) cd->vendor = VENDOR_CYGNAL_85ED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) cd->cdi.mask |= (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) CDC_MULTI_SESSION |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) CDC_CLOSE_TRAY | CDC_OPEN_TRAY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) CDC_LOCK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) CDC_GENERIC_PACKET |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) CDC_PLAY_AUDIO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /* small handy function for switching block length using MODE SELECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * used by sr_read_sector() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int sr_set_blocklength(Scsi_CD *cd, int blocklength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned char *buffer; /* the buffer for the ioctl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct packet_command cgc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct ccs_modesel_head *modesel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int rc, density = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (cd->vendor == VENDOR_TOSHIBA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) density = (blocklength > 2048) ? 0x81 : 0x83;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) buffer = kmalloc(512, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (!buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) sr_printk(KERN_INFO, cd, "MODE SELECT 0x%x/%d\n", density, blocklength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) memset(&cgc, 0, sizeof(struct packet_command));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) cgc.cmd[0] = MODE_SELECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) cgc.cmd[1] = (1 << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) cgc.cmd[4] = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) modesel = (struct ccs_modesel_head *) buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) memset(modesel, 0, sizeof(*modesel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) modesel->block_desc_length = 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) modesel->density = density;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) modesel->block_length_med = (blocklength >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) modesel->block_length_lo = blocklength & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) cgc.buffer = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) cgc.buflen = sizeof(*modesel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) cgc.data_direction = DMA_TO_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) cgc.timeout = VENDOR_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (0 == (rc = sr_do_ioctl(cd, &cgc))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) cd->device->sector_size = blocklength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) sr_printk(KERN_INFO, cd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) "switching blocklength to %d bytes failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) blocklength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) kfree(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* This function gets called after a media change. Checks if the CD is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) multisession, asks for offset etc. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) int sr_cd_check(struct cdrom_device_info *cdi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) Scsi_CD *cd = cdi->handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) unsigned long sector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) unsigned char *buffer; /* the buffer for the ioctl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct packet_command cgc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) int rc, no_multi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (cd->cdi.mask & CDC_MULTI_SESSION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) buffer = kmalloc(512, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (!buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) sector = 0; /* the multisession sector offset goes here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) no_multi = 0; /* flag: the drive can't handle multisession */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) memset(&cgc, 0, sizeof(struct packet_command));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) switch (cd->vendor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) case VENDOR_SCSI3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) cgc.cmd[0] = READ_TOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) cgc.cmd[8] = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) cgc.cmd[9] = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) cgc.buffer = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) cgc.buflen = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) cgc.quiet = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) cgc.data_direction = DMA_FROM_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) cgc.timeout = VENDOR_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) rc = sr_do_ioctl(cd, &cgc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (rc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if ((buffer[0] << 8) + buffer[1] < 0x0a) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) sr_printk(KERN_INFO, cd, "Hmm, seems the drive "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) "doesn't support multisession CD's\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) no_multi = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) sector = buffer[11] + (buffer[10] << 8) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) (buffer[9] << 16) + (buffer[8] << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (buffer[6] <= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* ignore sector offsets from first track */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) sector = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) case VENDOR_NEC:{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) unsigned long min, sec, frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) cgc.cmd[0] = 0xde;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) cgc.cmd[1] = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) cgc.cmd[2] = 0xb0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) cgc.buffer = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) cgc.buflen = 0x16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) cgc.quiet = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) cgc.data_direction = DMA_FROM_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) cgc.timeout = VENDOR_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) rc = sr_do_ioctl(cd, &cgc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (rc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (buffer[14] != 0 && buffer[14] != 0xb0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) sr_printk(KERN_INFO, cd, "Hmm, seems the cdrom "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) "doesn't support multisession CD's\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) no_multi = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) min = bcd2bin(buffer[15]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) sec = bcd2bin(buffer[16]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) frame = bcd2bin(buffer[17]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) sector = min * CD_SECS * CD_FRAMES + sec * CD_FRAMES + frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) case VENDOR_TOSHIBA:{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) unsigned long min, sec, frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* we request some disc information (is it a XA-CD ?,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * where starts the last session ?) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) cgc.cmd[0] = 0xc7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) cgc.cmd[1] = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) cgc.buffer = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) cgc.buflen = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) cgc.quiet = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) cgc.data_direction = DMA_FROM_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) cgc.timeout = VENDOR_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) rc = sr_do_ioctl(cd, &cgc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (rc == -EINVAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) sr_printk(KERN_INFO, cd, "Hmm, seems the drive "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) "doesn't support multisession CD's\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) no_multi = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (rc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) min = bcd2bin(buffer[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) sec = bcd2bin(buffer[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) frame = bcd2bin(buffer[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) sector = min * CD_SECS * CD_FRAMES + sec * CD_FRAMES + frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (sector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) sector -= CD_MSF_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) sr_set_blocklength(cd, 2048);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) case VENDOR_WRITER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) cgc.cmd[0] = READ_TOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) cgc.cmd[8] = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) cgc.cmd[9] = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) cgc.buffer = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) cgc.buflen = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) cgc.quiet = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) cgc.data_direction = DMA_FROM_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) cgc.timeout = VENDOR_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) rc = sr_do_ioctl(cd, &cgc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (rc != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if ((rc = buffer[2]) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) sr_printk(KERN_WARNING, cd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) "No finished session\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) cgc.cmd[0] = READ_TOC; /* Read TOC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) cgc.cmd[6] = rc & 0x7f; /* number of last session */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) cgc.cmd[8] = 0x0c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) cgc.cmd[9] = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) cgc.buffer = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) cgc.buflen = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) cgc.quiet = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) cgc.data_direction = DMA_FROM_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) cgc.timeout = VENDOR_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) rc = sr_do_ioctl(cd, &cgc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (rc != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) sector = buffer[11] + (buffer[10] << 8) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) (buffer[9] << 16) + (buffer[8] << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /* should not happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) sr_printk(KERN_WARNING, cd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) "unknown vendor code (%i), not initialized ?\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) cd->vendor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) sector = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) no_multi = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) cd->ms_offset = sector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) cd->xa_flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (CDS_AUDIO != sr_disk_status(cdi) && 1 == sr_is_xa(cd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) cd->xa_flag = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (2048 != cd->device->sector_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) sr_set_blocklength(cd, 2048);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (no_multi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) cdi->mask |= CDC_MULTI_SESSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (sector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) sr_printk(KERN_DEBUG, cd, "multisession offset=%lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) sector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) kfree(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }