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 #define DEBUG
308
309 static void sr_photocd(struct inode *inode)
310 {
311 unsigned long sector,min,sec,frame;
312 unsigned char buf[40];
313 unsigned char *cmd;
314 unsigned char *send;
315 unsigned char *rec;
316 int rc,is_xa;
317
318 if (!suser()) {
319
320
321
322
323
324
325 if (1 == scsi_CDs[MINOR(inode->i_rdev)].device->access_count)
326 scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = 0;
327 return;
328 }
329
330 cmd = rec = &buf[8];
331 switch(scsi_CDs[MINOR(inode->i_rdev)].device->manufacturer) {
332
333 case SCSI_MAN_NEC:
334 #ifdef DEBUG
335 printk("sr_photocd: use NEC code\n");
336 #endif
337 memset(buf,0,40);
338 *((unsigned long*)buf) = 0x0;
339 *((unsigned long*)buf+1) = 0x16;
340 cmd[0] = 0xde;
341 cmd[1] = 0x03;
342 cmd[2] = 0xb0;
343 rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
344 SCSI_IOCTL_SEND_COMMAND, buf);
345 if (rc != 0) {
346 printk("sr_photocd: ioctl error (NEC): 0x%x\n",rc);
347 sector = 0;
348 } else {
349 min = (unsigned long) rec[15]/16*10 + (unsigned long) rec[15]%16;
350 sec = (unsigned long) rec[16]/16*10 + (unsigned long) rec[16]%16;
351 frame = (unsigned long) rec[17]/16*10 + (unsigned long) rec[17]%16;
352
353 sector = (0xb0 == rec[14]) ? min*CD_SECS*CD_FRAMES + sec*CD_FRAMES + frame : 0;
354 #ifdef DEBUG
355 printk("NEC: (%2x) %2li:%02li:%02li = %li\n",buf[8+14],min,sec,frame,sector);
356 if (sector) {
357 printk("sr_photocd: multisession CD detected. start: %lu\n",sector);
358 }
359 #endif
360 }
361 break;
362
363 case SCSI_MAN_TOSHIBA:
364 #ifdef DEBUG
365 printk("sr_photocd: use TOSHIBA code\n");
366 #endif
367
368
369
370 memset(buf,0,40);
371 *((unsigned long*)buf) = 0;
372 *((unsigned long*)buf+1) = 4;
373 cmd[0] = 0xc7;
374 cmd[1] = 3;
375 rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
376 SCSI_IOCTL_SEND_COMMAND, buf);
377 if (rc != 0) {
378 printk("sr_photocd: ioctl error (TOSHIBA #1): 0x%x\n",rc);
379 sector = 0;
380 break;
381 }
382 is_xa = (rec[0] == 0x20);
383 #ifdef DEBUG
384 printk("sr_photocd: TOSHIBA %x\n",rec[0]);
385 #endif
386 min = (unsigned long) rec[1]/16*10 + (unsigned long) rec[1]%16;
387 sec = (unsigned long) rec[2]/16*10 + (unsigned long) rec[2]%16;
388 frame = (unsigned long) rec[3]/16*10 + (unsigned long) rec[3]%16;
389 sector = min*CD_SECS*CD_FRAMES + sec*CD_FRAMES + frame;
390 if (sector) {
391 sector -= CD_BLOCK_OFFSET;
392 #ifdef DEBUG
393 printk("sr_photocd: multisession CD detected: start: %lu\n",sector);
394 #endif
395 }
396
397
398 memset(buf,0,40);
399 *((unsigned long*)buf) = 0;
400 *((unsigned long*)buf+1) = 12;
401 cmd[0] = 0x1a;
402 cmd[2] = 1;
403 cmd[4] = 12;
404 rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
405 SCSI_IOCTL_SEND_COMMAND, buf);
406 if (rc != 0) {
407 printk("sr_photocd: ioctl error (TOSHIBA #2): 0x%x\n",rc);
408 break;
409 }
410 #ifdef DEBUG
411 printk("sr_photocd: get_density: 0x%x\n",rec[4]);
412 #endif
413
414
415 if ((rec[4] != 0x81 && is_xa) || (rec[4] != 0 && !is_xa)) {
416 #ifdef DEBUG
417 printk("sr_photocd: doing set_density\n");
418 #endif
419 memset(buf,0,40);
420 *((unsigned long*)buf) = 12;
421 *((unsigned long*)buf+1) = 0;
422 cmd[0] = 0x15;
423 cmd[1] = (1 << 4);
424 cmd[4] = 12;
425 send = &cmd[6];
426 send[ 3] = 0x08;
427 send[ 4] = (is_xa) ? 0x81 : 0;
428 send[10] = 0x08;
429 rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
430 SCSI_IOCTL_SEND_COMMAND, buf);
431 if (rc != 0) {
432 printk("sr_photocd: ioctl error (TOSHIBA #3): 0x%x\n",rc);
433 }
434 }
435 break;
436
437 case SCSI_MAN_UNKNOWN:
438 default:
439 #ifdef DEBUG
440 printk("sr_photocd: unknown drive, no special multisession code\n");
441 #endif
442 sector = 0;
443 break; }
444
445 scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = sector;
446
447 scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size = 1;
448 return;
449 }
450
451 #undef DEBUG
452
453 static int sr_open(struct inode * inode, struct file * filp)
454 {
455 if(MINOR(inode->i_rdev) >= sr_template.nr_dev ||
456 !scsi_CDs[MINOR(inode->i_rdev)].device) return -ENXIO;
457
458 if (filp->f_mode & 2)
459 return -EROFS;
460
461 check_disk_change(inode->i_rdev);
462
463 if(!scsi_CDs[MINOR(inode->i_rdev)].device->access_count++)
464 sr_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
465 if (scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)
466 (*scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)++;
467
468 sr_photocd(inode);
469
470
471
472
473
474
475 if(scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size)
476 get_sectorsize(MINOR(inode->i_rdev));
477
478 return 0;
479 }
480
481
482
483
484
485
486
487 static void do_sr_request (void)
488 {
489 Scsi_Cmnd * SCpnt = NULL;
490 struct request * req = NULL;
491 unsigned long flags;
492 int flag = 0;
493
494 while (1==1){
495 save_flags(flags);
496 cli();
497 if (CURRENT != NULL && CURRENT->dev == -1) {
498 restore_flags(flags);
499 return;
500 };
501
502 INIT_SCSI_REQUEST;
503
504 if (flag++ == 0)
505 SCpnt = allocate_device(&CURRENT,
506 scsi_CDs[DEVICE_NR(MINOR(CURRENT->dev))].device, 0);
507 else SCpnt = NULL;
508 restore_flags(flags);
509
510
511
512
513
514
515
516
517 if (!SCpnt && sr_template.nr_dev > 1){
518 struct request *req1;
519 req1 = NULL;
520 save_flags(flags);
521 cli();
522 req = CURRENT;
523 while(req){
524 SCpnt = request_queueable(req,
525 scsi_CDs[DEVICE_NR(MINOR(req->dev))].device);
526 if(SCpnt) break;
527 req1 = req;
528 req = req->next;
529 };
530 if (SCpnt && req->dev == -1) {
531 if (req == CURRENT)
532 CURRENT = CURRENT->next;
533 else
534 req1->next = req->next;
535 };
536 restore_flags(flags);
537 };
538
539 if (!SCpnt)
540 return;
541
542 wake_up(&wait_for_request);
543
544
545 requeue_sr_request(SCpnt);
546 };
547 }
548
549 void requeue_sr_request (Scsi_Cmnd * SCpnt)
550 {
551 unsigned int dev, block, realcount;
552 unsigned char cmd[10], *buffer, tries;
553 int this_count, start, end_rec;
554
555 tries = 2;
556
557 repeat:
558 if(!SCpnt || SCpnt->request.dev <= 0) {
559 do_sr_request();
560 return;
561 }
562
563 dev = MINOR(SCpnt->request.dev);
564 block = SCpnt->request.sector;
565 buffer = NULL;
566 this_count = 0;
567
568 if (dev >= sr_template.nr_dev)
569 {
570
571 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
572 tries = 2;
573 goto repeat;
574 }
575
576 if (!scsi_CDs[dev].use)
577 {
578
579 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
580 tries = 2;
581 goto repeat;
582 }
583
584 if (scsi_CDs[dev].device->changed)
585 {
586
587
588
589
590 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
591 tries = 2;
592 goto repeat;
593 }
594
595 switch (SCpnt->request.cmd)
596 {
597 case WRITE:
598 SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
599 goto repeat;
600 break;
601 case READ :
602 cmd[0] = READ_6;
603 break;
604 default :
605 panic ("Unknown sr command %d\n", SCpnt->request.cmd);
606 }
607
608 cmd[1] = (SCpnt->lun << 5) & 0xe0;
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626 SCpnt->use_sg = 0;
627
628 if (SCpnt->host->sg_tablesize > 0 &&
629 (!need_isa_buffer ||
630 dma_free_sectors >= 10)) {
631 struct buffer_head * bh;
632 struct scatterlist * sgpnt;
633 int count, this_count_max;
634 bh = SCpnt->request.bh;
635 this_count = 0;
636 count = 0;
637 this_count_max = (scsi_CDs[dev].ten ? 0xffff : 0xff) << 4;
638
639
640 this_count = SCpnt->request.sector % 4;
641 if(this_count) count++;
642 while(bh && count < SCpnt->host->sg_tablesize) {
643 if ((this_count + (bh->b_size >> 9)) > this_count_max) break;
644 this_count += (bh->b_size >> 9);
645 count++;
646 bh = bh->b_reqnext;
647 };
648
649 end_rec = 0;
650 if(this_count % 4) {
651 if (count < SCpnt->host->sg_tablesize) {
652 count++;
653 end_rec = (4 - (this_count % 4)) << 9;
654 this_count += 4 - (this_count % 4);
655 } else {
656 count--;
657 this_count -= (this_count % 4);
658 };
659 };
660 SCpnt->use_sg = count;
661 count = 512;
662 while( count < (SCpnt->use_sg * sizeof(struct scatterlist)))
663 count = count << 1;
664 SCpnt->sglist_len = count;
665 sgpnt = (struct scatterlist * ) scsi_malloc(count);
666 if (!sgpnt) {
667 printk("Warning - running *really* short on DMA buffers\n");
668 SCpnt->use_sg = 0;
669 } else {
670 buffer = (unsigned char *) sgpnt;
671 count = 0;
672 bh = SCpnt->request.bh;
673 if(SCpnt->request.sector % 4) {
674 sgpnt[count].length = (SCpnt->request.sector % 4) << 9;
675 sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
676 if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
677 sgpnt[count].alt_address = sgpnt[count].address;
678
679 count++;
680 };
681 for(bh = SCpnt->request.bh; count < SCpnt->use_sg;
682 count++, bh = bh->b_reqnext) {
683 if (bh) {
684 sgpnt[count].address = bh->b_data;
685 sgpnt[count].length = bh->b_size;
686 sgpnt[count].alt_address = NULL;
687 } else {
688 sgpnt[count].address = (char *) scsi_malloc(end_rec);
689 if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
690 sgpnt[count].length = end_rec;
691 sgpnt[count].alt_address = sgpnt[count].address;
692 if (count+1 != SCpnt->use_sg) panic("Bad sr request list");
693 break;
694 };
695 if (((int) sgpnt[count].address) + sgpnt[count].length >
696 ISA_DMA_THRESHOLD & (SCpnt->host->unchecked_isa_dma)) {
697 sgpnt[count].alt_address = sgpnt[count].address;
698
699
700
701 if(dma_free_sectors < (sgpnt[count].length >> 9) + 5) {
702 sgpnt[count].address = NULL;
703 } else {
704 sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
705 };
706
707
708
709
710 if(sgpnt[count].address == NULL){
711 printk("Warning: Running low on SCSI DMA buffers");
712
713 while(--count >= 0){
714 if(sgpnt[count].alt_address)
715 scsi_free(sgpnt[count].address, sgpnt[count].length);
716 };
717 SCpnt->use_sg = 0;
718 scsi_free(buffer, SCpnt->sglist_len);
719 break;
720 };
721 };
722 };
723 #ifdef DEBUG
724 printk("SR: %d %d %d %d %d *** ",SCpnt->use_sg, SCpnt->request.sector,
725 this_count,
726 SCpnt->request.current_nr_sectors,
727 SCpnt->request.nr_sectors);
728 for(count=0; count<SCpnt->use_sg; count++)
729 printk("SGlist: %d %x %x %x\n", count,
730 sgpnt[count].address,
731 sgpnt[count].alt_address,
732 sgpnt[count].length);
733 #endif
734 };
735 };
736
737 if (SCpnt->use_sg == 0){
738
739 if (!SCpnt->request.bh)
740 this_count = SCpnt->request.nr_sectors;
741 else
742 this_count = (SCpnt->request.bh->b_size >> 9);
743
744 start = block % 4;
745 if (start)
746 {
747 this_count = ((this_count > 4 - start) ?
748 (4 - start) : (this_count));
749 buffer = (unsigned char *) scsi_malloc(2048);
750 }
751 else if (this_count < 4)
752 {
753 buffer = (unsigned char *) scsi_malloc(2048);
754 }
755 else
756 {
757 this_count -= this_count % 4;
758 buffer = (unsigned char *) SCpnt->request.buffer;
759 if (((int) buffer) + (this_count << 9) > ISA_DMA_THRESHOLD &
760 (SCpnt->host->unchecked_isa_dma))
761 buffer = (unsigned char *) scsi_malloc(this_count << 9);
762 }
763 };
764
765 if (scsi_CDs[dev].sector_size == 2048)
766 block = block >> 2;
767 else
768 block = block & 0xfffffffc;
769
770 realcount = (this_count + 3) / 4;
771
772 if (scsi_CDs[dev].sector_size == 512) realcount = realcount << 2;
773
774 if (((realcount > 0xff) || (block > 0x1fffff)) && scsi_CDs[dev].ten)
775 {
776 if (realcount > 0xffff)
777 {
778 realcount = 0xffff;
779 this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
780 }
781
782 cmd[0] += READ_10 - READ_6 ;
783 cmd[2] = (unsigned char) (block >> 24) & 0xff;
784 cmd[3] = (unsigned char) (block >> 16) & 0xff;
785 cmd[4] = (unsigned char) (block >> 8) & 0xff;
786 cmd[5] = (unsigned char) block & 0xff;
787 cmd[6] = cmd[9] = 0;
788 cmd[7] = (unsigned char) (realcount >> 8) & 0xff;
789 cmd[8] = (unsigned char) realcount & 0xff;
790 }
791 else
792 {
793 if (realcount > 0xff)
794 {
795 realcount = 0xff;
796 this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
797 }
798
799 cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);
800 cmd[2] = (unsigned char) ((block >> 8) & 0xff);
801 cmd[3] = (unsigned char) block & 0xff;
802 cmd[4] = (unsigned char) realcount;
803 cmd[5] = 0;
804 }
805
806 #ifdef DEBUG
807 {
808 int i;
809 printk("ReadCD: %d %d %d %d\n",block, realcount, buffer, this_count);
810 printk("Use sg: %d\n", SCpnt->use_sg);
811 printk("Dumping command: ");
812 for(i=0; i<12; i++) printk("%2.2x ", cmd[i]);
813 printk("\n");
814 };
815 #endif
816
817
818
819
820
821
822
823
824
825
826
827 SCpnt->transfersize = (scsi_CDs[dev].sector_size > 1024) ?
828 1024 : scsi_CDs[dev].sector_size;
829
830 SCpnt->this_count = this_count;
831 scsi_do_cmd (SCpnt, (void *) cmd, buffer,
832 realcount * scsi_CDs[dev].sector_size,
833 rw_intr, SR_TIMEOUT, MAX_RETRIES);
834 }
835
836 static int sr_detect(Scsi_Device * SDp){
837
838 if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return 0;
839
840 printk("Detected scsi CD-ROM sr%d at scsi%d, id %d, lun %d\n",
841 sr_template.dev_noticed++,
842 SDp->host->host_no , SDp->id, SDp->lun);
843
844 return 1;
845 }
846
847 static int sr_attach(Scsi_Device * SDp){
848 Scsi_CD * cpnt;
849 int i;
850
851 if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return 1;
852
853 if (sr_template.nr_dev >= sr_template.dev_max)
854 {
855 SDp->attached--;
856 return 1;
857 }
858
859 for(cpnt = scsi_CDs, i=0; i<sr_template.dev_max; i++, cpnt++)
860 if(!cpnt->device) break;
861
862 if(i >= sr_template.dev_max) panic ("scsi_devices corrupt (sr)");
863
864 SDp->scsi_request_fn = do_sr_request;
865 scsi_CDs[i].device = SDp;
866 sr_template.nr_dev++;
867 if(sr_template.nr_dev > sr_template.dev_max)
868 panic ("scsi_devices corrupt (sr)");
869 return 0;
870 }
871
872
873 static void sr_init_done (Scsi_Cmnd * SCpnt)
874 {
875 struct request * req;
876
877 req = &SCpnt->request;
878 req->dev = 0xfffe;
879
880 if (req->sem != NULL) {
881 up(req->sem);
882 }
883 }
884
885 static void get_sectorsize(int i){
886 unsigned char cmd[10];
887 unsigned char *buffer;
888 int the_result, retries;
889 Scsi_Cmnd * SCpnt;
890
891 buffer = (unsigned char *) scsi_malloc(512);
892 SCpnt = allocate_device(NULL, scsi_CDs[i].device, 1);
893
894 retries = 3;
895 do {
896 cmd[0] = READ_CAPACITY;
897 cmd[1] = (scsi_CDs[i].device->lun << 5) & 0xe0;
898 memset ((void *) &cmd[2], 0, 8);
899 SCpnt->request.dev = 0xffff;
900 SCpnt->cmd_len = 0;
901
902 memset(buffer, 0, 8);
903
904 scsi_do_cmd (SCpnt,
905 (void *) cmd, (void *) buffer,
906 512, sr_init_done, SR_TIMEOUT,
907 MAX_RETRIES);
908
909 if (current == task[0])
910 while(SCpnt->request.dev != 0xfffe);
911 else
912 if (SCpnt->request.dev != 0xfffe){
913 struct semaphore sem = MUTEX_LOCKED;
914 SCpnt->request.sem = &sem;
915 down(&sem);
916
917 while (SCpnt->request.dev != 0xfffe) schedule();
918 };
919
920 the_result = SCpnt->result;
921 retries--;
922
923 } while(the_result && retries);
924
925 SCpnt->request.dev = -1;
926
927 wake_up(&SCpnt->device->device_wait);
928
929 if (the_result) {
930 scsi_CDs[i].capacity = 0x1fffff;
931 scsi_CDs[i].sector_size = 2048;
932 scsi_CDs[i].needs_sector_size = 1;
933 } else {
934 scsi_CDs[i].capacity = (buffer[0] << 24) |
935 (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
936 scsi_CDs[i].sector_size = (buffer[4] << 24) |
937 (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
938 if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;
939 if(scsi_CDs[i].sector_size != 2048 &&
940 scsi_CDs[i].sector_size != 512) {
941 printk ("scd%d : unsupported sector size %d.\n",
942 i, scsi_CDs[i].sector_size);
943 scsi_CDs[i].capacity = 0;
944 scsi_CDs[i].needs_sector_size = 1;
945 };
946 if(scsi_CDs[i].sector_size == 2048)
947 scsi_CDs[i].capacity *= 4;
948 scsi_CDs[i].needs_sector_size = 0;
949 sr_sizes[i] = scsi_CDs[i].capacity;
950 };
951 scsi_free(buffer, 512);
952 }
953
954 static void sr_init()
955 {
956 int i;
957 static int sr_registered = 0;
958
959 if(sr_template.dev_noticed == 0) return;
960
961 if(!sr_registered) {
962 if (register_blkdev(MAJOR_NR,"sr",&sr_fops)) {
963 printk("Unable to get major %d for SCSI-CD\n",MAJOR_NR);
964 return;
965 }
966 sr_registered++;
967 }
968
969
970 if (scsi_CDs) return;
971 sr_template.dev_max = sr_template.dev_noticed + SR_EXTRA_DEVS;
972 scsi_CDs = (Scsi_CD *) scsi_init_malloc(sr_template.dev_max * sizeof(Scsi_CD), GFP_ATOMIC);
973 memset(scsi_CDs, 0, sr_template.dev_max * sizeof(Scsi_CD));
974
975 sr_sizes = (int *) scsi_init_malloc(sr_template.dev_max * sizeof(int), GFP_ATOMIC);
976 memset(sr_sizes, 0, sr_template.dev_max * sizeof(int));
977
978 sr_blocksizes = (int *) scsi_init_malloc(sr_template.dev_max *
979 sizeof(int), GFP_ATOMIC);
980 for(i=0;i<sr_template.dev_max;i++) sr_blocksizes[i] = 2048;
981 blksize_size[MAJOR_NR] = sr_blocksizes;
982
983 }
984
985 void sr_finish()
986 {
987 int i;
988
989 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
990 blk_size[MAJOR_NR] = sr_sizes;
991
992 for (i = 0; i < sr_template.nr_dev; ++i)
993 {
994
995
996 if (scsi_CDs[i].capacity) continue;
997 scsi_CDs[i].capacity = 0x1fffff;
998 scsi_CDs[i].sector_size = 2048;
999 scsi_CDs[i].needs_sector_size = 1;
1000 #if 0
1001
1002 get_sectorsize(i);
1003 printk("Scd sectorsize = %d bytes.\n", scsi_CDs[i].sector_size);
1004 #endif
1005 scsi_CDs[i].use = 1;
1006 scsi_CDs[i].ten = 1;
1007 scsi_CDs[i].remap = 1;
1008 sr_sizes[i] = scsi_CDs[i].capacity;
1009 }
1010
1011
1012
1013
1014
1015 if(scsi_CDs[0].device && scsi_CDs[0].device->host->sg_tablesize)
1016 read_ahead[MAJOR_NR] = 32;
1017 else
1018 read_ahead[MAJOR_NR] = 4;
1019
1020 return;
1021 }
1022
1023 static void sr_detach(Scsi_Device * SDp)
1024 {
1025 Scsi_CD * cpnt;
1026 int i, major;
1027
1028 major = MAJOR_NR << 8;
1029
1030 for(cpnt = scsi_CDs, i=0; i<sr_template.dev_max; i++, cpnt++)
1031 if(cpnt->device == SDp) {
1032
1033
1034
1035
1036 invalidate_inodes(major | i);
1037 invalidate_buffers(major | i);
1038
1039
1040
1041
1042
1043 cpnt->device = NULL;
1044 cpnt->capacity = 0;
1045 SDp->attached--;
1046 sr_template.nr_dev--;
1047 sr_template.dev_noticed--;
1048 sr_sizes[i] = 0;
1049 return;
1050 }
1051 return;
1052 }