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