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