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