This source file includes following definitions.
- op_ok
- pa_ok
- sten_low
- dten_low
- statusAzt
- aztStatTimer
- aztcd_setup
- aztCloseDoor
- aztLockDoor
- aztUnlockDoor
- aztSendCmd
- sendAztCmd
- aztSeek
- aztSetDiskType
- check_aztcd_media_change
- aztStatus
- getAztStatus
- aztPlay
- aztcd_ioctl
- azt_transfer
- do_aztcd_request
- azt_poll
- azt_invalidate_buffers
- aztcd_open
- aztcd_release
- aztcd_init
- azt_hsg2msf
- azt_msf2hsg
- azt_bin2bcd
- azt_bcd2bin
- aztGetValue
- aztGetQChannelInfo
- aztUpdateToc
- aztGetDiskInfo
- aztGetMultiDiskInfo
- aztGetToc
- init_module
- cleanup_module
1 #define AZT_VERSION "2.30"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153 #include <linux/module.h>
154 #include <linux/errno.h>
155 #include <linux/sched.h>
156 #include <linux/mm.h>
157 #include <linux/timer.h>
158 #include <linux/fs.h>
159 #include <linux/kernel.h>
160 #include <linux/cdrom.h>
161 #include <linux/ioport.h>
162 #include <linux/string.h>
163 #include <linux/major.h>
164
165 #include <asm/system.h>
166 #include <asm/io.h>
167 #include <asm/segment.h>
168
169 #define MAJOR_NR AZTECH_CDROM_MAJOR
170
171 #include <linux/blk.h>
172 #include <linux/aztcd.h>
173
174 #define SET_TIMER(func, jifs) delay_timer.expires = jiffies + (jifs); \
175 delay_timer.function = (void *) (func); \
176 add_timer(&delay_timer);
177
178 #define CLEAR_TIMER del_timer(&delay_timer);
179
180 #define RETURNM(message,value) {printk("aztcd: Warning: %s failed\n",message);\
181 return value;}
182 #define RETURN(message) {printk("aztcd: Warning: %s failed\n",message);\
183 return;}
184
185
186 #define SWITCH_IDE_SLAVE outb_p(0xa0,azt_port+6); \
187 outb_p(0x10,azt_port+6); \
188 outb_p(0x00,azt_port+7); \
189 outb_p(0x10,azt_port+6);
190 #define SWITCH_IDE_MASTER outb_p(0xa0,azt_port+6);
191
192 static int aztPresent = 0;
193
194 #if 0
195 #define AZT_TEST
196 #define AZT_TEST1
197 #define AZT_TEST2
198 #define AZT_TEST3
199 #define AZT_TEST4
200 #define AZT_TEST5
201 #define AZT_DEBUG
202 #define AZT_DEBUG_MULTISESSION
203 #endif
204
205 #define CURRENT_VALID \
206 (CURRENT && MAJOR(CURRENT -> rq_dev) == MAJOR_NR && CURRENT -> cmd == READ \
207 && CURRENT -> sector != -1)
208
209 #define AFL_STATUSorDATA (AFL_STATUS | AFL_DATA)
210 #define AZT_BUF_SIZ 16
211
212 static volatile int azt_transfer_is_active=0;
213
214 static char azt_buf[CD_FRAMESIZE_RAW*AZT_BUF_SIZ];
215 #if AZT_PRIVATE_IOCTLS
216 static char buf[CD_FRAMESIZE_RAW];
217 #endif
218
219 static volatile int azt_buf_bn[AZT_BUF_SIZ], azt_next_bn;
220 static volatile int azt_buf_in, azt_buf_out = -1;
221 static volatile int azt_error=0;
222 static int azt_open_count=0;
223 enum azt_state_e
224 { AZT_S_IDLE,
225 AZT_S_START,
226 AZT_S_MODE,
227 AZT_S_READ,
228 AZT_S_DATA,
229 AZT_S_STOP,
230 AZT_S_STOPPING
231 };
232 static volatile enum azt_state_e azt_state = AZT_S_IDLE;
233 #ifdef AZT_TEST3
234 static volatile enum azt_state_e azt_state_old = AZT_S_STOP;
235 static volatile int azt_st_old = 0;
236 #endif
237 enum azt_read_modes
238 { AZT_MODE_0,
239 AZT_MODE_1,
240 AZT_MODE_2
241 };
242 static volatile enum azt_read_modes azt_read_mode = AZT_MODE_1;
243
244 static int azt_mode = -1;
245 static volatile int azt_read_count = 1;
246
247 #define READ_TIMEOUT 3000
248
249 #define azt_port aztcd
250 static int azt_port = AZT_BASE_ADDR;
251
252 static char azt_cont = 0;
253 static char azt_init_end = 0;
254 static char azt_auto_eject = AZT_AUTO_EJECT;
255
256 static int AztTimeout, AztTries;
257 static struct wait_queue *azt_waitq = NULL;
258 static struct timer_list delay_timer = { NULL, NULL, 0, 0, NULL };
259
260 static struct azt_DiskInfo DiskInfo;
261 static struct azt_Toc Toc[MAX_TRACKS];
262 static struct azt_Play_msf azt_Play;
263
264 static int aztAudioStatus = CDROM_AUDIO_NO_STATUS;
265 static char aztDiskChanged = 1;
266 static char aztTocUpToDate = 0;
267
268 static void azt_transfer(void);
269 static void azt_poll(void);
270 static void azt_invalidate_buffers(void);
271 static void do_aztcd_request(void);
272 static void azt_hsg2msf(long hsg, struct msf *msf);
273 static void azt_bin2bcd(unsigned char *p);
274 static long azt_msf2hsg(struct msf *mp);
275 static int azt_bcd2bin(unsigned char bcd);
276 static int aztStatus(void);
277 static int getAztStatus(void);
278 static int aztSendCmd(int cmd);
279 static int sendAztCmd(int cmd, struct azt_Play_msf *params);
280 static int aztGetQChannelInfo(struct azt_Toc *qp);
281 static int aztUpdateToc(void);
282 static int aztGetDiskInfo(void);
283 #if AZT_MULTISESSION
284 static int aztGetMultiDiskInfo(void);
285 #endif
286 static int aztGetToc(int multi);
287 static int aztGetValue(unsigned char *result);
288 static void aztStatTimer(void);
289 static void aztCloseDoor(void);
290 static void aztLockDoor(void);
291 static void aztUnlockDoor(void);
292
293 static unsigned char aztIndatum;
294 static unsigned long aztTimeOutCount;
295 static int aztCmd = 0;
296
297
298
299
300 # define OP_OK op_ok()
301 void op_ok(void)
302 { aztTimeOutCount=0;
303 do { aztIndatum=inb(DATA_PORT);
304 aztTimeOutCount++;
305 if (aztTimeOutCount>=AZT_TIMEOUT)
306 { printk("aztcd: Error Wait OP_OK\n");
307 break;
308 }
309 } while (aztIndatum!=AFL_OP_OK);
310 }
311
312
313 # define PA_OK pa_ok()
314 void pa_ok(void)
315 { aztTimeOutCount=0;
316 do { aztIndatum=inb(DATA_PORT);
317 aztTimeOutCount++;
318 if (aztTimeOutCount>=AZT_TIMEOUT)
319 { printk("aztcd: Error Wait PA_OK\n");
320 break;
321 }
322 } while (aztIndatum!=AFL_PA_OK);
323 }
324
325
326 # define STEN_LOW sten_low()
327 void sten_low(void)
328 { aztTimeOutCount=0;
329 do { aztIndatum=inb(STATUS_PORT);
330 aztTimeOutCount++;
331 if (aztTimeOutCount>=AZT_TIMEOUT)
332 { if (azt_init_end) printk("aztcd: Error Wait STEN_LOW commands:%x\n",aztCmd);
333 break;
334 }
335 } while (aztIndatum&AFL_STATUS);
336 }
337
338
339 # define DTEN_LOW dten_low()
340 void dten_low(void)
341 { aztTimeOutCount=0;
342 do { aztIndatum=inb(STATUS_PORT);
343 aztTimeOutCount++;
344 if (aztTimeOutCount>=AZT_TIMEOUT)
345 { printk("aztcd: Error Wait DTEN_OK\n");
346 break;
347 }
348 } while (aztIndatum&AFL_DATA);
349 }
350
351
352
353
354
355 #define STEN_LOW_WAIT statusAzt()
356 void statusAzt(void)
357 { AztTimeout = AZT_STATUS_DELAY;
358 SET_TIMER(aztStatTimer, HZ/100);
359 sleep_on(&azt_waitq);
360 if (AztTimeout <= 0) printk("aztcd: Error Wait STEN_LOW_WAIT command:%x\n",aztCmd);
361 return;
362 }
363
364 static void aztStatTimer(void)
365 { if (!(inb(STATUS_PORT) & AFL_STATUS))
366 { wake_up(&azt_waitq);
367 return;
368 }
369 AztTimeout--;
370 if (AztTimeout <= 0)
371 { wake_up(&azt_waitq);
372 printk("aztcd: Error aztStatTimer: Timeout\n");
373 return;
374 }
375 SET_TIMER(aztStatTimer, HZ/100);
376 }
377
378 void aztcd_setup(char *str, int *ints)
379 { if (ints[0] > 0)
380 azt_port = ints[1];
381 if (ints[0] > 1)
382 azt_cont = ints[2];
383 }
384
385
386
387
388
389
390 static void aztCloseDoor(void)
391 {
392 aztSendCmd(ACMD_CLOSE);
393 STEN_LOW;
394 return;
395 }
396
397 static void aztLockDoor(void)
398 {
399 #if AZT_ALLOW_TRAY_LOCK
400 aztSendCmd(ACMD_LOCK);
401 STEN_LOW;
402 #endif
403 return;
404 }
405
406 static void aztUnlockDoor(void)
407 {
408 #if AZT_ALLOW_TRAY_LOCK
409 aztSendCmd(ACMD_UNLOCK);
410 STEN_LOW;
411 #endif
412 return;
413 }
414
415
416
417
418 static int aztSendCmd(int cmd)
419 { unsigned char data;
420 int retry;
421
422 #ifdef AZT_DEBUG
423 printk("aztcd: Executing command %x\n",cmd);
424 #endif
425
426 if ((azt_port==0x1f0)||(azt_port==0x170))
427 SWITCH_IDE_SLAVE;
428
429 aztCmd=cmd;
430 outb(POLLED,MODE_PORT);
431 do { if (inb(STATUS_PORT)&AFL_STATUS) break;
432 inb(DATA_PORT);
433 } while (1);
434 do { if (inb(STATUS_PORT)&AFL_DATA) break;
435 inb(DATA_PORT);
436 } while (1);
437 for (retry=0;retry<AZT_RETRY_ATTEMPTS;retry++)
438 { outb((unsigned char) cmd,CMD_PORT);
439 STEN_LOW;
440 data=inb(DATA_PORT);
441 if (data==AFL_OP_OK)
442 { return 0;}
443 if (data==AFL_OP_ERR)
444 { STEN_LOW;
445 data=inb(DATA_PORT);
446 printk("### Error 1 aztcd: aztSendCmd %x Error Code %x\n",cmd,data);
447 }
448 }
449 if (retry>=AZT_RETRY_ATTEMPTS)
450 { printk("### Error 2 aztcd: aztSendCmd %x \n",cmd);
451 azt_error=0xA5;
452 }
453 RETURNM("aztSendCmd",-1);
454 }
455
456
457
458
459 static int sendAztCmd(int cmd, struct azt_Play_msf *params)
460 { unsigned char data;
461 int retry;
462
463 #ifdef AZT_DEBUG
464 printk("aztcd: play start=%02x:%02x:%02x end=%02x:%02x:%02x\n", \
465 params->start.min, params->start.sec, params->start.frame, \
466 params->end.min, params->end.sec, params->end.frame);
467 #endif
468 for (retry=0;retry<AZT_RETRY_ATTEMPTS;retry++)
469 { aztSendCmd(cmd);
470 outb(params -> start.min,CMD_PORT);
471 outb(params -> start.sec,CMD_PORT);
472 outb(params -> start.frame,CMD_PORT);
473 outb(params -> end.min,CMD_PORT);
474 outb(params -> end.sec,CMD_PORT);
475 outb(params -> end.frame,CMD_PORT);
476 STEN_LOW;
477 data=inb(DATA_PORT);
478 if (data==AFL_PA_OK)
479 { return 0;}
480 if (data==AFL_PA_ERR)
481 { STEN_LOW;
482 data=inb(DATA_PORT);
483 printk("### Error 1 aztcd: sendAztCmd %x Error Code %x\n",cmd,data);
484 }
485 }
486 if (retry>=AZT_RETRY_ATTEMPTS)
487 { printk("### Error 2 aztcd: sendAztCmd %x\n ",cmd);
488 azt_error=0xA5;
489 }
490 RETURNM("sendAztCmd",-1);
491 }
492
493
494
495
496 static int aztSeek(struct azt_Play_msf *params)
497 { unsigned char data;
498 int retry;
499
500 #ifdef AZT_DEBUG
501 printk("aztcd: aztSeek %02x:%02x:%02x\n", \
502 params->start.min, params->start.sec, params->start.frame);
503 #endif
504 for (retry=0;retry<AZT_RETRY_ATTEMPTS;retry++)
505 { aztSendCmd(ACMD_SEEK);
506 outb(params -> start.min,CMD_PORT);
507 outb(params -> start.sec,CMD_PORT);
508 outb(params -> start.frame,CMD_PORT);
509 STEN_LOW;
510 data=inb(DATA_PORT);
511 if (data==AFL_PA_OK)
512 { return 0;}
513 if (data==AFL_PA_ERR)
514 { STEN_LOW;
515 data=inb(DATA_PORT);
516 printk("### Error 1 aztcd: aztSeek\n");
517 }
518 }
519 if (retry>=AZT_RETRY_ATTEMPTS)
520 { printk("### Error 2 aztcd: aztSeek\n ");
521 azt_error=0xA5;
522 }
523 RETURNM("aztSeek",-1);
524 }
525
526
527
528
529
530 static int aztSetDiskType(int type)
531 { unsigned char data;
532 int retry;
533
534 #ifdef AZT_DEBUG
535 printk("aztcd: set disk type command: type= %i\n",type);
536 #endif
537 for (retry=0;retry<AZT_RETRY_ATTEMPTS;retry++)
538 { aztSendCmd(ACMD_SET_DISK_TYPE);
539 outb(type,CMD_PORT);
540 STEN_LOW;
541 data=inb(DATA_PORT);
542 if (data==AFL_PA_OK)
543 { azt_read_mode=type;
544 return 0;
545 }
546 if (data==AFL_PA_ERR)
547 { STEN_LOW;
548 data=inb(DATA_PORT);
549 printk("### Error 1 aztcd: aztSetDiskType %x Error Code %x\n",type,data);
550 }
551 }
552 if (retry>=AZT_RETRY_ATTEMPTS)
553 { printk("### Error 2 aztcd: aztSetDiskType %x\n ",type);
554 azt_error=0xA5;
555 }
556 RETURNM("aztSetDiskType",-1);
557 }
558
559
560
561
562
563 static int check_aztcd_media_change(kdev_t full_dev)
564 { return 0;
565 }
566
567
568
569
570
571 static int aztStatus(void)
572 { int st;
573
574
575
576
577 STEN_LOW;
578 if (aztTimeOutCount<AZT_TIMEOUT)
579 { st = inb(DATA_PORT) & 0xFF;
580 return st;
581 }
582 else
583 RETURNM("aztStatus",-1);
584 }
585
586
587
588
589 static int getAztStatus(void)
590 { int st;
591
592 if (aztSendCmd(ACMD_GET_STATUS)) RETURNM("getAztStatus 1",-1);
593 STEN_LOW;
594 st = inb(DATA_PORT) & 0xFF;
595 #ifdef AZT_DEBUG
596 printk("aztcd: Status = %x\n",st);
597 #endif
598 if ((st == 0xFF)||(st&AST_CMD_CHECK))
599 { printk("aztcd: AST_CMD_CHECK error or no status available\n");
600 return -1;
601 }
602
603 if (((st&AST_MODE_BITS)!=AST_BUSY) && (aztAudioStatus == CDROM_AUDIO_PLAY))
604
605 aztAudioStatus = CDROM_AUDIO_COMPLETED;
606
607 if ((st & AST_DSK_CHG)||(st & AST_NOT_READY))
608 { aztDiskChanged = 1;
609 aztTocUpToDate = 0;
610 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
611 }
612 return st;
613 }
614
615
616
617
618
619 static int aztPlay(struct azt_Play_msf *arg)
620 { if (sendAztCmd(ACMD_PLAY_AUDIO, arg) < 0) RETURNM("aztPlay",-1);
621 return 0;
622 }
623
624
625
626 static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
627 { int i, st;
628 struct azt_Toc qInfo;
629 struct cdrom_ti ti;
630 struct cdrom_tochdr tocHdr;
631 struct cdrom_msf msf;
632 struct cdrom_tocentry entry;
633 struct azt_Toc *tocPtr;
634 struct cdrom_subchnl subchnl;
635 struct cdrom_volctrl volctrl;
636
637 #ifdef AZT_DEBUG
638 printk("aztcd: starting aztcd_ioctl - Command:%x Time: %li\n",cmd, jiffies);
639 printk("aztcd Status %x\n", getAztStatus());
640 #endif
641 if (!ip) RETURNM("aztcd_ioctl 1",-EINVAL);
642 if (getAztStatus()<0) RETURNM("aztcd_ioctl 2", -EIO);
643 if ((!aztTocUpToDate)||(aztDiskChanged))
644 { if ((i=aztUpdateToc())<0) RETURNM("aztcd_ioctl 3", i);
645 }
646
647 switch (cmd)
648 {
649 case CDROMSTART:
650
651 #if AZT_PRIVATE_IOCTLS
652 if (aztSendCmd(ACMD_CLOSE)) RETURNM("aztcd_ioctl 4",-1);
653 STEN_LOW_WAIT;
654 #endif
655 break;
656 case CDROMSTOP:
657 if (aztSendCmd(ACMD_STOP)) RETURNM("aztcd_ioctl 5",-1);
658 STEN_LOW_WAIT;
659
660 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
661 break;
662 case CDROMPAUSE:
663 if (aztAudioStatus != CDROM_AUDIO_PLAY) return -EINVAL;
664
665 if (aztGetQChannelInfo(&qInfo) < 0)
666 {
667 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
668 RETURNM("aztcd_ioctl 7",0);
669 }
670 azt_Play.start = qInfo.diskTime;
671
672 if (aztSendCmd(ACMD_PAUSE)) RETURNM("aztcd_ioctl 8",-1);
673 STEN_LOW_WAIT;
674 aztAudioStatus = CDROM_AUDIO_PAUSED;
675 break;
676 case CDROMRESUME:
677 if (aztAudioStatus != CDROM_AUDIO_PAUSED) return -EINVAL;
678
679 i = aztPlay(&azt_Play);
680 if (i < 0)
681 { aztAudioStatus = CDROM_AUDIO_ERROR;
682 return -EIO;
683 }
684 aztAudioStatus = CDROM_AUDIO_PLAY;
685 break;
686 case CDROMMULTISESSION:
687 { struct cdrom_multisession ms;
688 #ifdef AZT_DEBUG
689 printk("aztcd ioctl MULTISESSION\n");
690 #endif
691 st = verify_area(VERIFY_READ, (void*) arg, sizeof(struct cdrom_multisession));
692 if (st) return st;
693 memcpy_fromfs(&ms, (void*) arg, sizeof(struct cdrom_multisession));
694 if (ms.addr_format == CDROM_MSF)
695 { ms.addr.msf.minute = azt_bcd2bin(DiskInfo.lastSession.min);
696 ms.addr.msf.second = azt_bcd2bin(DiskInfo.lastSession.sec);
697 ms.addr.msf.frame = azt_bcd2bin(DiskInfo.lastSession.frame);
698 }
699 else if (ms.addr_format == CDROM_LBA)
700 ms.addr.lba = azt_msf2hsg(&DiskInfo.lastSession);
701 else
702 return -EINVAL;
703 ms.xa_flag = DiskInfo.xa;
704 st = verify_area(VERIFY_WRITE, (void*) arg, sizeof(struct cdrom_multisession));
705 if (st) return st;
706 memcpy_tofs((void*) arg, &ms, sizeof(struct cdrom_multisession));
707 #ifdef AZT_DEBUG
708 if (ms.addr_format == CDROM_MSF)
709 printk("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n",
710 ms.xa_flag, ms.addr.msf.minute, ms.addr.msf.second,
711 ms.addr.msf.frame, DiskInfo.lastSession.min,
712 DiskInfo.lastSession.sec, DiskInfo.lastSession.frame);
713 else
714 printk("aztcd multisession %d, lba:0x%08x [%02x:%02x.%02x])\n",
715 ms.xa_flag, ms.addr.lba, DiskInfo.lastSession.min,
716 DiskInfo.lastSession.sec, DiskInfo.lastSession.frame);
717 #endif
718 return 0;
719 }
720 case CDROMPLAYTRKIND:
721 st = verify_area(VERIFY_READ, (void *) arg, sizeof ti);
722 if (st) return st;
723 memcpy_fromfs(&ti, (void *) arg, sizeof ti);
724 if (ti.cdti_trk0 < DiskInfo.first
725 || ti.cdti_trk0 > DiskInfo.last
726 || ti.cdti_trk1 < ti.cdti_trk0)
727 { return -EINVAL;
728 }
729 if (ti.cdti_trk1 > DiskInfo.last)
730 ti.cdti_trk1 = DiskInfo.last;
731 azt_Play.start = Toc[ti.cdti_trk0].diskTime;
732 azt_Play.end = Toc[ti.cdti_trk1 + 1].diskTime;
733 #ifdef AZT_DEBUG
734 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
735 azt_Play.start.min, azt_Play.start.sec, azt_Play.start.frame,
736 azt_Play.end.min, azt_Play.end.sec, azt_Play.end.frame);
737 #endif
738 i = aztPlay(&azt_Play);
739 if (i < 0)
740 { aztAudioStatus = CDROM_AUDIO_ERROR;
741 return -EIO;
742 }
743 aztAudioStatus = CDROM_AUDIO_PLAY;
744 break;
745 case CDROMPLAYMSF:
746
747
748
749
750
751
752 st = verify_area(VERIFY_READ, (void *) arg, sizeof msf);
753 if (st) return st;
754 memcpy_fromfs(&msf, (void *) arg, sizeof msf);
755
756 azt_bin2bcd(&msf.cdmsf_min0);
757 azt_bin2bcd(&msf.cdmsf_sec0);
758 azt_bin2bcd(&msf.cdmsf_frame0);
759 azt_bin2bcd(&msf.cdmsf_min1);
760 azt_bin2bcd(&msf.cdmsf_sec1);
761 azt_bin2bcd(&msf.cdmsf_frame1);
762 azt_Play.start.min = msf.cdmsf_min0;
763 azt_Play.start.sec = msf.cdmsf_sec0;
764 azt_Play.start.frame = msf.cdmsf_frame0;
765 azt_Play.end.min = msf.cdmsf_min1;
766 azt_Play.end.sec = msf.cdmsf_sec1;
767 azt_Play.end.frame = msf.cdmsf_frame1;
768 #ifdef AZT_DEBUG
769 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
770 azt_Play.start.min, azt_Play.start.sec, azt_Play.start.frame,
771 azt_Play.end.min, azt_Play.end.sec, azt_Play.end.frame);
772 #endif
773 i = aztPlay(&azt_Play);
774 if (i < 0)
775 { aztAudioStatus = CDROM_AUDIO_ERROR;
776 return -EIO;
777 }
778 aztAudioStatus = CDROM_AUDIO_PLAY;
779 break;
780
781 case CDROMREADTOCHDR:
782 st = verify_area(VERIFY_WRITE, (void *) arg, sizeof tocHdr);
783 if (st) return st;
784 tocHdr.cdth_trk0 = DiskInfo.first;
785 tocHdr.cdth_trk1 = DiskInfo.last;
786 memcpy_tofs((void *) arg, &tocHdr, sizeof tocHdr);
787 break;
788 case CDROMREADTOCENTRY:
789 st = verify_area(VERIFY_READ, (void *) arg, sizeof entry);
790 if (st) return st;
791 st = verify_area(VERIFY_WRITE, (void *) arg, sizeof entry);
792 if (st) return st;
793 memcpy_fromfs(&entry, (void *) arg, sizeof entry);
794 if ((!aztTocUpToDate)||aztDiskChanged) aztUpdateToc();
795 if (entry.cdte_track == CDROM_LEADOUT)
796 tocPtr = &Toc[DiskInfo.last + 1];
797 else if (entry.cdte_track > DiskInfo.last
798 || entry.cdte_track < DiskInfo.first)
799 { return -EINVAL;
800 }
801 else
802 tocPtr = &Toc[entry.cdte_track];
803 entry.cdte_adr = tocPtr -> ctrl_addr;
804 entry.cdte_ctrl = tocPtr -> ctrl_addr >> 4;
805 if (entry.cdte_format == CDROM_LBA)
806 entry.cdte_addr.lba = azt_msf2hsg(&tocPtr -> diskTime);
807 else if (entry.cdte_format == CDROM_MSF)
808 { entry.cdte_addr.msf.minute = azt_bcd2bin(tocPtr -> diskTime.min);
809 entry.cdte_addr.msf.second = azt_bcd2bin(tocPtr -> diskTime.sec);
810 entry.cdte_addr.msf.frame = azt_bcd2bin(tocPtr -> diskTime.frame);
811 }
812 else
813 { return -EINVAL;
814 }
815 memcpy_tofs((void *) arg, &entry, sizeof entry);
816 break;
817 case CDROMSUBCHNL:
818 st = verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_subchnl));
819 if (st) {
820 #ifdef AZT_DEBUG
821 printk("aztcd: exiting aztcd_ioctl - Error 1 - Command:%x\n",cmd);
822 #endif
823 return st;
824 }
825 st = verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct cdrom_subchnl));
826 if (st) {
827 #ifdef AZT_DEBUG
828 printk("aztcd: exiting aztcd_ioctl - Error 2 - Command:%x\n",cmd);
829 #endif
830 return st;
831 }
832 memcpy_fromfs(&subchnl, (void *) arg, sizeof (struct cdrom_subchnl));
833 if (aztGetQChannelInfo(&qInfo) < 0)
834 if (st) {
835 #ifdef AZT_DEBUG
836 printk("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",cmd);
837 #endif
838 return -EIO;
839 }
840 subchnl.cdsc_audiostatus = aztAudioStatus;
841 subchnl.cdsc_adr = qInfo.ctrl_addr;
842 subchnl.cdsc_ctrl = qInfo.ctrl_addr >> 4;
843 subchnl.cdsc_trk = azt_bcd2bin(qInfo.track);
844 subchnl.cdsc_ind = azt_bcd2bin(qInfo.pointIndex);
845 if (subchnl.cdsc_format == CDROM_LBA)
846 { subchnl.cdsc_absaddr.lba = azt_msf2hsg(&qInfo.diskTime);
847 subchnl.cdsc_reladdr.lba = azt_msf2hsg(&qInfo.trackTime);
848 }
849 else
850 { subchnl.cdsc_format = CDROM_MSF;
851 subchnl.cdsc_absaddr.msf.minute = azt_bcd2bin(qInfo.diskTime.min);
852 subchnl.cdsc_absaddr.msf.second = azt_bcd2bin(qInfo.diskTime.sec);
853 subchnl.cdsc_absaddr.msf.frame = azt_bcd2bin(qInfo.diskTime.frame);
854 subchnl.cdsc_reladdr.msf.minute = azt_bcd2bin(qInfo.trackTime.min);
855 subchnl.cdsc_reladdr.msf.second = azt_bcd2bin(qInfo.trackTime.sec);
856 subchnl.cdsc_reladdr.msf.frame = azt_bcd2bin(qInfo.trackTime.frame);
857 }
858 memcpy_tofs((void *) arg, &subchnl, sizeof (struct cdrom_subchnl));
859 break;
860 case CDROMVOLCTRL:
861
862
863
864 st=verify_area(VERIFY_READ,(void *) arg, sizeof(volctrl));
865 if (st) return (st);
866 memcpy_fromfs(&volctrl,(char *) arg,sizeof(volctrl));
867 azt_Play.start.min = 0x21;
868 azt_Play.start.sec = 0x84;
869 azt_Play.start.frame = volctrl.channel0;
870 azt_Play.end.min = volctrl.channel1;
871 azt_Play.end.sec = volctrl.channel2;
872 azt_Play.end.frame = volctrl.channel3;
873 sendAztCmd(ACMD_SET_VOLUME, &azt_Play);
874 STEN_LOW_WAIT;
875 break;
876 case CDROMEJECT:
877 aztUnlockDoor();
878
879 if (aztAudioStatus == CDROM_AUDIO_PLAY)
880 { if (aztSendCmd(ACMD_STOP)) RETURNM("azt_ioctl 10",-1);
881 STEN_LOW_WAIT;
882 }
883 if (aztSendCmd(ACMD_EJECT)) RETURNM("azt_ioctl 11",-1);
884 STEN_LOW_WAIT;
885 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
886 break;
887 case CDROMEJECT_SW:
888 azt_auto_eject = (char) arg;
889 break;
890 case CDROMRESET:
891 outb(ACMD_SOFT_RESET,CMD_PORT);
892 STEN_LOW;
893 if (inb(DATA_PORT)!=AFL_OP_OK)
894 { printk("aztcd: AZTECH CD-ROM drive does not respond\n");
895 }
896 break;
897
898
899
900
901 #if AZT_PRIVATE_IOCTLS
902 case CDROMREADCOOKED:
903 case CDROMREADRAW:
904 { st = verify_area(VERIFY_READ, (void *) arg, sizeof msf);
905 if (st) return st;
906 st = verify_area(VERIFY_WRITE, (void *) arg, sizeof buf);
907 if (st) return st;
908 memcpy_fromfs(&msf, (void *) arg, sizeof msf);
909
910 azt_bin2bcd(&msf.cdmsf_min0);
911 azt_bin2bcd(&msf.cdmsf_sec0);
912 azt_bin2bcd(&msf.cdmsf_frame0);
913 msf.cdmsf_min1=0;
914 msf.cdmsf_sec1=0;
915 msf.cdmsf_frame1=1;
916 azt_Play.start.min = msf.cdmsf_min0;
917 azt_Play.start.sec = msf.cdmsf_sec0;
918 azt_Play.start.frame = msf.cdmsf_frame0;
919 azt_Play.end.min = msf.cdmsf_min1;
920 azt_Play.end.sec = msf.cdmsf_sec1;
921 azt_Play.end.frame = msf.cdmsf_frame1;
922 if (cmd==CDROMREADRAW)
923 { if (DiskInfo.xa)
924 { return -1;
925 }
926 else
927 { if (sendAztCmd(ACMD_PLAY_READ_RAW, &azt_Play)) return -1;
928 DTEN_LOW;
929 insb(DATA_PORT,buf,CD_FRAMESIZE_RAW);
930 memcpy_tofs((void *) arg, &buf, CD_FRAMESIZE_RAW);
931 }
932 }
933 else
934 { if (sendAztCmd(ACMD_PLAY_READ, &azt_Play)) return -1;
935 DTEN_LOW;
936 insb(DATA_PORT,buf,CD_FRAMESIZE);
937 memcpy_tofs((void *) arg, &buf, CD_FRAMESIZE);
938 }
939 }
940 break;
941 case CDROMSEEK:
942 st = verify_area(VERIFY_READ, (void *) arg, sizeof msf);
943 if (st) return st;
944 memcpy_fromfs(&msf, (void *) arg, sizeof msf);
945
946 azt_bin2bcd(&msf.cdmsf_min0);
947 azt_bin2bcd(&msf.cdmsf_sec0);
948 azt_bin2bcd(&msf.cdmsf_frame0);
949 azt_Play.start.min = msf.cdmsf_min0;
950 azt_Play.start.sec = msf.cdmsf_sec0;
951 azt_Play.start.frame = msf.cdmsf_frame0;
952 if (aztSeek(&azt_Play)) return -1;
953 break;
954 #endif
955 case CDROMREADMODE1:
956 return aztSetDiskType(AZT_MODE_1);
957 case CDROMREADMODE2:
958 return aztSetDiskType(AZT_MODE_2);
959 default:
960 return -EINVAL;
961 }
962 #ifdef AZT_DEBUG
963 printk("aztcd: exiting aztcd_ioctl Command:%x Time:%li\n",cmd,jiffies);
964 #endif
965 return 0;
966 }
967
968
969
970
971
972
973 static void azt_transfer(void)
974 {
975 #ifdef AZT_TEST
976 printk("aztcd: executing azt_transfer Time:%li\n",jiffies);
977 #endif
978 if (CURRENT_VALID) {
979 while (CURRENT -> nr_sectors) {
980 int bn = CURRENT -> sector / 4;
981 int i;
982 for (i = 0; i < AZT_BUF_SIZ && azt_buf_bn[i] != bn; ++i)
983 ;
984 if (i < AZT_BUF_SIZ) {
985 int offs = (i * 4 + (CURRENT -> sector & 3)) * 512;
986 int nr_sectors = 4 - (CURRENT -> sector & 3);
987 if (azt_buf_out != i) {
988 azt_buf_out = i;
989 if (azt_buf_bn[i] != bn) {
990 azt_buf_out = -1;
991 continue;
992 }
993 }
994 if (nr_sectors > CURRENT -> nr_sectors)
995 nr_sectors = CURRENT -> nr_sectors;
996 memcpy(CURRENT -> buffer, azt_buf + offs, nr_sectors * 512);
997 CURRENT -> nr_sectors -= nr_sectors;
998 CURRENT -> sector += nr_sectors;
999 CURRENT -> buffer += nr_sectors * 512;
1000 } else {
1001 azt_buf_out = -1;
1002 break;
1003 }
1004 }
1005 }
1006 }
1007
1008
1009 static void do_aztcd_request(void)
1010 {
1011 #ifdef AZT_TEST
1012 printk(" do_aztcd_request(%ld+%ld) Time:%li\n", CURRENT -> sector, CURRENT -> nr_sectors,jiffies);
1013 #endif
1014 if (DiskInfo.audio)
1015 { printk("aztcd: Error, tried to mount an Audio CD\n");
1016 end_request(0);
1017 return;
1018 }
1019 azt_transfer_is_active = 1;
1020 while (CURRENT_VALID) {
1021 if (CURRENT->bh) {
1022 if (!buffer_locked(CURRENT->bh))
1023 panic(DEVICE_NAME ": block not locked");
1024 }
1025 azt_transfer();
1026 if (CURRENT -> nr_sectors == 0) {
1027 end_request(1);
1028 } else {
1029 azt_buf_out = -1;
1030 if (azt_state == AZT_S_IDLE) {
1031 if ((!aztTocUpToDate)||aztDiskChanged) {
1032 if (aztUpdateToc() < 0) {
1033 while (CURRENT_VALID)
1034 end_request(0);
1035 break;
1036 }
1037 }
1038 azt_state = AZT_S_START;
1039 AztTries = 5;
1040 SET_TIMER(azt_poll, HZ/100);
1041 }
1042 break;
1043 }
1044 }
1045 azt_transfer_is_active = 0;
1046 #ifdef AZT_TEST2
1047 printk("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n", \
1048 azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
1049 printk(" do_aztcd_request ends Time:%li\n",jiffies);
1050 #endif
1051 }
1052
1053 static void azt_poll(void)
1054 {
1055 int st = 0;
1056 int loop_ctl = 1;
1057 int skip = 0;
1058
1059 if (azt_error) {
1060 if (aztSendCmd(ACMD_GET_ERROR)) RETURN("azt_poll 1");
1061 STEN_LOW;
1062 azt_error=inb(DATA_PORT)&0xFF;
1063 printk("aztcd: I/O error 0x%02x\n", azt_error);
1064 azt_invalidate_buffers();
1065 #ifdef WARN_IF_READ_FAILURE
1066 if (AztTries == 5)
1067 printk("aztcd: Read of Block %d Failed - Maybe Audio Disk?\n", azt_next_bn);
1068 #endif
1069 if (!AztTries--) {
1070 printk("aztcd: Read of Block %d Failed, Maybe Audio Disk? Giving up\n", azt_next_bn);
1071 if (azt_transfer_is_active) {
1072 AztTries = 0;
1073 loop_ctl = 0;
1074 }
1075 if (CURRENT_VALID)
1076 end_request(0);
1077 AztTries = 5;
1078 }
1079 azt_error = 0;
1080 azt_state = AZT_S_STOP;
1081 }
1082
1083 while (loop_ctl)
1084 {
1085 loop_ctl = 0;
1086
1087 switch (azt_state) {
1088
1089 case AZT_S_IDLE:
1090 #ifdef AZT_TEST3
1091 if (azt_state!=azt_state_old) {
1092 azt_state_old=azt_state;
1093 printk("AZT_S_IDLE\n");
1094 }
1095 #endif
1096 return;
1097
1098 case AZT_S_START:
1099 #ifdef AZT_TEST3
1100 if (azt_state!=azt_state_old) {
1101 azt_state_old=azt_state;
1102 printk("AZT_S_START\n");
1103 }
1104 #endif
1105 if(aztSendCmd(ACMD_GET_STATUS)) RETURN("azt_poll 2");
1106 azt_state = azt_mode == 1 ? AZT_S_READ : AZT_S_MODE;
1107 AztTimeout = 3000;
1108 break;
1109
1110 case AZT_S_MODE:
1111 #ifdef AZT_TEST3
1112 if (azt_state!=azt_state_old) {
1113 azt_state_old=azt_state;
1114 printk("AZT_S_MODE\n");
1115 }
1116 #endif
1117 if (!skip) {
1118 if ((st = aztStatus()) != -1) {
1119 if ((st & AST_DSK_CHG)||(st & AST_NOT_READY)) {
1120 aztDiskChanged = 1;
1121 aztTocUpToDate = 0;
1122 azt_invalidate_buffers();
1123 end_request(0);
1124 printk("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n");
1125 }
1126 } else break;
1127 }
1128 skip = 0;
1129
1130 if ((st & AST_DOOR_OPEN)||(st & AST_NOT_READY)) {
1131 aztDiskChanged = 1;
1132 aztTocUpToDate = 0;
1133 printk("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n");
1134 end_request(0);
1135 printk((st & AST_DOOR_OPEN) ? "aztcd: door open\n" : "aztcd: disk removed\n");
1136 if (azt_transfer_is_active) {
1137 azt_state = AZT_S_START;
1138 loop_ctl = 1;
1139 break;
1140 }
1141 azt_state = AZT_S_IDLE;
1142 while (CURRENT_VALID)
1143 end_request(0);
1144 return;
1145 }
1146
1147
1148
1149
1150
1151 if (aztSendCmd(ACMD_GET_STATUS)) RETURN("azt_poll 4");
1152 STEN_LOW;
1153 azt_mode = 1;
1154 azt_state = AZT_S_READ;
1155 AztTimeout = 3000;
1156
1157 break;
1158
1159
1160 case AZT_S_READ:
1161 #ifdef AZT_TEST3
1162 if (azt_state!=azt_state_old) {
1163 azt_state_old=azt_state;
1164 printk("AZT_S_READ\n");
1165 }
1166 #endif
1167 if (!skip) {
1168 if ((st = aztStatus()) != -1) {
1169 if ((st & AST_DSK_CHG)||(st & AST_NOT_READY)) {
1170 aztDiskChanged = 1;
1171 aztTocUpToDate = 0;
1172 azt_invalidate_buffers();
1173 printk("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n");
1174 end_request(0);
1175 }
1176 } else break;
1177 }
1178
1179 skip = 0;
1180 if ((st & AST_DOOR_OPEN)||(st & AST_NOT_READY)) {
1181 aztDiskChanged = 1;
1182 aztTocUpToDate = 0;
1183 printk((st & AST_DOOR_OPEN) ? "aztcd: door open\n" : "aztcd: disk removed\n");
1184 if (azt_transfer_is_active) {
1185 azt_state = AZT_S_START;
1186 loop_ctl = 1;
1187 break;
1188 }
1189 azt_state = AZT_S_IDLE;
1190 while (CURRENT_VALID)
1191 end_request(0);
1192 return;
1193 }
1194
1195 if (CURRENT_VALID) {
1196 struct azt_Play_msf msf;
1197 int i;
1198 azt_next_bn = CURRENT -> sector / 4;
1199 azt_hsg2msf(azt_next_bn, &msf.start);
1200 i = 0;
1201
1202 while (azt_msf2hsg(&msf.start)>azt_msf2hsg(&Toc[++i].trackTime)) {};
1203 if (azt_msf2hsg(&msf.start)<azt_msf2hsg(&Toc[i].trackTime)-AZT_BUF_SIZ)
1204 { azt_read_count=AZT_BUF_SIZ;
1205
1206 }
1207 else
1208 #if AZT_MULTISESSION
1209 { azt_read_count=(azt_msf2hsg(&Toc[i].trackTime)/4)*4-azt_msf2hsg(&msf.start);
1210 if (azt_read_count < 0) azt_read_count=0;
1211 if (azt_read_count > AZT_BUF_SIZ) azt_read_count=AZT_BUF_SIZ;
1212 printk("aztcd: warning - trying to read beyond end of track\n");
1213
1214 }
1215 #else
1216 { azt_read_count=AZT_BUF_SIZ;
1217 }
1218 #endif
1219 msf.end.min = 0;
1220 msf.end.sec = 0;
1221 msf.end.frame = azt_read_count ;
1222 #ifdef AZT_TEST3
1223 printk("---reading msf-address %x:%x:%x %x:%x:%x\n",msf.start.min,msf.start.sec,msf.start.frame,msf.end.min,msf.end.sec,msf.end.frame);
1224 printk("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n", \
1225 azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
1226 #endif
1227 if (azt_read_mode==AZT_MODE_2)
1228 { sendAztCmd(ACMD_PLAY_READ_RAW, &msf);
1229 }
1230 else
1231 { sendAztCmd(ACMD_PLAY_READ, &msf);
1232 }
1233 azt_state = AZT_S_DATA;
1234 AztTimeout = READ_TIMEOUT;
1235 } else {
1236 azt_state = AZT_S_STOP;
1237 loop_ctl = 1;
1238 break;
1239 }
1240
1241 break;
1242
1243
1244 case AZT_S_DATA:
1245 #ifdef AZT_TEST3
1246 if (azt_state!=azt_state_old) {
1247 azt_state_old=azt_state;
1248 printk("AZT_S_DATA\n");
1249 }
1250 #endif
1251
1252 st = inb(STATUS_PORT) & AFL_STATUSorDATA;
1253
1254 switch (st) {
1255
1256 case AFL_DATA:
1257 #ifdef AZT_TEST3
1258 if (st!=azt_st_old) {
1259 azt_st_old=st;
1260 printk("---AFL_DATA st:%x\n",st);
1261 }
1262 #endif
1263 if (!AztTries--) {
1264 printk("aztcd: Read of Block %d Failed, Maybe Audio Disk ? Giving up\n", azt_next_bn);
1265 if (azt_transfer_is_active) {
1266 AztTries = 0;
1267 break;
1268 }
1269 if (CURRENT_VALID)
1270 end_request(0);
1271 AztTries = 5;
1272 }
1273 azt_state = AZT_S_START;
1274 AztTimeout = READ_TIMEOUT;
1275 loop_ctl = 1;
1276 break;
1277
1278 case AFL_STATUSorDATA:
1279 #ifdef AZT_TEST3
1280 if (st!=azt_st_old) {
1281 azt_st_old=st;
1282 printk("---AFL_STATUSorDATA st:%x\n",st);
1283 }
1284 #endif
1285 break;
1286
1287 default:
1288 #ifdef AZT_TEST3
1289 if (st!=azt_st_old) {
1290 azt_st_old=st;
1291 printk("---default: st:%x\n",st);
1292 }
1293 #endif
1294 AztTries = 5;
1295 if (!CURRENT_VALID && azt_buf_in == azt_buf_out) {
1296 azt_state = AZT_S_STOP;
1297 loop_ctl = 1;
1298 break;
1299 }
1300 if (azt_read_count<=0)
1301 printk("aztcd: warning - try to read 0 frames\n");
1302 while (azt_read_count)
1303 { azt_buf_bn[azt_buf_in] = -1;
1304 DTEN_LOW;
1305
1306
1307
1308
1309
1310
1311
1312
1313 if (aztTimeOutCount>=AZT_TIMEOUT)
1314 { printk("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n", azt_read_count,CURRENT->nr_sectors,azt_buf_in);
1315 printk("azt_transfer_is_active:%x\n",azt_transfer_is_active);
1316 azt_read_count=0;
1317 azt_state = AZT_S_STOP;
1318 loop_ctl = 1;
1319 end_request(1);
1320 }
1321 else
1322 { if (azt_read_mode==AZT_MODE_2)
1323 { insb(DATA_PORT, azt_buf + CD_FRAMESIZE_RAW * azt_buf_in, CD_FRAMESIZE_RAW);
1324 }
1325 else
1326 { insb(DATA_PORT, azt_buf + CD_FRAMESIZE * azt_buf_in, CD_FRAMESIZE);
1327 }
1328 azt_read_count--;
1329 #ifdef AZT_TEST3
1330 printk("AZT_S_DATA; ---I've read data- read_count: %d\n",azt_read_count);
1331 printk("azt_next_bn:%d azt_buf_in:%d azt_buf_out:%d azt_buf_bn:%d\n", \
1332 azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
1333 #endif
1334 azt_buf_bn[azt_buf_in] = azt_next_bn++;
1335 if (azt_buf_out == -1)
1336 azt_buf_out = azt_buf_in;
1337 azt_buf_in = azt_buf_in + 1 == AZT_BUF_SIZ ? 0 : azt_buf_in + 1;
1338 }
1339 }
1340 if (!azt_transfer_is_active) {
1341 while (CURRENT_VALID) {
1342 azt_transfer();
1343 if (CURRENT -> nr_sectors == 0)
1344 end_request(1);
1345 else
1346 break;
1347 }
1348 }
1349
1350 if (CURRENT_VALID
1351 && (CURRENT -> sector / 4 < azt_next_bn ||
1352 CURRENT -> sector / 4 > azt_next_bn + AZT_BUF_SIZ)) {
1353 azt_state = AZT_S_STOP;
1354 loop_ctl = 1;
1355 break;
1356 }
1357 AztTimeout = READ_TIMEOUT;
1358 if (azt_read_count==0) {
1359 azt_state = AZT_S_STOP;
1360 loop_ctl = 1;
1361 break;
1362 }
1363 break;
1364 }
1365 break;
1366
1367
1368 case AZT_S_STOP:
1369 #ifdef AZT_TEST3
1370 if (azt_state!=azt_state_old) {
1371 azt_state_old=azt_state;
1372 printk("AZT_S_STOP\n");
1373 }
1374 #endif
1375 if (azt_read_count!=0) printk("aztcd: discard data=%x frames\n",azt_read_count);
1376 while (azt_read_count!=0) {
1377 int i;
1378 if ( !(inb(STATUS_PORT) & AFL_DATA) ) {
1379 if (azt_read_mode==AZT_MODE_2)
1380 for (i=0; i<CD_FRAMESIZE_RAW; i++) inb(DATA_PORT);
1381 else
1382 for (i=0; i<CD_FRAMESIZE; i++) inb(DATA_PORT);
1383 }
1384 azt_read_count--;
1385 }
1386 if (aztSendCmd(ACMD_GET_STATUS)) RETURN("azt_poll 5");
1387 azt_state = AZT_S_STOPPING;
1388 AztTimeout = 1000;
1389 break;
1390
1391 case AZT_S_STOPPING:
1392 #ifdef AZT_TEST3
1393 if (azt_state!=azt_state_old) {
1394 azt_state_old=azt_state;
1395 printk("AZT_S_STOPPING\n");
1396 }
1397 #endif
1398
1399 if ((st = aztStatus()) == -1 && AztTimeout)
1400 break;
1401
1402 if ((st != -1) && ((st & AST_DSK_CHG)||(st & AST_NOT_READY))) {
1403 aztDiskChanged = 1;
1404 aztTocUpToDate = 0;
1405 azt_invalidate_buffers();
1406 printk("aztcd: Disk Changed or Not Ready 4 - Unmount Disk!\n");
1407 end_request(0);
1408 }
1409
1410
1411 #ifdef AZT_TEST3
1412 printk("CURRENT_VALID %d azt_mode %d\n",
1413 CURRENT_VALID, azt_mode);
1414 #endif
1415
1416 if (CURRENT_VALID) {
1417 if (st != -1) {
1418 if (azt_mode == 1) {
1419 azt_state = AZT_S_READ;
1420 loop_ctl = 1;
1421 skip = 1;
1422 break;
1423 } else {
1424 azt_state = AZT_S_MODE;
1425 loop_ctl = 1;
1426 skip = 1;
1427 break;
1428 }
1429 } else {
1430 azt_state = AZT_S_START;
1431 AztTimeout = 1;
1432 }
1433 } else {
1434 azt_state = AZT_S_IDLE;
1435 return;
1436 }
1437 break;
1438
1439 default:
1440 printk("aztcd: invalid state %d\n", azt_state);
1441 return;
1442 }
1443 }
1444
1445
1446 if (!AztTimeout--)
1447 { printk("aztcd: timeout in state %d\n", azt_state);
1448 azt_state = AZT_S_STOP;
1449 if (aztSendCmd(ACMD_STOP)) RETURN("azt_poll 6");
1450 STEN_LOW_WAIT;
1451 };
1452
1453 SET_TIMER(azt_poll, HZ/100);
1454 }
1455
1456 static void azt_invalidate_buffers(void)
1457 { int i;
1458
1459 #ifdef AZT_DEBUG
1460 printk("aztcd: executing azt_invalidate_buffers\n");
1461 #endif
1462 for (i = 0; i < AZT_BUF_SIZ; ++i)
1463 azt_buf_bn[i] = -1;
1464 azt_buf_out = -1;
1465 }
1466
1467
1468
1469
1470 int aztcd_open(struct inode *ip, struct file *fp)
1471 { int st;
1472
1473 #ifdef AZT_DEBUG
1474 printk("aztcd: starting aztcd_open\n");
1475 #endif
1476 if (aztPresent == 0)
1477 return -ENXIO;
1478
1479 if (!azt_open_count && azt_state == AZT_S_IDLE)
1480 { azt_invalidate_buffers();
1481
1482 st = getAztStatus();
1483 if (st == -1) return -EIO;
1484
1485 if (st & AST_DOOR_OPEN)
1486 {
1487 printk("aztcd: Door Open?\n");
1488 aztCloseDoor();
1489 st = getAztStatus();
1490 }
1491
1492 if ((st & AST_NOT_READY) || (st & AST_DSK_CHG))
1493 { printk("aztcd: Disk Changed or No Disk in Drive?\n");
1494 aztTocUpToDate=0;
1495 }
1496 if (aztUpdateToc()) return -EIO;
1497
1498 }
1499 ++azt_open_count;
1500 MOD_INC_USE_COUNT;
1501 aztLockDoor();
1502
1503
1504 #ifdef AZT_DEBUG
1505 printk("aztcd: exiting aztcd_open\n");
1506 #endif
1507 return 0;
1508 }
1509
1510
1511
1512
1513
1514 static void aztcd_release(struct inode * inode, struct file * file)
1515 {
1516 #ifdef AZT_DEBUG
1517 printk("aztcd: executing aztcd_release\n");
1518 printk("inode: %p, inode->i_rdev: %x file: %p\n",inode,inode->i_rdev,file);
1519 #endif
1520 MOD_DEC_USE_COUNT;
1521 if (!--azt_open_count) {
1522 azt_invalidate_buffers();
1523 sync_dev(inode->i_rdev);
1524 invalidate_buffers(inode -> i_rdev);
1525 aztUnlockDoor();
1526 if (azt_auto_eject)
1527 aztSendCmd(ACMD_EJECT);
1528 CLEAR_TIMER;
1529 }
1530 return;
1531 }
1532
1533
1534 static struct file_operations azt_fops = {
1535 NULL,
1536 block_read,
1537 block_write,
1538 NULL,
1539 NULL,
1540 aztcd_ioctl,
1541 NULL,
1542 aztcd_open,
1543 aztcd_release,
1544 NULL,
1545 NULL,
1546 check_aztcd_media_change,
1547 NULL
1548 };
1549
1550
1551
1552
1553
1554 int aztcd_init(void)
1555 { long int count, max_count;
1556 unsigned char result[50];
1557 int st;
1558
1559 if (azt_port <= 0) {
1560 printk("aztcd: no Aztech CD-ROM Initialization");
1561 return -EIO;
1562 }
1563 printk("aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM CD-ROM Driver\n");
1564 printk("aztcd: (C) 1994-96 W.Zimmermann\n");
1565 printk("aztcd: DriverVersion=%s BaseAddress=0x%x For IDE/ATAPI-drives use ide-cd.c\n",AZT_VERSION,azt_port);
1566 printk("aztcd: If you have problems, read /usr/src/linux/Documentation/cdrom/aztcd\n");
1567
1568 if ((azt_port==0x1f0)||(azt_port==0x170))
1569 st = check_region(azt_port, 8);
1570 else
1571 st = check_region(azt_port, 4);
1572 if (st)
1573 { printk("aztcd: conflict, I/O port (%X) already used\n",azt_port);
1574 return -EIO;
1575 }
1576
1577 #ifdef AZT_SW32
1578 if ((0xFF00 & inw(AZT_SW32_ID_REG)) != 0x4500)
1579 { printk("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n",
1580 AZT_SW32_BASE_ADDR,AZT_SW32_INIT,AZT_SW32_CONFIG_REG,AZT_SW32_ID_REG);
1581 return -EIO;
1582 }
1583 else
1584 { printk(KERN_INFO "aztcd: Soundwave32 card detected at %x Version %x\n",
1585 AZT_SW32_BASE_ADDR, inw(AZT_SW32_ID_REG));
1586 outw(AZT_SW32_INIT,AZT_SW32_CONFIG_REG);
1587 for (count=0;count<10000;count++);
1588 }
1589 #endif
1590
1591
1592
1593 if ((azt_port==0x1f0)||(azt_port==0x170))
1594 SWITCH_IDE_SLAVE;
1595
1596 outb(POLLED,MODE_PORT);
1597 inb(CMD_PORT);
1598 inb(CMD_PORT);
1599 outb(ACMD_GET_VERSION,CMD_PORT);
1600
1601
1602 aztTimeOutCount=0;
1603 do { aztIndatum=inb(STATUS_PORT);
1604 aztTimeOutCount++;
1605 if (aztTimeOutCount>=AZT_FAST_TIMEOUT) break;
1606 } while (aztIndatum&AFL_STATUS);
1607
1608 if (inb(DATA_PORT)!=AFL_OP_OK)
1609 {
1610 #ifndef MODULE
1611 if (azt_cont!=0x79)
1612 { printk("aztcd: no AZTECH CD-ROM drive found-Try boot parameter aztcd=<BaseAddress>,0x79\n");
1613 return -EIO;
1614 }
1615 #else
1616 if (0)
1617 {
1618 }
1619 #endif
1620 else
1621 { printk("aztcd: drive reset - please wait\n");
1622 for (count=0;count<50;count++)
1623 { inb(STATUS_PORT);
1624 inb(DATA_PORT);
1625 }
1626 outb(POLLED,MODE_PORT);
1627 inb(CMD_PORT);
1628 inb(CMD_PORT);
1629 getAztStatus();
1630 outb(ACMD_SOFT_RESET,CMD_PORT);
1631 STEN_LOW;
1632 if (inb(DATA_PORT)!=AFL_OP_OK)
1633 { printk("aztcd: no AZTECH CD-ROM drive found\n");
1634 return -EIO;
1635 }
1636 for (count = 0; count < AZT_TIMEOUT; count++);
1637 { count=count*2;
1638 count=count/2;
1639 }
1640 if ((st=getAztStatus())==-1)
1641 { printk("aztcd: Drive Status Error Status=%x\n",st);
1642 return -EIO;
1643 }
1644 #ifdef AZT_DEBUG
1645 printk("aztcd: Status = %x\n",st);
1646 #endif
1647 outb(POLLED,MODE_PORT);
1648 inb(CMD_PORT);
1649 inb(CMD_PORT);
1650 outb(ACMD_GET_VERSION,CMD_PORT);
1651 STEN_LOW;
1652 OP_OK;
1653 }
1654 }
1655 azt_init_end=1;
1656 STEN_LOW;
1657 result[0]=inb(DATA_PORT);
1658 for (count=1;count<50;count++)
1659 { aztTimeOutCount=0;
1660 do { aztIndatum=inb(STATUS_PORT);
1661 aztTimeOutCount++;
1662 if (aztTimeOutCount>=AZT_FAST_TIMEOUT) break;
1663 } while (aztIndatum&AFL_STATUS);
1664 if (aztTimeOutCount>=AZT_FAST_TIMEOUT) break;
1665 result[count]=inb(DATA_PORT);
1666 }
1667 if (count>30) max_count=30;
1668 else max_count=count;
1669 printk(KERN_INFO "aztcd: FirmwareVersion=");
1670 for (count=1;count<max_count;count++) printk("%c",result[count]);
1671 printk("<<>> ");
1672
1673 if ((result[1]=='A')&&(result[2]=='Z')&&(result[3]=='T'))
1674 { printk("AZTECH drive detected\n");
1675 }
1676 else if ((result[2]=='C')&&(result[3]=='D')&&(result[4]=='D'))
1677 { printk("ORCHID or WEARNES drive detected\n");
1678 }
1679 else if ((result[1]==0x03)&&(result[2]=='5'))
1680 { printk("TXC or CyCDROM drive detected\n");
1681 }
1682 else
1683 { printk("\nunknown drive or firmware version detected\n");
1684 printk("aztcd may not run stable, if you want to try anyhow,\n");
1685 printk("boot with: aztcd=<BaseAddress>,0x79\n");
1686 if ((azt_cont!=0x79))
1687 { printk("aztcd: FirmwareVersion=");
1688 for (count=1;count<5;count++) printk("%c",result[count]);
1689 printk("<<>> ");
1690 printk("Aborted\n");
1691 return -EIO;
1692 }
1693 }
1694 if (register_blkdev(MAJOR_NR, "aztcd", &azt_fops) != 0)
1695 {
1696 printk("aztcd: Unable to get major %d for Aztech CD-ROM\n",
1697 MAJOR_NR);
1698 return -EIO;
1699 }
1700 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
1701 read_ahead[MAJOR_NR] = 4;
1702
1703 if ((azt_port==0x1f0)||(azt_port==0x170))
1704 request_region(azt_port, 8, "aztcd");
1705 else
1706 request_region(azt_port, 4, "aztcd");
1707
1708 azt_invalidate_buffers();
1709 aztPresent = 1;
1710 aztCloseDoor();
1711
1712 return (0);
1713 }
1714
1715
1716 static void azt_hsg2msf(long hsg, struct msf *msf)
1717 { hsg += 150;
1718 msf -> min = hsg / 4500;
1719 hsg %= 4500;
1720 msf -> sec = hsg / 75;
1721 msf -> frame = hsg % 75;
1722 #ifdef AZT_DEBUG
1723 if (msf->min >=70) printk("aztcd: Error hsg2msf address Minutes\n");
1724 if (msf->sec >=60) printk("aztcd: Error hsg2msf address Seconds\n");
1725 if (msf->frame>=75) printk("aztcd: Error hsg2msf address Frames\n");
1726 #endif
1727 azt_bin2bcd(&msf -> min);
1728 azt_bin2bcd(&msf -> sec);
1729 azt_bin2bcd(&msf -> frame);
1730 }
1731
1732 static long azt_msf2hsg(struct msf *mp)
1733 { return azt_bcd2bin(mp -> frame) + azt_bcd2bin(mp -> sec) * 75
1734 + azt_bcd2bin(mp -> min) * 4500 - CD_BLOCK_OFFSET;
1735 }
1736
1737 static void azt_bin2bcd(unsigned char *p)
1738 { int u, t;
1739
1740 u = *p % 10;
1741 t = *p / 10;
1742 *p = u | (t << 4);
1743 }
1744
1745 static int azt_bcd2bin(unsigned char bcd)
1746 { return (bcd >> 4) * 10 + (bcd & 0xF);
1747 }
1748
1749
1750
1751
1752
1753
1754 static int aztGetValue(unsigned char *result)
1755 { int s;
1756
1757 STEN_LOW;
1758 if (aztTimeOutCount>=AZT_TIMEOUT)
1759 { printk("aztcd: aztGetValue timeout\n");
1760 return -1;
1761 }
1762 s = inb(DATA_PORT) & 0xFF;
1763 *result = (unsigned char) s;
1764 return 0;
1765 }
1766
1767
1768
1769
1770
1771
1772 int aztGetQChannelInfo(struct azt_Toc *qp)
1773 { unsigned char notUsed;
1774 int st;
1775
1776 #ifdef AZT_DEBUG
1777 printk("aztcd: starting aztGetQChannelInfo Time:%li\n",jiffies);
1778 #endif
1779 if ((st=getAztStatus())==-1) RETURNM("aztGetQChannelInfo 1",-1);
1780 if (aztSendCmd(ACMD_GET_Q_CHANNEL)) RETURNM("aztGetQChannelInfo 2",-1);
1781
1782 if (aztGetValue(¬Used)) RETURNM("aztGetQChannelInfo 3",-1);
1783 if ((st&AST_MODE_BITS)==AST_INITIAL)
1784 { qp->ctrl_addr=0;
1785 qp->track=0;
1786 qp->pointIndex=0;
1787 qp->trackTime.min=0;
1788 qp->trackTime.sec=0;
1789 qp->trackTime.frame=0;
1790 qp->diskTime.min=0;
1791 qp->diskTime.sec=0;
1792 qp->diskTime.frame=0;
1793 return 0;
1794 }
1795 else
1796 { if (aztGetValue(&qp -> ctrl_addr) < 0) RETURNM("aztGetQChannelInfo 4",-1);
1797 if (aztGetValue(&qp -> track) < 0) RETURNM("aztGetQChannelInfo 4",-1);
1798 if (aztGetValue(&qp -> pointIndex) < 0) RETURNM("aztGetQChannelInfo 4",-1);
1799 if (aztGetValue(&qp -> trackTime.min) < 0) RETURNM("aztGetQChannelInfo 4",-1);
1800 if (aztGetValue(&qp -> trackTime.sec) < 0) RETURNM("aztGetQChannelInfo 4",-1);
1801 if (aztGetValue(&qp -> trackTime.frame) < 0) RETURNM("aztGetQChannelInfo 4",-1);
1802 if (aztGetValue(¬Used) < 0) RETURNM("aztGetQChannelInfo 4",-1);
1803 if (aztGetValue(&qp -> diskTime.min) < 0) RETURNM("aztGetQChannelInfo 4",-1);
1804 if (aztGetValue(&qp -> diskTime.sec) < 0) RETURNM("aztGetQChannelInfo 4",-1);
1805 if (aztGetValue(&qp -> diskTime.frame) < 0) RETURNM("aztGetQChannelInfo 4",-1);
1806 }
1807 #ifdef AZT_DEBUG
1808 printk("aztcd: exiting aztGetQChannelInfo Time:%li\n",jiffies);
1809 #endif
1810 return 0;
1811 }
1812
1813
1814
1815
1816 static int aztUpdateToc()
1817 { int st;
1818
1819 #ifdef AZT_DEBUG
1820 printk("aztcd: starting aztUpdateToc Time:%li\n",jiffies);
1821 #endif
1822 if (aztTocUpToDate)
1823 return 0;
1824
1825 if (aztGetDiskInfo() < 0)
1826 return -EIO;
1827
1828 if (aztGetToc(0) < 0)
1829 return -EIO;
1830
1831
1832
1833
1834
1835 if (!(Toc[DiskInfo.first].ctrl_addr & 0x40))
1836 DiskInfo.audio=1;
1837 else
1838 DiskInfo.audio=0;
1839
1840
1841 if (! DiskInfo.audio)
1842 { azt_Play.start.min = 0;
1843 azt_Play.start.sec = 2;
1844 azt_Play.start.frame = 0;
1845 azt_Play.end.min = 0;
1846 azt_Play.end.sec = 0;
1847 azt_Play.end.frame = 1;
1848 if (sendAztCmd(ACMD_PLAY_READ, &azt_Play)) return -1;
1849 DTEN_LOW;
1850 for (st=0;st<CD_FRAMESIZE;st++) inb(DATA_PORT);
1851 }
1852 DiskInfo.xa = getAztStatus() & AST_MODE;
1853 if (DiskInfo.xa)
1854 { printk("aztcd: XA support experimental - mail results to zimmerma@rz.fht-esslingen.de\n");
1855 }
1856
1857
1858
1859
1860
1861 DiskInfo.multi=0;
1862 #if AZT_MULTISESSION
1863 if (DiskInfo.xa)
1864 { aztGetMultiDiskInfo();
1865 }
1866 #endif
1867 if (DiskInfo.multi)
1868 { DiskInfo.lastSession.min = Toc[DiskInfo.next].diskTime.min;
1869 DiskInfo.lastSession.sec = Toc[DiskInfo.next].diskTime.sec;
1870 DiskInfo.lastSession.frame= Toc[DiskInfo.next].diskTime.frame;
1871 printk("aztcd: Multisession support experimental\n");
1872 }
1873 else
1874 { DiskInfo.lastSession.min = Toc[DiskInfo.first].diskTime.min;
1875 DiskInfo.lastSession.sec = Toc[DiskInfo.first].diskTime.sec;
1876 DiskInfo.lastSession.frame= Toc[DiskInfo.first].diskTime.frame;
1877 }
1878
1879 aztTocUpToDate = 1;
1880 #ifdef AZT_DEBUG
1881 printk("aztcd: exiting aztUpdateToc Time:%li\n",jiffies);
1882 #endif
1883 return 0;
1884 }
1885
1886
1887
1888
1889
1890 static int aztGetDiskInfo()
1891 { int limit;
1892 unsigned char test;
1893 struct azt_Toc qInfo;
1894
1895 #ifdef AZT_DEBUG
1896 printk("aztcd: starting aztGetDiskInfo Time:%li\n",jiffies);
1897 #endif
1898 if (aztSendCmd(ACMD_SEEK_TO_LEADIN)) RETURNM("aztGetDiskInfo 1",-1);
1899 STEN_LOW_WAIT;
1900 test=0;
1901 for (limit=300;limit>0;limit--)
1902 { if (aztGetQChannelInfo(&qInfo)<0) RETURNM("aztGetDiskInfo 2",-1);
1903 if (qInfo.pointIndex==0xA0)
1904 { DiskInfo.first = qInfo.diskTime.min;
1905 DiskInfo.first = azt_bcd2bin(DiskInfo.first);
1906 test=test|0x01;
1907 }
1908 if (qInfo.pointIndex==0xA1)
1909 { DiskInfo.last = qInfo.diskTime.min;
1910 DiskInfo.last = azt_bcd2bin(DiskInfo.last);
1911 test=test|0x02;
1912 }
1913 if (qInfo.pointIndex==0xA2)
1914 { DiskInfo.diskLength.min=qInfo.diskTime.min;
1915 DiskInfo.diskLength.sec=qInfo.diskTime.sec;
1916 DiskInfo.diskLength.frame=qInfo.diskTime.frame;
1917 test=test|0x04;
1918 }
1919 if ((qInfo.pointIndex==DiskInfo.first)&&(test&0x01))
1920 { DiskInfo.firstTrack.min=qInfo.diskTime.min;
1921 DiskInfo.firstTrack.sec=qInfo.diskTime.sec;
1922 DiskInfo.firstTrack.frame=qInfo.diskTime.frame;
1923 test=test|0x08;
1924 }
1925 if (test==0x0F) break;
1926 }
1927 #ifdef AZT_DEBUG
1928 printk ("aztcd: exiting aztGetDiskInfo Time:%li\n",jiffies);
1929 printk("Disk Info: first %d last %d length %02X:%02X.%02X dez first %02X:%02X.%02X dez\n",
1930 DiskInfo.first,
1931 DiskInfo.last,
1932 DiskInfo.diskLength.min,
1933 DiskInfo.diskLength.sec,
1934 DiskInfo.diskLength.frame,
1935 DiskInfo.firstTrack.min,
1936 DiskInfo.firstTrack.sec,
1937 DiskInfo.firstTrack.frame);
1938 #endif
1939 if (test!=0x0F) return -1;
1940 return 0;
1941 }
1942
1943 #if AZT_MULTISESSION
1944
1945
1946
1947 static int aztGetMultiDiskInfo(void)
1948 { int limit, k=5;
1949 unsigned char test;
1950 struct azt_Toc qInfo;
1951
1952 #ifdef AZT_DEBUG
1953 printk("aztcd: starting aztGetMultiDiskInfo\n");
1954 #endif
1955
1956 do { azt_Play.start.min = Toc[DiskInfo.last+1].diskTime.min;
1957 azt_Play.start.sec = Toc[DiskInfo.last+1].diskTime.sec;
1958 azt_Play.start.frame = Toc[DiskInfo.last+1].diskTime.frame;
1959 test=0;
1960
1961 for (limit=30;limit>0;limit--)
1962 { if (aztSeek(&azt_Play)) RETURNM("aztGetMultiDiskInfo 1",-1);
1963 if (aztGetQChannelInfo(&qInfo)<0) RETURNM("aztGetMultiDiskInfo 2",-1);
1964 if ((qInfo.track==0)&&(qInfo.pointIndex)) break;
1965 if ((azt_Play.start.sec+=10) > 59)
1966 { azt_Play.start.sec=0;
1967 azt_Play.start.min++;
1968 }
1969 }
1970 if (!limit) break;
1971
1972 #ifdef AZT_DEBUG_MULTISESSION
1973 printk("leadin found track %d pointIndex %x limit %d\n",qInfo.track,qInfo.pointIndex,limit);
1974 #endif
1975 for (limit=300;limit>0;limit--)
1976 { if (++azt_Play.start.frame>74)
1977 { azt_Play.start.frame=0;
1978 if (azt_Play.start.sec > 59)
1979 { azt_Play.start.sec=0;
1980 azt_Play.start.min++;
1981 }
1982 }
1983 if (aztSeek(&azt_Play)) RETURNM("aztGetMultiDiskInfo 3",-1);
1984 if (aztGetQChannelInfo(&qInfo)<0) RETURNM("aztGetMultiDiskInfo 4",-1);
1985 if (qInfo.pointIndex==0xA0)
1986 { DiskInfo.next = qInfo.diskTime.min;
1987 DiskInfo.next = azt_bcd2bin(DiskInfo.next);
1988 test=test|0x01;
1989 }
1990 if (qInfo.pointIndex==0xA1)
1991 { DiskInfo.last = qInfo.diskTime.min;
1992 DiskInfo.last = azt_bcd2bin(DiskInfo.last);
1993 test=test|0x02;
1994 }
1995 if (qInfo.pointIndex==0xA2)
1996 { DiskInfo.diskLength.min =qInfo.diskTime.min;
1997 DiskInfo.diskLength.sec =qInfo.diskTime.sec;
1998 DiskInfo.diskLength.frame=qInfo.diskTime.frame;
1999 test=test|0x04;
2000 }
2001 if ((qInfo.pointIndex==DiskInfo.next)&&(test&0x01))
2002 { DiskInfo.nextSession.min=qInfo.diskTime.min;
2003 DiskInfo.nextSession.sec=qInfo.diskTime.sec;
2004 DiskInfo.nextSession.frame=qInfo.diskTime.frame;
2005 test=test|0x08;
2006 }
2007 if (test==0x0F) break;
2008 }
2009 #ifdef AZT_DEBUG_MULTISESSION
2010 printk ("MultiDisk Info: first %d next %d last %d length %02x:%02x.%02x dez first %02x:%02x.%02x dez next %02x:%02x.%02x dez\n",
2011 DiskInfo.first,
2012 DiskInfo.next,
2013 DiskInfo.last,
2014 DiskInfo.diskLength.min,
2015 DiskInfo.diskLength.sec,
2016 DiskInfo.diskLength.frame,
2017 DiskInfo.firstTrack.min,
2018 DiskInfo.firstTrack.sec,
2019 DiskInfo.firstTrack.frame,
2020 DiskInfo.nextSession.min,
2021 DiskInfo.nextSession.sec,
2022 DiskInfo.nextSession.frame);
2023 #endif
2024 if (test!=0x0F)
2025 break;
2026 else
2027 DiskInfo.multi=1;
2028 aztGetToc(1);
2029 } while(--k);
2030
2031 #ifdef AZT_DEBUG
2032 printk ("aztcd: exiting aztGetMultiDiskInfo Time:%li\n",jiffies);
2033 #endif
2034 return 0;
2035 }
2036 #endif
2037
2038
2039
2040
2041 static int aztGetToc(int multi)
2042 { int i, px;
2043 int limit;
2044 struct azt_Toc qInfo;
2045
2046 #ifdef AZT_DEBUG
2047 printk("aztcd: starting aztGetToc Time:%li\n",jiffies);
2048 #endif
2049 if (!multi)
2050 { for (i = 0; i < MAX_TRACKS; i++)
2051 Toc[i].pointIndex = 0;
2052 i = DiskInfo.last + 3;
2053 }
2054 else
2055 { for (i = DiskInfo.next; i < MAX_TRACKS; i++)
2056 Toc[i].pointIndex = 0;
2057 i = DiskInfo.last + 4 - DiskInfo.next;
2058 }
2059
2060
2061
2062
2063
2064
2065 if (!multi)
2066 { azt_mode = 0x05;
2067 if (aztSendCmd(ACMD_SEEK_TO_LEADIN)) RETURNM("aztGetToc 2",-1);
2068 STEN_LOW_WAIT;
2069 }
2070 for (limit = 300; limit > 0; limit--)
2071 { if (multi)
2072 { if (++azt_Play.start.sec > 59)
2073 { azt_Play.start.sec=0;
2074 azt_Play.start.min++;
2075 }
2076 if (aztSeek(&azt_Play)) RETURNM("aztGetToc 3",-1);
2077 }
2078 if (aztGetQChannelInfo(&qInfo) < 0)
2079 break;
2080
2081 px = azt_bcd2bin(qInfo.pointIndex);
2082
2083 if (px > 0 && px < MAX_TRACKS && qInfo.track == 0)
2084 if (Toc[px].pointIndex == 0)
2085 { Toc[px] = qInfo;
2086 i--;
2087 }
2088
2089 if (i <= 0)
2090 break;
2091 }
2092
2093 Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength;
2094 Toc[DiskInfo.last].trackTime = DiskInfo.diskLength;
2095
2096 #ifdef AZT_DEBUG_MULTISESSION
2097 printk("aztcd: exiting aztGetToc\n");
2098 for (i = 1; i <= DiskInfo.last+1; i++)
2099 printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n",
2100 i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
2101 Toc[i].trackTime.min, Toc[i].trackTime.sec, Toc[i].trackTime.frame,
2102 Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame);
2103 for (i = 100; i < 103; i++)
2104 printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n",
2105 i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
2106 Toc[i].trackTime.min, Toc[i].trackTime.sec, Toc[i].trackTime.frame,
2107 Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame);
2108 #endif
2109
2110 return limit > 0 ? 0 : -1;
2111 }
2112
2113 #ifdef MODULE
2114
2115 int init_module(void)
2116 {
2117 return aztcd_init();
2118 }
2119
2120 void cleanup_module(void)
2121 {
2122 if ((unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL))
2123 { printk("What's that: can't unregister aztcd\n");
2124 return;
2125 }
2126 if ((azt_port==0x1f0)||(azt_port==0x170))
2127 { SWITCH_IDE_MASTER;
2128 release_region(azt_port,8);
2129 }
2130 else
2131 release_region(azt_port,4);
2132 printk(KERN_INFO "aztcd module released.\n");
2133 }
2134 #endif MODULE