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