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