1 /** @(#)drv_jvc.c 1.95 10/12/19 Copyright 1997-2010 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)drv_jvc.c 1.95 10/12/19 Copyright 1997-2010 J. Schilling";
6 #endif
7 /*
8 * CDR device implementation for
9 * JVC/TEAC
10 *
11 * Copyright (c) 1997-2010 J. Schilling
12 */
13 /*
14 * The contents of this file are subject to the terms of the
15 * Common Development and Distribution License, Version 1.0 only
16 * (the "License"). You may not use this file except in compliance
17 * with the License.
18 *
19 * See the file CDDL.Schily.txt in this distribution for details.
20 * A copy of the CDDL is also available via the Internet at
21 * http://www.opensource.org/licenses/cddl1.txt
22 *
23 * When distributing Covered Code, include this CDDL HEADER in each
24 * file and include the License file CDDL.Schily.txt from this distribution.
25 */
26 /*#define XXDEBUG*/
27 /*#define XXBUFFER*/
28
29 #include <schily/mconfig.h>
30
31 #include <schily/stdio.h>
32 #include <schily/standard.h>
33 #include <schily/fcntl.h>
34 #include <schily/errno.h>
35 #include <schily/string.h>
36 #include <schily/unistd.h>
37 #ifdef XXDEBUG
38 #include <schily/stdlib.h>
39 #endif
40
41 #include <schily/utypes.h>
42 #include <schily/btorder.h>
43 #include <schily/intcvt.h>
44 #include <schily/schily.h>
45 #include <schily/nlsdefs.h>
46
47 #include <scg/scgcmd.h>
48 #include <scg/scsidefs.h>
49 #include <scg/scsireg.h>
50 #include <scg/scsitransp.h>
51
52 #include "cdrecord.h"
53
54 /* just a hack */
55 long lba_addr;
56 BOOL last_done;
57
58 /*
59 * macros for building MSF values from LBA
60 */
61 #define LBA_MIN(x) ((x)/(60*75))
62 #define LBA_SEC(x) (((x)%(60*75))/75)
63 #define LBA_FRM(x) ((x)%75)
64 #define MSF_CONV(a) ((((a)%(unsigned)100)/10)*16 + ((a)%(unsigned)10))
65
66 extern int lverbose;
67
68 #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */
69 struct teac_mode_page_21 { /* teac dummy selection */
70 MP_P_CODE; /* parsave & pagecode */
71 Uchar p_len; /* 0x01 = 1 Byte */
72 Ucbit dummy : 2;
73 Ucbit res : 6;
74 };
75 #else
76 struct teac_mode_page_21 { /* teac dummy selection */
77 MP_P_CODE; /* parsave & pagecode */
78 Uchar p_len; /* 0x01 = 1 Byte */
79 Ucbit res : 6;
80 Ucbit dummy : 2;
81 };
82 #endif
83
84 struct teac_mode_page_31 { /* teac speed selection */
85 MP_P_CODE; /* parsave & pagecode */
86 Uchar p_len; /* 0x02 = 2 Byte */
87 Uchar speed;
88 Uchar res;
89 };
90
91 struct cdd_52x_mode_data {
92 struct scsi_mode_header header;
93 union cdd_pagex {
94 struct teac_mode_page_21 teac_page21;
95 struct teac_mode_page_31 teac_page31;
96 } pagex;
97 };
98
99 #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */
100
101 struct pgm_subcode { /* subcode for progam area */
102 Uchar subcode;
103 Ucbit addr : 4;
104 Ucbit control : 4;
105 Uchar track;
106 Uchar index;
107 };
108
109 #else
110
111 struct pgm_subcode { /* subcode for progam area */
112 Uchar subcode;
113 Ucbit control : 4;
114 Ucbit addr : 4;
115 Uchar track;
116 Uchar index;
117 };
118
119 #endif
120
121 #define set_pgm_subcode(sp, t, c, a, tr, idx) (\
122 (sp)->subcode = (t), \
123 (sp)->control = (c), \
124 (sp)->addr = (a), \
125 (sp)->track = MSF_CONV(tr), \
126 (sp)->index = (idx))
127
128 #define SC_P 1 /* Subcode defines pre-gap (Pause) */
129 #define SC_TR 0 /* Subcode defines track data */
130
131 #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */
132
133 typedef struct lin_subcode { /* subcode for lead in area */
134 Ucbit addr : 4;
135 Ucbit control : 4;
136 Uchar track;
137 Uchar msf[3];
138 } lsc_t;
139
140 #else
141
142 typedef struct lin_subcode { /* subcode for lead in area */
143 Ucbit control : 4;
144 Ucbit addr : 4;
145 Uchar track;
146 Uchar msf[3];
147 } lsc_t;
148
149 #endif
150
151 #define set_toc_subcode(sp, c, a, tr, bno) (\
152 ((lsc_t *)sp)->control = (c), \
153 ((lsc_t *)sp)->addr = (a), \
154 ((lsc_t *)sp)->track = MSF_CONV(tr), \
155 ((lsc_t *)sp)->msf[0] = MSF_CONV(LBA_MIN(bno)), \
156 ((lsc_t *)sp)->msf[1] = MSF_CONV(LBA_SEC(bno)), \
157 ((lsc_t *)sp)->msf[2] = MSF_CONV(LBA_FRM(bno)), \
158 &((lsc_t *)sp)->msf[3])
159
160 #define set_lin_subcode(sp, c, a, pt, min, sec, frm) (\
161 ((lsc_t *)sp)->control = (c), \
162 ((lsc_t *)sp)->addr = (a), \
163 ((lsc_t *)sp)->track = (pt), \
164 ((lsc_t *)sp)->msf[0] = (min), \
165 ((lsc_t *)sp)->msf[1] = (sec), \
166 ((lsc_t *)sp)->msf[2] = (frm), \
167 &((lsc_t *)sp)->msf[3])
168
169 #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */
170
171 struct upc_subcode { /* subcode for upc/bar code */
172 Uchar res;
173 Ucbit addr : 4;
174 Ucbit control : 4;
175 Uchar upc[13];
176 };
177
178 #else
179
180 struct upc_subcode { /* subcode for upc/bar code */
181 Uchar res;
182 Ucbit control : 4;
183 Ucbit addr : 4;
184 Uchar upc[13];
185 };
186
187 #endif
188
189 #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */
190
191 struct isrc_subcode { /* subcode for ISRC code */
192 Uchar res;
193 Ucbit addr : 4;
194 Ucbit control : 4;
195 Uchar isrc[12];
196 Uchar res14;
197 };
198
199 #else
200
201 struct isrc_subcode { /* subcode for ISRC code */
202 Uchar res;
203 Ucbit control : 4;
204 Ucbit addr : 4;
205 Uchar isrc[12];
206 Uchar res14;
207 };
208
209 #endif
210
211
212 LOCAL int teac_attach __PR((SCSI *scgp, cdr_t *dp));
213 LOCAL int teac_init __PR((SCSI *scgp, cdr_t *dp));
214 LOCAL int teac_getdisktype __PR((SCSI *scgp, cdr_t *dp));
215 LOCAL int speed_select_teac __PR((SCSI *scgp, cdr_t *dp, int *speedp));
216 LOCAL int select_secsize_teac __PR((SCSI *scgp, track_t *trackp));
217 LOCAL int next_wr_addr_jvc __PR((SCSI *scgp, track_t *, long *ap));
218 LOCAL int write_teac_xg1 __PR((SCSI *scgp, caddr_t, long, long, int, BOOL));
219 LOCAL int cdr_write_teac __PR((SCSI *scgp, caddr_t bp, long sectaddr, long size, int blocks, BOOL islast));
220 LOCAL int open_track_jvc __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
221 LOCAL int teac_fixation __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
222 LOCAL int close_track_teac __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
223 LOCAL int teac_open_session __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
224 LOCAL int initsub_teac __PR((SCSI *scgp, int toctype, int multi));
225 LOCAL int teac_doopc __PR((SCSI *scgp));
226 LOCAL int teac_opc __PR((SCSI *scgp, caddr_t, int cnt, int doopc));
227 LOCAL int opt_power_judge __PR((SCSI *scgp, int judge));
228 LOCAL int clear_subcode __PR((SCSI *scgp));
229 LOCAL int set_limits __PR((SCSI *scgp, long lba, long length));
230 LOCAL int set_subcode __PR((SCSI *scgp, Uchar *subcode_data, int length));
231 #ifdef XDI
232 LOCAL int read_disk_info_teac __PR((SCSI *scgp, Uchar *data, int length, int type));
233 #endif
234 LOCAL int teac_freeze __PR((SCSI *scgp, int bp_flag));
235 LOCAL int teac_wr_pma __PR((SCSI *scgp));
236 LOCAL int teac_rd_pma __PR((SCSI *scgp));
237 LOCAL int next_wr_addr_teac __PR((SCSI *scgp, long start_lba, long last_lba));
238 LOCAL int blank_jvc __PR((SCSI *scgp, cdr_t *dp, long addr, int blanktype));
239 LOCAL int buf_cap_teac __PR((SCSI *scgp, long *sp, long *fp));
240 LOCAL long read_peak_buffer_cap_teac __PR((SCSI *scgp));
241 #ifdef XXBUFFER
242 LOCAL int buffer_inquiry_teac __PR((SCSI *scgp, int fmt));
243 LOCAL void check_buffer_teac __PR((SCSI *scgp));
244 #endif
245 #ifdef XXDEBUG
246 LOCAL void xxtest_teac __PR((SCSI *scgp));
247 #endif
248
249
250 cdr_t cdr_teac_cdr50 = {
251 0, 0, 0,
252 /* CDR_TAO|CDR_SAO|CDR_SWABAUDIO|CDR_NO_LOLIMIT,*/
253 CDR_TAO|CDR_SWABAUDIO|CDR_NO_LOLIMIT,
254 0,
255 CDR_CDRW_ALL,
256 WM_TAO,
257 2, 4,
258 "teac_cdr50",
259 "driver for Teac CD-R50S, Teac CD-R55S, JVC XR-W2010, Pinnacle RCD-5020",
260 0,
261 (dstat_t *)0,
262 drive_identify,
263 teac_attach,
264 teac_init,
265 teac_getdisktype,
266 no_diskstatus,
267 scsi_load,
268 scsi_unload,
269 buf_cap_teac,
270 cmd_dummy, /* recovery_needed */
271 (int(*)__PR((SCSI *, cdr_t *, int)))cmd_dummy, /* recover */
272 speed_select_teac,
273 select_secsize,
274 next_wr_addr_jvc,
275 (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */
276 cdr_write_teac,
277 (int(*)__PR((track_t *, void *, BOOL)))cmd_dummy, /* gen_cue */
278 no_sendcue,
279 (int(*)__PR((SCSI *, cdr_t *, track_t *)))cmd_dummy, /* leadin */
280 open_track_jvc,
281 close_track_teac,
282 teac_open_session,
283 cmd_dummy,
284 cmd_dummy, /* abort */
285 read_session_offset_philips,
286 teac_fixation,
287 cmd_dummy, /* stats */
288 /* blank_dummy,*/
289 blank_jvc,
290 format_dummy,
291 teac_opc,
292 cmd_dummy, /* opt1 */
293 cmd_dummy, /* opt2 */
294 };
295
296 LOCAL int
teac_init(scgp,dp)297 teac_init(scgp, dp)
298 SCSI *scgp;
299 cdr_t *dp;
300 {
301 return (speed_select_teac(scgp, dp, NULL));
302 }
303
304 LOCAL int
teac_getdisktype(scgp,dp)305 teac_getdisktype(scgp, dp)
306 SCSI *scgp;
307 cdr_t *dp;
308 {
309 dstat_t *dsp = dp->cdr_dstat;
310 struct scsi_mode_data md;
311 int count = sizeof (struct scsi_mode_header) +
312 sizeof (struct scsi_mode_blockdesc);
313 int len;
314 int page = 0;
315 long l;
316
317 fillbytes((caddr_t)&md, sizeof (md), '\0');
318
319 (void) test_unit_ready(scgp);
320 if (mode_sense(scgp, (Uchar *)&md, count, page, 0) < 0) { /* Page n current */
321 return (-1);
322 } else {
323 len = ((struct scsi_mode_header *)&md)->sense_data_len + 1;
324 }
325 if (((struct scsi_mode_header *)&md)->blockdesc_len < 8)
326 return (-1);
327
328 l = a_to_u_3_byte(md.blockdesc.nlblock);
329 dsp->ds_maxblocks = l;
330 return (drive_getdisktype(scgp, dp));
331 }
332
333 LOCAL int
speed_select_teac(scgp,dp,speedp)334 speed_select_teac(scgp, dp, speedp)
335 SCSI *scgp;
336 cdr_t *dp;
337 int *speedp;
338 {
339 struct cdd_52x_mode_data md;
340 int count;
341 int status;
342 int speed = 1;
343 BOOL dummy = (dp->cdr_cmdflags & F_DUMMY) != 0;
344
345 if (speedp)
346 speed = *speedp;
347
348 fillbytes((caddr_t)&md, sizeof (md), '\0');
349
350 count = sizeof (struct scsi_mode_header) +
351 sizeof (struct teac_mode_page_21);
352
353 md.pagex.teac_page21.p_code = 0x21;
354 md.pagex.teac_page21.p_len = 0x01;
355 md.pagex.teac_page21.dummy = dummy?3:0;
356
357 status = mode_select(scgp, (Uchar *)&md, count, 0, scgp->inq->data_format >= 2);
358 if (status < 0)
359 return (status);
360
361 if (speedp == 0)
362 return (0);
363
364 fillbytes((caddr_t)&md, sizeof (md), '\0');
365
366 count = sizeof (struct scsi_mode_header) +
367 sizeof (struct teac_mode_page_31);
368
369 speed >>= 1;
370 md.pagex.teac_page31.p_code = 0x31;
371 md.pagex.teac_page31.p_len = 0x02;
372 md.pagex.teac_page31.speed = speed;
373
374 return (mode_select(scgp, (Uchar *)&md, count, 0, scgp->inq->data_format >= 2));
375 }
376
377 LOCAL int
select_secsize_teac(scgp,trackp)378 select_secsize_teac(scgp, trackp)
379 SCSI *scgp;
380 track_t *trackp;
381 {
382 struct scsi_mode_data md;
383 int count = sizeof (struct scsi_mode_header) +
384 sizeof (struct scsi_mode_blockdesc);
385 int len;
386 int page = 0;
387
388 fillbytes((caddr_t)&md, sizeof (md), '\0');
389
390 (void) test_unit_ready(scgp);
391 if (mode_sense(scgp, (Uchar *)&md, count, page, 0) < 0) { /* Page n current */
392 return (-1);
393 } else {
394 len = ((struct scsi_mode_header *)&md)->sense_data_len + 1;
395 }
396 if (((struct scsi_mode_header *)&md)->blockdesc_len < 8)
397 return (-1);
398
399 md.header.sense_data_len = 0;
400 md.header.blockdesc_len = 8;
401
402 md.blockdesc.density = 1;
403 if (trackp->secsize == 2352)
404 md.blockdesc.density = 4;
405 i_to_3_byte(md.blockdesc.lblen, trackp->secsize);
406
407 return (mode_select(scgp, (Uchar *)&md, count, 0, scgp->inq->data_format >= 2));
408 }
409
410 LOCAL int
next_wr_addr_jvc(scgp,trackp,ap)411 next_wr_addr_jvc(scgp, trackp, ap)
412 SCSI *scgp;
413 track_t *trackp;
414 long *ap;
415 {
416 if (trackp != 0 && trackp->track > 0) {
417 *ap = lba_addr;
418 } else {
419 long nwa;
420
421 if (read_B0(scgp, TRUE, &nwa, NULL) < 0)
422 return (-1);
423
424 *ap = nwa + 150;
425 }
426 return (0);
427 }
428
429 LOCAL int
write_teac_xg1(scgp,bp,sectaddr,size,blocks,extwr)430 write_teac_xg1(scgp, bp, sectaddr, size, blocks, extwr)
431 SCSI *scgp;
432 caddr_t bp; /* address of buffer */
433 long sectaddr; /* disk address (sector) to put */
434 long size; /* number of bytes to transfer */
435 int blocks; /* sector count */
436 BOOL extwr; /* is an extended write */
437 {
438 register struct scg_cmd *scmd = scgp->scmd;
439
440 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
441 scmd->addr = bp;
442 scmd->size = size;
443 scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY;
444 /* scmd->flags = SCG_DISRE_ENA;*/
445 scmd->cdb_len = SC_G1_CDBLEN;
446 scmd->sense_len = CCS_SENSE_LEN;
447 scmd->cdb.g1_cdb.cmd = SC_EWRITE;
448 scmd->cdb.g1_cdb.lun = scg_lun(scgp);
449 g1_cdbaddr(&scmd->cdb.g1_cdb, sectaddr);
450 g1_cdblen(&scmd->cdb.g1_cdb, blocks);
451 scmd->cdb.g1_cdb.vu_97 = extwr;
452
453 scgp->cmdname = "write_teac_g1";
454
455 if (scg_cmd(scgp) < 0)
456 return (-1);
457 return (size - scg_getresid(scgp));
458 }
459
460 LOCAL int
cdr_write_teac(scgp,bp,sectaddr,size,blocks,islast)461 cdr_write_teac(scgp, bp, sectaddr, size, blocks, islast)
462 SCSI *scgp;
463 caddr_t bp; /* address of buffer */
464 long sectaddr; /* disk address (sector) to put */
465 long size; /* number of bytes to transfer */
466 int blocks; /* sector count */
467 BOOL islast; /* last write for track */
468 {
469 int ret;
470
471 if (islast)
472 last_done = TRUE;
473
474 ret = write_teac_xg1(scgp, bp, sectaddr, size, blocks, !islast);
475 if (ret < 0)
476 return (ret);
477
478 lba_addr = sectaddr + blocks;
479 #ifdef XXBUFFER
480 check_buffer_teac(scgp);
481 #endif
482 return (ret);
483 }
484
485 LOCAL int
open_track_jvc(scgp,dp,trackp)486 open_track_jvc(scgp, dp, trackp)
487 SCSI *scgp;
488 cdr_t *dp;
489 track_t *trackp;
490 {
491 int status;
492 long blocks;
493 long pregapsize;
494 struct pgm_subcode sc;
495
496 last_done = FALSE;
497
498 if (select_secsize_teac(scgp, trackp) < 0)
499 return (-1);
500
501 status = clear_subcode(scgp);
502 /*next_wr_addr_teac(scgp);*/
503 if (status < 0)
504 return (status);
505
506 if (trackp->pregapsize != 0) {
507 if (lverbose > 1) {
508 printf(_("set_limits(%ld, %ld)-> %ld\n"),
509 lba_addr, trackp->pregapsize, lba_addr + trackp->pregapsize);
510 }
511
512 status = set_limits(scgp, lba_addr, trackp->pregapsize);
513 if (status < 0)
514 return (status);
515
516 /*
517 * Set pre-gap (pause - index 0)
518 */
519 set_pgm_subcode(&sc, SC_P,
520 st2mode[trackp->sectype&ST_MASK], ADR_POS, trackp->trackno, 0);
521
522 if (lverbose > 1)
523 scg_prbytes(_("Subcode:"), (Uchar *)&sc, sizeof (sc));
524
525 status = set_subcode(scgp, (Uchar *)&sc, sizeof (sc));
526 if (status < 0)
527 return (status);
528
529 pregapsize = trackp->pregapsize;
530 if (!is_audio(trackp)) {
531 lba_addr += 5; /* link & run in blocks */
532 pregapsize -= 5;
533 }
534 if (lverbose > 1) {
535 printf(_("pad_track(%ld, %ld)-> %ld\n"),
536 lba_addr, pregapsize, lba_addr + pregapsize);
537 }
538 /*
539 * XXX Do we need to check isecsize too?
540 */
541 if (pad_track(scgp, dp, trackp,
542 lba_addr, (Llong)pregapsize*trackp->secsize,
543 FALSE, (Llong *)0) < 0)
544 return (-1);
545 }
546
547 blocks = trackp->tracksize/trackp->secsize +
548 (trackp->tracksize%trackp->secsize?1:0);
549 blocks += trackp->padsecs;
550 if (blocks < 300)
551 blocks = 300;
552 if (!is_audio(trackp))
553 blocks += 2;
554 if (!is_last(trackp) && trackp[1].pregapsize == 0)
555 blocks -= 150;
556
557 /*
558 * set the limits for the new subcode - seems to apply to all
559 * of the data track.
560 * Unknown tracksize is handled in open_session.
561 * We definitely need to know the tracksize in this driver.
562 */
563 if (lverbose > 1) {
564 printf(_("set_limits(%ld, %ld)-> %ld\n"),
565 lba_addr, blocks, lba_addr + blocks);
566 }
567 status = set_limits(scgp, lba_addr, blocks);
568 if (status < 0)
569 return (status);
570
571 /*
572 * Set track start (index 1)
573 */
574 set_pgm_subcode(&sc, SC_TR,
575 st2mode[trackp->sectype&ST_MASK], ADR_POS, trackp->trackno, 1);
576
577 if (lverbose > 1)
578 scg_prbytes(_("Subcode:"), (Uchar *)&sc, sizeof (sc));
579
580 status = set_subcode(scgp, (Uchar *)&sc, sizeof (sc));
581 if (status < 0)
582 return (status);
583
584 if (!is_last(trackp) && trackp[1].pregapsize == 0) {
585 blocks += lba_addr;
586 pregapsize = 150;
587
588 if (lverbose > 1) {
589 printf(_("set_limits(%ld, %ld)-> %ld\n"),
590 blocks, pregapsize, blocks + pregapsize);
591 }
592
593 status = set_limits(scgp, blocks, pregapsize);
594 if (status < 0)
595 return (status);
596
597 /*
598 * Set pre-gap (pause - index 0)
599 */
600 trackp++;
601 set_pgm_subcode(&sc, SC_P,
602 st2mode[trackp->sectype&ST_MASK], ADR_POS, trackp->trackno, 0);
603
604 if (lverbose > 1)
605 scg_prbytes(_("Subcode:"), (Uchar *)&sc, sizeof (sc));
606
607 status = set_subcode(scgp, (Uchar *)&sc, sizeof (sc));
608 if (status < 0)
609 return (status);
610 }
611 return (status);
612 }
613
614 LOCAL char sector[3000];
615
616 LOCAL int
close_track_teac(scgp,dp,trackp)617 close_track_teac(scgp, dp, trackp)
618 SCSI *scgp;
619 cdr_t *dp;
620 track_t *trackp;
621 {
622 int ret = 0;
623
624 if (!last_done) {
625 printf(_("WARNING: adding dummy block to close track.\n"));
626 /*
627 * need read sector size
628 * XXX do we really need this ?
629 * XXX if we need this can we set blocks to 0 ?
630 */
631 ret = write_teac_xg1(scgp, sector, lba_addr, 2352, 1, FALSE);
632 lba_addr++;
633 }
634 if (!is_audio(trackp))
635 lba_addr += 2;
636 teac_wr_pma(scgp);
637 return (ret);
638 }
639
640
641
642 static const char *sd_teac50_error_str[] = {
643 "\100\200diagnostic failure on component parts", /* 40 80 */
644 "\100\201diagnostic failure on memories", /* 40 81 */
645 "\100\202diagnostic failure on cd-rom ecc circuit", /* 40 82 */
646 "\100\203diagnostic failure on gate array", /* 40 83 */
647 "\100\204diagnostic failure on internal SCSI controller", /* 40 84 */
648 "\100\205diagnostic failure on servo processor", /* 40 85 */
649 "\100\206diagnostic failure on program rom", /* 40 86 */
650 "\100\220thermal sensor failure", /* 40 90 */
651 "\200\000controller prom error", /* 80 00 */ /* JVC */
652 "\201\000no disk present - couldn't get focus", /* 81 00 */ /* JVC */
653 "\202\000no cartridge present", /* 82 00 */ /* JVC */
654 "\203\000unable to spin up", /* 83 00 */ /* JVC */
655 "\204\000addr exceeded the last valid block addr", /* 84 00 */ /* JVC */
656 "\205\000sync error", /* 85 00 */ /* JVC */
657 "\206\000address can't find or not data track", /* 86 00 */ /* JVC */
658 "\207\000missing track", /* 87 00 */ /* JVC */
659 "\213\000cartridge could not be ejected", /* 8B 00 */ /* JVC */
660 "\215\000audio not playing", /* 8D 00 */ /* JVC */
661 "\216\000read toc error", /* 8E 00 */ /* JVC */
662 "\217\000a blank disk is detected by read toc", /* 8F 00 */
663 "\220\000pma less disk - not a recordable disk", /* 90 00 */
664 "\223\000mount error", /* 93 00 */ /* JVC */
665 "\224\000toc less disk", /* 94 00 */
666 "\225\000disc information less disk", /* 95 00 */ /* JVC */
667 "\226\000disc information read error", /* 96 00 */ /* JVC */
668 "\227\000linear velocity measurement error", /* 97 00 */ /* JVC */
669 "\230\000drive sequence stop", /* 98 00 */ /* JVC */
670 "\231\000actuator velocity control error", /* 99 00 */ /* JVC */
671 "\232\000slider velocity control error", /* 9A 00 */ /* JVC */
672 "\233\000opc initialize error", /* 9B 00 */
673 "\233\001power calibration not executed", /* 9B 01 */
674 "\234\000opc execution eror", /* 9C 00 */
675 "\234\001alpc error - opc execution", /* 9C 01 */
676 "\234\002opc execution timeout", /* 9C 02 */
677 "\245\000disk application code does not match host application code", /* A5 00 */
678 "\255\000completed preview write", /* AD 00 */
679 "\256\000invalid B0 value", /* AE 00 */ /* JVC */
680 "\257\000pca area full", /* AF 00 */
681 "\260\000efm isn't detected", /* B0 00 */ /* JVC */
682 "\263\000no logical sector", /* B3 00 */ /* JVC */
683 "\264\000full pma area", /* B4 00 */
684 "\265\000read address is atip area - blank", /* B5 00 */
685 "\266\000write address is efm area - aleady written", /* B6 00 */
686 "\271\000abnormal spinning - servo irq", /* B9 00 */ /* JVC */
687 "\272\000no write data - buffer empty", /* BA 00 */
688 "\273\000write emergency occurred", /* BB 00 */
689 "\274\000read timeout", /* BC 00 */ /* JVC */
690 "\277\000abnormal spin - nmi", /* BF 00 */ /* JVC */
691 "\301\0004th run-in block detected", /* C1 00 */
692 "\302\0003rd run-in block detected", /* C2 00 */
693 "\303\0002nd run-in block detected", /* C3 00 */
694 "\304\0001st run-in block detected", /* C4 00 */
695 "\305\000link block detected", /* C5 00 */
696 "\306\0001st run-out block detected", /* C6 00 */
697 "\307\0002nd run-out block detected", /* C7 00 */
698 "\314\000write request means mixed data mode", /* CC 00 */
699 "\315\000unable to ensure reliable writing with the inserted disk - unsupported disk", /* CD 00 */
700 "\316\000unable to ensure reliable writing as the inserted disk does not support speed", /* CE 00 */
701 "\317\000unable to ensure reliable writing as the inserted disk has no char id code", /* CF 00 */
702 NULL
703 };
704
705 LOCAL int
teac_attach(scgp,dp)706 teac_attach(scgp, dp)
707 SCSI *scgp;
708 cdr_t *dp;
709 {
710 scg_setnonstderrs(scgp, sd_teac50_error_str);
711 #ifdef XXDEBUG
712 xxtest_teac(scgp);
713 exit(0);
714 #endif
715 return (0);
716 }
717
718 LOCAL int
teac_fixation(scgp,dp,trackp)719 teac_fixation(scgp, dp, trackp)
720 SCSI *scgp;
721 cdr_t *dp;
722 track_t *trackp;
723 {
724 long lba;
725 int status;
726 Uchar *sp;
727 Uint i;
728 extern char *buf;
729
730 if (trackp->tracks < 1) {
731 /*
732 * We come here if cdrecord isonly called with the -fix option.
733 * As long as we cannot read and interpret the PMA, we must
734 * abort here.
735 */
736 teac_rd_pma(scgp);
737 /* errmsgno(EX_BAD, "Cannot fixate zero track disk.\n");*/
738 errmsgno(EX_BAD, _("Cannot fixate without track list (not yet implemented).\n"));
739 return (-1);
740 }
741 sp = (Uchar *)buf;
742
743 sleep(1);
744
745 status = clear_subcode(scgp);
746 sleep(1);
747 if (status < 0)
748 return (status);
749
750 sp[0] = 0; /* reserved */
751 sp[1] = 0; /* reserved */
752 sp[2] = 0; /* Q TNO */
753
754 sp = &sp[3]; /* point past header */
755
756 /*
757 * Set up TOC entries for all tracks
758 */
759 for (i = 1; i <= trackp->tracks; i++) {
760 lba = trackp[i].trackstart+150; /* MSF=00:02:00 is LBA=0 */
761
762 sp = set_toc_subcode(sp,
763 /* ctrl/adr for this track */
764 st2mode[trackp[i].sectype&ST_MASK], ADR_POS,
765 trackp[i].trackno, lba);
766 }
767
768 /*
769 * Set first track on disk
770 *
771 * XXX We set the track type for the lead-in to the track type
772 * XXX of the first track. The TEAC manual states that we should use
773 * XXX audio if the disk contains both, audio and data tracks.
774 */
775 sp = set_lin_subcode(sp,
776 /* ctrl/adr for first track */
777 st2mode[trackp[1].sectype&ST_MASK], ADR_POS,
778 0xA0, /* Point A0 */
779 trackp[1].trackno, /* first track # */
780 toc2sess[track_base(trackp)->tracktype & TOC_MASK], /* disk type */
781 0); /* reserved */
782
783 /*
784 * Set last track on disk
785 */
786 sp = set_lin_subcode(sp,
787 /* ctrl/adr for first track */
788 st2mode[trackp[1].sectype&ST_MASK], ADR_POS,
789 0xA1, /* Point A1 */
790 MSF_CONV(trackp[trackp->tracks].trackno), /* last track # */
791 0, /* reserved */
792 0); /* reserved */
793
794 /*
795 * Set start of lead out area in MSF
796 * MSF=00:02:00 is LBA=0
797 */
798 lba = lba_addr + 150;
799 if (lverbose > 1)
800 printf(_("lba: %ld lba_addr: %ld\n"), lba, lba_addr);
801
802 if (lverbose > 1)
803 printf(_("Lead out start: (%02d:%02d/%02d)\n"),
804 minutes(lba*2352),
805 seconds(lba*2352),
806 frames(lba*2352));
807
808 sp = set_lin_subcode(sp,
809 /* ctrl/adr for first track */
810 st2mode[trackp[1].sectype&ST_MASK], ADR_POS,
811 0xA2, /* Point A2 */
812 MSF_CONV(LBA_MIN(lba)),
813 MSF_CONV(LBA_SEC(lba)),
814 MSF_CONV(LBA_FRM(lba)));
815
816 status = sp - ((Uchar *)buf);
817 if (lverbose > 1) {
818 printf(_("Subcode len: %d\n"), status);
819 scg_prbytes(_("Subcode:"), (Uchar *)buf, status);
820 }
821 status = set_subcode(scgp, (Uchar *)buf, status);
822 sleep(1);
823 if (status < 0)
824 return (status);
825
826 /*
827 * now write the toc
828 */
829 status = teac_freeze(scgp, (track_base(trackp)->tracktype & TOCF_MULTI) == 0);
830 return (status);
831
832 }
833
834 LOCAL int
teac_open_session(scgp,dp,trackp)835 teac_open_session(scgp, dp, trackp)
836 SCSI *scgp;
837 cdr_t *dp;
838 track_t *trackp;
839 {
840 Uint i;
841
842 for (i = 1; i <= trackp->tracks; i++) {
843 if (trackp[i].tracksize < (tsize_t)0) {
844 /*
845 * XXX How about setting the subcode range to infinity.
846 * XXX and correct it in clode track before writing
847 * XXX the PMA?
848 */
849 errmsgno(EX_BAD, _("Track %d has unknown length.\n"), i);
850 return (-1);
851 }
852 }
853 return (initsub_teac(scgp, track_base(trackp)->tracktype & TOC_MASK,
854 track_base(trackp)->tracktype & TOCF_MULTI));
855 }
856
857 LOCAL int
initsub_teac(scgp,toctype,multi)858 initsub_teac(scgp, toctype, multi)
859 SCSI *scgp;
860 int toctype;
861 int multi;
862 {
863 int status;
864
865 scgp->silent++;
866 if (read_B0(scgp, TRUE, &lba_addr, NULL) < 0)
867 lba_addr = -150;
868 scgp->silent--;
869
870 status = clear_subcode(scgp);
871 if (status < 0)
872 return (status);
873
874 return (0);
875 }
876
877 LOCAL int
teac_doopc(scgp)878 teac_doopc(scgp)
879 SCSI *scgp;
880 {
881 int status;
882
883 if (lverbose) {
884 fprintf(stdout, _("Judging disk..."));
885 flush();
886 }
887 status = opt_power_judge(scgp, 1);
888 if (status < 0) {
889 printf("\n");
890 return (status);
891 }
892 if (lverbose) {
893 fprintf(stdout, _("done.\nCalibrating laser..."));
894 flush();
895 }
896
897 status = opt_power_judge(scgp, 0);
898 if (lverbose) {
899 fprintf(stdout, _("done.\n"));
900 }
901 /*
902 * Check for error codes 0xCD ... 0xCF
903 */
904 scgp->silent++;
905 if (next_wr_addr_teac(scgp, -1, -1) < 0) {
906 if (scgp->verbose == 0 && scg_sense_key(scgp) != SC_ILLEGAL_REQUEST)
907 scg_printerr(scgp);
908 }
909 scgp->silent--;
910 return (status);
911 }
912
913 LOCAL int
teac_opc(scgp,bp,cnt,doopc)914 teac_opc(scgp, bp, cnt, doopc)
915 SCSI *scgp;
916 caddr_t bp;
917 int cnt;
918 int doopc;
919 {
920 int status;
921 int count = 0;
922
923 do {
924 status = teac_doopc(scgp);
925 } while (++count <= 1 && status < 0);
926
927 return (status);
928 }
929
930 /*--------------------------------------------------------------------------*/
931 #define SC_SET_LIMITS 0xb3 /* teac 12 byte command */
932 #define SC_SET_SUBCODE 0xc2 /* teac 10 byte command */
933 #define SC_READ_PMA 0xc4 /* teac 10 byte command */
934 #define SC_READ_DISK_INFO 0xc7 /* teac 10 byte command */
935 #define SC_BUFFER_INQUIRY 0xe0 /* teac 12 byte command */
936
937 #define SC_WRITE_PMA 0xe1 /* teac 12 byte command */
938 #define SC_FREEZE 0xe3 /* teac 12 byte command */
939 #define SC_OPC_EXECUTE 0xec /* teac 12 byte command */
940 #define SC_CLEAR_SUBCODE 0xe4 /* teac 12 byte command */
941 #define SC_NEXT_WR_ADDRESS 0xe6 /* teac 12 byte command */
942
943 #define SC_READ_PEAK_BUF_CAP 0xef /* teac 12 byte command */
944
945 /*
946 * Optimum power calibration for Teac Drives.
947 */
948 LOCAL int
opt_power_judge(scgp,judge)949 opt_power_judge(scgp, judge)
950 SCSI *scgp;
951 int judge;
952 {
953 register struct scg_cmd *scmd = scgp->scmd;
954
955 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
956 scmd->addr = (caddr_t)0;
957 scmd->size = 0;
958 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
959 scmd->cdb_len = SC_G5_CDBLEN;
960 scmd->sense_len = CCS_SENSE_LEN;
961 scmd->timeout = 60;
962
963 scmd->cdb.g5_cdb.cmd = SC_OPC_EXECUTE;
964 scmd->cdb.g5_cdb.lun = scg_lun(scgp);
965 scmd->cdb.g5_cdb.reladr = judge; /* Judge the Disc */
966
967 scgp->cmdname = "opt_power_judge";
968
969 return (scg_cmd(scgp));
970 }
971
972 /*
973 * Clear subcodes for Teac Drives.
974 */
975 LOCAL int
clear_subcode(scgp)976 clear_subcode(scgp)
977 SCSI *scgp;
978 {
979 register struct scg_cmd *scmd = scgp->scmd;
980
981 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
982 scmd->addr = (caddr_t)0;
983 scmd->size = 0;
984 scmd->flags = SCG_DISRE_ENA;
985 scmd->cdb_len = SC_G5_CDBLEN;
986 scmd->sense_len = CCS_SENSE_LEN;
987
988 scmd->cdb.g5_cdb.cmd = SC_CLEAR_SUBCODE;
989 scmd->cdb.g5_cdb.lun = scg_lun(scgp);
990 scmd->cdb.g5_cdb.addr[3] = 0x80;
991
992 scgp->cmdname = "clear subcode";
993
994 return (scg_cmd(scgp));
995 }
996
997 /*
998 * Set limits for command linking for Teac Drives.
999 */
1000 LOCAL int
set_limits(scgp,lba,length)1001 set_limits(scgp, lba, length)
1002 SCSI *scgp;
1003 long lba;
1004 long length;
1005 {
1006 register struct scg_cmd *scmd = scgp->scmd;
1007
1008 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
1009 scmd->addr = (caddr_t)0;
1010 scmd->size = 0;
1011 scmd->flags = SCG_DISRE_ENA;
1012 scmd->cdb_len = SC_G5_CDBLEN;
1013 scmd->sense_len = CCS_SENSE_LEN;
1014
1015 scmd->cdb.g5_cdb.cmd = SC_SET_LIMITS;
1016 scmd->cdb.g5_cdb.lun = scg_lun(scgp);
1017 i_to_4_byte(&scmd->cdb.g5_cdb.addr[0], lba);
1018 i_to_4_byte(&scmd->cdb.g5_cdb.count[0], length);
1019
1020 scgp->cmdname = "set limits";
1021
1022 return (scg_cmd(scgp));
1023 }
1024
1025 /*
1026 * Set subcode for Teac Drives.
1027 */
1028 LOCAL int
set_subcode(scgp,subcode_data,length)1029 set_subcode(scgp, subcode_data, length)
1030 SCSI *scgp;
1031 Uchar *subcode_data;
1032 int length;
1033 {
1034 register struct scg_cmd *scmd = scgp->scmd;
1035
1036 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
1037 scmd->addr = (caddr_t)subcode_data;
1038 scmd->size = length;
1039 scmd->flags = SCG_DISRE_ENA;
1040 scmd->cdb_len = SC_G1_CDBLEN;
1041 scmd->sense_len = CCS_SENSE_LEN;
1042
1043 scmd->cdb.g1_cdb.cmd = SC_SET_SUBCODE;
1044 scmd->cdb.g1_cdb.lun = scg_lun(scgp);
1045 g1_cdblen(&scmd->cdb.g1_cdb, length);
1046
1047 scgp->cmdname = "set subcode";
1048
1049 return (scg_cmd(scgp));
1050 }
1051
1052 #ifdef XDI
1053 LOCAL int
read_disk_info_teac(scgp,data,length,type)1054 read_disk_info_teac(scgp, data, length, type)
1055 SCSI *scgp;
1056 Uchar *data;
1057 int length;
1058 int type;
1059 {
1060 register struct scg_cmd *scmd = scgp->scmd;
1061
1062 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
1063 scmd->addr = (caddr_t)data;
1064 scmd->size = length;
1065 scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
1066 scmd->cdb_len = SC_G1_CDBLEN;
1067 scmd->sense_len = CCS_SENSE_LEN;
1068
1069 scmd->cdb.g1_cdb.cmd = SC_READ_DISK_INFO;
1070 scmd->cdb.g1_cdb.lun = scg_lun(scgp);
1071
1072 scmd->cdb.g1_cdb.reladr = type & 1;
1073 scmd->cdb.g1_cdb.res = (type & 2) >> 1;
1074
1075 scgp->cmdname = "read disk info teac";
1076
1077 return (scg_cmd(scgp));
1078 }
1079 #endif
1080
1081 /*
1082 * Perform the freeze command for Teac Drives.
1083 */
1084 LOCAL int
teac_freeze(scgp,bp_flag)1085 teac_freeze(scgp, bp_flag)
1086 SCSI *scgp;
1087 int bp_flag;
1088 {
1089 register struct scg_cmd *scmd = scgp->scmd;
1090
1091 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
1092 scmd->addr = (caddr_t)0;
1093 scmd->size = 0;
1094 scmd->flags = SCG_DISRE_ENA;
1095 scmd->cdb_len = SC_G5_CDBLEN;
1096 scmd->sense_len = CCS_SENSE_LEN;
1097 scmd->timeout = 8 * 60; /* Needs up to 4 minutes */
1098
1099 scmd->cdb.g5_cdb.cmd = SC_FREEZE;
1100 scmd->cdb.g5_cdb.lun = scg_lun(scgp);
1101 scmd->cdb.g5_cdb.addr[3] = bp_flag ? 0x80 : 0;
1102
1103 scgp->cmdname = "teac_freeze";
1104
1105 return (scg_cmd(scgp));
1106 }
1107
1108 LOCAL int
teac_wr_pma(scgp)1109 teac_wr_pma(scgp)
1110 SCSI *scgp;
1111 {
1112 register struct scg_cmd *scmd = scgp->scmd;
1113
1114 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
1115 scmd->addr = (caddr_t)0;
1116 scmd->size = 0;
1117 scmd->flags = SCG_DISRE_ENA;
1118 scmd->cdb_len = SC_G5_CDBLEN;
1119 scmd->sense_len = CCS_SENSE_LEN;
1120
1121 scmd->cdb.g5_cdb.cmd = SC_WRITE_PMA;
1122 scmd->cdb.g5_cdb.lun = scg_lun(scgp);
1123
1124 scgp->cmdname = "teac_write_pma";
1125
1126 return (scg_cmd(scgp));
1127 }
1128
1129 /*
1130 * Read PMA for Teac Drives.
1131 */
1132 LOCAL int
teac_rd_pma(scgp)1133 teac_rd_pma(scgp)
1134 SCSI *scgp;
1135 {
1136 unsigned char xx[256];
1137 register struct scg_cmd *scmd = scgp->scmd;
1138
1139 fillbytes((caddr_t)xx, sizeof (xx), '\0');
1140 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
1141 scmd->addr = (caddr_t)xx;
1142 scmd->size = sizeof (xx);
1143 scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
1144 scmd->cdb_len = SC_G1_CDBLEN;
1145 scmd->sense_len = CCS_SENSE_LEN;
1146
1147 scmd->cdb.g1_cdb.cmd = SC_READ_PMA;
1148 scmd->cdb.g1_cdb.lun = scg_lun(scgp);
1149
1150 g1_cdblen(&scmd->cdb.g1_cdb, sizeof (xx));
1151
1152 scgp->cmdname = "teac_read_pma";
1153
1154 /* return (scg_cmd(scgp));*/
1155 if (scg_cmd(scgp) < 0)
1156 return (-1);
1157
1158 if (scgp->verbose) {
1159 scg_prbytes(_("PMA Data"), xx, sizeof (xx) - scg_getresid(scgp));
1160 }
1161 if (lverbose) {
1162 unsigned i;
1163 Uchar *p;
1164
1165 scg_prbytes(_("PMA Header: "), xx, 4);
1166 i = xx[2];
1167 p = &xx[4];
1168 for (; i <= xx[3]; i++) {
1169 scg_prbytes("PMA: ", p, 10);
1170 p += 10;
1171 }
1172 }
1173 return (0);
1174 }
1175
1176 /*
1177 * Next writable address for Teac Drives.
1178 */
1179 LOCAL int
next_wr_addr_teac(scgp,start_lba,last_lba)1180 next_wr_addr_teac(scgp, start_lba, last_lba)
1181 SCSI *scgp;
1182 long start_lba;
1183 long last_lba;
1184 {
1185 unsigned char xx[256];
1186 register struct scg_cmd *scmd = scgp->scmd;
1187
1188 fillbytes((caddr_t)xx, sizeof (xx), '\0');
1189 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
1190 scmd->addr = (caddr_t)xx;
1191 scmd->size = sizeof (xx);
1192 scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
1193 scmd->cdb_len = SC_G5_CDBLEN;
1194 scmd->sense_len = CCS_SENSE_LEN;
1195
1196 scmd->cdb.g5_cdb.cmd = SC_NEXT_WR_ADDRESS;
1197 scmd->cdb.g5_cdb.lun = scg_lun(scgp);
1198
1199 i_to_4_byte(&scmd->cdb.g5_cdb.addr[0], start_lba);
1200 i_to_4_byte(&scmd->cdb.g5_cdb.count[0], last_lba);
1201
1202 if (scgp->verbose)
1203 printf(_("start lba: %ld last lba: %ld\n"),
1204 start_lba, last_lba);
1205
1206 scgp->cmdname = "next writable address";
1207
1208 /* return (scg_cmd(scgp));*/
1209 if (scg_cmd(scgp) < 0)
1210 return (-1);
1211
1212 if (scgp->verbose) {
1213 scg_prbytes(_("WRa Data"), xx, sizeof (xx) - scg_getresid(scgp));
1214 printf(_("NWA: %ld\n"), a_to_4_byte(xx));
1215 }
1216 return (0);
1217 }
1218
1219 LOCAL int
blank_jvc(scgp,dp,addr,blanktype)1220 blank_jvc(scgp, dp, addr, blanktype)
1221 SCSI *scgp;
1222 cdr_t *dp;
1223 long addr;
1224 int blanktype;
1225 {
1226 extern char *blank_types[];
1227
1228 if (lverbose) {
1229 printf(_("Blanking %s\n"), blank_types[blanktype & 0x07]);
1230 flush();
1231 }
1232
1233 return (scsi_blank(scgp, addr, blanktype, FALSE));
1234 }
1235
1236 LOCAL int
buf_cap_teac(scgp,sp,fp)1237 buf_cap_teac(scgp, sp, fp)
1238 SCSI *scgp;
1239 long *sp; /* Size pointer */
1240 long *fp; /* Free pointer */
1241 {
1242 Ulong freespace;
1243 Ulong bufsize;
1244 long ret;
1245 int per;
1246
1247 ret = read_peak_buffer_cap_teac(scgp);
1248 if (ret < 0)
1249 return (-1);
1250 bufsize = ret;
1251 freespace = 0;
1252 if (sp)
1253 *sp = bufsize;
1254 if (fp)
1255 *fp = freespace;
1256
1257 if (scgp->verbose || (sp == 0 && fp == 0))
1258 printf(_("BFree: %ld K BSize: %ld K\n"), freespace >> 10, bufsize >> 10);
1259
1260 if (bufsize == 0)
1261 return (0);
1262 per = (100 * (bufsize - freespace)) / bufsize;
1263 if (per < 0)
1264 return (0);
1265 if (per > 100)
1266 return (100);
1267 return (per);
1268 }
1269
1270 LOCAL long
read_peak_buffer_cap_teac(scgp)1271 read_peak_buffer_cap_teac(scgp)
1272 SCSI *scgp;
1273 {
1274 Uchar xx[4];
1275 register struct scg_cmd *scmd = scgp->scmd;
1276
1277 fillbytes((caddr_t)xx, sizeof (xx), '\0');
1278 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
1279 scmd->addr = (caddr_t)xx;
1280 scmd->size = sizeof (xx);
1281 scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
1282 scmd->cdb_len = SC_G5_CDBLEN;
1283 scmd->sense_len = CCS_SENSE_LEN;
1284
1285 scmd->cdb.g5_cdb.cmd = SC_READ_PEAK_BUF_CAP;
1286 scmd->cdb.g5_cdb.lun = scg_lun(scgp);
1287
1288 scgp->cmdname = "read peak buffer capacity";
1289
1290 #define BDEBUG
1291 #ifndef BDEBUG
1292 return (scg_cmd(scgp));
1293 #else
1294 if (scg_cmd(scgp) < 0)
1295 return (-1);
1296
1297 if (scgp->verbose) {
1298 scg_prbytes(_("WRa Data"), xx, sizeof (xx) - scg_getresid(scgp));
1299 printf(_("Buffer cap: %ld\n"), a_to_u_3_byte(&xx[1]));
1300 }
1301 return (a_to_u_3_byte(&xx[1]));
1302 /* return (0);*/
1303 #endif
1304 }
1305
1306 #define BI_ONE_BYTE 0xC0
1307 #define BI_448_BYTE 0x40
1308 #define BI_APP_CODE 0x10
1309
1310 #ifdef XXBUFFER
1311 LOCAL int
buffer_inquiry_teac(scgp,fmt)1312 buffer_inquiry_teac(scgp, fmt)
1313 SCSI *scgp;
1314 int fmt;
1315 {
1316 Uchar xx[448];
1317 register struct scg_cmd *scmd = scgp->scmd;
1318
1319 fillbytes((caddr_t)xx, sizeof (xx), '\0');
1320 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
1321 scmd->addr = (caddr_t)xx;
1322 scmd->size = sizeof (xx);
1323 scmd->size = 448;
1324 scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
1325 scmd->cdb_len = SC_G5_CDBLEN;
1326 scmd->sense_len = CCS_SENSE_LEN;
1327
1328 scmd->cdb.g5_cdb.cmd = SC_BUFFER_INQUIRY;
1329 scmd->cdb.g5_cdb.lun = scg_lun(scgp);
1330
1331 if (fmt > 0) {
1332 scmd->cdb.g5_cdb.addr[3] = fmt;
1333 if (fmt == BI_ONE_BYTE)
1334 scmd->size = 1;
1335 } else {
1336 scmd->cdb.g5_cdb.addr[3] = BI_448_BYTE;
1337 /* scmd->cdb.g5_cdb.addr[3] = BI_APP_CODE;*/
1338 }
1339
1340 scgp->cmdname = "buffer inquiry";
1341
1342 #define BDEBUG
1343 #ifndef BDEBUG
1344 return (scg_cmd(scgp));
1345 #else
1346 if (scg_cmd(scgp) < 0)
1347 return (-1);
1348
1349 if (scgp->verbose) {
1350 /* scg_prbytes("WRa Data", xx, sizeof (xx) - scg_getresid(scgp));*/
1351 /* scg_prbytes("WRa Data", xx, 1);*/
1352
1353 if (fmt > 0) printf("fmt: %X ", fmt);
1354 scg_prbytes(_("WRa Data"), xx, 9);
1355 printf("%d\n", xx[8] - xx[1]);
1356 /* printf("Buffer cap: %ld\n", a_to_u_3_byte(&xx[1]));*/
1357 }
1358 return (0);
1359 #endif
1360 }
1361
1362 LOCAL void
check_buffer_teac(scgp)1363 check_buffer_teac(scgp)
1364 SCSI *scgp;
1365 {
1366 printf("-------\n");
1367 buffer_inquiry_teac(scgp, 0);
1368 #ifdef SL
1369 usleep(40000);
1370 buffer_inquiry_teac(scgp, 0);
1371 #endif
1372 read_peak_buffer_cap_teac(scgp);
1373 }
1374 #endif
1375 /*--------------------------------------------------------------------------*/
1376 #ifdef XXDEBUG
1377 #include "scsimmc.h"
1378
1379 LOCAL int g7_teac __PR((SCSI *scgp));
1380 LOCAL int g6_teac __PR((SCSI *scgp));
1381
1382 LOCAL int
g7_teac(scgp)1383 g7_teac(scgp)
1384 SCSI *scgp;
1385 {
1386 Uchar xx[2048];
1387 register struct scg_cmd *scmd = scgp->scmd;
1388
1389 fillbytes((caddr_t)xx, sizeof (xx), '\0');
1390 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
1391 scmd->addr = (caddr_t)xx;
1392 scmd->size = sizeof (xx);
1393 scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
1394 scmd->cdb_len = SC_G5_CDBLEN;
1395 scmd->sense_len = CCS_SENSE_LEN;
1396
1397 scmd->cdb.g5_cdb.cmd = 0xDF;
1398 /* scmd->cdb.g5_cdb.cmd = 0xE5;*/
1399 scmd->cdb.g5_cdb.lun = scg_lun(scgp);
1400
1401 /* scmd->cdb.g5_cdb.addr[3] = BI_ONE_BYTE;*/
1402 /* scmd->size = 1;*/
1403
1404 /* scmd->cdb.g5_cdb.addr[3] = BI_448_BYTE;*/
1405 /* scmd->cdb.g5_cdb.addr[3] = BI_APP_CODE;*/
1406
1407 scgp->cmdname = "g7 teac";
1408
1409 /* return (scg_cmd(scgp));*/
1410 if (scg_cmd(scgp) < 0)
1411 return (-1);
1412
1413 /* if (scgp->verbose) {*/
1414 scg_prbytes(_("WRa Data"), xx, sizeof (xx) - scg_getresid(scgp));
1415 /* scg_prbytes("WRa Data", xx, 1);*/
1416 /* scg_prbytes("WRa Data", xx, 9);*/
1417 /*printf("%d\n", xx[8] - xx[1]);*/
1418 /* printf("Buffer cap: %ld\n", a_to_u_3_byte(&xx[1]));*/
1419 /* }*/
1420 return (0);
1421 }
1422
1423 LOCAL int
g6_teac(scgp)1424 g6_teac(scgp)
1425 SCSI *scgp;
1426 {
1427 Uchar xx[2048];
1428 register struct scg_cmd *scmd = scgp->scmd;
1429
1430 fillbytes((caddr_t)xx, sizeof (xx), '\0');
1431 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
1432 scmd->addr = (caddr_t)xx;
1433 scmd->size = sizeof (xx);
1434 scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
1435 scmd->cdb_len = SC_G1_CDBLEN;
1436 scmd->sense_len = CCS_SENSE_LEN;
1437
1438 scmd->cdb.g1_cdb.cmd = 0xC1;
1439 scmd->cdb.g1_cdb.cmd = 0xC3;
1440 scmd->cdb.g1_cdb.cmd = 0xC6;
1441 scmd->cdb.g1_cdb.cmd = 0xC7; /* Read TOC */
1442 scmd->cdb.g1_cdb.cmd = 0xCE;
1443 scmd->cdb.g1_cdb.cmd = 0xCF;
1444 scmd->cdb.g1_cdb.cmd = 0xC7; /* Read TOC */
1445 scmd->cdb.g1_cdb.lun = scg_lun(scgp);
1446
1447 scgp->cmdname = "g6 teac";
1448
1449 /* return (scg_cmd(scgp));*/
1450 if (scg_cmd(scgp) < 0)
1451 return (-1);
1452
1453 /* if (scgp->verbose) {*/
1454 scg_prbytes(_("WRa Data"), xx, sizeof (xx) - scg_getresid(scgp));
1455 /* scg_prbytes("WRa Data", xx, 1);*/
1456 /* scg_prbytes("WRa Data", xx, 9);*/
1457 /*printf("%d\n", xx[8] - xx[1]);*/
1458 /* printf("Buffer cap: %ld\n", a_to_u_3_byte(&xx[1]));*/
1459 /* }*/
1460 return (0);
1461 }
1462
1463 LOCAL void
xxtest_teac(scgp)1464 xxtest_teac(scgp)
1465 SCSI *scgp;
1466 {
1467 read_peak_buffer_cap_teac(scgp);
1468
1469 /*#define XDI*/
1470 #ifdef XDI
1471 {
1472 Uchar cbuf[512];
1473
1474 /* read_disk_info_teac(scgp, data, length, type)*/
1475 /* read_disk_info_teac(scgp, cbuf, 512, 2);*/
1476 /* read_disk_info_teac(scgp, cbuf, 512, 2);*/
1477 read_disk_info_teac(scgp, cbuf, 512, 3);
1478 scg_prbytes(_("DI Data"), cbuf, sizeof (cbuf) - scg_getresid(scgp));
1479 }
1480 #endif /* XDI */
1481
1482 buffer_inquiry_teac(scgp, -1);
1483
1484 /*#define XBU*/
1485 #ifdef XBU
1486 {
1487 int i;
1488
1489 for (i = 0; i < 63; i++) {
1490 scgp->silent++;
1491 buffer_inquiry_teac(scgp, i<<2);
1492 scgp->silent--;
1493 }
1494 }
1495 #endif /* XBU */
1496
1497 /* printf("LLLL\n");*/
1498 /* g7_teac(scgp);*/
1499 /* g6_teac(scgp);*/
1500 }
1501 #endif /* XXDEBUG */
1502