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