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 11
24
25 #include "../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) scsi_CDs[target].device->changed = 0;
106 return retval;
107 }
108
109
110
111
112
113
114 static void rw_intr (Scsi_Cmnd * SCpnt)
115 {
116 int result = SCpnt->result;
117 int this_count = SCpnt->this_count;
118
119 #ifdef DEBUG
120 printk("sr.c done: %x %x\n",result, SCpnt->request.bh->b_data);
121 #endif
122 if (!result)
123 {
124 if (SCpnt->use_sg == 0) {
125 if (SCpnt->buffer != SCpnt->request.buffer)
126 {
127 int offset;
128 offset = (SCpnt->request.sector % 4) << 9;
129 memcpy((char *)SCpnt->request.buffer,
130 SCpnt->buffer + offset,
131 this_count << 9);
132
133
134
135
136 if((offset == 0) && this_count == 2 &&
137 SCpnt->request.nr_sectors > this_count &&
138 SCpnt->request.bh &&
139 SCpnt->request.bh->b_reqnext &&
140 SCpnt->request.bh->b_reqnext->b_size == 1024) {
141 memcpy((char *)SCpnt->request.bh->b_reqnext->b_data,
142 SCpnt->buffer + 1024,
143 1024);
144 this_count += 2;
145 };
146
147 scsi_free(SCpnt->buffer, 2048);
148 }
149 } else {
150 struct scatterlist * sgpnt;
151 int i;
152 sgpnt = (struct scatterlist *) SCpnt->buffer;
153 for(i=0; i<SCpnt->use_sg; i++) {
154 if (sgpnt[i].alt_address) {
155 if (sgpnt[i].alt_address != sgpnt[i].address) {
156 memcpy(sgpnt[i].alt_address, sgpnt[i].address, sgpnt[i].length);
157 };
158 scsi_free(sgpnt[i].address, sgpnt[i].length);
159 };
160 };
161 scsi_free(SCpnt->buffer, SCpnt->sglist_len);
162 if(SCpnt->request.sector % 4) this_count -= 2;
163
164 if(this_count > SCpnt->request.nr_sectors)
165 this_count -= 2;
166 };
167
168 #ifdef DEBUG
169 printk("(%x %x %x) ",SCpnt->request.bh, SCpnt->request.nr_sectors,
170 this_count);
171 #endif
172 if (SCpnt->request.nr_sectors > this_count)
173 {
174 SCpnt->request.errors = 0;
175 if (!SCpnt->request.bh)
176 {
177 printk("sr.c: linked page request. (%x %x)",
178 SCpnt->request.sector, this_count);
179 panic("Aiiiiiiiiiiiieeeeeeeee");
180 }
181 }
182
183 end_scsi_request(SCpnt, 1, this_count);
184 requeue_sr_request(SCpnt);
185 return;
186 }
187
188
189
190
191 if (SCpnt->use_sg) {
192 struct scatterlist * sgpnt;
193 int i;
194 sgpnt = (struct scatterlist *) SCpnt->buffer;
195 for(i=0; i<SCpnt->use_sg; i++) {
196 if (sgpnt[i].alt_address) {
197 scsi_free(sgpnt[i].address, sgpnt[i].length);
198 };
199 };
200 scsi_free(SCpnt->buffer, SCpnt->sglist_len);
201 } else {
202 if (SCpnt->buffer != SCpnt->request.buffer)
203 scsi_free(SCpnt->buffer, SCpnt->bufflen);
204 };
205
206 if (driver_byte(result) != 0) {
207 if ((SCpnt->sense_buffer[0] & 0x7f) == 0x70) {
208 if ((SCpnt->sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
209
210
211
212 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->changed = 1;
213 end_scsi_request(SCpnt, 0, this_count);
214 requeue_sr_request(SCpnt);
215 return;
216 }
217 }
218
219 if (SCpnt->sense_buffer[2] == ILLEGAL_REQUEST) {
220 printk("CD-ROM error: Drive reports ILLEGAL REQUEST.\n");
221 if (scsi_CDs[DEVICE_NR(SCpnt->request.dev)].ten) {
222 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].ten = 0;
223 requeue_sr_request(SCpnt);
224 result = 0;
225 return;
226 } else {
227 printk("CD-ROM error: Drive reports %d.\n", SCpnt->sense_buffer[2]);
228 end_scsi_request(SCpnt, 0, this_count);
229 requeue_sr_request(SCpnt);
230 return;
231 }
232
233 }
234
235 if (SCpnt->sense_buffer[2] == NOT_READY) {
236 printk("CDROM not ready. Make sure you have a disc in the drive.\n");
237 end_scsi_request(SCpnt, 0, this_count);
238 requeue_sr_request(SCpnt);
239 return;
240 };
241 }
242
243
244 if(result) {
245 printk("SCSI CD error : host %d id %d lun %d return code = %03x\n",
246 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->host_no,
247 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->id,
248 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->lun,
249 result);
250
251 if (status_byte(result) == CHECK_CONDITION)
252 print_sense("sr", SCpnt);
253
254 end_scsi_request(SCpnt, 0, SCpnt->request.current_nr_sectors);
255 requeue_sr_request(SCpnt);
256 }
257 }
258
259 static int sr_open(struct inode * inode, struct file * filp)
260 {
261 if(MINOR(inode->i_rdev) >= NR_SR ||
262 !scsi_CDs[MINOR(inode->i_rdev)].device) return -ENODEV;
263
264 check_disk_change(inode->i_rdev);
265
266 if(!scsi_CDs[MINOR(inode->i_rdev)].device->access_count++)
267 sr_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
268
269
270
271
272
273
274 if(scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size)
275 get_sectorsize(MINOR(inode->i_rdev));
276
277 return 0;
278 }
279
280
281
282
283
284
285
286 static void do_sr_request (void)
287 {
288 Scsi_Cmnd * SCpnt = NULL;
289 struct request * req = NULL;
290 int flag = 0;
291
292 while (1==1){
293 cli();
294 if (CURRENT != NULL && CURRENT->dev == -1) {
295 sti();
296 return;
297 };
298
299 INIT_SCSI_REQUEST;
300
301 if (flag++ == 0)
302 SCpnt = allocate_device(&CURRENT,
303 scsi_CDs[DEVICE_NR(MINOR(CURRENT->dev))].device->index, 0);
304 else SCpnt = NULL;
305 sti();
306
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) {
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 printk ("Unknown sr command %d\n", SCpnt->request.cmd);
403 panic("");
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 (scsi_hosts[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 < scsi_hosts[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 < scsi_hosts[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 & (scsi_hosts[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 (scsi_hosts[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 printk("ReadCD: %d %d %d %d\n",block, realcount, buffer, this_count);
606 #endif
607
608 SCpnt->this_count = this_count;
609 scsi_do_cmd (SCpnt, (void *) cmd, buffer,
610 realcount * scsi_CDs[dev].sector_size,
611 rw_intr, SR_TIMEOUT, MAX_RETRIES);
612 }
613
614 unsigned long sr_init1(unsigned long mem_start, unsigned long mem_end){
615 scsi_CDs = (Scsi_CD *) mem_start;
616 mem_start += MAX_SR * sizeof(Scsi_CD);
617 return mem_start;
618 };
619
620 void sr_attach(Scsi_Device * SDp){
621 scsi_CDs[NR_SR++].device = SDp;
622 if(NR_SR > MAX_SR) panic ("scsi_devices corrupt (sr)");
623 };
624
625 static void sr_init_done (Scsi_Cmnd * SCpnt)
626 {
627 struct request * req;
628 struct task_struct * p;
629
630 req = &SCpnt->request;
631 req->dev = 0xfffe;
632
633 if ((p = req->waiting) != NULL) {
634 req->waiting = NULL;
635 p->state = TASK_RUNNING;
636 if (p->counter > current->counter)
637 need_resched = 1;
638 }
639 }
640
641 static void get_sectorsize(int i){
642 unsigned char cmd[10];
643 unsigned char buffer[513];
644 int the_result, retries;
645 Scsi_Cmnd * SCpnt;
646
647 SCpnt = allocate_device(NULL, scsi_CDs[i].device->index, 1);
648
649 retries = 3;
650 do {
651 cmd[0] = READ_CAPACITY;
652 cmd[1] = (scsi_CDs[i].device->lun << 5) & 0xe0;
653 memset ((void *) &cmd[2], 0, 8);
654 SCpnt->request.dev = 0xffff;
655
656 scsi_do_cmd (SCpnt,
657 (void *) cmd, (void *) buffer,
658 512, sr_init_done, SR_TIMEOUT,
659 MAX_RETRIES);
660
661 if (current == task[0])
662 while(SCpnt->request.dev != 0xfffe);
663 else
664 if (SCpnt->request.dev != 0xfffe){
665 SCpnt->request.waiting = current;
666 current->state = TASK_UNINTERRUPTIBLE;
667 while (SCpnt->request.dev != 0xfffe) schedule();
668 };
669
670 the_result = SCpnt->result;
671 retries--;
672
673 } while(the_result && retries);
674
675 SCpnt->request.dev = -1;
676
677 wake_up(&scsi_devices[SCpnt->index].device_wait);
678
679 if (the_result) {
680 scsi_CDs[i].capacity = 0x1fffff;
681 scsi_CDs[i].sector_size = 2048;
682 scsi_CDs[i].needs_sector_size = 1;
683 } else {
684 scsi_CDs[i].capacity = (buffer[0] << 24) |
685 (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
686 scsi_CDs[i].sector_size = (buffer[4] << 24) |
687 (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
688 if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;
689 if(scsi_CDs[i].sector_size != 2048 &&
690 scsi_CDs[i].sector_size != 512) {
691 printk ("scd%d : unsupported sector size %d.\n",
692 i, scsi_CDs[i].sector_size);
693 scsi_CDs[i].capacity = 0;
694 };
695 if(scsi_CDs[i].sector_size == 2048)
696 scsi_CDs[i].capacity *= 4;
697 scsi_CDs[i].needs_sector_size = 0;
698 };
699 }
700
701 unsigned long sr_init(unsigned long memory_start, unsigned long memory_end)
702 {
703 int i;
704
705 if (register_blkdev(MAJOR_NR,"sr",&sr_fops)) {
706 printk("Unable to get major %d for SCSI-CD\n",MAJOR_NR);
707 return memory_start;
708 }
709 if(MAX_SR == 0) return memory_start;
710
711 sr_sizes = (int *) memory_start;
712 memory_start += MAX_SR * sizeof(int);
713 memset(sr_sizes, 0, MAX_SR * sizeof(int));
714
715 sr_blocksizes = (int *) memory_start;
716 memory_start += MAX_SR * sizeof(int);
717 for(i=0;i<MAX_SR;i++) sr_blocksizes[i] = 2048;
718 blksize_size[MAJOR_NR] = sr_blocksizes;
719
720 for (i = 0; i < NR_SR; ++i)
721 {
722 get_sectorsize(i);
723 printk("Scd sectorsize = %d bytes\n", scsi_CDs[i].sector_size);
724 scsi_CDs[i].use = 1;
725 scsi_CDs[i].ten = 1;
726 scsi_CDs[i].remap = 1;
727 sr_sizes[i] = scsi_CDs[i].capacity;
728 }
729
730 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
731 blk_size[MAJOR_NR] = sr_sizes;
732
733
734
735
736 if(scsi_hosts[scsi_CDs[0].device->host_no].sg_tablesize)
737 read_ahead[MAJOR_NR] = 16;
738 else
739 read_ahead[MAJOR_NR] = 4;
740
741 return memory_start;
742 }