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