v2.5.0.7 -> v2.5.0.8
[opensuse:kernel.git] / drivers / block / block_ioctl.c
1 /*
2  * Copyright (C) 2001 Jens Axboe <axboe@suse.de>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public Licens
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-
17  *
18  */
19 #include <linux/sched.h>
20 #include <linux/kernel.h>
21 #include <linux/errno.h>
22 #include <linux/string.h>
23 #include <linux/config.h>
24 #include <linux/locks.h>
25 #include <linux/swap.h>
26 #include <linux/init.h>
27 #include <linux/smp_lock.h>
28 #include <linux/module.h>
29 #include <linux/blk.h>
30
31 #include <linux/cdrom.h>
32
33 int blk_do_rq(request_queue_t *q, struct request *rq)
34 {
35         DECLARE_COMPLETION(wait);
36         int err = 0;
37
38         rq->flags |= REQ_BARRIER;
39         rq->waiting = &wait;
40         elv_add_request(q, rq, 1);
41         generic_unplug_device(q);
42         wait_for_completion(&wait);
43
44         /*
45          * for now, never retry anything
46          */
47         if (rq->errors)
48                 err = -EIO;
49
50         return err;
51 }
52
53 int block_ioctl(kdev_t dev, unsigned int cmd, unsigned long arg)
54 {
55         request_queue_t *q;
56         struct request *rq;
57         int close = 0, err;
58
59         q = blk_get_queue(dev);
60         if (!q)
61                 return -ENXIO;
62
63         switch (cmd) {
64                 case CDROMCLOSETRAY:
65                         close = 1;
66                 case CDROMEJECT:
67                         rq = blk_get_request(q, WRITE, __GFP_WAIT);
68                         rq->flags = REQ_BLOCK_PC;
69                         memset(rq->cmd, 0, sizeof(rq->cmd));
70                         rq->cmd[0] = GPCMD_START_STOP_UNIT;
71                         rq->cmd[4] = 0x02 + (close != 0);
72                         err = blk_do_rq(q, rq);
73                         blk_put_request(rq);
74                         break;
75                 default:
76                         err = -ENOTTY;
77         }
78
79         return err;
80 }