]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/ide/ide-cd_ioctl.c
Merge branch 'stable/fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad...
[karo-tx-linux.git] / drivers / ide / ide-cd_ioctl.c
1 /*
2  * cdrom.c IOCTLs handling for ide-cd driver.
3  *
4  * Copyright (C) 1994-1996  Scott Snyder <snyder@fnald0.fnal.gov>
5  * Copyright (C) 1996-1998  Erik Andersen <andersee@debian.org>
6  * Copyright (C) 1998-2000  Jens Axboe <axboe@suse.de>
7  */
8
9 #include <linux/kernel.h>
10 #include <linux/cdrom.h>
11 #include <linux/gfp.h>
12 #include <linux/ide.h>
13 #include <scsi/scsi.h>
14
15 #include "ide-cd.h"
16
17 /****************************************************************************
18  * Other driver requests (open, close, check media change).
19  */
20 int ide_cdrom_open_real(struct cdrom_device_info *cdi, int purpose)
21 {
22         return 0;
23 }
24
25 /*
26  * Close down the device.  Invalidate all cached blocks.
27  */
28 void ide_cdrom_release_real(struct cdrom_device_info *cdi)
29 {
30         ide_drive_t *drive = cdi->handle;
31
32         if (!cdi->use_count)
33                 drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID;
34 }
35
36 /*
37  * add logic to try GET_EVENT command first to check for media and tray
38  * status. this should be supported by newer cd-r/w and all DVD etc
39  * drives
40  */
41 int ide_cdrom_drive_status(struct cdrom_device_info *cdi, int slot_nr)
42 {
43         ide_drive_t *drive = cdi->handle;
44         struct media_event_desc med;
45         struct request_sense sense;
46         int stat;
47
48         if (slot_nr != CDSL_CURRENT)
49                 return -EINVAL;
50
51         stat = cdrom_check_status(drive, &sense);
52         if (!stat || sense.sense_key == UNIT_ATTENTION)
53                 return CDS_DISC_OK;
54
55         if (!cdrom_get_media_event(cdi, &med)) {
56                 if (med.media_present)
57                         return CDS_DISC_OK;
58                 else if (med.door_open)
59                         return CDS_TRAY_OPEN;
60                 else
61                         return CDS_NO_DISC;
62         }
63
64         if (sense.sense_key == NOT_READY && sense.asc == 0x04
65                         && sense.ascq == 0x04)
66                 return CDS_DISC_OK;
67
68         /*
69          * If not using Mt Fuji extended media tray reports,
70          * just return TRAY_OPEN since ATAPI doesn't provide
71          * any other way to detect this...
72          */
73         if (sense.sense_key == NOT_READY) {
74                 if (sense.asc == 0x3a && sense.ascq == 1)
75                         return CDS_NO_DISC;
76                 else
77                         return CDS_TRAY_OPEN;
78         }
79         return CDS_DRIVE_NOT_READY;
80 }
81
82 int ide_cdrom_check_media_change_real(struct cdrom_device_info *cdi,
83                                        int slot_nr)
84 {
85         ide_drive_t *drive = cdi->handle;
86         int retval;
87
88         if (slot_nr == CDSL_CURRENT) {
89                 (void) cdrom_check_status(drive, NULL);
90                 retval = (drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED) ? 1 : 0;
91                 drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
92                 return retval;
93         } else {
94                 return -EINVAL;
95         }
96 }
97
98 /* Eject the disk if EJECTFLAG is 0.
99    If EJECTFLAG is 1, try to reload the disk. */
100 static
101 int cdrom_eject(ide_drive_t *drive, int ejectflag,
102                 struct request_sense *sense)
103 {
104         struct cdrom_info *cd = drive->driver_data;
105         struct cdrom_device_info *cdi = &cd->devinfo;
106         char loej = 0x02;
107         unsigned char cmd[BLK_MAX_CDB];
108
109         if ((drive->atapi_flags & IDE_AFLAG_NO_EJECT) && !ejectflag)
110                 return -EDRIVE_CANT_DO_THIS;
111
112         /* reload fails on some drives, if the tray is locked */
113         if ((drive->atapi_flags & IDE_AFLAG_DOOR_LOCKED) && ejectflag)
114                 return 0;
115
116         /* only tell drive to close tray if open, if it can do that */
117         if (ejectflag && (cdi->mask & CDC_CLOSE_TRAY))
118                 loej = 0;
119
120         memset(cmd, 0, BLK_MAX_CDB);
121
122         cmd[0] = GPCMD_START_STOP_UNIT;
123         cmd[4] = loej | (ejectflag != 0);
124
125         return ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, sense, 0, 0);
126 }
127
128 /* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */
129 static
130 int ide_cd_lockdoor(ide_drive_t *drive, int lockflag,
131                     struct request_sense *sense)
132 {
133         struct request_sense my_sense;
134         int stat;
135
136         if (sense == NULL)
137                 sense = &my_sense;
138
139         /* If the drive cannot lock the door, just pretend. */
140         if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) {
141                 stat = 0;
142         } else {
143                 unsigned char cmd[BLK_MAX_CDB];
144
145                 memset(cmd, 0, BLK_MAX_CDB);
146
147                 cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
148                 cmd[4] = lockflag ? 1 : 0;
149
150                 stat = ide_cd_queue_pc(drive, cmd, 0, NULL, NULL,
151                                        sense, 0, 0);
152         }
153
154         /* If we got an illegal field error, the drive
155            probably cannot lock the door. */
156         if (stat != 0 &&
157             sense->sense_key == ILLEGAL_REQUEST &&
158             (sense->asc == 0x24 || sense->asc == 0x20)) {
159                 printk(KERN_ERR "%s: door locking not supported\n",
160                         drive->name);
161                 drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
162                 stat = 0;
163         }
164
165         /* no medium, that's alright. */
166         if (stat != 0 && sense->sense_key == NOT_READY && sense->asc == 0x3a)
167                 stat = 0;
168
169         if (stat == 0) {
170                 if (lockflag)
171                         drive->atapi_flags |= IDE_AFLAG_DOOR_LOCKED;
172                 else
173                         drive->atapi_flags &= ~IDE_AFLAG_DOOR_LOCKED;
174         }
175
176         return stat;
177 }
178
179 int ide_cdrom_tray_move(struct cdrom_device_info *cdi, int position)
180 {
181         ide_drive_t *drive = cdi->handle;
182         struct request_sense sense;
183
184         if (position) {
185                 int stat = ide_cd_lockdoor(drive, 0, &sense);
186
187                 if (stat)
188                         return stat;
189         }
190
191         return cdrom_eject(drive, !position, &sense);
192 }
193
194 int ide_cdrom_lock_door(struct cdrom_device_info *cdi, int lock)
195 {
196         ide_drive_t *drive = cdi->handle;
197
198         return ide_cd_lockdoor(drive, lock, NULL);
199 }
200
201 /*
202  * ATAPI devices are free to select the speed you request or any slower
203  * rate. :-(  Requesting too fast a speed will _not_ produce an error.
204  */
205 int ide_cdrom_select_speed(struct cdrom_device_info *cdi, int speed)
206 {
207         ide_drive_t *drive = cdi->handle;
208         struct cdrom_info *cd = drive->driver_data;
209         struct request_sense sense;
210         u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE];
211         int stat;
212         unsigned char cmd[BLK_MAX_CDB];
213
214         if (speed == 0)
215                 speed = 0xffff; /* set to max */
216         else
217                 speed *= 177;   /* Nx to kbytes/s */
218
219         memset(cmd, 0, BLK_MAX_CDB);
220
221         cmd[0] = GPCMD_SET_SPEED;
222         /* Read Drive speed in kbytes/second MSB/LSB */
223         cmd[2] = (speed >> 8) & 0xff;
224         cmd[3] = speed & 0xff;
225         if ((cdi->mask & (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) !=
226             (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) {
227                 /* Write Drive speed in kbytes/second MSB/LSB */
228                 cmd[4] = (speed >> 8) & 0xff;
229                 cmd[5] = speed & 0xff;
230         }
231
232         stat = ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, &sense, 0, 0);
233
234         if (!ide_cdrom_get_capabilities(drive, buf)) {
235                 ide_cdrom_update_speed(drive, buf);
236                 cdi->speed = cd->current_speed;
237         }
238
239         return 0;
240 }
241
242 int ide_cdrom_get_last_session(struct cdrom_device_info *cdi,
243                                struct cdrom_multisession *ms_info)
244 {
245         struct atapi_toc *toc;
246         ide_drive_t *drive = cdi->handle;
247         struct cdrom_info *info = drive->driver_data;
248         struct request_sense sense;
249         int ret;
250
251         if ((drive->atapi_flags & IDE_AFLAG_TOC_VALID) == 0 || !info->toc) {
252                 ret = ide_cd_read_toc(drive, &sense);
253                 if (ret)
254                         return ret;
255         }
256
257         toc = info->toc;
258         ms_info->addr.lba = toc->last_session_lba;
259         ms_info->xa_flag = toc->xa_flag;
260
261         return 0;
262 }
263
264 int ide_cdrom_get_mcn(struct cdrom_device_info *cdi,
265                       struct cdrom_mcn *mcn_info)
266 {
267         ide_drive_t *drive = cdi->handle;
268         int stat, mcnlen;
269         char buf[24];
270         unsigned char cmd[BLK_MAX_CDB];
271         unsigned len = sizeof(buf);
272
273         memset(cmd, 0, BLK_MAX_CDB);
274
275         cmd[0] = GPCMD_READ_SUBCHANNEL;
276         cmd[1] = 2;             /* MSF addressing */
277         cmd[2] = 0x40;  /* request subQ data */
278         cmd[3] = 2;             /* format */
279         cmd[8] = len;
280
281         stat = ide_cd_queue_pc(drive, cmd, 0, buf, &len, NULL, 0, 0);
282         if (stat)
283                 return stat;
284
285         mcnlen = sizeof(mcn_info->medium_catalog_number) - 1;
286         memcpy(mcn_info->medium_catalog_number, buf + 9, mcnlen);
287         mcn_info->medium_catalog_number[mcnlen] = '\0';
288
289         return 0;
290 }
291
292 int ide_cdrom_reset(struct cdrom_device_info *cdi)
293 {
294         ide_drive_t *drive = cdi->handle;
295         struct cdrom_info *cd = drive->driver_data;
296         struct request_sense sense;
297         struct request *rq;
298         int ret;
299
300         rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
301         rq->cmd_type = REQ_TYPE_SPECIAL;
302         rq->cmd_flags = REQ_QUIET;
303         ret = blk_execute_rq(drive->queue, cd->disk, rq, 0);
304         blk_put_request(rq);
305         /*
306          * A reset will unlock the door. If it was previously locked,
307          * lock it again.
308          */
309         if (drive->atapi_flags & IDE_AFLAG_DOOR_LOCKED)
310                 (void)ide_cd_lockdoor(drive, 1, &sense);
311
312         return ret;
313 }
314
315 static int ide_cd_get_toc_entry(ide_drive_t *drive, int track,
316                                 struct atapi_toc_entry **ent)
317 {
318         struct cdrom_info *info = drive->driver_data;
319         struct atapi_toc *toc = info->toc;
320         int ntracks;
321
322         /*
323          * don't serve cached data, if the toc isn't valid
324          */
325         if ((drive->atapi_flags & IDE_AFLAG_TOC_VALID) == 0)
326                 return -EINVAL;
327
328         /* Check validity of requested track number. */
329         ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
330
331         if (toc->hdr.first_track == CDROM_LEADOUT)
332                 ntracks = 0;
333
334         if (track == CDROM_LEADOUT)
335                 *ent = &toc->ent[ntracks];
336         else if (track < toc->hdr.first_track || track > toc->hdr.last_track)
337                 return -EINVAL;
338         else
339                 *ent = &toc->ent[track - toc->hdr.first_track];
340
341         return 0;
342 }
343
344 static int ide_cd_fake_play_trkind(ide_drive_t *drive, void *arg)
345 {
346         struct cdrom_ti *ti = arg;
347         struct atapi_toc_entry *first_toc, *last_toc;
348         unsigned long lba_start, lba_end;
349         int stat;
350         struct request_sense sense;
351         unsigned char cmd[BLK_MAX_CDB];
352
353         stat = ide_cd_get_toc_entry(drive, ti->cdti_trk0, &first_toc);
354         if (stat)
355                 return stat;
356
357         stat = ide_cd_get_toc_entry(drive, ti->cdti_trk1, &last_toc);
358         if (stat)
359                 return stat;
360
361         if (ti->cdti_trk1 != CDROM_LEADOUT)
362                 ++last_toc;
363         lba_start = first_toc->addr.lba;
364         lba_end   = last_toc->addr.lba;
365
366         if (lba_end <= lba_start)
367                 return -EINVAL;
368
369         memset(cmd, 0, BLK_MAX_CDB);
370
371         cmd[0] = GPCMD_PLAY_AUDIO_MSF;
372         lba_to_msf(lba_start,   &cmd[3], &cmd[4], &cmd[5]);
373         lba_to_msf(lba_end - 1, &cmd[6], &cmd[7], &cmd[8]);
374
375         return ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, &sense, 0, 0);
376 }
377
378 static int ide_cd_read_tochdr(ide_drive_t *drive, void *arg)
379 {
380         struct cdrom_info *cd = drive->driver_data;
381         struct cdrom_tochdr *tochdr = arg;
382         struct atapi_toc *toc;
383         int stat;
384
385         /* Make sure our saved TOC is valid. */
386         stat = ide_cd_read_toc(drive, NULL);
387         if (stat)
388                 return stat;
389
390         toc = cd->toc;
391         tochdr->cdth_trk0 = toc->hdr.first_track;
392         tochdr->cdth_trk1 = toc->hdr.last_track;
393
394         return 0;
395 }
396
397 static int ide_cd_read_tocentry(ide_drive_t *drive, void *arg)
398 {
399         struct cdrom_tocentry *tocentry = arg;
400         struct atapi_toc_entry *toce;
401         int stat;
402
403         stat = ide_cd_get_toc_entry(drive, tocentry->cdte_track, &toce);
404         if (stat)
405                 return stat;
406
407         tocentry->cdte_ctrl = toce->control;
408         tocentry->cdte_adr  = toce->adr;
409         if (tocentry->cdte_format == CDROM_MSF) {
410                 lba_to_msf(toce->addr.lba,
411                            &tocentry->cdte_addr.msf.minute,
412                            &tocentry->cdte_addr.msf.second,
413                            &tocentry->cdte_addr.msf.frame);
414         } else
415                 tocentry->cdte_addr.lba = toce->addr.lba;
416
417         return 0;
418 }
419
420 int ide_cdrom_audio_ioctl(struct cdrom_device_info *cdi,
421                           unsigned int cmd, void *arg)
422 {
423         ide_drive_t *drive = cdi->handle;
424
425         switch (cmd) {
426         /*
427          * emulate PLAY_AUDIO_TI command with PLAY_AUDIO_10, since
428          * atapi doesn't support it
429          */
430         case CDROMPLAYTRKIND:
431                 return ide_cd_fake_play_trkind(drive, arg);
432         case CDROMREADTOCHDR:
433                 return ide_cd_read_tochdr(drive, arg);
434         case CDROMREADTOCENTRY:
435                 return ide_cd_read_tocentry(drive, arg);
436         default:
437                 return -EINVAL;
438         }
439 }
440
441 /* the generic packet interface to cdrom.c */
442 int ide_cdrom_packet(struct cdrom_device_info *cdi,
443                             struct packet_command *cgc)
444 {
445         ide_drive_t *drive = cdi->handle;
446         unsigned int flags = 0;
447         unsigned len = cgc->buflen;
448
449         if (cgc->timeout <= 0)
450                 cgc->timeout = ATAPI_WAIT_PC;
451
452         /* here we queue the commands from the uniform CD-ROM
453            layer. the packet must be complete, as we do not
454            touch it at all. */
455
456         if (cgc->data_direction == CGC_DATA_WRITE)
457                 flags |= REQ_WRITE;
458
459         if (cgc->sense)
460                 memset(cgc->sense, 0, sizeof(struct request_sense));
461
462         if (cgc->quiet)
463                 flags |= REQ_QUIET;
464
465         cgc->stat = ide_cd_queue_pc(drive, cgc->cmd,
466                                     cgc->data_direction == CGC_DATA_WRITE,
467                                     cgc->buffer, &len,
468                                     cgc->sense, cgc->timeout, flags);
469         if (!cgc->stat)
470                 cgc->buflen -= len;
471         return cgc->stat;
472 }