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