This source file includes following definitions.
- sr_ioctl_done
- do_ioctl
- sr_ioctl
1 #ifdef MODULE
2 #include <linux/autoconf.h>
3 #include <linux/module.h>
4 #include <linux/version.h>
5 #endif
6
7 #include <linux/kernel.h>
8 #include <linux/sched.h>
9 #include <linux/mm.h>
10 #include <linux/fs.h>
11 #include <asm/segment.h>
12 #include <linux/errno.h>
13
14 #include <linux/blk.h>
15 #include "scsi.h"
16 #include "hosts.h"
17 #include "sr.h"
18 #include "scsi_ioctl.h"
19
20 #include <linux/cdrom.h>
21
22 #define IOCTL_RETRIES 3
23
24
25 #define IOCTL_TIMEOUT 3000
26
27 static void sr_ioctl_done(Scsi_Cmnd * SCpnt)
28 {
29 struct request * req;
30
31 req = &SCpnt->request;
32 req->rq_status = RQ_SCSI_DONE;
33
34 if (req->sem != NULL) {
35 up(req->sem);
36 }
37 }
38
39
40
41
42
43 static int do_ioctl(int target, unsigned char * sr_cmd, void * buffer, unsigned buflength)
44 {
45 Scsi_Cmnd * SCpnt;
46 int result;
47
48 SCpnt = allocate_device(NULL, scsi_CDs[target].device, 1);
49 {
50 struct semaphore sem = MUTEX_LOCKED;
51 SCpnt->request.sem = &sem;
52 scsi_do_cmd(SCpnt,
53 (void *) sr_cmd, buffer, buflength, sr_ioctl_done,
54 IOCTL_TIMEOUT, IOCTL_RETRIES);
55 down(&sem);
56 }
57
58 result = SCpnt->result;
59
60
61 if(driver_byte(result) != 0)
62 switch(SCpnt->sense_buffer[2] & 0xf) {
63 case UNIT_ATTENTION:
64 scsi_CDs[target].device->changed = 1;
65 printk("Disc change detected.\n");
66 break;
67 case NOT_READY:
68 printk("CDROM not ready. Make sure there is a disc in the drive.\n");
69 break;
70 case ILLEGAL_REQUEST:
71 printk("CDROM (ioctl) reports ILLEGAL REQUEST.\n");
72 break;
73 default:
74 printk("SCSI CD error: host %d id %d lun %d return code = %03x\n",
75 scsi_CDs[target].device->host->host_no,
76 scsi_CDs[target].device->id,
77 scsi_CDs[target].device->lun,
78 result);
79 printk("\tSense class %x, sense error %x, extended sense %x\n",
80 sense_class(SCpnt->sense_buffer[0]),
81 sense_error(SCpnt->sense_buffer[0]),
82 SCpnt->sense_buffer[2] & 0xf);
83
84 };
85
86 result = SCpnt->result;
87 SCpnt->request.rq_status = RQ_INACTIVE;
88 wake_up(&SCpnt->device->device_wait);
89
90 return result;
91 }
92
93 int sr_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
94 {
95 u_char sr_cmd[10];
96
97 kdev_t dev = inode->i_rdev;
98 int result, target, err;
99
100 target = MINOR(dev);
101
102 if (target >= sr_template.nr_dev ||
103 !scsi_CDs[target].device) return -ENXIO;
104
105 switch (cmd)
106 {
107
108 case CDROMPAUSE:
109
110 sr_cmd[0] = SCMD_PAUSE_RESUME;
111 sr_cmd[1] = scsi_CDs[target].device->lun << 5;
112 sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
113 sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
114 sr_cmd[8] = 0;
115 sr_cmd[9] = 0;
116
117 result = do_ioctl(target, sr_cmd, NULL, 255);
118 return result;
119
120 case CDROMRESUME:
121
122 sr_cmd[0] = SCMD_PAUSE_RESUME;
123 sr_cmd[1] = scsi_CDs[target].device->lun << 5;
124 sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
125 sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
126 sr_cmd[8] = 1;
127 sr_cmd[9] = 0;
128
129 result = do_ioctl(target, sr_cmd, NULL, 255);
130
131 return result;
132
133 case CDROMPLAYMSF:
134 {
135 struct cdrom_msf msf;
136
137 err = verify_area (VERIFY_READ, (void *) arg, sizeof (msf));
138 if (err) return err;
139
140 memcpy_fromfs(&msf, (void *) arg, sizeof(msf));
141
142 sr_cmd[0] = SCMD_PLAYAUDIO_MSF;
143 sr_cmd[1] = scsi_CDs[target].device->lun << 5;
144 sr_cmd[2] = 0;
145 sr_cmd[3] = msf.cdmsf_min0;
146 sr_cmd[4] = msf.cdmsf_sec0;
147 sr_cmd[5] = msf.cdmsf_frame0;
148 sr_cmd[6] = msf.cdmsf_min1;
149 sr_cmd[7] = msf.cdmsf_sec1;
150 sr_cmd[8] = msf.cdmsf_frame1;
151 sr_cmd[9] = 0;
152
153 result = do_ioctl(target, sr_cmd, NULL, 255);
154 return result;
155 }
156
157 case CDROMPLAYBLK:
158 {
159 struct cdrom_blk blk;
160
161 err = verify_area (VERIFY_READ, (void *) arg, sizeof (blk));
162 if (err) return err;
163
164 memcpy_fromfs(&blk, (void *) arg, sizeof(blk));
165
166 sr_cmd[0] = SCMD_PLAYAUDIO10;
167 sr_cmd[1] = scsi_CDs[target].device->lun << 5;
168 sr_cmd[2] = blk.from >> 24;
169 sr_cmd[3] = blk.from >> 16;
170 sr_cmd[4] = blk.from >> 8;
171 sr_cmd[5] = blk.from;
172 sr_cmd[6] = 0;
173 sr_cmd[7] = blk.len >> 8;
174 sr_cmd[8] = blk.len;
175 sr_cmd[9] = 0;
176
177 result = do_ioctl(target, sr_cmd, NULL, 255);
178 return result;
179 }
180
181 case CDROMPLAYTRKIND:
182 {
183 struct cdrom_ti ti;
184
185 err = verify_area (VERIFY_READ, (void *) arg, sizeof (ti));
186 if (err) return err;
187
188 memcpy_fromfs(&ti, (void *) arg, sizeof(ti));
189
190 sr_cmd[0] = SCMD_PLAYAUDIO_TI;
191 sr_cmd[1] = scsi_CDs[target].device->lun << 5;
192 sr_cmd[2] = 0;
193 sr_cmd[3] = 0;
194 sr_cmd[4] = ti.cdti_trk0;
195 sr_cmd[5] = ti.cdti_ind0;
196 sr_cmd[6] = 0;
197 sr_cmd[7] = ti.cdti_trk1;
198 sr_cmd[8] = ti.cdti_ind1;
199 sr_cmd[9] = 0;
200
201 result = do_ioctl(target, sr_cmd, NULL, 255);
202
203 return result;
204 }
205
206 case CDROMREADTOCHDR:
207 {
208 struct cdrom_tochdr tochdr;
209 char * buffer;
210
211 sr_cmd[0] = SCMD_READ_TOC;
212 sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 0x02;
213 sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
214 sr_cmd[6] = 0;
215 sr_cmd[7] = 0;
216 sr_cmd[8] = 12;
217 sr_cmd[9] = 0;
218
219 buffer = (unsigned char *) scsi_malloc(512);
220 if(!buffer) return -ENOMEM;
221
222 result = do_ioctl(target, sr_cmd, buffer, 12);
223
224 tochdr.cdth_trk0 = buffer[2];
225 tochdr.cdth_trk1 = buffer[3];
226
227 scsi_free(buffer, 512);
228
229 err = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_tochdr));
230 if (err)
231 return err;
232 memcpy_tofs ((void *) arg, &tochdr, sizeof (struct cdrom_tochdr));
233
234 return result;
235 }
236
237 case CDROMREADTOCENTRY:
238 {
239 struct cdrom_tocentry tocentry;
240 char * buffer;
241
242 err = verify_area (VERIFY_READ, (void *) arg, sizeof (struct cdrom_tocentry));
243 if (err) return err;
244
245 memcpy_fromfs (&tocentry, (void *) arg, sizeof (struct cdrom_tocentry));
246
247 sr_cmd[0] = SCMD_READ_TOC;
248 sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 0x02;
249 sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
250 sr_cmd[6] = tocentry.cdte_track;
251 sr_cmd[7] = 0;
252 sr_cmd[8] = 12;
253 sr_cmd[9] = 0;
254
255 buffer = (unsigned char *) scsi_malloc(512);
256 if(!buffer) return -ENOMEM;
257
258 result = do_ioctl (target, sr_cmd, buffer, 12);
259
260 if (tocentry.cdte_format == CDROM_MSF) {
261 tocentry.cdte_addr.msf.minute = buffer[9];
262 tocentry.cdte_addr.msf.second = buffer[10];
263 tocentry.cdte_addr.msf.frame = buffer[11];
264 tocentry.cdte_ctrl = buffer[5] & 0xf;
265 }
266 else
267 tocentry.cdte_addr.lba = (int) buffer[0];
268
269 scsi_free(buffer, 512);
270
271 err = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_tocentry));
272 if (err)
273 return err;
274 memcpy_tofs ((void *) arg, &tocentry, sizeof (struct cdrom_tocentry));
275
276 return result;
277 }
278
279 case CDROMSTOP:
280 sr_cmd[0] = START_STOP;
281 sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
282 sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
283 sr_cmd[4] = 0;
284
285 result = do_ioctl(target, sr_cmd, NULL, 255);
286 return result;
287
288 case CDROMSTART:
289 sr_cmd[0] = START_STOP;
290 sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
291 sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
292 sr_cmd[4] = 1;
293
294 result = do_ioctl(target, sr_cmd, NULL, 255);
295 return result;
296
297 case CDROMEJECT:
298
299
300
301 if (scsi_CDs[target].device -> access_count > 1)
302 return -EBUSY;
303
304 sr_ioctl (inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0);
305 sr_cmd[0] = START_STOP;
306 sr_cmd[1] = ((scsi_CDs[target].device -> lun) << 5) | 1;
307 sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
308 sr_cmd[4] = 0x02;
309
310 if (!(result = do_ioctl(target, sr_cmd, NULL, 255)))
311 scsi_CDs[target].device -> changed = 1;
312
313 return result;
314
315 case CDROMEJECT_SW:
316 scsi_CDs[target].auto_eject = !!arg;
317 return 0;
318
319 case CDROMVOLCTRL:
320 {
321 char * buffer, * mask;
322 struct cdrom_volctrl volctrl;
323
324 err = verify_area (VERIFY_READ, (void *) arg, sizeof (struct cdrom_volctrl));
325 if (err) return err;
326
327 memcpy_fromfs (&volctrl, (void *) arg, sizeof (struct cdrom_volctrl));
328
329
330
331 sr_cmd[0] = MODE_SENSE;
332 sr_cmd[1] = (scsi_CDs[target].device -> lun) << 5;
333 sr_cmd[2] = 0xe;
334 sr_cmd[3] = 0;
335 sr_cmd[4] = 28;
336 sr_cmd[5] = 0;
337
338 buffer = (unsigned char *) scsi_malloc(512);
339 if(!buffer) return -ENOMEM;
340
341 if ((result = do_ioctl (target, sr_cmd, buffer, 28))) {
342 printk ("Hosed while obtaining audio mode page\n");
343 scsi_free(buffer, 512);
344 return result;
345 }
346
347 sr_cmd[0] = MODE_SENSE;
348 sr_cmd[1] = (scsi_CDs[target].device -> lun) << 5;
349 sr_cmd[2] = 0x4e;
350 sr_cmd[3] = 0;
351 sr_cmd[4] = 28;
352 sr_cmd[5] = 0;
353
354 mask = (unsigned char *) scsi_malloc(512);
355 if(!mask) {
356 scsi_free(buffer, 512);
357 return -ENOMEM;
358 };
359
360 if ((result = do_ioctl (target, sr_cmd, mask, 28))) {
361 printk ("Hosed while obtaining mask for audio mode page\n");
362 scsi_free(buffer, 512);
363 scsi_free(mask, 512);
364 return result;
365 }
366
367
368 buffer[0] = 0;
369
370 buffer[21] = volctrl.channel0 & mask[21];
371 buffer[23] = volctrl.channel1 & mask[23];
372 buffer[25] = volctrl.channel2 & mask[25];
373 buffer[27] = volctrl.channel3 & mask[27];
374
375 sr_cmd[0] = MODE_SELECT;
376 sr_cmd[1] = ((scsi_CDs[target].device -> lun) << 5) | 0x10;
377 sr_cmd[2] = sr_cmd[3] = 0;
378 sr_cmd[4] = 28;
379 sr_cmd[5] = 0;
380
381 result = do_ioctl (target, sr_cmd, buffer, 28);
382 scsi_free(buffer, 512);
383 scsi_free(mask, 512);
384 return result;
385 }
386
387 case CDROMSUBCHNL:
388 {
389 struct cdrom_subchnl subchnl;
390 char * buffer;
391
392 sr_cmd[0] = SCMD_READ_SUBCHANNEL;
393 sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 0x02;
394 sr_cmd[2] = 0x40;
395 sr_cmd[3] = 0x01;
396 sr_cmd[4] = sr_cmd[5] = 0;
397 sr_cmd[6] = 0;
398 sr_cmd[7] = 0;
399 sr_cmd[8] = 16;
400 sr_cmd[9] = 0;
401
402 buffer = (unsigned char*) scsi_malloc(512);
403 if(!buffer) return -ENOMEM;
404
405 result = do_ioctl(target, sr_cmd, buffer, 16);
406
407 subchnl.cdsc_audiostatus = buffer[1];
408 subchnl.cdsc_format = CDROM_MSF;
409 subchnl.cdsc_ctrl = buffer[5] & 0xf;
410 subchnl.cdsc_trk = buffer[6];
411 subchnl.cdsc_ind = buffer[7];
412
413 subchnl.cdsc_reladdr.msf.minute = buffer[13];
414 subchnl.cdsc_reladdr.msf.second = buffer[14];
415 subchnl.cdsc_reladdr.msf.frame = buffer[15];
416 subchnl.cdsc_absaddr.msf.minute = buffer[9];
417 subchnl.cdsc_absaddr.msf.second = buffer[10];
418 subchnl.cdsc_absaddr.msf.frame = buffer[11];
419
420 scsi_free(buffer, 512);
421
422 err = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_subchnl));
423 if (err)
424 return err;
425 memcpy_tofs ((void *) arg, &subchnl, sizeof (struct cdrom_subchnl));
426 return result;
427 }
428
429 case CDROMREADMODE2:
430 return -EINVAL;
431 case CDROMREADMODE1:
432 return -EINVAL;
433
434
435 case CDROMMULTISESSION:
436 {
437 struct cdrom_multisession ms_info;
438 long lba;
439
440 err = verify_area(VERIFY_READ, (void *) arg,
441 sizeof(struct cdrom_multisession));
442 if (err) return (err);
443
444 memcpy_fromfs(&ms_info, (void *) arg, sizeof(struct cdrom_multisession));
445
446 if (ms_info.addr_format==CDROM_MSF) {
447 lba = scsi_CDs[target].mpcd_sector+CD_BLOCK_OFFSET;
448 ms_info.addr.msf.minute = lba / (CD_SECS*CD_FRAMES);
449 lba %= CD_SECS*CD_FRAMES;
450 ms_info.addr.msf.second = lba / CD_FRAMES;
451 ms_info.addr.msf.frame = lba % CD_FRAMES;
452 } else if (ms_info.addr_format==CDROM_LBA)
453 ms_info.addr.lba=scsi_CDs[target].mpcd_sector;
454 else return (-EINVAL);
455
456 ms_info.xa_flag=scsi_CDs[target].xa_flags & 0x01;
457
458 err=verify_area(VERIFY_WRITE,(void *) arg,
459 sizeof(struct cdrom_multisession));
460 if (err) return (err);
461
462 memcpy_tofs((void *) arg, &ms_info, sizeof(struct cdrom_multisession));
463 return (0);
464 }
465
466 case BLKRASET:
467 if(!suser()) return -EACCES;
468 if(!(inode->i_rdev)) return -EINVAL;
469 if(arg > 0xff) return -EINVAL;
470 read_ahead[MAJOR(inode->i_rdev)] = arg;
471 return 0;
472 RO_IOCTLS(dev,arg);
473 default:
474 return scsi_ioctl(scsi_CDs[target].device,cmd,(void *) arg);
475 }
476 }
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495