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