This source file includes following definitions.
- sr_release
- check_cdrom_media_change
- rw_intr
- sr_open
- do_sr_request
- requeue_sr_request
- sr_init1
- sr_attach
- sr_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #include <linux/fs.h>
17 #include <linux/kernel.h>
18 #include <linux/sched.h>
19 #include <linux/string.h>
20 #include <linux/errno.h>
21 #include <asm/system.h>
22
23 #define MAJOR_NR 11
24
25 #include "../blk.h"
26 #include "scsi.h"
27 #include "hosts.h"
28 #include "sr.h"
29 #include "scsi_ioctl.h"
30
31 #define MAX_RETRIES 0
32 #define SR_TIMEOUT 250
33
34 int NR_SR=0;
35 int MAX_SR=0;
36 Scsi_CD * scsi_CDs;
37 static int * sr_sizes;
38
39 static int sr_open(struct inode *, struct file *);
40
41 extern int sr_ioctl(struct inode *, struct file *, unsigned int, unsigned int);
42
43 void requeue_sr_request (Scsi_Cmnd * SCpnt);
44
45 static void sr_release(struct inode * inode, struct file * file)
46 {
47 sync_dev(inode->i_rdev);
48 if(! --scsi_CDs[MINOR(inode->i_rdev)].device->access_count)
49 sr_ioctl(inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0);
50 }
51
52 static struct file_operations sr_fops =
53 {
54 NULL,
55 block_read,
56 block_write,
57 NULL,
58 NULL,
59 sr_ioctl,
60 NULL,
61 sr_open,
62 sr_release
63 };
64
65
66
67
68
69
70
71
72
73
74
75 int check_cdrom_media_change(int full_dev, int flag){
76 int retval, target;
77 struct inode inode;
78
79 target = MINOR(full_dev);
80
81 if (target >= NR_SR) {
82 printk("CD-ROM request error: invalid device.\n");
83 return 0;
84 };
85
86 inode.i_rdev = full_dev;
87 retval = sr_ioctl(&inode, NULL, SCSI_IOCTL_TEST_UNIT_READY, 0);
88
89 if(retval){
90
91
92
93
94 scsi_CDs[target].device->changed = 1;
95 return 1;
96
97 };
98
99 retval = scsi_CDs[target].device->changed;
100 if(!flag) scsi_CDs[target].device->changed = 0;
101 return retval;
102 }
103
104
105
106
107
108
109 static void rw_intr (Scsi_Cmnd * SCpnt)
110 {
111 int result = SCpnt->result;
112 int this_count = SCpnt->this_count;
113
114 #ifdef DEBUG
115 printk("sr.c done: %x %x\n",result, SCpnt->request.bh->b_data);
116 #endif
117 if (!result)
118 {
119 if (SCpnt->use_sg == 0) {
120 if (SCpnt->buffer != SCpnt->request.buffer)
121 {
122 int offset;
123 offset = (SCpnt->request.sector % 4) << 9;
124 memcpy((char *)SCpnt->request.buffer,
125 SCpnt->buffer + offset,
126 this_count << 9);
127
128
129
130
131 if((offset == 0) && this_count == 2 &&
132 SCpnt->request.nr_sectors > this_count &&
133 SCpnt->request.bh &&
134 SCpnt->request.bh->b_reqnext &&
135 SCpnt->request.bh->b_reqnext->b_size == 1024) {
136 memcpy((char *)SCpnt->request.bh->b_reqnext->b_data,
137 SCpnt->buffer + 1024,
138 1024);
139 this_count += 2;
140 };
141
142 scsi_free(SCpnt->buffer, 2048);
143 }
144 } else {
145 struct scatterlist * sgpnt;
146 int i;
147 sgpnt = (struct scatterlist *) SCpnt->buffer;
148 for(i=0; i<SCpnt->use_sg; i++) {
149 if (sgpnt[i].alt_address) {
150 if (sgpnt[i].alt_address != sgpnt[i].address) {
151 memcpy(sgpnt[i].alt_address, sgpnt[i].address, sgpnt[i].length);
152 };
153 scsi_free(sgpnt[i].address, sgpnt[i].length);
154 };
155 };
156 scsi_free(SCpnt->buffer, SCpnt->sglist_len);
157 if(SCpnt->request.sector % 4) this_count -= 2;
158
159 if(this_count > SCpnt->request.nr_sectors)
160 this_count -= 2;
161 };
162
163 #ifdef DEBUG
164 printk("(%x %x %x) ",SCpnt->request.bh, SCpnt->request.nr_sectors,
165 this_count);
166 #endif
167 if (SCpnt->request.nr_sectors > this_count)
168 {
169 SCpnt->request.errors = 0;
170 if (!SCpnt->request.bh)
171 {
172 printk("sr.c: linked page request. (%x %x)",
173 SCpnt->request.sector, this_count);
174 panic("Aiiiiiiiiiiiieeeeeeeee");
175 }
176 }
177
178 end_scsi_request(SCpnt, 1, this_count);
179 requeue_sr_request(SCpnt);
180 return;
181 }
182
183
184
185
186 if (SCpnt->use_sg) {
187 struct scatterlist * sgpnt;
188 int i;
189 sgpnt = (struct scatterlist *) SCpnt->buffer;
190 for(i=0; i<SCpnt->use_sg; i++) {
191 if (sgpnt[i].alt_address) {
192 scsi_free(sgpnt[i].address, sgpnt[i].length);
193 };
194 };
195 scsi_free(SCpnt->buffer, SCpnt->sglist_len);
196 } else {
197 if (SCpnt->buffer != SCpnt->request.buffer)
198 scsi_free(SCpnt->buffer, SCpnt->bufflen);
199 };
200
201 if (driver_byte(result) != 0) {
202 if ((SCpnt->sense_buffer[0] & 0x7f) == 0x70) {
203 if ((SCpnt->sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
204
205
206
207 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->changed = 1;
208 end_scsi_request(SCpnt, 0, this_count);
209 requeue_sr_request(SCpnt);
210 return;
211 }
212 }
213
214 if (SCpnt->sense_buffer[2] == ILLEGAL_REQUEST) {
215 printk("CD-ROM error: Drive reports ILLEGAL REQUEST.\n");
216 if (scsi_CDs[DEVICE_NR(SCpnt->request.dev)].ten) {
217 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].ten = 0;
218 requeue_sr_request(SCpnt);
219 result = 0;
220 return;
221 } else {
222 printk("CD-ROM error: Drive reports %d.\n", SCpnt->sense_buffer[2]);
223 end_scsi_request(SCpnt, 0, this_count);
224 requeue_sr_request(SCpnt);
225 return;
226 }
227
228 }
229
230 if (SCpnt->sense_buffer[2] == NOT_READY) {
231 printk("CDROM not ready. Make sure you have a disc in the drive.\n");
232 end_scsi_request(SCpnt, 0, this_count);
233 requeue_sr_request(SCpnt);
234 return;
235 };
236 }
237
238
239 if(result) {
240 printk("SCSI CD error : host %d id %d lun %d return code = %03x\n",
241 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->host_no,
242 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->id,
243 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->lun,
244 result);
245
246 if (status_byte(result) == CHECK_CONDITION)
247 printk("\tSense class %x, sense error %x, extended sense %x\n",
248 sense_class(SCpnt->sense_buffer[0]),
249 sense_error(SCpnt->sense_buffer[0]),
250 SCpnt->sense_buffer[2] & 0xf);
251
252 end_scsi_request(SCpnt, 0, SCpnt->request.current_nr_sectors);
253 requeue_sr_request(SCpnt);
254 }
255 }
256
257 static int sr_open(struct inode * inode, struct file * filp)
258 {
259 if(MINOR(inode->i_rdev) >= NR_SR ||
260 !scsi_CDs[MINOR(inode->i_rdev)].device) return -ENODEV;
261
262 check_disk_change(inode->i_rdev);
263
264 if(!scsi_CDs[MINOR(inode->i_rdev)].device->access_count++)
265 sr_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
266 return 0;
267 }
268
269
270
271
272
273
274
275 static void do_sr_request (void)
276 {
277 Scsi_Cmnd * SCpnt = NULL;
278 struct request * req = NULL;
279 int flag = 0;
280
281 while (1==1){
282 if (CURRENT != NULL && CURRENT->dev == -1) return;
283
284 INIT_REQUEST;
285
286 if (flag++ == 0)
287 SCpnt = allocate_device(&CURRENT,
288 scsi_CDs[DEVICE_NR(MINOR(CURRENT->dev))].device->index, 0);
289 else SCpnt = NULL;
290
291
292
293
294
295
296
297
298
299 if (!SCpnt && NR_SR > 1){
300 struct request *req1;
301 req1 = NULL;
302 cli();
303 req = CURRENT;
304 while(req){
305 SCpnt = request_queueable(req,
306 scsi_CDs[DEVICE_NR(MINOR(req->dev))].device->index);
307 if(SCpnt) break;
308 req1 = req;
309 req = req->next;
310 };
311 if (SCpnt) {
312 if (req == CURRENT)
313 CURRENT = CURRENT->next;
314 else
315 req1->next = req->next;
316 };
317 sti();
318 };
319
320 if (!SCpnt)
321 return;
322
323 wake_up(&wait_for_request);
324
325
326 requeue_sr_request(SCpnt);
327 };
328 }
329
330 void requeue_sr_request (Scsi_Cmnd * SCpnt)
331 {
332 unsigned int dev, block, realcount;
333 unsigned char cmd[10], *buffer, tries;
334 int this_count, start, end_rec;
335
336 tries = 2;
337
338 repeat:
339 if(SCpnt->request.dev <= 0)
340 return do_sr_request();
341
342 dev = MINOR(SCpnt->request.dev);
343 block = SCpnt->request.sector;
344 buffer = NULL;
345 this_count = 0;
346
347 if (dev >= NR_SR)
348 {
349
350 end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
351 tries = 2;
352 goto repeat;
353 }
354
355 if (!scsi_CDs[dev].use)
356 {
357
358 end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
359 tries = 2;
360 goto repeat;
361 }
362
363 if (scsi_CDs[dev].device->changed)
364 {
365
366
367
368
369 end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
370 tries = 2;
371 goto repeat;
372 }
373
374 switch (SCpnt->request.cmd)
375 {
376 case WRITE:
377 end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
378 goto repeat;
379 break;
380 case READ :
381 cmd[0] = READ_6;
382 break;
383 default :
384 printk ("Unknown sr command %d\r\n", SCpnt->request.cmd);
385 panic("");
386 }
387
388 cmd[1] = (SCpnt->lun << 5) & 0xe0;
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406 SCpnt->use_sg = 0;
407
408 if (scsi_hosts[SCpnt->host].sg_tablesize > 0 &&
409 (!need_isa_buffer ||
410 dma_free_sectors >= 10)) {
411 struct buffer_head * bh;
412 struct scatterlist * sgpnt;
413 int count, this_count_max;
414 bh = SCpnt->request.bh;
415 this_count = 0;
416 count = 0;
417 this_count_max = (scsi_CDs[dev].ten ? 0xffff : 0xff) << 4;
418
419
420 this_count = SCpnt->request.sector % 4;
421 if(this_count) count++;
422 while(bh && count < scsi_hosts[SCpnt->host].sg_tablesize) {
423 if ((this_count + (bh->b_size >> 9)) > this_count_max) break;
424 this_count += (bh->b_size >> 9);
425 count++;
426 bh = bh->b_reqnext;
427 };
428
429 end_rec = 0;
430 if(this_count % 4) {
431 if (count < scsi_hosts[SCpnt->host].sg_tablesize) {
432 count++;
433 end_rec = (4 - (this_count % 4)) << 9;
434 this_count += 4 - (this_count % 4);
435 } else {
436 count--;
437 this_count -= (this_count % 4);
438 };
439 };
440 SCpnt->use_sg = count;
441 count = 512;
442 while( count < (SCpnt->use_sg * sizeof(struct scatterlist)))
443 count = count << 1;
444 SCpnt->sglist_len = count;
445 sgpnt = (struct scatterlist * ) scsi_malloc(count);
446 if (!sgpnt) {
447 printk("Warning - running *really* short on DMA buffers\n");
448 SCpnt->use_sg = 0;
449 } else {
450 buffer = (char *) sgpnt;
451 count = 0;
452 bh = SCpnt->request.bh;
453 if(SCpnt->request.sector % 4) {
454 sgpnt[count].length = (SCpnt->request.sector % 4) << 9;
455 sgpnt[count].address = scsi_malloc(sgpnt[count].length);
456 if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
457 sgpnt[count].alt_address = sgpnt[count].address;
458
459 count++;
460 };
461 for(bh = SCpnt->request.bh; count < SCpnt->use_sg;
462 count++, bh = bh->b_reqnext) {
463 if (bh) {
464 sgpnt[count].address = bh->b_data;
465 sgpnt[count].length = bh->b_size;
466 sgpnt[count].alt_address = NULL;
467 } else {
468 sgpnt[count].address = scsi_malloc(end_rec);
469 if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
470 sgpnt[count].length = end_rec;
471 sgpnt[count].alt_address = sgpnt[count].address;
472 if (count+1 != SCpnt->use_sg) panic("Bad sr request list");
473 break;
474 };
475 if (((int) sgpnt[count].address) + sgpnt[count].length >
476 ISA_DMA_THRESHOLD & (scsi_hosts[SCpnt->host].unchecked_isa_dma)) {
477 sgpnt[count].alt_address = sgpnt[count].address;
478
479
480
481 if(dma_free_sectors < (sgpnt[count].length >> 9) + 5) {
482 sgpnt[count].address = NULL;
483 } else {
484 sgpnt[count].address = scsi_malloc(sgpnt[count].length);
485 };
486
487
488
489
490 if(sgpnt[count].address == NULL){
491 printk("Warning: Running low on SCSI DMA buffers");
492
493 while(--count){
494 if(sgpnt[count].alt_address)
495 scsi_free(sgpnt[count].address, sgpnt[count].length);
496 };
497 SCpnt->use_sg = 0;
498 scsi_free(buffer, SCpnt->sglist_len);
499 break;
500 };
501 };
502 };
503 #ifdef DEBUG
504 printk("SG: %d %d %d %d %d *** ",SCpnt->use_sg, SCpnt->request.sector,
505 this_count,
506 SCpnt->request.current_nr_sectors,
507 SCpnt->request.nr_sectors);
508 for(count=0; count<SCpnt->use_sg; count++)
509 printk("SGlist: %d %x %x %x\n", count,
510 sgpnt[count].address,
511 sgpnt[count].alt_address,
512 sgpnt[count].length);
513 #endif
514 };
515 };
516
517 if (SCpnt->use_sg == 0){
518
519 if (!SCpnt->request.bh)
520 this_count = SCpnt->request.nr_sectors;
521 else
522 this_count = (SCpnt->request.bh->b_size >> 9);
523
524 start = block % 4;
525 if (start)
526 {
527 this_count = ((this_count > 4 - start) ?
528 (4 - start) : (this_count));
529 buffer = scsi_malloc(2048);
530 }
531 else if (this_count < 4)
532 {
533 buffer = scsi_malloc(2048);
534 }
535 else
536 {
537 this_count -= this_count % 4;
538 buffer = SCpnt->request.buffer;
539 if (((int) buffer) + (this_count << 9) > ISA_DMA_THRESHOLD &
540 (scsi_hosts[SCpnt->host].unchecked_isa_dma))
541 buffer = scsi_malloc(this_count << 9);
542 }
543 };
544
545 block = block >> 2;
546 realcount = (this_count + 3) / 4;
547
548 if (((realcount > 0xff) || (block > 0x1fffff)) && scsi_CDs[dev].ten)
549 {
550 if (realcount > 0xffff)
551 {
552 realcount = 0xffff;
553 this_count = realcount * 4;
554 }
555
556 cmd[0] += READ_10 - READ_6 ;
557 cmd[2] = (unsigned char) (block >> 24) & 0xff;
558 cmd[3] = (unsigned char) (block >> 16) & 0xff;
559 cmd[4] = (unsigned char) (block >> 8) & 0xff;
560 cmd[5] = (unsigned char) block & 0xff;
561 cmd[6] = cmd[9] = 0;
562 cmd[7] = (unsigned char) (realcount >> 8) & 0xff;
563 cmd[8] = (unsigned char) realcount & 0xff;
564 }
565 else
566 {
567 if (realcount > 0xff)
568 {
569 realcount = 0xff;
570 this_count = realcount * 4;
571 }
572
573 cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);
574 cmd[2] = (unsigned char) ((block >> 8) & 0xff);
575 cmd[3] = (unsigned char) block & 0xff;
576 cmd[4] = (unsigned char) realcount;
577 cmd[5] = 0;
578 }
579
580 #ifdef DEBUG
581 printk("ReadCD: %d %d %d\n",block, realcount, buffer);
582 #endif
583
584 SCpnt->this_count = this_count;
585 scsi_do_cmd (SCpnt, (void *) cmd, buffer, realcount << 11,
586 rw_intr, SR_TIMEOUT, MAX_RETRIES);
587 }
588
589 unsigned long sr_init1(unsigned long mem_start, unsigned long mem_end){
590 scsi_CDs = (Scsi_CD *) mem_start;
591 mem_start += MAX_SR * sizeof(Scsi_CD);
592 return mem_start;
593 };
594
595 void sr_attach(Scsi_Device * SDp){
596 scsi_CDs[NR_SR++].device = SDp;
597 if(NR_SR > MAX_SR) panic ("scsi_devices corrupt (sr)");
598 };
599
600 unsigned long sr_init(unsigned long memory_start, unsigned long memory_end)
601 {
602 int i;
603
604 if (register_blkdev(MAJOR_NR,"sr",&sr_fops)) {
605 printk("Unable to get major %d for SCSI-CD\n",MAJOR_NR);
606 return memory_start;
607 }
608 if(MAX_SR == 0) return memory_start;
609
610 sr_sizes = (int *) memory_start;
611 memory_start += MAX_SR * sizeof(int);
612 memset(sr_sizes, 0, MAX_SR * sizeof(int));
613
614 for (i = 0; i < NR_SR; ++i)
615 {
616 scsi_CDs[i].capacity = 0x1fffff;
617 scsi_CDs[i].sector_size = 2048;
618 scsi_CDs[i].use = 1;
619 scsi_CDs[i].ten = 1;
620 scsi_CDs[i].remap = 1;
621 sr_sizes[i] = scsi_CDs[i].capacity;
622 }
623
624 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
625 blk_size[MAJOR_NR] = sr_sizes;
626
627
628
629
630 if(scsi_hosts[scsi_CDs[0].device->host_no].sg_tablesize)
631 read_ahead[MAJOR_NR] = 16;
632 else
633 read_ahead[MAJOR_NR] = 4;
634
635 return memory_start;
636 }