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