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