drm/etnaviv: Implement mmap as GEM object function
[linux-2.6-microblaze.git] / drivers / ide / ide-cd_ioctl.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * cdrom.c IOCTLs handling for ide-cd driver.
4  *
5  * Copyright (C) 1994-1996  Scott Snyder <snyder@fnald0.fnal.gov>
6  * Copyright (C) 1996-1998  Erik Andersen <andersee@debian.org>
7  * Copyright (C) 1998-2000  Jens Axboe <axboe@suse.de>
8  */
9
10 #include <linux/kernel.h>
11 #include <linux/cdrom.h>
12 #include <linux/gfp.h>
13 #include <linux/ide.h>
14 #include <scsi/scsi.h>
15
16 #include "ide-cd.h"
17
18 /****************************************************************************
19  * Other driver requests (open, close, check media change).
20  */
21 int ide_cdrom_open_real(struct cdrom_device_info *cdi, int purpose)
22 {
23         return 0;
24 }
25
26 /*
27  * Close down the device.  Invalidate all cached blocks.
28  */
29 void ide_cdrom_release_real(struct cdrom_device_info *cdi)
30 {
31         ide_drive_t *drive = cdi->handle;
32
33         if (!cdi->use_count)
34                 drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID;
35 }
36
37 /*
38  * add logic to try GET_EVENT command first to check for media and tray
39  * status. this should be supported by newer cd-r/w and all DVD etc
40  * drives
41  */
42 int ide_cdrom_drive_status(struct cdrom_device_info *cdi, int slot_nr)
43 {
44         ide_drive_t *drive = cdi->handle;
45         struct media_event_desc med;
46         struct scsi_sense_hdr sshdr;
47         int stat;
48
49         if (slot_nr != CDSL_CURRENT)
50                 return -EINVAL;
51
52         stat = cdrom_check_status(drive, &sshdr);
53         if (!stat || sshdr.sense_key == UNIT_ATTENTION)
54                 return CDS_DISC_OK;
55
56         if (!cdrom_get_media_event(cdi, &med)) {
57                 if (med.media_present)
58                         return CDS_DISC_OK;
59                 else if (med.door_open)
60                         return CDS_TRAY_OPEN;
61                 else
62                         return CDS_NO_DISC;
63         }
64
65         if (sshdr.sense_key == NOT_READY && sshdr.asc == 0x04
66                         && sshdr.ascq == 0x04)
67                 return CDS_DISC_OK;
68
69         /*
70          * If not using Mt Fuji extended media tray reports,
71          * just return TRAY_OPEN since ATAPI doesn't provide
72          * any other way to detect this...
73          */
74         if (sshdr.sense_key == NOT_READY) {
75                 if (sshdr.asc == 0x3a && sshdr.ascq == 1)
76                         return CDS_NO_DISC;
77                 else
78                         return CDS_TRAY_OPEN;
79         }
80         return CDS_DRIVE_NOT_READY;
81 }
82
83 /*
84  * ide-cd always generates media changed event if media is missing, which
85  * makes it impossible to use for proper event reporting, so
86  * DISK_EVENT_FLAG_UEVENT is cleared in disk->event_flags
87  * and the following function is used only to trigger
88  * revalidation and never propagated to userland.
89  */
90 unsigned int ide_cdrom_check_events_real(struct cdrom_device_info *cdi,
91                                          unsigned int clearing, int slot_nr)
92 {
93         ide_drive_t *drive = cdi->handle;
94         int retval;
95
96         if (slot_nr == CDSL_CURRENT) {
97                 (void) cdrom_check_status(drive, NULL);
98                 retval = (drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED) ? 1 : 0;
99                 drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
100                 return retval ? DISK_EVENT_MEDIA_CHANGE : 0;
101         } else {
102                 return 0;
103         }
104 }
105
106 /* Eject the disk if EJECTFLAG is 0.
107    If EJECTFLAG is 1, try to reload the disk. */
108 static
109 int cdrom_eject(ide_drive_t *drive, int ejectflag)
110 {
111         struct cdrom_info *cd = drive->driver_data;
112         struct cdrom_device_info *cdi = &cd->devinfo;
113         char loej = 0x02;
114         unsigned char cmd[BLK_MAX_CDB];
115
116         if ((drive->atapi_flags & IDE_AFLAG_NO_EJECT) && !ejectflag)
117                 return -EDRIVE_CANT_DO_THIS;
118
119         /* reload fails on some drives, if the tray is locked */
120         if ((drive->atapi_flags & IDE_AFLAG_DOOR_LOCKED) && ejectflag)
121                 return 0;
122
123         /* only tell drive to close tray if open, if it can do that */
124         if (ejectflag && (cdi->mask & CDC_CLOSE_TRAY))
125                 loej = 0;
126
127         memset(cmd, 0, BLK_MAX_CDB);
128
129         cmd[0] = GPCMD_START_STOP_UNIT;
130         cmd[4] = loej | (ejectflag != 0);
131
132         return ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, NULL, 0, 0);
133 }
134
135 /* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */
136 static
137 int ide_cd_lockdoor(ide_drive_t *drive, int lockflag)
138 {
139         struct scsi_sense_hdr sshdr;
140         int stat;
141
142         /* If the drive cannot lock the door, just pretend. */
143         if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) {
144                 stat = 0;
145         } else {
146                 unsigned char cmd[BLK_MAX_CDB];
147
148                 memset(cmd, 0, BLK_MAX_CDB);
149
150                 cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
151                 cmd[4] = lockflag ? 1 : 0;
152
153                 stat = ide_cd_queue_pc(drive, cmd, 0, NULL, NULL,
154                                        &sshdr, 0, 0);
155         }
156
157         /* If we got an illegal field error, the drive
158            probably cannot lock the door. */
159         if (stat != 0 &&
160             sshdr.sense_key == ILLEGAL_REQUEST &&
161             (sshdr.asc == 0x24 || sshdr.asc == 0x20)) {
162                 printk(KERN_ERR "%s: door locking not supported\n",
163                         drive->name);
164                 drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
165                 stat = 0;
166         }
167
168         /* no medium, that's alright. */
169         if (stat != 0 && sshdr.sense_key == NOT_READY && sshdr.asc == 0x3a)
170                 stat = 0;
171
172         if (stat == 0) {
173                 if (lockflag)
174                         drive->atapi_flags |= IDE_AFLAG_DOOR_LOCKED;
175                 else
176                         drive->atapi_flags &= ~IDE_AFLAG_DOOR_LOCKED;
177         }
178
179         return stat;
180 }
181
182 int ide_cdrom_tray_move(struct cdrom_device_info *cdi, int position)
183 {
184         ide_drive_t *drive = cdi->handle;
185
186         if (position) {
187                 int stat = ide_cd_lockdoor(drive, 0);
188
189                 if (stat)
190                         return stat;
191         }
192
193         return cdrom_eject(drive, !position);
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);
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         u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE];
212         int stat;
213         unsigned char cmd[BLK_MAX_CDB];
214
215         if (speed == 0)
216                 speed = 0xffff; /* set to max */
217         else
218                 speed *= 177;   /* Nx to kbytes/s */
219
220         memset(cmd, 0, BLK_MAX_CDB);
221
222         cmd[0] = GPCMD_SET_SPEED;
223         /* Read Drive speed in kbytes/second MSB/LSB */
224         cmd[2] = (speed >> 8) & 0xff;
225         cmd[3] = speed & 0xff;
226         if ((cdi->mask & (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) !=
227             (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) {
228                 /* Write Drive speed in kbytes/second MSB/LSB */
229                 cmd[4] = (speed >> 8) & 0xff;
230                 cmd[5] = speed & 0xff;
231         }
232
233         stat = ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, NULL, 0, 0);
234
235         if (!ide_cdrom_get_capabilities(drive, buf)) {
236                 ide_cdrom_update_speed(drive, buf);
237                 cdi->speed = cd->current_speed;
238         }
239
240         return 0;
241 }
242
243 int ide_cdrom_get_last_session(struct cdrom_device_info *cdi,
244                                struct cdrom_multisession *ms_info)
245 {
246         struct atapi_toc *toc;
247         ide_drive_t *drive = cdi->handle;
248         struct cdrom_info *info = drive->driver_data;
249         int ret;
250
251         if ((drive->atapi_flags & IDE_AFLAG_TOC_VALID) == 0 || !info->toc) {
252                 ret = ide_cd_read_toc(drive);
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 *rq;
297         int ret;
298
299         rq = blk_get_request(drive->queue, REQ_OP_DRV_IN, 0);
300         ide_req(rq)->type = ATA_PRIV_MISC;
301         rq->rq_flags = RQF_QUIET;
302         blk_execute_rq(cd->disk, rq, 0);
303         ret = scsi_req(rq)->result ? -EIO : 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);
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         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, NULL, 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);
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         req_flags_t 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->sshdr)
456                 memset(cgc->sshdr, 0, sizeof(*cgc->sshdr));
457
458         if (cgc->quiet)
459                 flags |= RQF_QUIET;
460
461         cgc->stat = ide_cd_queue_pc(drive, cgc->cmd,
462                                     cgc->data_direction == CGC_DATA_WRITE,
463                                     cgc->buffer, &len,
464                                     cgc->sshdr, cgc->timeout, flags);
465         if (!cgc->stat)
466                 cgc->buflen -= len;
467         return cgc->stat;
468 }