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