This source file includes following definitions.
- sr_release
- rw_intr
- sr_open
- do_sr_request
- sr_init
1
2
3
4
5
6
7
8
9
10
11
12 #include <linux/config.h>
13
14 #ifdef CONFIG_BLK_DEV_SR
15
16 #include <linux/fs.h>
17 #include <linux/kernel.h>
18 #include <linux/sched.h>
19 #include <linux/string.h>
20
21 #include "scsi.h"
22 #include "sr.h"
23
24 #define MAJOR_NR 11
25
26 #include "../blk.h"
27
28 #define MAX_RETRIES 0
29 #define SR_TIMEOUT 200
30
31 int NR_SR=0;
32 Scsi_CD scsi_CDs[MAX_SR];
33 static int sr_sizes[MAX_SR << 4];
34 static unsigned long int this_count;
35
36 struct block_buffer
37 {
38 unsigned block;
39 unsigned start;
40 unsigned use:1;
41 unsigned char buffer[2048];
42 };
43
44 static struct block_buffer bb[MAX_SR];
45
46 static int sr_result;
47
48 static int sr_open(struct inode *, struct file *);
49
50 extern int sr_ioctl(struct inode *, struct file *, unsigned int, unsigned int);
51
52 static void sr_release(struct inode * inode, struct file * file)
53 {
54 sync_dev(inode->i_rdev);
55 }
56
57 static struct file_operations sr_fops =
58 {
59 NULL,
60 block_read,
61 block_write,
62 NULL,
63 NULL,
64 sr_ioctl,
65 sr_open,
66 sr_release
67 };
68
69
70
71
72
73 static unsigned char sense_buffer[255];
74
75
76
77
78
79
80 static void rw_intr (int host, int result)
81 {
82 if (SR_HOST != host)
83 {
84 panic ("sr.o : rw_intr() recieving interrupt for different host.");
85 }
86
87 if (!result)
88 {
89 if (bb[DEVICE_NR(CURRENT->dev)].use)
90 {
91 memcpy((char *)CURRENT->buffer,
92 bb[DEVICE_NR(CURRENT->dev)].buffer +
93 (bb[DEVICE_NR(CURRENT->dev)].start << 9),
94 this_count << 9);
95 }
96
97 CURRENT->nr_sectors -= this_count;
98
99 #ifdef DEBUG
100 printk("(%x %x %x) ",CURRENT->bh, CURRENT->nr_sectors,
101 this_count);
102 #endif
103 if (CURRENT->nr_sectors)
104 {
105 CURRENT->sector += this_count;
106 CURRENT->errors = 0;
107 if (!CURRENT->bh)
108 {
109 (char *) CURRENT->buffer += this_count << 9;
110 } else {
111 end_request(1);
112 do_sr_request();
113 }
114 }
115 else
116 {
117 end_request(1);
118 do_sr_request();
119 }
120 }
121
122
123
124 if (driver_byte(result) != 0) {
125 bb[DEVICE_NR(CURRENT->dev)].block = -1;
126
127 if ((sense_buffer[0] & 0x7f) == 0x70) {
128 if ((sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
129
130
131
132 scsi_CDs[DEVICE_NR(CURRENT->dev)].changed = 1;
133 end_request(0);
134 return;
135 }
136 }
137
138 if (sense_buffer[2] == ILLEGAL_REQUEST) {
139 printk("CD-ROM error: Drive reports ILLEGAL REQUEST.\n");
140 if (scsi_CDs[DEVICE_NR(CURRENT->dev)].ten) {
141 scsi_CDs[DEVICE_NR(CURRENT->dev)].ten = 0;
142 do_sr_request();
143 result = 0;
144 return;
145 } else {
146 end_request(0);
147 do_sr_request();
148 return;
149 }
150
151 }
152
153 if (sense_buffer[2] == NOT_READY) {
154 printk("CDROM not ready. Make sure you have a disc in the drive.\n");
155 end_request(0);
156 do_sr_request();
157 return;
158 };
159 }
160
161
162 if(result) {
163 printk("SCSI CD error : host %d id %d lun %d return code = %03x\n",
164 scsi_CDs[DEVICE_NR(CURRENT->dev)].device->host_no,
165 scsi_CDs[DEVICE_NR(CURRENT->dev)].device->id,
166 scsi_CDs[DEVICE_NR(CURRENT->dev)].device->lun,
167 result);
168
169 if (status_byte(result) == CHECK_CONDITION)
170 printk("\tSense class %x, sense error %x, extended sense %x\n",
171 sense_class(sense_buffer[0]),
172 sense_error(sense_buffer[0]),
173 sense_buffer[2] & 0xf);
174
175 end_request(0);
176 do_sr_request();
177 }
178 }
179
180 static int sr_open(struct inode * inode, struct file * filp)
181 {
182 if (filp->f_mode)
183 check_disk_change(inode->i_rdev);
184 return 0;
185 }
186
187
188
189
190
191
192 void do_sr_request (void)
193 {
194 unsigned int dev, block, realcount;
195 unsigned char cmd[10], *buffer, tries;
196
197 tries = 2;
198
199 repeat:
200 INIT_REQUEST;
201 dev = MINOR(CURRENT->dev);
202 block = CURRENT->sector;
203
204 bb[dev].start = block % 4;
205 block = block / 4;
206
207 if (dev >= NR_SR)
208 {
209
210 end_request(0);
211 tries = 2;
212 goto repeat;
213 }
214
215 if (!scsi_CDs[dev].use)
216 {
217
218 end_request(0);
219 tries = 2;
220 goto repeat;
221 }
222
223 if (scsi_CDs[dev].changed)
224 {
225
226
227
228
229 end_request(0);
230 tries = 2;
231 goto repeat;
232 }
233
234 if (!CURRENT->bh)
235 this_count = CURRENT->nr_sectors;
236 else
237 this_count = (CURRENT->bh->b_size / 512);
238
239 if (bb[dev].start)
240 {
241 bb[dev].use = 1;
242
243 this_count = ((this_count > 4 - bb[dev].start) ?
244 (4 - bb[dev].start) : (this_count));
245
246 if (bb[dev].block == block)
247 {
248 rw_intr(SR_HOST, 0);
249 return;
250 }
251
252 buffer = bb[dev].buffer;
253 bb[dev].block = block;
254 }
255 else if (this_count < 4)
256 {
257 bb[dev].use = 1;
258
259 if (bb[dev].block == block)
260 {
261 rw_intr(SR_HOST, 0);
262 return;
263 }
264
265 buffer = bb[dev].buffer;
266 bb[dev].block = block;
267 }
268 else
269 {
270 this_count -= this_count % 4;
271 buffer = CURRENT->buffer;
272 bb[dev].use = 0;
273 }
274
275 realcount = (this_count + 3) / 4;
276
277 switch (CURRENT->cmd)
278 {
279 case WRITE:
280 end_request(0);
281 goto repeat;
282 break;
283 case READ :
284 cmd[0] = READ_6;
285 break;
286 default :
287 printk ("Unknown sr command %d\r\n", CURRENT->cmd);
288 panic("");
289 }
290
291 cmd[1] = (SR_LUN << 5) & 0xe0;
292
293 if (((realcount > 0xff) || (block > 0x1fffff)) && scsi_CDs[dev].ten)
294 {
295 if (realcount > 0xffff)
296 {
297 realcount = 0xffff;
298 this_count = realcount * 4;
299 }
300
301 cmd[0] += READ_10 - READ_6 ;
302 cmd[2] = (unsigned char) (block >> 24) & 0xff;
303 cmd[3] = (unsigned char) (block >> 16) & 0xff;
304 cmd[4] = (unsigned char) (block >> 8) & 0xff;
305 cmd[5] = (unsigned char) block & 0xff;
306 cmd[6] = cmd[9] = 0;
307 cmd[7] = (unsigned char) (realcount >> 8) & 0xff;
308 cmd[8] = (unsigned char) realcount & 0xff;
309 }
310 else
311 {
312 if (realcount > 0xff)
313 {
314 realcount = 0xff;
315 this_count = realcount * 4;
316 }
317
318 cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);
319 cmd[2] = (unsigned char) ((block >> 8) & 0xff);
320 cmd[3] = (unsigned char) block & 0xff;
321 cmd[4] = (unsigned char) realcount;
322 cmd[5] = 0;
323 }
324
325 scsi_do_cmd (SR_HOST, SR_ID, (void *) cmd, buffer, realcount << 11,
326 rw_intr, SR_TIMEOUT, sense_buffer, MAX_RETRIES);
327 }
328
329 void sr_init(void)
330 {
331 int i;
332
333 for (i = 0; i < NR_SR; ++i)
334 {
335 scsi_CDs[i].capacity = 0x1fffff;
336 scsi_CDs[i].sector_size = 2048;
337 scsi_CDs[i].use = 1;
338 scsi_CDs[i].ten = 1;
339 scsi_CDs[i].remap = 1;
340 scsi_CDs[i].changed = 0;
341 sr_sizes[i] = scsi_CDs[i].capacity;
342
343 bb[i].block = -1;
344 }
345
346 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
347 blk_size[MAJOR_NR] = sr_sizes;
348 blkdev_fops[MAJOR_NR] = &sr_fops;
349 }
350 #endif
351
352
353
354
355