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