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