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