This source file includes following definitions.
- sr_release
- check_cdrom_media_change
- rw_intr
- sr_photocd
- sr_open
- do_sr_request
- requeue_sr_request
- sr_detect
- sr_attach
- sr_init_done
- get_sectorsize
- sr_init
- sr_finish
- sr_detach
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <linux/fs.h>
21 #include <linux/kernel.h>
22 #include <linux/sched.h>
23 #include <linux/string.h>
24 #include <linux/errno.h>
25 #include <linux/cdrom.h>
26 #include <asm/system.h>
27
28 #define MAJOR_NR SCSI_CDROM_MAJOR
29 #include "../block/blk.h"
30 #include "scsi.h"
31 #include "hosts.h"
32 #include "sr.h"
33 #include "scsi_ioctl.h"
34 #include "constants.h"
35
36 #define MAX_RETRIES 3
37 #define SR_TIMEOUT 15000
38
39 static void sr_init(void);
40 static void sr_finish(void);
41 static int sr_attach(Scsi_Device *);
42 static int sr_detect(Scsi_Device *);
43 static void sr_detach(Scsi_Device *);
44
45 struct Scsi_Device_Template sr_template = {NULL, "cdrom", "sr", TYPE_ROM,
46 SCSI_CDROM_MAJOR, 0, 0, 0, 1,
47 sr_detect, sr_init,
48 sr_finish, sr_attach, sr_detach};
49
50 Scsi_CD * scsi_CDs;
51 static int * sr_sizes;
52
53 static int * sr_blocksizes;
54
55 static int sr_open(struct inode *, struct file *);
56 static void get_sectorsize(int);
57
58 extern int sr_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
59
60 void requeue_sr_request (Scsi_Cmnd * SCpnt);
61 static int check_cdrom_media_change(dev_t);
62
63 static void sr_release(struct inode * inode, struct file * file)
64 {
65 sync_dev(inode->i_rdev);
66 if(! --scsi_CDs[MINOR(inode->i_rdev)].device->access_count)
67 sr_ioctl(inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0);
68 if (scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)
69 (*scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)--;
70 }
71
72 static struct file_operations sr_fops =
73 {
74 NULL,
75 block_read,
76 block_write,
77 NULL,
78 NULL,
79 sr_ioctl,
80 NULL,
81 sr_open,
82 sr_release,
83 NULL,
84 NULL,
85 check_cdrom_media_change,
86 NULL
87 };
88
89
90
91
92
93
94
95
96
97
98
99 int check_cdrom_media_change(dev_t full_dev){
100 int retval, target;
101 struct inode inode;
102 int flag = 0;
103
104 target = MINOR(full_dev);
105
106 if (target >= sr_template.nr_dev) {
107 printk("CD-ROM request error: invalid device.\n");
108 return 0;
109 };
110
111 inode.i_rdev = full_dev;
112 retval = sr_ioctl(&inode, NULL, SCSI_IOCTL_TEST_UNIT_READY, 0);
113
114 if(retval){
115
116
117
118
119 scsi_CDs[target].device->changed = 1;
120 return 1;
121
122 };
123
124 retval = scsi_CDs[target].device->changed;
125 if(!flag) {
126 scsi_CDs[target].device->changed = 0;
127
128
129 if (retval) scsi_CDs[target].needs_sector_size = 1;
130 };
131 return retval;
132 }
133
134
135
136
137
138
139 static void rw_intr (Scsi_Cmnd * SCpnt)
140 {
141 int result = SCpnt->result;
142 int this_count = SCpnt->this_count;
143
144 #ifdef DEBUG
145 printk("sr.c done: %x %x\n",result, SCpnt->request.bh->b_data);
146 #endif
147 if (!result)
148 {
149 if (SCpnt->use_sg == 0) {
150 if (SCpnt->buffer != SCpnt->request.buffer)
151 {
152 int offset;
153 offset = (SCpnt->request.sector % 4) << 9;
154 memcpy((char *)SCpnt->request.buffer,
155 (char *)SCpnt->buffer + offset,
156 this_count << 9);
157
158
159
160
161 if((offset == 0) && this_count == 2 &&
162 SCpnt->request.nr_sectors > this_count &&
163 SCpnt->request.bh &&
164 SCpnt->request.bh->b_reqnext &&
165 SCpnt->request.bh->b_reqnext->b_size == 1024) {
166 memcpy((char *)SCpnt->request.bh->b_reqnext->b_data,
167 (char *)SCpnt->buffer + 1024,
168 1024);
169 this_count += 2;
170 };
171
172 scsi_free(SCpnt->buffer, 2048);
173 }
174 } else {
175 struct scatterlist * sgpnt;
176 int i;
177 sgpnt = (struct scatterlist *) SCpnt->buffer;
178 for(i=0; i<SCpnt->use_sg; i++) {
179 if (sgpnt[i].alt_address) {
180 if (sgpnt[i].alt_address != sgpnt[i].address) {
181 memcpy(sgpnt[i].alt_address, sgpnt[i].address, sgpnt[i].length);
182 };
183 scsi_free(sgpnt[i].address, sgpnt[i].length);
184 };
185 };
186 scsi_free(SCpnt->buffer, SCpnt->sglist_len);
187 if(SCpnt->request.sector % 4) this_count -= 2;
188
189 if(this_count > SCpnt->request.nr_sectors)
190 this_count -= 2;
191 };
192
193 #ifdef DEBUG
194 printk("(%x %x %x) ",SCpnt->request.bh, SCpnt->request.nr_sectors,
195 this_count);
196 #endif
197 if (SCpnt->request.nr_sectors > this_count)
198 {
199 SCpnt->request.errors = 0;
200 if (!SCpnt->request.bh)
201 panic("sr.c: linked page request (%lx %x)",
202 SCpnt->request.sector, this_count);
203 }
204
205 SCpnt = end_scsi_request(SCpnt, 1, this_count);
206 requeue_sr_request(SCpnt);
207 return;
208 }
209
210
211
212
213 if (SCpnt->use_sg) {
214 struct scatterlist * sgpnt;
215 int i;
216 sgpnt = (struct scatterlist *) SCpnt->buffer;
217 for(i=0; i<SCpnt->use_sg; i++) {
218 if (sgpnt[i].alt_address) {
219 scsi_free(sgpnt[i].address, sgpnt[i].length);
220 };
221 };
222 scsi_free(SCpnt->buffer, SCpnt->sglist_len);
223 } else {
224 if (SCpnt->buffer != SCpnt->request.buffer)
225 scsi_free(SCpnt->buffer, SCpnt->bufflen);
226 };
227
228 if (driver_byte(result) != 0) {
229 if ((SCpnt->sense_buffer[0] & 0x7f) == 0x70) {
230 if ((SCpnt->sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
231
232
233
234 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->changed = 1;
235 SCpnt = end_scsi_request(SCpnt, 0, this_count);
236 requeue_sr_request(SCpnt);
237 return;
238 }
239 }
240
241 if (SCpnt->sense_buffer[2] == ILLEGAL_REQUEST) {
242 printk("CD-ROM error: ");
243 print_sense("sr", SCpnt);
244 printk("command was: ");
245 print_command(SCpnt->cmnd);
246 if (scsi_CDs[DEVICE_NR(SCpnt->request.dev)].ten) {
247 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].ten = 0;
248 requeue_sr_request(SCpnt);
249 result = 0;
250 return;
251 } else {
252 SCpnt = end_scsi_request(SCpnt, 0, this_count);
253 requeue_sr_request(SCpnt);
254 return;
255 }
256
257 }
258
259 if (SCpnt->sense_buffer[2] == NOT_READY) {
260 printk("CDROM not ready. Make sure you have a disc in the drive.\n");
261 SCpnt = end_scsi_request(SCpnt, 0, this_count);
262 requeue_sr_request(SCpnt);
263 return;
264 };
265 }
266
267
268 if(result) {
269 printk("SCSI CD error : host %d id %d lun %d return code = %03x\n",
270 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->host->host_no,
271 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->id,
272 scsi_CDs[DEVICE_NR(SCpnt->request.dev)].device->lun,
273 result);
274
275 if (status_byte(result) == CHECK_CONDITION)
276 print_sense("sr", SCpnt);
277
278 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.current_nr_sectors);
279 requeue_sr_request(SCpnt);
280 }
281 }
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306 static void sr_photocd(struct inode *inode)
307 {
308 unsigned long sector,min,sec,frame;
309 unsigned char buf[40];
310 int rc;
311
312 if (!suser()) {
313
314
315
316
317
318
319 if (1 == scsi_CDs[MINOR(inode->i_rdev)].device->access_count)
320 scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = 0;
321 return;
322 }
323
324 switch(scsi_CDs[MINOR(inode->i_rdev)].device->manufacturer) {
325
326 case SCSI_MAN_NEC:
327 #ifdef DEBUG
328 printk("sr_photocd: use NEC code\n");
329 #endif
330 memset(buf,0,40);
331 *((unsigned long*)buf) = 0;
332 *((unsigned long*)buf+1) = 0x16;
333 buf[8+0] = 0xde;
334 buf[8+1] = 0x03;
335 buf[8+2] = 0xb0;
336 rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
337 SCSI_IOCTL_SEND_COMMAND, buf);
338 if (rc != 0) {
339 printk("sr_photocd: ioctl error (NEC): 0x%x\n",rc);
340 sector = 0;
341 } else {
342 min = (unsigned long)buf[8+15]/16*10 + (unsigned long)buf[8+15]%16;
343 sec = (unsigned long)buf[8+16]/16*10 + (unsigned long)buf[8+16]%16;
344 frame = (unsigned long)buf[8+17]/16*10 + (unsigned long)buf[8+17]%16;
345 sector = min*60*75 + sec*75 + frame;
346 #ifdef DEBUG
347 if (sector) {
348 printk("sr_photocd: multisession CD detected. start: %lu\n",sector);
349 }
350 #endif
351 }
352 break;
353
354 case SCSI_MAN_TOSHIBA:
355 #ifdef DEBUG
356 printk("sr_photocd: use TOSHIBA code\n");
357 #endif
358
359
360 memset(buf,0,40);
361 *((unsigned long*)buf) = 12;
362 *((unsigned long*)buf+1) = 12;
363 buf[8+0] = 0x15;
364 buf[8+1] = (1 << 4);
365 buf[8+4] = 12;
366 buf[14+ 3] = 0x08;
367 buf[14+ 4] = 0x83;
368 buf[14+10] = 0x08;
369 rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
370 SCSI_IOCTL_SEND_COMMAND, buf);
371 if (rc != 0) {
372 printk("sr_photocd: ioctl error (TOSHIBA #1): 0x%x\n",rc);
373 }
374
375
376 memset(buf,0,40);
377 *((unsigned long*)buf) = 0;
378 *((unsigned long*)buf+1) = 4;
379 buf[8+0] = 0xc7;
380 buf[8+1] = 3;
381 rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
382 SCSI_IOCTL_SEND_COMMAND, buf);
383 if (rc != 0) {
384 printk("sr_photocd: ioctl error (TOSHIBA #2): 0x%x\n",rc);
385 sector = 0;
386 } else {
387 min = (unsigned long)buf[8+1]/16*10 + (unsigned long)buf[8+1]%16;
388 sec = (unsigned long)buf[8+2]/16*10 + (unsigned long)buf[8+2]%16;
389 frame = (unsigned long)buf[8+3]/16*10 + (unsigned long)buf[8+3]%16;
390 sector = min*60*75 + sec*75 + frame;
391 if (sector) {
392 sector -= CD_BLOCK_OFFSET;
393 #ifdef DEBUG
394 printk("sr_photocd: multisession CD detected: start: %lu\n",sector);
395 #endif
396 }
397 }
398 break;
399
400 case SCSI_MAN_UNKNOWN:
401 default:
402 #ifdef DEBUG
403 printk("sr_photocd: unknown drive, no special multisession code\n");
404 #endif
405 sector = 0;
406 break; }
407
408 scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = sector;
409 return;
410 }
411
412 static int sr_open(struct inode * inode, struct file * filp)
413 {
414 if(MINOR(inode->i_rdev) >= sr_template.nr_dev ||
415 !scsi_CDs[MINOR(inode->i_rdev)].device) return -ENXIO;
416
417 if (filp->f_mode & 2)
418 return -EROFS;
419
420 check_disk_change(inode->i_rdev);
421
422 if(!scsi_CDs[MINOR(inode->i_rdev)].device->access_count++)
423 sr_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
424 if (scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)
425 (*scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)++;
426
427
428
429
430
431
432 if(scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size)
433 get_sectorsize(MINOR(inode->i_rdev));
434
435 #if 1
436 sr_photocd(inode);
437 #endif
438
439 return 0;
440 }
441
442
443
444
445
446
447
448 static void do_sr_request (void)
449 {
450 Scsi_Cmnd * SCpnt = NULL;
451 struct request * req = NULL;
452 unsigned long flags;
453 int flag = 0;
454
455 while (1==1){
456 save_flags(flags);
457 cli();
458 if (CURRENT != NULL && CURRENT->dev == -1) {
459 restore_flags(flags);
460 return;
461 };
462
463 INIT_SCSI_REQUEST;
464
465 if (flag++ == 0)
466 SCpnt = allocate_device(&CURRENT,
467 scsi_CDs[DEVICE_NR(MINOR(CURRENT->dev))].device, 0);
468 else SCpnt = NULL;
469 restore_flags(flags);
470
471
472
473
474
475
476
477
478 if (!SCpnt && sr_template.nr_dev > 1){
479 struct request *req1;
480 req1 = NULL;
481 save_flags(flags);
482 cli();
483 req = CURRENT;
484 while(req){
485 SCpnt = request_queueable(req,
486 scsi_CDs[DEVICE_NR(MINOR(req->dev))].device);
487 if(SCpnt) break;
488 req1 = req;
489 req = req->next;
490 };
491 if (SCpnt && req->dev == -1) {
492 if (req == CURRENT)
493 CURRENT = CURRENT->next;
494 else
495 req1->next = req->next;
496 };
497 restore_flags(flags);
498 };
499
500 if (!SCpnt)
501 return;
502
503 wake_up(&wait_for_request);
504
505
506 requeue_sr_request(SCpnt);
507 };
508 }
509
510 void requeue_sr_request (Scsi_Cmnd * SCpnt)
511 {
512 unsigned int dev, block, realcount;
513 unsigned char cmd[10], *buffer, tries;
514 int this_count, start, end_rec;
515
516 tries = 2;
517
518 repeat:
519 if(!SCpnt || SCpnt->request.dev <= 0) {
520 do_sr_request();
521 return;
522 }
523
524 dev = MINOR(SCpnt->request.dev);
525 block = SCpnt->request.sector;
526 buffer = NULL;
527 this_count = 0;
528
529 if (dev >= sr_template.nr_dev)
530 {
531
532 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
533 tries = 2;
534 goto repeat;
535 }
536
537 if (!scsi_CDs[dev].use)
538 {
539
540 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
541 tries = 2;
542 goto repeat;
543 }
544
545 if (scsi_CDs[dev].device->changed)
546 {
547
548
549
550
551 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
552 tries = 2;
553 goto repeat;
554 }
555
556 switch (SCpnt->request.cmd)
557 {
558 case WRITE:
559 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
560 goto repeat;
561 break;
562 case READ :
563 cmd[0] = READ_6;
564 break;
565 default :
566 panic ("Unknown sr command %d\n", SCpnt->request.cmd);
567 }
568
569 cmd[1] = (SCpnt->lun << 5) & 0xe0;
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587 #if 1
588
589
590
591
592 if (block >= 64 && block < 68) {
593 block += scsi_CDs[dev].mpcd_sector*4; }
594 #endif
595
596 SCpnt->use_sg = 0;
597
598 if (SCpnt->host->sg_tablesize > 0 &&
599 (!need_isa_buffer ||
600 dma_free_sectors >= 10)) {
601 struct buffer_head * bh;
602 struct scatterlist * sgpnt;
603 int count, this_count_max;
604 bh = SCpnt->request.bh;
605 this_count = 0;
606 count = 0;
607 this_count_max = (scsi_CDs[dev].ten ? 0xffff : 0xff) << 4;
608
609
610 this_count = SCpnt->request.sector % 4;
611 if(this_count) count++;
612 while(bh && count < SCpnt->host->sg_tablesize) {
613 if ((this_count + (bh->b_size >> 9)) > this_count_max) break;
614 this_count += (bh->b_size >> 9);
615 count++;
616 bh = bh->b_reqnext;
617 };
618
619 end_rec = 0;
620 if(this_count % 4) {
621 if (count < SCpnt->host->sg_tablesize) {
622 count++;
623 end_rec = (4 - (this_count % 4)) << 9;
624 this_count += 4 - (this_count % 4);
625 } else {
626 count--;
627 this_count -= (this_count % 4);
628 };
629 };
630 SCpnt->use_sg = count;
631 count = 512;
632 while( count < (SCpnt->use_sg * sizeof(struct scatterlist)))
633 count = count << 1;
634 SCpnt->sglist_len = count;
635 sgpnt = (struct scatterlist * ) scsi_malloc(count);
636 if (!sgpnt) {
637 printk("Warning - running *really* short on DMA buffers\n");
638 SCpnt->use_sg = 0;
639 } else {
640 buffer = (unsigned char *) sgpnt;
641 count = 0;
642 bh = SCpnt->request.bh;
643 if(SCpnt->request.sector % 4) {
644 sgpnt[count].length = (SCpnt->request.sector % 4) << 9;
645 sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
646 if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
647 sgpnt[count].alt_address = sgpnt[count].address;
648
649 count++;
650 };
651 for(bh = SCpnt->request.bh; count < SCpnt->use_sg;
652 count++, bh = bh->b_reqnext) {
653 if (bh) {
654 sgpnt[count].address = bh->b_data;
655 sgpnt[count].length = bh->b_size;
656 sgpnt[count].alt_address = NULL;
657 } else {
658 sgpnt[count].address = (char *) scsi_malloc(end_rec);
659 if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
660 sgpnt[count].length = end_rec;
661 sgpnt[count].alt_address = sgpnt[count].address;
662 if (count+1 != SCpnt->use_sg) panic("Bad sr request list");
663 break;
664 };
665 if (((int) sgpnt[count].address) + sgpnt[count].length >
666 ISA_DMA_THRESHOLD & (SCpnt->host->unchecked_isa_dma)) {
667 sgpnt[count].alt_address = sgpnt[count].address;
668
669
670
671 if(dma_free_sectors < (sgpnt[count].length >> 9) + 5) {
672 sgpnt[count].address = NULL;
673 } else {
674 sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
675 };
676
677
678
679
680 if(sgpnt[count].address == NULL){
681 printk("Warning: Running low on SCSI DMA buffers");
682
683 while(--count >= 0){
684 if(sgpnt[count].alt_address)
685 scsi_free(sgpnt[count].address, sgpnt[count].length);
686 };
687 SCpnt->use_sg = 0;
688 scsi_free(buffer, SCpnt->sglist_len);
689 break;
690 };
691 };
692 };
693 #ifdef DEBUG
694 printk("SG: %d %d %d %d %d *** ",SCpnt->use_sg, SCpnt->request.sector,
695 this_count,
696 SCpnt->request.current_nr_sectors,
697 SCpnt->request.nr_sectors);
698 for(count=0; count<SCpnt->use_sg; count++)
699 printk("SGlist: %d %x %x %x\n", count,
700 sgpnt[count].address,
701 sgpnt[count].alt_address,
702 sgpnt[count].length);
703 #endif
704 };
705 };
706
707 if (SCpnt->use_sg == 0){
708
709 if (!SCpnt->request.bh)
710 this_count = SCpnt->request.nr_sectors;
711 else
712 this_count = (SCpnt->request.bh->b_size >> 9);
713
714 start = block % 4;
715 if (start)
716 {
717 this_count = ((this_count > 4 - start) ?
718 (4 - start) : (this_count));
719 buffer = (unsigned char *) scsi_malloc(2048);
720 }
721 else if (this_count < 4)
722 {
723 buffer = (unsigned char *) scsi_malloc(2048);
724 }
725 else
726 {
727 this_count -= this_count % 4;
728 buffer = (unsigned char *) SCpnt->request.buffer;
729 if (((int) buffer) + (this_count << 9) > ISA_DMA_THRESHOLD &
730 (SCpnt->host->unchecked_isa_dma))
731 buffer = (unsigned char *) scsi_malloc(this_count << 9);
732 }
733 };
734
735 if (scsi_CDs[dev].sector_size == 2048)
736 block = block >> 2;
737 else
738 block = block & 0xfffffffc;
739
740 realcount = (this_count + 3) / 4;
741
742 if (scsi_CDs[dev].sector_size == 512) realcount = realcount << 2;
743
744 if (((realcount > 0xff) || (block > 0x1fffff)) && scsi_CDs[dev].ten)
745 {
746 if (realcount > 0xffff)
747 {
748 realcount = 0xffff;
749 this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
750 }
751
752 cmd[0] += READ_10 - READ_6 ;
753 cmd[2] = (unsigned char) (block >> 24) & 0xff;
754 cmd[3] = (unsigned char) (block >> 16) & 0xff;
755 cmd[4] = (unsigned char) (block >> 8) & 0xff;
756 cmd[5] = (unsigned char) block & 0xff;
757 cmd[6] = cmd[9] = 0;
758 cmd[7] = (unsigned char) (realcount >> 8) & 0xff;
759 cmd[8] = (unsigned char) realcount & 0xff;
760 }
761 else
762 {
763 if (realcount > 0xff)
764 {
765 realcount = 0xff;
766 this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
767 }
768
769 cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);
770 cmd[2] = (unsigned char) ((block >> 8) & 0xff);
771 cmd[3] = (unsigned char) block & 0xff;
772 cmd[4] = (unsigned char) realcount;
773 cmd[5] = 0;
774 }
775
776 #ifdef DEBUG
777 {
778 int i;
779 printk("ReadCD: %d %d %d %d\n",block, realcount, buffer, this_count);
780 printk("Use sg: %d\n", SCpnt->use_sg);
781 printk("Dumping command: ");
782 for(i=0; i<12; i++) printk("%2.2x ", cmd[i]);
783 printk("\n");
784 };
785 #endif
786
787
788
789
790
791
792
793
794
795
796
797 SCpnt->transfersize = (scsi_CDs[dev].sector_size > 1024) ?
798 1024 : scsi_CDs[dev].sector_size;
799
800 SCpnt->this_count = this_count;
801 scsi_do_cmd (SCpnt, (void *) cmd, buffer,
802 realcount * scsi_CDs[dev].sector_size,
803 rw_intr, SR_TIMEOUT, MAX_RETRIES);
804 }
805
806 static int sr_detect(Scsi_Device * SDp){
807
808 if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return 0;
809
810 printk("Detected scsi CD-ROM sr%d at scsi%d, id %d, lun %d\n",
811 sr_template.dev_noticed++,
812 SDp->host->host_no , SDp->id, SDp->lun);
813
814 return 1;
815 }
816
817 static int sr_attach(Scsi_Device * SDp){
818 Scsi_CD * cpnt;
819 int i;
820
821 if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return 1;
822
823 if (sr_template.nr_dev >= sr_template.dev_max)
824 {
825 SDp->attached--;
826 return 1;
827 }
828
829 for(cpnt = scsi_CDs, i=0; i<sr_template.dev_max; i++, cpnt++)
830 if(!cpnt->device) break;
831
832 if(i >= sr_template.dev_max) panic ("scsi_devices corrupt (sr)");
833
834 SDp->scsi_request_fn = do_sr_request;
835 scsi_CDs[i].device = SDp;
836 sr_template.nr_dev++;
837 if(sr_template.nr_dev > sr_template.dev_max)
838 panic ("scsi_devices corrupt (sr)");
839 return 0;
840 }
841
842
843 static void sr_init_done (Scsi_Cmnd * SCpnt)
844 {
845 struct request * req;
846
847 req = &SCpnt->request;
848 req->dev = 0xfffe;
849
850 if (req->sem != NULL) {
851 up(req->sem);
852 }
853 }
854
855 static void get_sectorsize(int i){
856 unsigned char cmd[10];
857 unsigned char *buffer;
858 int the_result, retries;
859 Scsi_Cmnd * SCpnt;
860
861 buffer = (unsigned char *) scsi_malloc(512);
862 SCpnt = allocate_device(NULL, scsi_CDs[i].device, 1);
863
864 retries = 3;
865 do {
866 cmd[0] = READ_CAPACITY;
867 cmd[1] = (scsi_CDs[i].device->lun << 5) & 0xe0;
868 memset ((void *) &cmd[2], 0, 8);
869 SCpnt->request.dev = 0xffff;
870 SCpnt->cmd_len = 0;
871
872 memset(buffer, 0, 8);
873
874 scsi_do_cmd (SCpnt,
875 (void *) cmd, (void *) buffer,
876 512, sr_init_done, SR_TIMEOUT,
877 MAX_RETRIES);
878
879 if (current == task[0])
880 while(SCpnt->request.dev != 0xfffe);
881 else
882 if (SCpnt->request.dev != 0xfffe){
883 struct semaphore sem = MUTEX_LOCKED;
884 SCpnt->request.sem = &sem;
885 down(&sem);
886
887 while (SCpnt->request.dev != 0xfffe) schedule();
888 };
889
890 the_result = SCpnt->result;
891 retries--;
892
893 } while(the_result && retries);
894
895 SCpnt->request.dev = -1;
896
897 wake_up(&SCpnt->device->device_wait);
898
899 if (the_result) {
900 scsi_CDs[i].capacity = 0x1fffff;
901 scsi_CDs[i].sector_size = 2048;
902 scsi_CDs[i].needs_sector_size = 1;
903 } else {
904 scsi_CDs[i].capacity = (buffer[0] << 24) |
905 (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
906 scsi_CDs[i].sector_size = (buffer[4] << 24) |
907 (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
908 if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;
909 if(scsi_CDs[i].sector_size != 2048 &&
910 scsi_CDs[i].sector_size != 512) {
911 printk ("scd%d : unsupported sector size %d.\n",
912 i, scsi_CDs[i].sector_size);
913 scsi_CDs[i].capacity = 0;
914 scsi_CDs[i].needs_sector_size = 1;
915 };
916 if(scsi_CDs[i].sector_size == 2048)
917 scsi_CDs[i].capacity *= 4;
918 scsi_CDs[i].needs_sector_size = 0;
919 };
920 scsi_free(buffer, 512);
921 }
922
923 static void sr_init()
924 {
925 int i;
926 static int sr_registered = 0;
927
928 if(sr_template.dev_noticed == 0) return;
929
930 if(!sr_registered) {
931 if (register_blkdev(MAJOR_NR,"sr",&sr_fops)) {
932 printk("Unable to get major %d for SCSI-CD\n",MAJOR_NR);
933 return;
934 }
935 sr_registered++;
936 }
937
938
939 if (scsi_CDs) return;
940 sr_template.dev_max = sr_template.dev_noticed + SR_EXTRA_DEVS;
941 scsi_CDs = (Scsi_CD *) scsi_init_malloc(sr_template.dev_max * sizeof(Scsi_CD), GFP_ATOMIC);
942 memset(scsi_CDs, 0, sr_template.dev_max * sizeof(Scsi_CD));
943
944 sr_sizes = (int *) scsi_init_malloc(sr_template.dev_max * sizeof(int), GFP_ATOMIC);
945 memset(sr_sizes, 0, sr_template.dev_max * sizeof(int));
946
947 sr_blocksizes = (int *) scsi_init_malloc(sr_template.dev_max *
948 sizeof(int), GFP_ATOMIC);
949 for(i=0;i<sr_template.dev_max;i++) sr_blocksizes[i] = 2048;
950 blksize_size[MAJOR_NR] = sr_blocksizes;
951
952 }
953
954 void sr_finish()
955 {
956 int i;
957
958 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
959 blk_size[MAJOR_NR] = sr_sizes;
960
961 for (i = 0; i < sr_template.nr_dev; ++i)
962 {
963
964
965 if (scsi_CDs[i].capacity) continue;
966 scsi_CDs[i].capacity = 0x1fffff;
967 scsi_CDs[i].sector_size = 2048;
968 scsi_CDs[i].needs_sector_size = 1;
969 #if 0
970
971 get_sectorsize(i);
972 printk("Scd sectorsize = %d bytes.\n", scsi_CDs[i].sector_size);
973 #endif
974 scsi_CDs[i].use = 1;
975 scsi_CDs[i].ten = 1;
976 scsi_CDs[i].remap = 1;
977 sr_sizes[i] = scsi_CDs[i].capacity;
978 }
979
980
981
982
983
984 if(scsi_CDs[0].device && scsi_CDs[0].device->host->sg_tablesize)
985 read_ahead[MAJOR_NR] = 32;
986 else
987 read_ahead[MAJOR_NR] = 4;
988
989 return;
990 }
991
992 static void sr_detach(Scsi_Device * SDp)
993 {
994 Scsi_CD * cpnt;
995 int i, major;
996
997 major = MAJOR_NR << 8;
998
999 for(cpnt = scsi_CDs, i=0; i<sr_template.dev_max; i++, cpnt++)
1000 if(cpnt->device == SDp) {
1001
1002
1003
1004
1005 invalidate_inodes(major | i);
1006 invalidate_buffers(major | i);
1007
1008
1009
1010
1011
1012 cpnt->device = NULL;
1013 cpnt->capacity = 0;
1014 SDp->attached--;
1015 sr_template.nr_dev--;
1016 sr_template.dev_noticed--;
1017 sr_sizes[i] = 0;
1018 return;
1019 }
1020 return;
1021 }