This source file includes following definitions.
- lock_sr_ioctl
- unlock_sr_ioctl
- sr_ioctl_done
- do_ioctl
- check_cdrom_media_change
- 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
13 #include <linux/cdrom.h>
14
15 #define IOCTL_RETRIES 3
16
17 #define IOCTL_TIMEOUT 200
18
19 static u_char sr_cmd[10];
20 static u_char data_buffer[255];
21 static u_char sense_buffer[255];
22 static int the_result;
23
24 static struct wait_queue *sr_cmd_wait = NULL;
25 static u_char sr_lock = 0;
26
27 static int target;
28
29 extern int scsi_ioctl (int dev, int cmd, void *arg);
30
31 static void lock_sr_ioctl( void )
32 {
33
34
35
36
37
38 while (sr_lock);
39 sr_lock = 1;
40 }
41
42 static void unlock_sr_ioctl( void )
43 {
44 sr_lock = 0;
45 }
46
47 static void sr_ioctl_done( int host, int result )
48 {
49 the_result = result;
50 wake_up(&sr_cmd_wait);
51 }
52
53
54
55
56
57 static int do_ioctl( void )
58 {
59 int retries = IOCTL_RETRIES;
60 retry:
61
62 the_result = -1;
63
64 scsi_do_cmd(scsi_CDs[target].device->host_no, scsi_CDs[target].device->id,
65 (void *) sr_cmd, (void *) data_buffer, 255, sr_ioctl_done,
66 IOCTL_TIMEOUT, (void *) sense_buffer, 0);
67
68 while (the_result < 0) sleep_on(&sr_cmd_wait);
69
70 if(driver_byte(the_result) != 0 &&
71 (sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
72 scsi_CDs[target].changed = 1;
73 printk("Disc change detected.\n");
74 };
75
76 if (the_result && retries)
77 {
78 retries--;
79 goto retry;
80 }
81
82
83 if(driver_byte(the_result) != 0)
84 switch(sense_buffer[2] & 0xf) {
85 case UNIT_ATTENTION:
86 scsi_CDs[target].changed = 1;
87 printk("Disc change detected.\n");
88 break;
89 case NOT_READY:
90 printk("CDROM not ready. Make sure there is a disc in the drive.\n");
91 break;
92 case ILLEGAL_REQUEST:
93 printk("CDROM (ioctl) reports ILLEGAL REQUEST.\n");
94 break;
95 default:
96 printk("SCSI CD error: host %d id %d lun %d return code = %03x\n",
97 scsi_CDs[target].device->host_no,
98 scsi_CDs[target].device->id,
99 scsi_CDs[target].device->lun,
100 the_result);
101 printk("\tSense class %x, sense error %x, extended sense %x\n",
102 sense_class(sense_buffer[0]),
103 sense_error(sense_buffer[0]),
104 sense_buffer[2] & 0xf);
105
106 };
107 return the_result;
108 }
109
110
111
112
113
114
115
116
117
118
119
120 int check_cdrom_media_change(int full_dev, int flag){
121 int retval;
122
123 lock_sr_ioctl();
124
125 target = MINOR(full_dev);
126
127 if (target >= NR_SR) {
128 printk("CD-ROM request error: invalid device.\n");
129 unlock_sr_ioctl();
130 return 0;
131 };
132
133 sr_cmd[0] = TEST_UNIT_READY;
134 sr_cmd[1] = (scsi_CDs[target].device->lun << 5) & 0xe0;
135 sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
136
137 retval = do_ioctl();
138
139 if(retval){
140
141
142
143
144 scsi_CDs[target].changed = 1;
145 unlock_sr_ioctl();
146 return 1;
147
148 };
149
150 retval = scsi_CDs[target].changed;
151 if(!flag) scsi_CDs[target].changed = 0;
152 unlock_sr_ioctl();
153
154 return retval;
155 }
156
157 int sr_ioctl(struct inode * inode, struct file * file, unsigned long cmd, unsigned long arg)
158 {
159 int dev = inode->i_rdev;
160 int result;
161
162 target = MINOR(dev);
163
164 switch (cmd)
165 {
166
167 case CDROMDOORUNLOCK:
168 lock_sr_ioctl();
169
170 sr_cmd[0] = ALLOW_MEDIUM_REMOVAL;
171 sr_cmd[1] = scsi_CDs[target].device->lun << 5;
172 sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
173 sr_cmd[4] = SR_REMOVAL_ALLOW;
174
175 result = do_ioctl();
176
177 unlock_sr_ioctl();
178 return result;
179
180 case CDROMDOORLOCK:
181 lock_sr_ioctl();
182
183 sr_cmd[0] = ALLOW_MEDIUM_REMOVAL;
184 sr_cmd[1] = scsi_CDs[target].device->lun << 5;
185 sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
186 sr_cmd[4] = SR_REMOVAL_PREVENT;
187
188 result = do_ioctl();
189
190 unlock_sr_ioctl();
191 return result;
192
193
194 case CDROMPAUSE:
195 lock_sr_ioctl();
196
197 sr_cmd[0] = SCMD_PAUSE_RESUME;
198 sr_cmd[1] = scsi_CDs[target].device->lun << 5;
199 sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
200 sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
201 sr_cmd[8] = 1;
202 sr_cmd[9] = 0;
203
204 result = do_ioctl();
205
206 unlock_sr_ioctl();
207 return result;
208
209 case CDROMRESUME:
210 lock_sr_ioctl();
211
212 sr_cmd[0] = SCMD_PAUSE_RESUME;
213 sr_cmd[1] = scsi_CDs[target].device->lun << 5;
214 sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
215 sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
216 sr_cmd[8] = 0;
217 sr_cmd[9] = 0;
218
219 result = do_ioctl();
220
221 unlock_sr_ioctl();
222 return result;
223
224 case CDROMPLAYMSF:
225 {
226 struct cdrom_msf msf;
227 lock_sr_ioctl();
228
229 memcpy_fromfs(&msf, (void *) arg, sizeof(msf));
230
231 sr_cmd[0] = SCMD_PLAYAUDIO_MSF;
232 sr_cmd[1] = scsi_CDs[target].device->lun << 5;
233 sr_cmd[2] = 0;
234 sr_cmd[3] = msf.cdmsf_min0;
235 sr_cmd[4] = msf.cdmsf_sec0;
236 sr_cmd[5] = msf.cdmsf_frame0;
237 sr_cmd[6] = msf.cdmsf_min1;
238 sr_cmd[7] = msf.cdmsf_sec1;
239 sr_cmd[8] = msf.cdmsf_frame1;
240 sr_cmd[9] = 0;
241
242 result = do_ioctl();
243
244 unlock_sr_ioctl();
245 return result;
246 }
247
248 case CDROMPLAYTRKIND:
249 {
250 struct cdrom_ti ti;
251 lock_sr_ioctl();
252
253 memcpy_fromfs(&ti, (void *) arg, sizeof(ti));
254
255 sr_cmd[0] = SCMD_PLAYAUDIO_TI;
256 sr_cmd[1] = scsi_CDs[target].device->lun << 5;
257 sr_cmd[2] = 0;
258 sr_cmd[3] = 0;
259 sr_cmd[4] = ti.cdti_trk0;
260 sr_cmd[5] = ti.cdti_ind0;
261 sr_cmd[6] = 0;
262 sr_cmd[7] = ti.cdti_trk1;
263 sr_cmd[8] = ti.cdti_ind1;
264 sr_cmd[9] = 0;
265
266 result = do_ioctl();
267
268 unlock_sr_ioctl();
269 return result;
270 }
271
272 case CDROMREADTOCHDR:
273 return -EINVAL;
274 case CDROMREADTOCENTRY:
275 return -EINVAL;
276
277 case CDROMSTOP:
278 lock_sr_ioctl();
279
280 sr_cmd[0] = START_STOP;
281 sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
282 sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
283 sr_cmd[4] = 0;
284
285 result = do_ioctl();
286
287 unlock_sr_ioctl();
288 return result;
289
290 case CDROMSTART:
291 lock_sr_ioctl();
292
293 sr_cmd[0] = START_STOP;
294 sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
295 sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
296 sr_cmd[4] = 1;
297
298 result = do_ioctl();
299
300 unlock_sr_ioctl();
301 return result;
302
303 case CDROMEJECT:
304 lock_sr_ioctl();
305
306 sr_cmd[0] = START_STOP;
307 sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
308 sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
309 sr_cmd[4] = 0x02;
310
311 result = do_ioctl();
312
313 unlock_sr_ioctl();
314 return result;
315
316 case CDROMVOLCTRL:
317 return -EINVAL;
318 case CDROMSUBCHNL:
319 return -EINVAL;
320 case CDROMREADMODE2:
321 return -EINVAL;
322 case CDROMREADMODE1:
323 return -EINVAL;
324
325 RO_IOCTLS(dev,arg);
326 default:
327 return scsi_ioctl(scsi_CDs[target].device,cmd,(void *) arg);
328 }
329 }
330
331 #endif