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