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