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