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