treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / scsi / sr_vendor.c
blob17a56c87d383a2797bb4f33973138e18e3fdd41c
1 // SPDX-License-Identifier: GPL-2.0
2 /* -*-linux-c-*-
4 * vendor-specific code for SCSI CD-ROM's goes here.
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).
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).
13 * Rearranged stuff here: SCSI-3 is included allways, support
14 * for NEC/TOSHIBA/HP commands is optional.
16 * Gerd Knorr <kraxel@cs.tu-berlin.de>
18 * --------------------------------------------------------------------------
20 * support for XA/multisession-CD's
22 * - NEC: Detection and support of multisession CD's.
24 * - TOSHIBA: Detection and support of multisession CD's.
25 * Some XA-Sector tweaking, required for older drives.
27 * - SONY: Detection and support of multisession CD's.
28 * added by Thomas Quinot <thomas@cuivre.freenix.fr>
30 * - PIONEER, HITACHI, PLEXTOR, MATSHITA, TEAC, PHILIPS: known to
31 * work with SONY (SCSI3 now) code.
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.
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>
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>
51 #include "sr.h"
53 #if 0
54 #define DEBUG
55 #endif
57 /* here are some constants to sort the vendors into groups */
59 #define VENDOR_SCSI3 1 /* default: scsi-3 mmc */
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 */
66 #define VENDOR_TIMEOUT 30*HZ
68 void sr_vendor_init(Scsi_CD *cd)
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;
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;
82 if (cd->device->type == TYPE_WORM) {
83 cd->vendor = VENDOR_WRITER;
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
97 /* these can't handle multisession, may hang */
98 cd->cdi.mask |= CDC_MULTI_SESSION;
100 } else if (!strncmp(vendor, "TOSHIBA", 7)) {
101 cd->vendor = VENDOR_TOSHIBA;
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.
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
121 #endif
125 /* small handy function for switching block length using MODE SELECT,
126 * used by sr_read_sector() */
128 int sr_set_blocklength(Scsi_CD *cd, int blocklength)
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;
135 #ifdef CONFIG_BLK_DEV_SR_VENDOR
136 if (cd->vendor == VENDOR_TOSHIBA)
137 density = (blocklength > 2048) ? 0x81 : 0x83;
138 #endif
140 buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
141 if (!buffer)
142 return -ENOMEM;
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;
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;
174 /* This function gets called after a media change. Checks if the CD is
175 multisession, asks for offset etc. */
177 int sr_cd_check(struct cdrom_device_info *cdi)
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;
185 if (cd->cdi.mask & CDC_MULTI_SESSION)
186 return 0;
188 buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
189 if (!buffer)
190 return -ENOMEM;
192 sector = 0; /* the multisession sector offset goes here */
193 no_multi = 0; /* flag: the drive can't handle multisession */
194 rc = 0;
196 memset(&cgc, 0, sizeof(struct packet_command));
198 switch (cd->vendor) {
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;
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;
224 break;
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");
244 no_multi = 1;
245 break;
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;
254 case VENDOR_TOSHIBA:{
255 unsigned long min, sec, frame;
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;
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;
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;
298 if ((rc = buffer[2]) == 0) {
299 sr_printk(KERN_WARNING, cd,
300 "No finished session\n");
301 break;
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;
316 sector = buffer[11] + (buffer[10] << 8) +
317 (buffer[9] << 16) + (buffer[8] << 24);
318 break;
319 #endif /* CONFIG_BLK_DEV_SR_VENDOR */
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;
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;
335 if (2048 != cd->device->sector_size) {
336 sr_set_blocklength(cd, 2048);
338 if (no_multi)
339 cdi->mask |= CDC_MULTI_SESSION;
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;