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 if (filp->f_mode & 2)
272 return -EACCES;
273
274 check_disk_change(inode->i_rdev);
275
276 if(!scsi_CDs[MINOR(inode->i_rdev)].device->access_count++)
277 sr_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
278
279
280
281
282
283
284 if(scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size)
285 get_sectorsize(MINOR(inode->i_rdev));
286
287 return 0;
288 }
289
290
291
292
293
294
295
296 static void do_sr_request (void)
297 {
298 Scsi_Cmnd * SCpnt = NULL;
299 struct request * req = NULL;
300 int flag = 0;
301
302 while (1==1){
303 cli();
304 if (CURRENT != NULL && CURRENT->dev == -1) {
305 sti();
306 return;
307 };
308
309 INIT_SCSI_REQUEST;
310
311 if (flag++ == 0)
312 SCpnt = allocate_device(&CURRENT,
313 scsi_CDs[DEVICE_NR(MINOR(CURRENT->dev))].device, 0);
314 else SCpnt = NULL;
315 sti();
316
317
318
319
320
321
322
323
324 if (!SCpnt && NR_SR > 1){
325 struct request *req1;
326 req1 = NULL;
327 cli();
328 req = CURRENT;
329 while(req){
330 SCpnt = request_queueable(req,
331 scsi_CDs[DEVICE_NR(MINOR(req->dev))].device);
332 if(SCpnt) break;
333 req1 = req;
334 req = req->next;
335 };
336 if (SCpnt && req->dev == -1) {
337 if (req == CURRENT)
338 CURRENT = CURRENT->next;
339 else
340 req1->next = req->next;
341 };
342 sti();
343 };
344
345 if (!SCpnt)
346 return;
347
348 wake_up(&wait_for_request);
349
350
351 requeue_sr_request(SCpnt);
352 };
353 }
354
355 void requeue_sr_request (Scsi_Cmnd * SCpnt)
356 {
357 unsigned int dev, block, realcount;
358 unsigned char cmd[10], *buffer, tries;
359 int this_count, start, end_rec;
360
361 tries = 2;
362
363 repeat:
364 if(SCpnt->request.dev <= 0) {
365 do_sr_request();
366 return;
367 }
368
369 dev = MINOR(SCpnt->request.dev);
370 block = SCpnt->request.sector;
371 buffer = NULL;
372 this_count = 0;
373
374 if (dev >= NR_SR)
375 {
376
377 end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
378 tries = 2;
379 goto repeat;
380 }
381
382 if (!scsi_CDs[dev].use)
383 {
384
385 end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
386 tries = 2;
387 goto repeat;
388 }
389
390 if (scsi_CDs[dev].device->changed)
391 {
392
393
394
395
396 end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
397 tries = 2;
398 goto repeat;
399 }
400
401 switch (SCpnt->request.cmd)
402 {
403 case WRITE:
404 end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
405 goto repeat;
406 break;
407 case READ :
408 cmd[0] = READ_6;
409 break;
410 default :
411 panic ("Unknown sr command %d\n", SCpnt->request.cmd);
412 }
413
414 cmd[1] = (SCpnt->lun << 5) & 0xe0;
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432 SCpnt->use_sg = 0;
433
434 if (SCpnt->host->sg_tablesize > 0 &&
435 (!need_isa_buffer ||
436 dma_free_sectors >= 10)) {
437 struct buffer_head * bh;
438 struct scatterlist * sgpnt;
439 int count, this_count_max;
440 bh = SCpnt->request.bh;
441 this_count = 0;
442 count = 0;
443 this_count_max = (scsi_CDs[dev].ten ? 0xffff : 0xff) << 4;
444
445
446 this_count = SCpnt->request.sector % 4;
447 if(this_count) count++;
448 while(bh && count < SCpnt->host->sg_tablesize) {
449 if ((this_count + (bh->b_size >> 9)) > this_count_max) break;
450 this_count += (bh->b_size >> 9);
451 count++;
452 bh = bh->b_reqnext;
453 };
454
455 end_rec = 0;
456 if(this_count % 4) {
457 if (count < SCpnt->host->sg_tablesize) {
458 count++;
459 end_rec = (4 - (this_count % 4)) << 9;
460 this_count += 4 - (this_count % 4);
461 } else {
462 count--;
463 this_count -= (this_count % 4);
464 };
465 };
466 SCpnt->use_sg = count;
467 count = 512;
468 while( count < (SCpnt->use_sg * sizeof(struct scatterlist)))
469 count = count << 1;
470 SCpnt->sglist_len = count;
471 sgpnt = (struct scatterlist * ) scsi_malloc(count);
472 if (!sgpnt) {
473 printk("Warning - running *really* short on DMA buffers\n");
474 SCpnt->use_sg = 0;
475 } else {
476 buffer = (unsigned char *) sgpnt;
477 count = 0;
478 bh = SCpnt->request.bh;
479 if(SCpnt->request.sector % 4) {
480 sgpnt[count].length = (SCpnt->request.sector % 4) << 9;
481 sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
482 if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
483 sgpnt[count].alt_address = sgpnt[count].address;
484
485 count++;
486 };
487 for(bh = SCpnt->request.bh; count < SCpnt->use_sg;
488 count++, bh = bh->b_reqnext) {
489 if (bh) {
490 sgpnt[count].address = bh->b_data;
491 sgpnt[count].length = bh->b_size;
492 sgpnt[count].alt_address = NULL;
493 } else {
494 sgpnt[count].address = (char *) scsi_malloc(end_rec);
495 if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
496 sgpnt[count].length = end_rec;
497 sgpnt[count].alt_address = sgpnt[count].address;
498 if (count+1 != SCpnt->use_sg) panic("Bad sr request list");
499 break;
500 };
501 if (((int) sgpnt[count].address) + sgpnt[count].length >
502 ISA_DMA_THRESHOLD & (SCpnt->host->unchecked_isa_dma)) {
503 sgpnt[count].alt_address = sgpnt[count].address;
504
505
506
507 if(dma_free_sectors < (sgpnt[count].length >> 9) + 5) {
508 sgpnt[count].address = NULL;
509 } else {
510 sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
511 };
512
513
514
515
516 if(sgpnt[count].address == NULL){
517 printk("Warning: Running low on SCSI DMA buffers");
518
519 while(--count >= 0){
520 if(sgpnt[count].alt_address)
521 scsi_free(sgpnt[count].address, sgpnt[count].length);
522 };
523 SCpnt->use_sg = 0;
524 scsi_free(buffer, SCpnt->sglist_len);
525 break;
526 };
527 };
528 };
529 #ifdef DEBUG
530 printk("SG: %d %d %d %d %d *** ",SCpnt->use_sg, SCpnt->request.sector,
531 this_count,
532 SCpnt->request.current_nr_sectors,
533 SCpnt->request.nr_sectors);
534 for(count=0; count<SCpnt->use_sg; count++)
535 printk("SGlist: %d %x %x %x\n", count,
536 sgpnt[count].address,
537 sgpnt[count].alt_address,
538 sgpnt[count].length);
539 #endif
540 };
541 };
542
543 if (SCpnt->use_sg == 0){
544
545 if (!SCpnt->request.bh)
546 this_count = SCpnt->request.nr_sectors;
547 else
548 this_count = (SCpnt->request.bh->b_size >> 9);
549
550 start = block % 4;
551 if (start)
552 {
553 this_count = ((this_count > 4 - start) ?
554 (4 - start) : (this_count));
555 buffer = (unsigned char *) scsi_malloc(2048);
556 }
557 else if (this_count < 4)
558 {
559 buffer = (unsigned char *) scsi_malloc(2048);
560 }
561 else
562 {
563 this_count -= this_count % 4;
564 buffer = (unsigned char *) SCpnt->request.buffer;
565 if (((int) buffer) + (this_count << 9) > ISA_DMA_THRESHOLD &
566 (SCpnt->host->unchecked_isa_dma))
567 buffer = (unsigned char *) scsi_malloc(this_count << 9);
568 }
569 };
570
571 if (scsi_CDs[dev].sector_size == 2048)
572 block = block >> 2;
573 else
574 block = block & 0xfffffffc;
575
576 realcount = (this_count + 3) / 4;
577
578 if (scsi_CDs[dev].sector_size == 512) realcount = realcount << 2;
579
580 if (((realcount > 0xff) || (block > 0x1fffff)) && scsi_CDs[dev].ten)
581 {
582 if (realcount > 0xffff)
583 {
584 realcount = 0xffff;
585 this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
586 }
587
588 cmd[0] += READ_10 - READ_6 ;
589 cmd[2] = (unsigned char) (block >> 24) & 0xff;
590 cmd[3] = (unsigned char) (block >> 16) & 0xff;
591 cmd[4] = (unsigned char) (block >> 8) & 0xff;
592 cmd[5] = (unsigned char) block & 0xff;
593 cmd[6] = cmd[9] = 0;
594 cmd[7] = (unsigned char) (realcount >> 8) & 0xff;
595 cmd[8] = (unsigned char) realcount & 0xff;
596 }
597 else
598 {
599 if (realcount > 0xff)
600 {
601 realcount = 0xff;
602 this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
603 }
604
605 cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);
606 cmd[2] = (unsigned char) ((block >> 8) & 0xff);
607 cmd[3] = (unsigned char) block & 0xff;
608 cmd[4] = (unsigned char) realcount;
609 cmd[5] = 0;
610 }
611
612 #ifdef DEBUG
613 {
614 int i;
615 printk("ReadCD: %d %d %d %d\n",block, realcount, buffer, this_count);
616 printk("Use sg: %d\n", SCpnt->use_sg);
617 printk("Dumping command: ");
618 for(i=0; i<12; i++) printk("%2.2x ", cmd[i]);
619 printk("\n");
620 };
621 #endif
622
623 SCpnt->this_count = this_count;
624 scsi_do_cmd (SCpnt, (void *) cmd, buffer,
625 realcount * scsi_CDs[dev].sector_size,
626 rw_intr, SR_TIMEOUT, MAX_RETRIES);
627 }
628
629 void sr_init1(){
630 scsi_CDs = (Scsi_CD *) scsi_init_malloc(MAX_SR * sizeof(Scsi_CD));
631 };
632
633 void sr_attach(Scsi_Device * SDp){
634 SDp->scsi_request_fn = do_sr_request;
635 scsi_CDs[NR_SR++].device = SDp;
636 if(NR_SR > MAX_SR) panic ("scsi_devices corrupt (sr)");
637 };
638
639 static void sr_init_done (Scsi_Cmnd * SCpnt)
640 {
641 struct request * req;
642
643 req = &SCpnt->request;
644 req->dev = 0xfffe;
645
646 if (req->sem != NULL) {
647 up(req->sem);
648 }
649 }
650
651 static void get_sectorsize(int i){
652 unsigned char cmd[10];
653 unsigned char buffer[513];
654 int the_result, retries;
655 Scsi_Cmnd * SCpnt;
656
657 SCpnt = allocate_device(NULL, scsi_CDs[i].device, 1);
658
659 retries = 3;
660 do {
661 cmd[0] = READ_CAPACITY;
662 cmd[1] = (scsi_CDs[i].device->lun << 5) & 0xe0;
663 memset ((void *) &cmd[2], 0, 8);
664 SCpnt->request.dev = 0xffff;
665
666 memset(buffer, 0, 8);
667
668 scsi_do_cmd (SCpnt,
669 (void *) cmd, (void *) buffer,
670 512, sr_init_done, SR_TIMEOUT,
671 MAX_RETRIES);
672
673 if (current == task[0])
674 while(SCpnt->request.dev != 0xfffe);
675 else
676 if (SCpnt->request.dev != 0xfffe){
677 struct semaphore sem = MUTEX_LOCKED;
678 SCpnt->request.sem = &sem;
679 down(&sem);
680
681 while (SCpnt->request.dev != 0xfffe) schedule();
682 };
683
684 the_result = SCpnt->result;
685 retries--;
686
687 } while(the_result && retries);
688
689 SCpnt->request.dev = -1;
690
691 wake_up(&SCpnt->device->device_wait);
692
693 if (the_result) {
694 scsi_CDs[i].capacity = 0x1fffff;
695 scsi_CDs[i].sector_size = 2048;
696 scsi_CDs[i].needs_sector_size = 1;
697 } else {
698 scsi_CDs[i].capacity = (buffer[0] << 24) |
699 (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
700 scsi_CDs[i].sector_size = (buffer[4] << 24) |
701 (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
702 if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;
703 if(scsi_CDs[i].sector_size != 2048 &&
704 scsi_CDs[i].sector_size != 512) {
705 printk ("scd%d : unsupported sector size %d.\n",
706 i, scsi_CDs[i].sector_size);
707 scsi_CDs[i].capacity = 0;
708 scsi_CDs[i].needs_sector_size = 1;
709 };
710 if(scsi_CDs[i].sector_size == 2048)
711 scsi_CDs[i].capacity *= 4;
712 scsi_CDs[i].needs_sector_size = 0;
713 };
714 }
715
716 unsigned long sr_init(unsigned long memory_start, unsigned long memory_end)
717 {
718 int i;
719
720 if (register_blkdev(MAJOR_NR,"sr",&sr_fops)) {
721 printk("Unable to get major %d for SCSI-CD\n",MAJOR_NR);
722 return memory_start;
723 }
724 if(MAX_SR == 0) return memory_start;
725
726 sr_sizes = (int *) memory_start;
727 memory_start += MAX_SR * sizeof(int);
728 memset(sr_sizes, 0, MAX_SR * sizeof(int));
729
730 sr_blocksizes = (int *) memory_start;
731 memory_start += MAX_SR * sizeof(int);
732 for(i=0;i<MAX_SR;i++) sr_blocksizes[i] = 2048;
733 blksize_size[MAJOR_NR] = sr_blocksizes;
734
735 for (i = 0; i < NR_SR; ++i)
736 {
737 get_sectorsize(i);
738 printk("Scd sectorsize = %d bytes\n", scsi_CDs[i].sector_size);
739 scsi_CDs[i].use = 1;
740 scsi_CDs[i].ten = 1;
741 scsi_CDs[i].remap = 1;
742 sr_sizes[i] = scsi_CDs[i].capacity;
743 }
744
745 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
746 blk_size[MAJOR_NR] = sr_sizes;
747
748
749
750
751 if(scsi_CDs[0].device->host->sg_tablesize)
752 read_ahead[MAJOR_NR] = 32;
753 else
754 read_ahead[MAJOR_NR] = 4;
755
756 return memory_start;
757 }