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