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