This source file includes following definitions.
- lock_sr_ioctl
- unlock_sr_ioctl
- sr_ioctl_done
- do_ioctl
- sr_ioctl
1 #include <linux/config.h>
2 #ifdef CONFIG_BLK_DEV_SR
3 #include <linux/kernel.h>
4 #include <linux/sched.h>
5 #include <linux/fs.h>
6 #include <asm/segment.h>
7 #include <linux/errno.h>
8
9 #include "../blk.h"
10 #include "scsi.h"
11 #include "sr.h"
12 #include "scsi_ioctl.h"
13
14 #include <linux/cdrom.h>
15
16 #define IOCTL_RETRIES 3
17
18 #define IOCTL_TIMEOUT 200
19
20 static u_char sr_cmd[10];
21 static u_char data_buffer[255];
22 static u_char sense_buffer[255];
23 static int the_result;
24
25 static struct wait_queue *sr_cmd_wait = NULL;
26 static u_char sr_lock = 0;
27
28 static int target;
29
30 extern int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg);
31
32 static void lock_sr_ioctl( void )
33 {
34
35
36
37
38
39 while (sr_lock);
40 sr_lock = 1;
41 }
42
43 static void unlock_sr_ioctl( void )
44 {
45 sr_lock = 0;
46 }
47
48 static void sr_ioctl_done( int host, int result )
49 {
50 the_result = result;
51 wake_up(&sr_cmd_wait);
52 }
53
54
55
56
57
58 static int do_ioctl( void )
59 {
60 int retries = IOCTL_RETRIES;
61 retry:
62
63 the_result = -1;
64
65 scsi_do_cmd(scsi_CDs[target].device->host_no, scsi_CDs[target].device->id,
66 (void *) sr_cmd, (void *) data_buffer, 255, sr_ioctl_done,
67 IOCTL_TIMEOUT, (void *) sense_buffer, 0);
68
69 while (the_result < 0) sleep_on(&sr_cmd_wait);
70
71 if(driver_byte(the_result) != 0 &&
72 (sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
73 scsi_CDs[target].device->changed = 1;
74 printk("Disc change detected.\n");
75 };
76
77 if (the_result && retries)
78 {
79 retries--;
80 goto retry;
81 }
82
83
84 if(driver_byte(the_result) != 0)
85 switch(sense_buffer[2] & 0xf) {
86 case UNIT_ATTENTION:
87 scsi_CDs[target].device->changed = 1;
88 printk("Disc change detected.\n");
89 break;
90 case NOT_READY:
91 printk("CDROM not ready. Make sure there is a disc in the drive.\n");
92 break;
93 case ILLEGAL_REQUEST:
94 printk("CDROM (ioctl) reports ILLEGAL REQUEST.\n");
95 break;
96 default:
97 printk("SCSI CD error: host %d id %d lun %d return code = %03x\n",
98 scsi_CDs[target].device->host_no,
99 scsi_CDs[target].device->id,
100 scsi_CDs[target].device->lun,
101 the_result);
102 printk("\tSense class %x, sense error %x, extended sense %x\n",
103 sense_class(sense_buffer[0]),
104 sense_error(sense_buffer[0]),
105 sense_buffer[2] & 0xf);
106
107 };
108 return the_result;
109 }
110
111 int sr_ioctl(struct inode * inode, struct file * file, unsigned long cmd, unsigned long arg)
112 {
113 int dev = inode->i_rdev;
114 int result;
115
116 target = MINOR(dev);
117
118 switch (cmd)
119 {
120
121 case CDROMPAUSE:
122 lock_sr_ioctl();
123
124 sr_cmd[0] = SCMD_PAUSE_RESUME;
125 sr_cmd[1] = scsi_CDs[target].device->lun << 5;
126 sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
127 sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
128 sr_cmd[8] = 1;
129 sr_cmd[9] = 0;
130
131 result = do_ioctl();
132
133 unlock_sr_ioctl();
134 return result;
135
136 case CDROMRESUME:
137 lock_sr_ioctl();
138
139 sr_cmd[0] = SCMD_PAUSE_RESUME;
140 sr_cmd[1] = scsi_CDs[target].device->lun << 5;
141 sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
142 sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
143 sr_cmd[8] = 0;
144 sr_cmd[9] = 0;
145
146 result = do_ioctl();
147
148 unlock_sr_ioctl();
149 return result;
150
151 case CDROMPLAYMSF:
152 {
153 struct cdrom_msf msf;
154 lock_sr_ioctl();
155
156 memcpy_fromfs(&msf, (void *) arg, sizeof(msf));
157
158 sr_cmd[0] = SCMD_PLAYAUDIO_MSF;
159 sr_cmd[1] = scsi_CDs[target].device->lun << 5;
160 sr_cmd[2] = 0;
161 sr_cmd[3] = msf.cdmsf_min0;
162 sr_cmd[4] = msf.cdmsf_sec0;
163 sr_cmd[5] = msf.cdmsf_frame0;
164 sr_cmd[6] = msf.cdmsf_min1;
165 sr_cmd[7] = msf.cdmsf_sec1;
166 sr_cmd[8] = msf.cdmsf_frame1;
167 sr_cmd[9] = 0;
168
169 result = do_ioctl();
170
171 unlock_sr_ioctl();
172 return result;
173 }
174
175 case CDROMPLAYTRKIND:
176 {
177 struct cdrom_ti ti;
178 lock_sr_ioctl();
179
180 memcpy_fromfs(&ti, (void *) arg, sizeof(ti));
181
182 sr_cmd[0] = SCMD_PLAYAUDIO_TI;
183 sr_cmd[1] = scsi_CDs[target].device->lun << 5;
184 sr_cmd[2] = 0;
185 sr_cmd[3] = 0;
186 sr_cmd[4] = ti.cdti_trk0;
187 sr_cmd[5] = ti.cdti_ind0;
188 sr_cmd[6] = 0;
189 sr_cmd[7] = ti.cdti_trk1;
190 sr_cmd[8] = ti.cdti_ind1;
191 sr_cmd[9] = 0;
192
193 result = do_ioctl();
194
195 unlock_sr_ioctl();
196 return result;
197 }
198
199 case CDROMREADTOCHDR:
200 return -EINVAL;
201 case CDROMREADTOCENTRY:
202 return -EINVAL;
203
204 case CDROMSTOP:
205 lock_sr_ioctl();
206
207 sr_cmd[0] = START_STOP;
208 sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
209 sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
210 sr_cmd[4] = 0;
211
212 result = do_ioctl();
213
214 unlock_sr_ioctl();
215 return result;
216
217 case CDROMSTART:
218 lock_sr_ioctl();
219
220 sr_cmd[0] = START_STOP;
221 sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
222 sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
223 sr_cmd[4] = 1;
224
225 result = do_ioctl();
226
227 unlock_sr_ioctl();
228 return result;
229
230 case CDROMEJECT:
231 lock_sr_ioctl();
232
233 sr_cmd[0] = START_STOP;
234 sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
235 sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
236 sr_cmd[4] = 0x02;
237
238 result = do_ioctl();
239
240 unlock_sr_ioctl();
241 return result;
242
243 case CDROMVOLCTRL:
244 return -EINVAL;
245 case CDROMSUBCHNL:
246 return -EINVAL;
247 case CDROMREADMODE2:
248 return -EINVAL;
249 case CDROMREADMODE1:
250 return -EINVAL;
251
252 RO_IOCTLS(dev,arg);
253 default:
254 return scsi_ioctl(scsi_CDs[target].device,cmd,(void *) arg);
255 }
256 }
257
258 #endif