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