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