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