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