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