xref: /linux/drivers/scsi/sr_vendor.c (revision 396bbe1427828be1025fb052b7e04b42f421352d)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds /* -*-linux-c-*-
31da177e4SLinus Torvalds 
41da177e4SLinus Torvalds  * vendor-specific code for SCSI CD-ROM's goes here.
51da177e4SLinus Torvalds  *
61da177e4SLinus Torvalds  * This is needed becauce most of the new features (multisession and
71da177e4SLinus Torvalds  * the like) are too new to be included into the SCSI-II standard (to
81da177e4SLinus Torvalds  * be exact: there is'nt anything in my draft copy).
91da177e4SLinus Torvalds  *
101da177e4SLinus Torvalds  * Aug 1997: Ha! Got a SCSI-3 cdrom spec across my fingers. SCSI-3 does
111da177e4SLinus Torvalds  *           multisession using the READ TOC command (like SONY).
121da177e4SLinus Torvalds  *
131da177e4SLinus Torvalds  *           Rearranged stuff here: SCSI-3 is included allways, support
141da177e4SLinus Torvalds  *           for NEC/TOSHIBA/HP commands is optional.
151da177e4SLinus Torvalds  *
161da177e4SLinus Torvalds  *   Gerd Knorr <kraxel@cs.tu-berlin.de>
171da177e4SLinus Torvalds  *
181da177e4SLinus Torvalds  * --------------------------------------------------------------------------
191da177e4SLinus Torvalds  *
201da177e4SLinus Torvalds  * support for XA/multisession-CD's
211da177e4SLinus Torvalds  *
221da177e4SLinus Torvalds  *   - NEC:     Detection and support of multisession CD's.
231da177e4SLinus Torvalds  *
241da177e4SLinus Torvalds  *   - TOSHIBA: Detection and support of multisession CD's.
251da177e4SLinus Torvalds  *              Some XA-Sector tweaking, required for older drives.
261da177e4SLinus Torvalds  *
271da177e4SLinus Torvalds  *   - SONY:    Detection and support of multisession CD's.
281da177e4SLinus Torvalds  *              added by Thomas Quinot <thomas@cuivre.freenix.fr>
291da177e4SLinus Torvalds  *
301da177e4SLinus Torvalds  *   - PIONEER, HITACHI, PLEXTOR, MATSHITA, TEAC, PHILIPS: known to
311da177e4SLinus Torvalds  *              work with SONY (SCSI3 now)  code.
321da177e4SLinus Torvalds  *
331da177e4SLinus Torvalds  *   - HP:      Much like SONY, but a little different... (Thomas)
341da177e4SLinus Torvalds  *              HP-Writers only ??? Maybe other CD-Writers work with this too ?
351da177e4SLinus Torvalds  *              HP 6020 writers now supported.
361da177e4SLinus Torvalds  */
371da177e4SLinus Torvalds 
381da177e4SLinus Torvalds #include <linux/cdrom.h>
391da177e4SLinus Torvalds #include <linux/errno.h>
401da177e4SLinus Torvalds #include <linux/string.h>
411da177e4SLinus Torvalds #include <linux/bcd.h>
421da177e4SLinus Torvalds #include <linux/blkdev.h>
435a0e3ad6STejun Heo #include <linux/slab.h>
441da177e4SLinus Torvalds 
451da177e4SLinus Torvalds #include <scsi/scsi.h>
461da177e4SLinus Torvalds #include <scsi/scsi_cmnd.h>
471da177e4SLinus Torvalds #include <scsi/scsi_device.h>
481da177e4SLinus Torvalds #include <scsi/scsi_host.h>
491da177e4SLinus Torvalds #include <scsi/scsi_ioctl.h>
501da177e4SLinus Torvalds 
511da177e4SLinus Torvalds #include "sr.h"
521da177e4SLinus Torvalds 
531da177e4SLinus Torvalds #if 0
541da177e4SLinus Torvalds #define DEBUG
551da177e4SLinus Torvalds #endif
561da177e4SLinus Torvalds 
571da177e4SLinus Torvalds /* here are some constants to sort the vendors into groups */
581da177e4SLinus Torvalds 
591da177e4SLinus Torvalds #define VENDOR_SCSI3           1	/* default: scsi-3 mmc */
601da177e4SLinus Torvalds 
611da177e4SLinus Torvalds #define VENDOR_NEC             2
621da177e4SLinus Torvalds #define VENDOR_TOSHIBA         3
631da177e4SLinus Torvalds #define VENDOR_WRITER          4	/* pre-scsi3 writers */
64*396bbe14SDiego Elio Pettenò #define VENDOR_CYGNAL_85ED     5	/* CD-on-a-chip */
651da177e4SLinus Torvalds 
661da177e4SLinus Torvalds #define VENDOR_TIMEOUT	30*HZ
671da177e4SLinus Torvalds 
681da177e4SLinus Torvalds void sr_vendor_init(Scsi_CD *cd)
691da177e4SLinus Torvalds {
701da177e4SLinus Torvalds #ifndef CONFIG_BLK_DEV_SR_VENDOR
711da177e4SLinus Torvalds 	cd->vendor = VENDOR_SCSI3;
721da177e4SLinus Torvalds #else
737b32b8e0SMatthew Wilcox 	const char *vendor = cd->device->vendor;
747b32b8e0SMatthew Wilcox 	const char *model = cd->device->model;
751da177e4SLinus Torvalds 
761da177e4SLinus Torvalds 	/* default */
771da177e4SLinus Torvalds 	cd->vendor = VENDOR_SCSI3;
781da177e4SLinus Torvalds 	if (cd->readcd_known)
791da177e4SLinus Torvalds 		/* this is true for scsi3/mmc drives - no more checks */
801da177e4SLinus Torvalds 		return;
811da177e4SLinus Torvalds 
821da177e4SLinus Torvalds 	if (cd->device->type == TYPE_WORM) {
831da177e4SLinus Torvalds 		cd->vendor = VENDOR_WRITER;
841da177e4SLinus Torvalds 
851da177e4SLinus Torvalds 	} else if (!strncmp(vendor, "NEC", 3)) {
861da177e4SLinus Torvalds 		cd->vendor = VENDOR_NEC;
871da177e4SLinus Torvalds 		if (!strncmp(model, "CD-ROM DRIVE:25", 15) ||
881da177e4SLinus Torvalds 		    !strncmp(model, "CD-ROM DRIVE:36", 15) ||
891da177e4SLinus Torvalds 		    !strncmp(model, "CD-ROM DRIVE:83", 15) ||
901da177e4SLinus Torvalds 		    !strncmp(model, "CD-ROM DRIVE:84 ", 16)
911da177e4SLinus Torvalds #if 0
921da177e4SLinus Torvalds 		/* my NEC 3x returns the read-raw data if a read-raw
931da177e4SLinus Torvalds 		   is followed by a read for the same sector - aeb */
941da177e4SLinus Torvalds 		    || !strncmp(model, "CD-ROM DRIVE:500", 16)
951da177e4SLinus Torvalds #endif
961da177e4SLinus Torvalds 		    )
971da177e4SLinus Torvalds 			/* these can't handle multisession, may hang */
981da177e4SLinus Torvalds 			cd->cdi.mask |= CDC_MULTI_SESSION;
991da177e4SLinus Torvalds 
1001da177e4SLinus Torvalds 	} else if (!strncmp(vendor, "TOSHIBA", 7)) {
1011da177e4SLinus Torvalds 		cd->vendor = VENDOR_TOSHIBA;
1021da177e4SLinus Torvalds 
103*396bbe14SDiego Elio Pettenò 	} else if (!strncmp(vendor, "Beurer", 6) &&
104*396bbe14SDiego Elio Pettenò 		   !strncmp(model, "Gluco Memory", 12)) {
105*396bbe14SDiego Elio Pettenò 		/* The Beurer GL50 evo uses a Cygnal-manufactured CD-on-a-chip
106*396bbe14SDiego Elio Pettenò 		   that only accepts a subset of SCSI commands.  Most of the
107*396bbe14SDiego Elio Pettenò 		   not-implemented commands are fine to fail, but a few,
108*396bbe14SDiego Elio Pettenò 		   particularly around the MMC or Audio commands, will put the
109*396bbe14SDiego Elio Pettenò 		   device into an unrecoverable state, so they need to be
110*396bbe14SDiego Elio Pettenò 		   avoided at all costs.
111*396bbe14SDiego Elio Pettenò 		*/
112*396bbe14SDiego Elio Pettenò 		cd->vendor = VENDOR_CYGNAL_85ED;
113*396bbe14SDiego Elio Pettenò 		cd->cdi.mask |= (
114*396bbe14SDiego Elio Pettenò 			CDC_MULTI_SESSION |
115*396bbe14SDiego Elio Pettenò 			CDC_CLOSE_TRAY | CDC_OPEN_TRAY |
116*396bbe14SDiego Elio Pettenò 			CDC_LOCK |
117*396bbe14SDiego Elio Pettenò 			CDC_GENERIC_PACKET |
118*396bbe14SDiego Elio Pettenò 			CDC_PLAY_AUDIO
119*396bbe14SDiego Elio Pettenò 			);
1201da177e4SLinus Torvalds 	}
1211da177e4SLinus Torvalds #endif
1221da177e4SLinus Torvalds }
1231da177e4SLinus Torvalds 
1241da177e4SLinus Torvalds 
1251da177e4SLinus Torvalds /* small handy function for switching block length using MODE SELECT,
1261da177e4SLinus Torvalds  * used by sr_read_sector() */
1271da177e4SLinus Torvalds 
1281da177e4SLinus Torvalds int sr_set_blocklength(Scsi_CD *cd, int blocklength)
1291da177e4SLinus Torvalds {
1301da177e4SLinus Torvalds 	unsigned char *buffer;	/* the buffer for the ioctl */
1311da177e4SLinus Torvalds 	struct packet_command cgc;
1321da177e4SLinus Torvalds 	struct ccs_modesel_head *modesel;
1331da177e4SLinus Torvalds 	int rc, density = 0;
1341da177e4SLinus Torvalds 
1351da177e4SLinus Torvalds #ifdef CONFIG_BLK_DEV_SR_VENDOR
1361da177e4SLinus Torvalds 	if (cd->vendor == VENDOR_TOSHIBA)
1371da177e4SLinus Torvalds 		density = (blocklength > 2048) ? 0x81 : 0x83;
1381da177e4SLinus Torvalds #endif
1391da177e4SLinus Torvalds 
1405cbded58SRobert P. J. Day 	buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
1411da177e4SLinus Torvalds 	if (!buffer)
1421da177e4SLinus Torvalds 		return -ENOMEM;
1431da177e4SLinus Torvalds 
1441da177e4SLinus Torvalds #ifdef DEBUG
14596eefad2SHannes Reinecke 	sr_printk(KERN_INFO, cd, "MODE SELECT 0x%x/%d\n", density, blocklength);
1461da177e4SLinus Torvalds #endif
1471da177e4SLinus Torvalds 	memset(&cgc, 0, sizeof(struct packet_command));
1481da177e4SLinus Torvalds 	cgc.cmd[0] = MODE_SELECT;
1491da177e4SLinus Torvalds 	cgc.cmd[1] = (1 << 4);
1501da177e4SLinus Torvalds 	cgc.cmd[4] = 12;
1511da177e4SLinus Torvalds 	modesel = (struct ccs_modesel_head *) buffer;
1521da177e4SLinus Torvalds 	memset(modesel, 0, sizeof(*modesel));
1531da177e4SLinus Torvalds 	modesel->block_desc_length = 0x08;
1541da177e4SLinus Torvalds 	modesel->density = density;
1551da177e4SLinus Torvalds 	modesel->block_length_med = (blocklength >> 8) & 0xff;
1561da177e4SLinus Torvalds 	modesel->block_length_lo = blocklength & 0xff;
1571da177e4SLinus Torvalds 	cgc.buffer = buffer;
1581da177e4SLinus Torvalds 	cgc.buflen = sizeof(*modesel);
1591da177e4SLinus Torvalds 	cgc.data_direction = DMA_TO_DEVICE;
1601da177e4SLinus Torvalds 	cgc.timeout = VENDOR_TIMEOUT;
1611da177e4SLinus Torvalds 	if (0 == (rc = sr_do_ioctl(cd, &cgc))) {
1621da177e4SLinus Torvalds 		cd->device->sector_size = blocklength;
1631da177e4SLinus Torvalds 	}
1641da177e4SLinus Torvalds #ifdef DEBUG
1651da177e4SLinus Torvalds 	else
16696eefad2SHannes Reinecke 		sr_printk(KERN_INFO, cd,
16796eefad2SHannes Reinecke 			  "switching blocklength to %d bytes failed\n",
16896eefad2SHannes Reinecke 			  blocklength);
1691da177e4SLinus Torvalds #endif
1701da177e4SLinus Torvalds 	kfree(buffer);
1711da177e4SLinus Torvalds 	return rc;
1721da177e4SLinus Torvalds }
1731da177e4SLinus Torvalds 
1741da177e4SLinus Torvalds /* This function gets called after a media change. Checks if the CD is
1751da177e4SLinus Torvalds    multisession, asks for offset etc. */
1761da177e4SLinus Torvalds 
1771da177e4SLinus Torvalds int sr_cd_check(struct cdrom_device_info *cdi)
1781da177e4SLinus Torvalds {
1791da177e4SLinus Torvalds 	Scsi_CD *cd = cdi->handle;
1801da177e4SLinus Torvalds 	unsigned long sector;
1811da177e4SLinus Torvalds 	unsigned char *buffer;	/* the buffer for the ioctl */
1821da177e4SLinus Torvalds 	struct packet_command cgc;
1831da177e4SLinus Torvalds 	int rc, no_multi;
1841da177e4SLinus Torvalds 
1851da177e4SLinus Torvalds 	if (cd->cdi.mask & CDC_MULTI_SESSION)
1861da177e4SLinus Torvalds 		return 0;
1871da177e4SLinus Torvalds 
1885cbded58SRobert P. J. Day 	buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
1891da177e4SLinus Torvalds 	if (!buffer)
1901da177e4SLinus Torvalds 		return -ENOMEM;
1911da177e4SLinus Torvalds 
1921da177e4SLinus Torvalds 	sector = 0;		/* the multisession sector offset goes here  */
1931da177e4SLinus Torvalds 	no_multi = 0;		/* flag: the drive can't handle multisession */
1941da177e4SLinus Torvalds 	rc = 0;
1951da177e4SLinus Torvalds 
1961da177e4SLinus Torvalds 	memset(&cgc, 0, sizeof(struct packet_command));
1971da177e4SLinus Torvalds 
1981da177e4SLinus Torvalds 	switch (cd->vendor) {
1991da177e4SLinus Torvalds 
2001da177e4SLinus Torvalds 	case VENDOR_SCSI3:
2011da177e4SLinus Torvalds 		cgc.cmd[0] = READ_TOC;
2021da177e4SLinus Torvalds 		cgc.cmd[8] = 12;
2031da177e4SLinus Torvalds 		cgc.cmd[9] = 0x40;
2041da177e4SLinus Torvalds 		cgc.buffer = buffer;
2051da177e4SLinus Torvalds 		cgc.buflen = 12;
2061da177e4SLinus Torvalds 		cgc.quiet = 1;
2071da177e4SLinus Torvalds 		cgc.data_direction = DMA_FROM_DEVICE;
2081da177e4SLinus Torvalds 		cgc.timeout = VENDOR_TIMEOUT;
2091da177e4SLinus Torvalds 		rc = sr_do_ioctl(cd, &cgc);
2101da177e4SLinus Torvalds 		if (rc != 0)
2111da177e4SLinus Torvalds 			break;
2121da177e4SLinus Torvalds 		if ((buffer[0] << 8) + buffer[1] < 0x0a) {
21396eefad2SHannes Reinecke 			sr_printk(KERN_INFO, cd, "Hmm, seems the drive "
21496eefad2SHannes Reinecke 			   "doesn't support multisession CD's\n");
2151da177e4SLinus Torvalds 			no_multi = 1;
2161da177e4SLinus Torvalds 			break;
2171da177e4SLinus Torvalds 		}
2181da177e4SLinus Torvalds 		sector = buffer[11] + (buffer[10] << 8) +
2191da177e4SLinus Torvalds 		    (buffer[9] << 16) + (buffer[8] << 24);
2201da177e4SLinus Torvalds 		if (buffer[6] <= 1) {
2211da177e4SLinus Torvalds 			/* ignore sector offsets from first track */
2221da177e4SLinus Torvalds 			sector = 0;
2231da177e4SLinus Torvalds 		}
2241da177e4SLinus Torvalds 		break;
2251da177e4SLinus Torvalds 
2261da177e4SLinus Torvalds #ifdef CONFIG_BLK_DEV_SR_VENDOR
2271da177e4SLinus Torvalds 	case VENDOR_NEC:{
2281da177e4SLinus Torvalds 			unsigned long min, sec, frame;
2291da177e4SLinus Torvalds 			cgc.cmd[0] = 0xde;
2301da177e4SLinus Torvalds 			cgc.cmd[1] = 0x03;
2311da177e4SLinus Torvalds 			cgc.cmd[2] = 0xb0;
2321da177e4SLinus Torvalds 			cgc.buffer = buffer;
2331da177e4SLinus Torvalds 			cgc.buflen = 0x16;
2341da177e4SLinus Torvalds 			cgc.quiet = 1;
2351da177e4SLinus Torvalds 			cgc.data_direction = DMA_FROM_DEVICE;
2361da177e4SLinus Torvalds 			cgc.timeout = VENDOR_TIMEOUT;
2371da177e4SLinus Torvalds 			rc = sr_do_ioctl(cd, &cgc);
2381da177e4SLinus Torvalds 			if (rc != 0)
2391da177e4SLinus Torvalds 				break;
2401da177e4SLinus Torvalds 			if (buffer[14] != 0 && buffer[14] != 0xb0) {
24196eefad2SHannes Reinecke 				sr_printk(KERN_INFO, cd, "Hmm, seems the cdrom "
24296eefad2SHannes Reinecke 					  "doesn't support multisession CD's\n");
24396eefad2SHannes Reinecke 
2441da177e4SLinus Torvalds 				no_multi = 1;
2451da177e4SLinus Torvalds 				break;
2461da177e4SLinus Torvalds 			}
2472cee5dfaSAdrian Bunk 			min = bcd2bin(buffer[15]);
2482cee5dfaSAdrian Bunk 			sec = bcd2bin(buffer[16]);
2492cee5dfaSAdrian Bunk 			frame = bcd2bin(buffer[17]);
2501da177e4SLinus Torvalds 			sector = min * CD_SECS * CD_FRAMES + sec * CD_FRAMES + frame;
2511da177e4SLinus Torvalds 			break;
2521da177e4SLinus Torvalds 		}
2531da177e4SLinus Torvalds 
2541da177e4SLinus Torvalds 	case VENDOR_TOSHIBA:{
2551da177e4SLinus Torvalds 			unsigned long min, sec, frame;
2561da177e4SLinus Torvalds 
2571da177e4SLinus Torvalds 			/* we request some disc information (is it a XA-CD ?,
2581da177e4SLinus Torvalds 			 * where starts the last session ?) */
2591da177e4SLinus Torvalds 			cgc.cmd[0] = 0xc7;
2601da177e4SLinus Torvalds 			cgc.cmd[1] = 0x03;
2611da177e4SLinus Torvalds 			cgc.buffer = buffer;
2621da177e4SLinus Torvalds 			cgc.buflen = 4;
2631da177e4SLinus Torvalds 			cgc.quiet = 1;
2641da177e4SLinus Torvalds 			cgc.data_direction = DMA_FROM_DEVICE;
2651da177e4SLinus Torvalds 			cgc.timeout = VENDOR_TIMEOUT;
2661da177e4SLinus Torvalds 			rc = sr_do_ioctl(cd, &cgc);
2671da177e4SLinus Torvalds 			if (rc == -EINVAL) {
26896eefad2SHannes Reinecke 				sr_printk(KERN_INFO, cd, "Hmm, seems the drive "
26996eefad2SHannes Reinecke 					  "doesn't support multisession CD's\n");
2701da177e4SLinus Torvalds 				no_multi = 1;
2711da177e4SLinus Torvalds 				break;
2721da177e4SLinus Torvalds 			}
2731da177e4SLinus Torvalds 			if (rc != 0)
2741da177e4SLinus Torvalds 				break;
2752cee5dfaSAdrian Bunk 			min = bcd2bin(buffer[1]);
2762cee5dfaSAdrian Bunk 			sec = bcd2bin(buffer[2]);
2772cee5dfaSAdrian Bunk 			frame = bcd2bin(buffer[3]);
2781da177e4SLinus Torvalds 			sector = min * CD_SECS * CD_FRAMES + sec * CD_FRAMES + frame;
2791da177e4SLinus Torvalds 			if (sector)
2801da177e4SLinus Torvalds 				sector -= CD_MSF_OFFSET;
2811da177e4SLinus Torvalds 			sr_set_blocklength(cd, 2048);
2821da177e4SLinus Torvalds 			break;
2831da177e4SLinus Torvalds 		}
2841da177e4SLinus Torvalds 
2851da177e4SLinus Torvalds 	case VENDOR_WRITER:
2861da177e4SLinus Torvalds 		cgc.cmd[0] = READ_TOC;
2871da177e4SLinus Torvalds 		cgc.cmd[8] = 0x04;
2881da177e4SLinus Torvalds 		cgc.cmd[9] = 0x40;
2891da177e4SLinus Torvalds 		cgc.buffer = buffer;
2901da177e4SLinus Torvalds 		cgc.buflen = 0x04;
2911da177e4SLinus Torvalds 		cgc.quiet = 1;
2921da177e4SLinus Torvalds 		cgc.data_direction = DMA_FROM_DEVICE;
2931da177e4SLinus Torvalds 		cgc.timeout = VENDOR_TIMEOUT;
2941da177e4SLinus Torvalds 		rc = sr_do_ioctl(cd, &cgc);
2951da177e4SLinus Torvalds 		if (rc != 0) {
2961da177e4SLinus Torvalds 			break;
2971da177e4SLinus Torvalds 		}
2981da177e4SLinus Torvalds 		if ((rc = buffer[2]) == 0) {
29996eefad2SHannes Reinecke 			sr_printk(KERN_WARNING, cd,
30096eefad2SHannes Reinecke 				  "No finished session\n");
3011da177e4SLinus Torvalds 			break;
3021da177e4SLinus Torvalds 		}
3031da177e4SLinus Torvalds 		cgc.cmd[0] = READ_TOC;	/* Read TOC */
3041da177e4SLinus Torvalds 		cgc.cmd[6] = rc & 0x7f;	/* number of last session */
3051da177e4SLinus Torvalds 		cgc.cmd[8] = 0x0c;
3061da177e4SLinus Torvalds 		cgc.cmd[9] = 0x40;
3071da177e4SLinus Torvalds 		cgc.buffer = buffer;
3081da177e4SLinus Torvalds 		cgc.buflen = 12;
3091da177e4SLinus Torvalds 		cgc.quiet = 1;
3101da177e4SLinus Torvalds 		cgc.data_direction = DMA_FROM_DEVICE;
3111da177e4SLinus Torvalds 		cgc.timeout = VENDOR_TIMEOUT;
3121da177e4SLinus Torvalds 		rc = sr_do_ioctl(cd, &cgc);
3131da177e4SLinus Torvalds 		if (rc != 0) {
3141da177e4SLinus Torvalds 			break;
3151da177e4SLinus Torvalds 		}
3161da177e4SLinus Torvalds 		sector = buffer[11] + (buffer[10] << 8) +
3171da177e4SLinus Torvalds 		    (buffer[9] << 16) + (buffer[8] << 24);
3181da177e4SLinus Torvalds 		break;
3191da177e4SLinus Torvalds #endif				/* CONFIG_BLK_DEV_SR_VENDOR */
3201da177e4SLinus Torvalds 
3211da177e4SLinus Torvalds 	default:
3221da177e4SLinus Torvalds 		/* should not happen */
32396eefad2SHannes Reinecke 		sr_printk(KERN_WARNING, cd,
32496eefad2SHannes Reinecke 			  "unknown vendor code (%i), not initialized ?\n",
32596eefad2SHannes Reinecke 			  cd->vendor);
3261da177e4SLinus Torvalds 		sector = 0;
3271da177e4SLinus Torvalds 		no_multi = 1;
3281da177e4SLinus Torvalds 		break;
3291da177e4SLinus Torvalds 	}
3301da177e4SLinus Torvalds 	cd->ms_offset = sector;
3311da177e4SLinus Torvalds 	cd->xa_flag = 0;
3321da177e4SLinus Torvalds 	if (CDS_AUDIO != sr_disk_status(cdi) && 1 == sr_is_xa(cd))
3331da177e4SLinus Torvalds 		cd->xa_flag = 1;
3341da177e4SLinus Torvalds 
3351da177e4SLinus Torvalds 	if (2048 != cd->device->sector_size) {
3361da177e4SLinus Torvalds 		sr_set_blocklength(cd, 2048);
3371da177e4SLinus Torvalds 	}
3381da177e4SLinus Torvalds 	if (no_multi)
3391da177e4SLinus Torvalds 		cdi->mask |= CDC_MULTI_SESSION;
3401da177e4SLinus Torvalds 
3411da177e4SLinus Torvalds #ifdef DEBUG
3421da177e4SLinus Torvalds 	if (sector)
34396eefad2SHannes Reinecke 		sr_printk(KERN_DEBUG, cd, "multisession offset=%lu\n",
34496eefad2SHannes Reinecke 			  sector);
3451da177e4SLinus Torvalds #endif
3461da177e4SLinus Torvalds 	kfree(buffer);
3471da177e4SLinus Torvalds 	return rc;
3481da177e4SLinus Torvalds }
349