drv_jvc.c
上传用户:xiejiait
上传日期:2007-01-06
资源大小:881k
文件大小:35k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /** @(#)drv_jvc.c 1.46 99/10/17 Copyright 1997 J. Schilling */
  2. #ifndef lint
  3. static char sccsid[] =
  4. "@(#)drv_jvc.c 1.46 99/10/17 Copyright 1997 J. Schilling";
  5. #endif
  6. /*
  7.  * CDR device implementation for
  8.  * JVC/TEAC
  9.  *
  10.  * Copyright (c) 1997 J. Schilling
  11.  */
  12. /*
  13.  * This program is free software; you can redistribute it and/or modify
  14.  * it under the terms of the GNU General Public License as published by
  15.  * the Free Software Foundation; either version 2, or (at your option)
  16.  * any later version.
  17.  *
  18.  * This program is distributed in the hope that it will be useful,
  19.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  * GNU General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU General Public License
  24.  * along with this program; see the file COPYING.  If not, write to
  25.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  26.  */
  27. /*#define XXDEBUG*/
  28. /*#define XXBUFFER*/
  29. #include <mconfig.h>
  30. #include <stdio.h>
  31. #include <standard.h>
  32. #include <fctldefs.h>
  33. #include <errno.h>
  34. #include <strdefs.h>
  35. #include <unixstd.h>
  36. #ifdef XXDEBUG
  37. #include <stdxlib.h>
  38. #endif
  39. #include <utypes.h>
  40. #include <btorder.h>
  41. #include <intcvt.h>
  42. #include <scg/scgcmd.h>
  43. #include <scg/scsidefs.h>
  44. #include <scg/scsireg.h>
  45. #include <scg/scsitransp.h>
  46. #include "cdrecord.h"
  47. /* just a hack */
  48. long lba_addr;
  49. BOOL last_done;
  50. /*
  51.  * macros for building MSF values from LBA
  52.  */
  53. #define LBA_MIN(x) ((x)/(60*75))
  54. #define LBA_SEC(x) (((x)%(60*75))/75)
  55. #define LBA_FRM(x) ((x)%75)
  56. #define MSF_CONV(a) ((((a)%100)/10)*16 + ((a)%10))
  57. extern int lverbose;
  58. #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */
  59. struct teac_mode_page_21 { /* teac dummy selection */
  60. MP_P_CODE; /* parsave & pagecode */
  61. u_char p_len; /* 0x01 = 1 Byte */
  62. Ucbit dummy : 2;
  63. Ucbit res : 6;
  64. };
  65. #else
  66. struct teac_mode_page_21 { /* teac dummy selection */
  67. MP_P_CODE; /* parsave & pagecode */
  68. u_char p_len; /* 0x01 = 1 Byte */
  69. Ucbit res : 6;
  70. Ucbit dummy : 2;
  71. };
  72. #endif
  73. struct teac_mode_page_31 { /* teac speed selection */
  74. MP_P_CODE; /* parsave & pagecode */
  75. u_char p_len; /* 0x02 = 2 Byte */
  76. u_char speed;
  77. u_char res;
  78. };
  79. struct cdd_52x_mode_data {
  80. struct scsi_mode_header header;
  81. union cdd_pagex {
  82. struct teac_mode_page_21 teac_page21;
  83. struct teac_mode_page_31 teac_page31;
  84. } pagex;
  85. };
  86. #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */
  87. struct pgm_subcode { /* subcode for progam area */
  88. u_char subcode;
  89. Ucbit addr : 4;
  90. Ucbit control : 4;
  91. u_char track;
  92. u_char index;
  93. };
  94. #else
  95. struct pgm_subcode { /* subcode for progam area */
  96. u_char subcode;
  97. Ucbit control : 4;
  98. Ucbit addr : 4;
  99. u_char track;
  100. u_char index;
  101. };
  102. #endif
  103. #define set_pgm_subcode(sp, t, c, a, tr, idx) (
  104. (sp)->subcode = (t),  
  105. (sp)->control = (c),  
  106. (sp)->addr = (a),  
  107. (sp)->track = MSF_CONV(tr),  
  108. (sp)->index = (idx))
  109. #define SC_P 1 /* Subcode defines pre-gap (Pause) */
  110. #define SC_TR 0 /* Subcode defines track data */
  111. #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */
  112. typedef struct lin_subcode { /* subcode for lead in area */
  113. Ucbit addr : 4;
  114. Ucbit control : 4;
  115. u_char track;
  116. u_char msf[3];
  117. } lsc_t;
  118. #else
  119. typedef struct lin_subcode { /* subcode for lead in area */
  120. Ucbit control : 4;
  121. Ucbit addr : 4;
  122. u_char track;
  123. u_char msf[3];
  124. } lsc_t;
  125. #endif
  126. #define set_toc_subcode(sp, c, a, tr, bno) (
  127. ((lsc_t *)sp)->control = (c),  
  128. ((lsc_t *)sp)->addr = (a),  
  129. ((lsc_t *)sp)->track = MSF_CONV(tr),  
  130. ((lsc_t *)sp)->msf[0] = MSF_CONV(LBA_MIN(bno)),  
  131. ((lsc_t *)sp)->msf[1] = MSF_CONV(LBA_SEC(bno)),  
  132. ((lsc_t *)sp)->msf[2] = MSF_CONV(LBA_FRM(bno)),  
  133. &((lsc_t *)sp)->msf[3])
  134. #define set_lin_subcode(sp, c, a, pt, min, sec, frm) (
  135. ((lsc_t *)sp)->control = (c),  
  136. ((lsc_t *)sp)->addr = (a),  
  137. ((lsc_t *)sp)->track = (pt),  
  138. ((lsc_t *)sp)->msf[0] = (min),  
  139. ((lsc_t *)sp)->msf[1] = (sec),  
  140. ((lsc_t *)sp)->msf[2] = (frm),  
  141. &((lsc_t *)sp)->msf[3])
  142. #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */
  143. struct upc_subcode { /* subcode for upc/bar code */
  144. u_char res;
  145. Ucbit addr : 4;
  146. Ucbit control : 4;
  147. u_char upc[13];
  148. };
  149. #else
  150. struct upc_subcode { /* subcode for upc/bar code */
  151. u_char res;
  152. Ucbit control : 4;
  153. Ucbit addr : 4;
  154. u_char upc[13];
  155. };
  156. #endif
  157. #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */
  158. struct isrc_subcode { /* subcode for ISRC code */
  159. u_char res;
  160. Ucbit addr : 4;
  161. Ucbit control : 4;
  162. u_char isrc[12];
  163. u_char res14;
  164. };
  165. #else
  166. struct isrc_subcode { /* subcode for ISRC code */
  167. u_char res;
  168. Ucbit control : 4;
  169. Ucbit addr : 4;
  170. u_char isrc[12];
  171. u_char res14;
  172. };
  173. #endif
  174. LOCAL int teac_attach __PR((SCSI *scgp, cdr_t *dp));
  175. LOCAL int teac_getdisktype __PR((SCSI *scgp, cdr_t *dp, dstat_t *dsp));
  176. LOCAL int speed_select_teac __PR((SCSI *scgp, int *speedp, int dummy));
  177. LOCAL int select_secsize_teac __PR((SCSI *scgp, track_t *trackp));
  178. LOCAL int next_wr_addr_jvc __PR((SCSI *scgp, int track, track_t *, long *ap));
  179. LOCAL int write_teac_xg1 __PR((SCSI *scgp, caddr_t, long, long, int, BOOL));
  180. LOCAL int cdr_write_teac __PR((SCSI *scgp, caddr_t bp, long sectaddr, long size, int blocks, BOOL islast));
  181. LOCAL int open_track_jvc __PR((SCSI *scgp, cdr_t *dp, int track, track_t *trackp));
  182. LOCAL int teac_fixation __PR((SCSI *scgp, int onp, int dummy, int toctype, int tracks, track_t *trackp));
  183. LOCAL int close_track_teac __PR((SCSI *scgp, int track, track_t *trackp));
  184. LOCAL int teac_open_session __PR((SCSI *scgp, int tracks, track_t *trackp, int toctype, int multi));
  185. LOCAL int teac_calibrate __PR((SCSI *scgp, int toctype, int multi));
  186. LOCAL int opt_power_judge __PR((SCSI *scgp, int judge));
  187. LOCAL int clear_subcode __PR((SCSI *scgp));
  188. LOCAL int set_limits __PR((SCSI *scgp, long lba, long length));
  189. LOCAL int set_subcode __PR((SCSI *scgp, u_char *subcode_data, int length));
  190. LOCAL int read_disk_info_teac __PR((SCSI *scgp, u_char *data, int length, int type));
  191. LOCAL int teac_freeze __PR((SCSI *scgp, int bp_flag));
  192. LOCAL int teac_wr_pma __PR((SCSI *scgp));
  193. LOCAL int teac_rd_pma __PR((SCSI *scgp));
  194. LOCAL int next_wr_addr_teac __PR((SCSI *scgp, long start_lba, long last_lba));
  195. LOCAL int blank_jvc __PR((SCSI *scgp, long addr, int blanktype));
  196. LOCAL int buf_cap_teac __PR((SCSI *scgp, long *sp, long *fp));
  197. LOCAL long read_peak_buffer_cap_teac __PR((SCSI *scgp));
  198. LOCAL int buffer_inquiry_teac __PR((SCSI *scgp, int fmt));
  199. #ifdef XXBUFFER
  200. LOCAL void check_buffer_teac __PR((SCSI *scgp));
  201. #endif
  202. #ifdef XXDEBUG
  203. LOCAL void xxtest_teac __PR((SCSI *scgp));
  204. #endif
  205. cdr_t cdr_teac_cdr50 = {
  206. 0,
  207. CDR_TAO|CDR_DAO|CDR_SWABAUDIO|CDR_NO_LOLIMIT,
  208. "teac_cdr50",
  209. "driver for Teac CD-R50S, Teac CD-R55S, JVC XR-W2010, Pinnacle RCD-5020",
  210. 0,
  211. drive_identify,
  212. teac_attach,
  213. teac_getdisktype,
  214. scsi_load,
  215. scsi_unload,
  216. buf_cap_teac,
  217. (int(*)__PR((SCSI *)))cmd_dummy, /* recovery_needed */
  218. (int(*)__PR((SCSI *, int)))cmd_dummy, /* recover */
  219. speed_select_teac,
  220. select_secsize,
  221. next_wr_addr_jvc,
  222. (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */
  223. cdr_write_teac,
  224. no_sendcue,
  225. open_track_jvc,
  226. close_track_teac,
  227. teac_open_session,
  228. cmd_dummy,
  229. read_session_offset_philips,
  230. teac_fixation,
  231. /* blank_dummy,*/
  232. blank_jvc,
  233. };
  234. LOCAL int
  235. teac_getdisktype(scgp, dp, dsp)
  236. SCSI *scgp;
  237. cdr_t *dp;
  238. dstat_t *dsp;
  239. {
  240. struct scsi_mode_data md;
  241. int count = sizeof(struct scsi_mode_header) +
  242. sizeof(struct scsi_mode_blockdesc);
  243. int len;
  244. int page = 0;
  245. long l;
  246. fillbytes((caddr_t)&md, sizeof(md), '');
  247. (void)test_unit_ready(scgp);
  248. if (mode_sense(scgp, (u_char *)&md, count, page, 0) < 0) { /* Page n current */
  249. return (-1);
  250. } else {
  251. len = ((struct scsi_mode_header *)&md)->sense_data_len + 1;
  252. }
  253. if (((struct scsi_mode_header *)&md)->blockdesc_len < 8)
  254. return (-1);
  255. l = a_to_u_3_byte(md.blockdesc.nlblock);
  256. dsp->ds_maxblocks = l;
  257. return (0);
  258. }
  259. LOCAL int
  260. speed_select_teac(scgp, speedp, dummy)
  261. SCSI *scgp;
  262. int *speedp;
  263. int dummy;
  264. {
  265. struct cdd_52x_mode_data md;
  266. int count;
  267. int status;
  268. int speed = 1;
  269. if (speedp)
  270. speed = *speedp;
  271. fillbytes((caddr_t)&md, sizeof(md), '');
  272. count  = sizeof(struct scsi_mode_header) +
  273. sizeof(struct teac_mode_page_21);
  274. md.pagex.teac_page21.p_code = 0x21;
  275. md.pagex.teac_page21.p_len =  0x01;
  276. md.pagex.teac_page21.dummy = dummy?3:0;
  277. status = mode_select(scgp, (u_char *)&md, count, 0, scgp->inq->data_format >= 2);
  278. if (status < 0)
  279. return (status);
  280. if (speedp == 0)
  281. return (0);
  282. fillbytes((caddr_t)&md, sizeof(md), '');
  283. count  = sizeof(struct scsi_mode_header) +
  284. sizeof(struct teac_mode_page_31);
  285. speed >>= 1;
  286. md.pagex.teac_page31.p_code = 0x31;
  287. md.pagex.teac_page31.p_len =  0x02;
  288. md.pagex.teac_page31.speed = speed;
  289. return (mode_select(scgp, (u_char *)&md, count, 0, scgp->inq->data_format >= 2));
  290. }
  291. LOCAL int
  292. select_secsize_teac(scgp, trackp)
  293. SCSI *scgp;
  294. track_t *trackp;
  295. {
  296. struct scsi_mode_data md;
  297. int count = sizeof(struct scsi_mode_header) +
  298. sizeof(struct scsi_mode_blockdesc);
  299. int len;
  300. int page = 0;
  301. fillbytes((caddr_t)&md, sizeof(md), '');
  302. (void)test_unit_ready(scgp);
  303. if (mode_sense(scgp, (u_char *)&md, count, page, 0) < 0) { /* Page n current */
  304. return (-1);
  305. } else {
  306. len = ((struct scsi_mode_header *)&md)->sense_data_len + 1;
  307. }
  308. if (((struct scsi_mode_header *)&md)->blockdesc_len < 8)
  309. return (-1);
  310. md.header.sense_data_len = 0;
  311. md.header.blockdesc_len = 8;
  312. md.blockdesc.density = 1;
  313. if (trackp->secsize == 2352)
  314. md.blockdesc.density = 4;
  315. i_to_3_byte(md.blockdesc.lblen, trackp->secsize);
  316. return (mode_select(scgp, (u_char *)&md, count, 0, scgp->inq->data_format >= 2));
  317. }
  318. LOCAL int
  319. next_wr_addr_jvc(scgp, track, trackp, ap)
  320. SCSI *scgp;
  321. int track;
  322. track_t *trackp;
  323. long *ap;
  324. {
  325. if (track > 0) {
  326. *ap = lba_addr;
  327. } else {
  328. long nwa;
  329. if (read_B0(scgp, TRUE, &nwa, NULL) < 0)
  330. return (-1);
  331. *ap = nwa + 150;
  332. }
  333. return (0);
  334. }
  335. LOCAL int
  336. write_teac_xg1(scgp, bp, sectaddr, size, blocks, extwr)
  337. SCSI *scgp;
  338. caddr_t bp; /* address of buffer */
  339. long sectaddr; /* disk address (sector) to put */
  340. long size; /* number of bytes to transfer */
  341. int blocks; /* sector count */
  342. BOOL extwr; /* is an extended write */
  343. {
  344. register struct scg_cmd *scmd = scgp->scmd;
  345. fillbytes((caddr_t)scmd, sizeof(*scmd), '');
  346. scmd->addr = bp;
  347. scmd->size = size;
  348. scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY;
  349. /* scmd->flags = SCG_DISRE_ENA;*/
  350. scmd->cdb_len = SC_G1_CDBLEN;
  351. scmd->sense_len = CCS_SENSE_LEN;
  352. scmd->target = scgp->target;
  353. scmd->cdb.g1_cdb.cmd = SC_EWRITE;
  354. scmd->cdb.g1_cdb.lun = scgp->lun;
  355. g1_cdbaddr(&scmd->cdb.g1_cdb, sectaddr);
  356. g1_cdblen(&scmd->cdb.g1_cdb, blocks);
  357. scmd->cdb.g1_cdb.vu_97 = extwr;
  358. scgp->cmdname = "write_teac_g1";
  359. if (scsicmd(scgp) < 0)
  360. return (-1);
  361. return (size - scsigetresid(scgp));
  362. }
  363. LOCAL int
  364. cdr_write_teac(scgp, bp, sectaddr, size, blocks, islast)
  365. SCSI *scgp;
  366. caddr_t bp; /* address of buffer */
  367. long sectaddr; /* disk address (sector) to put */
  368. long size; /* number of bytes to transfer */
  369. int blocks; /* sector count */
  370. BOOL islast; /* last write for track */
  371. {
  372. int ret;
  373. if (islast)
  374. last_done = TRUE;
  375. ret = write_teac_xg1(scgp, bp, sectaddr, size, blocks, !islast);
  376. if (ret < 0)
  377. return (ret);
  378. lba_addr = sectaddr + blocks;
  379. #ifdef XXBUFFER
  380. check_buffer_teac(scgp);
  381. #endif
  382. return (ret);
  383. }
  384. LOCAL int
  385. open_track_jvc(scgp, dp, track, trackp)
  386. SCSI *scgp;
  387. cdr_t *dp;
  388. int track;
  389. track_t *trackp;
  390. {
  391. int status;
  392. long blocks;
  393. long pregapsize;
  394. struct pgm_subcode sc;
  395. last_done = FALSE;
  396. if (select_secsize_teac(scgp, trackp) < 0)
  397. return (-1);
  398. status = clear_subcode(scgp);
  399. /*next_wr_addr_teac(scgp);*/
  400. if (status < 0)
  401. return (status);
  402. if (trackp->pregapsize != 0) {
  403. if (lverbose > 1) {
  404. printf("set_limits(%ld, %ld)-> %ldn",
  405. lba_addr, trackp->pregapsize, lba_addr + trackp->pregapsize);
  406. }
  407. status = set_limits(scgp, lba_addr, trackp->pregapsize);
  408. if (status < 0)
  409. return (status);
  410. /*
  411.  * Set pre-gap (pause - index 0)
  412.  */
  413. set_pgm_subcode(&sc, SC_P,
  414. st2mode[trackp->sectype&ST_MASK], ADR_POS, track, 0);
  415. if (lverbose > 1)
  416. scsiprbytes("Subcode:", (u_char *)&sc, sizeof(sc));
  417. status = set_subcode(scgp, (u_char *)&sc, sizeof(sc));
  418. if (status < 0)
  419. return (status);
  420. pregapsize = trackp->pregapsize;
  421. if (!is_audio(trackp)) {
  422. lba_addr += 5; /* link & run in blocks */
  423. pregapsize -= 5;
  424. }
  425. if (lverbose > 1) {
  426. printf("pad_track(%ld, %ld)-> %ldn",
  427. lba_addr, pregapsize, lba_addr + pregapsize);
  428. }
  429. if (pad_track(scgp, dp, track, trackp,
  430. lba_addr, pregapsize*trackp->secsize,
  431. FALSE, (long *)0) < 0)
  432. return (-1);
  433. }
  434. blocks = trackp->tracksize/trackp->secsize +
  435.  (trackp->tracksize%trackp->secsize?1:0);
  436. blocks += trackp->padsize/trackp->secsize +
  437.  (trackp->padsize%trackp->secsize?1:0);
  438. if (blocks < 300)
  439. blocks = 300;
  440. if (!is_audio(trackp))
  441. blocks += 2;
  442. if (!is_last(trackp) && trackp[1].pregapsize == 0)
  443. blocks -= 150;
  444. /*
  445.  * set the limits for the new subcode - seems to apply to all
  446.  * of the data track.
  447.  * Unknown tracksize is handled in open_session.
  448.  * We definitely need to know the tracksize in this driver.
  449.  */
  450. if (lverbose > 1) {
  451. printf("set_limits(%ld, %ld)-> %ldn",
  452. lba_addr, blocks, lba_addr + blocks);
  453. }
  454. status = set_limits(scgp, lba_addr, blocks);
  455. if (status < 0)
  456. return (status);
  457. /*
  458.  * Set track start (index 1)
  459.  */
  460. set_pgm_subcode(&sc, SC_TR,
  461. st2mode[trackp->sectype&ST_MASK], ADR_POS, track, 1);
  462. if (lverbose > 1)
  463. scsiprbytes("Subcode:", (u_char *)&sc, sizeof(sc));
  464. status = set_subcode(scgp, (u_char *)&sc, sizeof(sc));
  465. if (status < 0)
  466. return (status);
  467. if (!is_last(trackp) && trackp[1].pregapsize == 0) {
  468. blocks += lba_addr;
  469. pregapsize = 150;
  470. if (lverbose > 1) {
  471. printf("set_limits(%ld, %ld)-> %ldn",
  472. blocks, pregapsize, blocks + pregapsize);
  473. }
  474. status = set_limits(scgp, blocks, pregapsize);
  475. if (status < 0)
  476. return (status);
  477. /*
  478.  * Set pre-gap (pause - index 0)
  479.  */
  480. track++;
  481. trackp++;
  482. set_pgm_subcode(&sc, SC_P,
  483. st2mode[trackp->sectype&ST_MASK], ADR_POS, track, 0);
  484. if (lverbose > 1)
  485. scsiprbytes("Subcode:", (u_char *)&sc, sizeof(sc));
  486. status = set_subcode(scgp, (u_char *)&sc, sizeof(sc));
  487. if (status < 0)
  488. return (status);
  489. }
  490. return (status);
  491. }
  492. LOCAL char sector[3000];
  493. LOCAL int
  494. close_track_teac(scgp, track, trackp)
  495. SCSI *scgp;
  496. int track;
  497. track_t *trackp;
  498. {
  499. int ret = 0;
  500. if (!last_done) {
  501. printf("WARNING: adding dummy block to close track.n");
  502. /*
  503.  * need read sector size
  504.  * XXX do we really need this ?
  505.  * XXX if we need this can we set blocks to 0 ?
  506.  */
  507. ret =  write_teac_xg1(scgp, sector, lba_addr, 2352, 1, FALSE);
  508. lba_addr++;
  509. }
  510. if (!is_audio(trackp))
  511. lba_addr += 2;
  512. teac_wr_pma(scgp);
  513. return (ret);
  514. }
  515. static const char *sd_teac50_error_str[] = {
  516. "100200diagnostic failure on component parts", /* 40 80 */
  517. "100201diagnostic failure on memories", /* 40 81 */
  518. "100202diagnostic failure on cd-rom ecc circuit", /* 40 82 */
  519. "100203diagnostic failure on gate array", /* 40 83 */
  520. "100204diagnostic failure on internal SCSI controller", /* 40 84 */
  521. "100205diagnostic failure on servo processor", /* 40 85 */
  522. "100206diagnostic failure on program rom", /* 40 86 */
  523. "100220thermal sensor failure", /* 40 90 */
  524. "20000controller prom error", /* 80 00 */ /* JVC */
  525. "20100no disk present - couldn't get focus", /* 81 00 */ /* JVC */
  526. "20200no cartridge present", /* 82 00 */ /* JVC */
  527. "20300unable to spin up", /* 83 00 */ /* JVC */
  528. "20400addr exceeded the last valid block addr", /* 84 00 */ /* JVC */
  529. "20500sync error", /* 85 00 */ /* JVC */
  530. "20600address can't find or not data track", /* 86 00 */ /* JVC */
  531. "20700missing track", /* 87 00 */ /* JVC */
  532. "21300cartridge could not be ejected", /* 8B 00 */ /* JVC */
  533. "21500audio not playing", /* 8D 00 */ /* JVC */
  534. "21600read toc error", /* 8E 00 */ /* JVC */
  535. "21700a blank disk is detected by read toc", /* 8F 00 */
  536. "22000pma less disk - not a recordable disk", /* 90 00 */
  537. "22300mount error", /* 93 00 */ /* JVC */
  538. "22400toc less disk", /* 94 00 */
  539. "22500disc information less disk", /* 95 00 */ /* JVC */
  540. "22600disc information read error", /* 96 00 */ /* JVC */
  541. "22700linear velocity measurement error", /* 97 00 */ /* JVC */
  542. "23000drive sequence stop", /* 98 00 */ /* JVC */
  543. "23100actuator velocity control error", /* 99 00 */ /* JVC */
  544. "23200slider velocity control error", /* 9A 00 */ /* JVC */
  545. "23300opc initialize error", /* 9B 00 */
  546. "23301power calibration not executed", /* 9B 01 */
  547. "23400opc execution eror", /* 9C 00 */
  548. "23401alpc error - opc execution", /* 9C 01 */
  549. "23402opc execution timeout", /* 9C 02 */
  550. "24500disk application code does not match host application code", /* A5 00 */
  551. "25500completed preview write", /* AD 00 */
  552. "25600invalid B0 value", /* AE 00 */ /* JVC */
  553. "25700pca area full", /* AF 00 */
  554. "26000efm isn't detected", /* B0 00 */ /* JVC */
  555. "26300no logical sector", /* B3 00 */ /* JVC */
  556. "26400full pma area", /* B4 00 */
  557. "26500read address is atip area - blank", /* B5 00 */
  558. "26600write address is efm area - aleady written", /* B6 00 */
  559. "27100abnormal spinning - servo irq", /* B9 00 */ /* JVC */
  560. "27200no write data - buffer empty", /* BA 00 */
  561. "27300write emergency occurred", /* BB 00 */
  562. "27400read timeout", /* BC 00 */ /* JVC */
  563. "27700abnormal spin - nmi", /* BF 00 */ /* JVC */
  564. "301004th run-in block detected", /* C1 00 */
  565. "302003rd run-in block detected", /* C2 00 */
  566. "303002nd run-in block detected", /* C3 00 */
  567. "304001st run-in block detected", /* C4 00 */
  568. "30500link block detected", /* C5 00 */
  569. "306001st run-out block detected", /* C6 00 */
  570. "307002nd run-out block detected", /* C7 00 */
  571. "31400write request means mixed data mode", /* CC 00 */
  572. "31500unable to ensure reliable writing with the inserted disk - unsupported disk", /* CD 00 */
  573. "31600unable to ensure reliable writing as the inserted disk does not support speed",/* CE 00 */
  574. "31700unable to ensure reliable writing as the inserted disk has no char id code", /* CF 00 */
  575. NULL
  576. };
  577. LOCAL int
  578. teac_attach(scgp, dp)
  579. SCSI *scgp;
  580. cdr_t *dp;
  581. {
  582. scsi_setnonstderrs(scgp, sd_teac50_error_str);
  583. #ifdef XXDEBUG
  584. xxtest_teac(scgp);
  585. exit(0);
  586. #endif
  587. return (0);
  588. }
  589. LOCAL int
  590. teac_fixation(scgp, onp, dummy, toctype, tracks, trackp)
  591. SCSI *scgp;
  592. int onp;
  593. int dummy;
  594. int toctype;
  595. int tracks;
  596. track_t *trackp;
  597. {
  598. long lba;
  599. int status;
  600. u_char *sp;
  601. int i;
  602. extern char *buf;
  603. if (tracks < 1) {
  604. /*
  605.  * We come here if cdrecord isonly called with the -fix option.
  606.  * As long as we cannot read and interpret the PMA, we must
  607.  * abort here.
  608.  */
  609. teac_rd_pma(scgp);
  610. /* errmsgno(EX_BAD, "Cannot fixate zero track disk.n");;*/
  611. errmsgno(EX_BAD, "Cannot fixate without track list (not yet implemented).n");;
  612. return (-1);
  613. }
  614. sp = (u_char *)buf;
  615. sleep(1);
  616. status = clear_subcode(scgp);
  617. sleep(1);
  618. if (status < 0)
  619. return (status);
  620. sp[0] = 0; /* reserved */
  621. sp[1] = 0; /* reserved */
  622. sp[2] = 0; /* Q TNO */
  623. sp = &sp[3]; /* point past header */
  624. /*
  625.  * Set up TOC entries for all tracks
  626.  */
  627. for(i=1; i <= tracks; i++) {
  628. lba = trackp[i].trackstart+150; /* MSF=00:02:00 is LBA=0 */
  629. sp = set_toc_subcode(sp,
  630. /* ctrl/adr for this track */
  631. st2mode[trackp[i].sectype&ST_MASK], ADR_POS,
  632. trackp[i].trackno, lba);
  633. }
  634. /*
  635.  * Set first track on disk
  636.  *
  637.  * XXX We set the track type for the lead-in to the track type
  638.  * XXX of the first track. The TEAC manual states that we should use
  639.  * XXX audio if the disk contains both, audio and data tracks.
  640.  */
  641. sp = set_lin_subcode(sp,
  642. /* ctrl/adr for first track */
  643. st2mode[trackp[1].sectype&ST_MASK], ADR_POS,
  644. 0xA0, /* Point A0 */
  645. trackp[1].trackno, /* first track # */
  646. toc2sess[toctype & TOC_MASK], /* disk type */
  647. 0); /* reserved */
  648. /*
  649.  * Set last track on disk
  650.  */
  651. sp = set_lin_subcode(sp,
  652. /* ctrl/adr for first track */
  653. st2mode[trackp[1].sectype&ST_MASK], ADR_POS,
  654. 0xA1, /* Point A1 */
  655. MSF_CONV(trackp[tracks].trackno),/* last track # */
  656. 0, /* reserved */
  657. 0); /* reserved */
  658. /*
  659.  * Set start of lead out area in MSF
  660.  * MSF=00:02:00 is LBA=0
  661.  */
  662. lba = lba_addr + 150;
  663. if (lverbose > 1)
  664. printf("lba: %ld lba_addr: %ldn", lba, lba_addr);
  665. if (lverbose > 1)
  666. printf("Lead out start: (%02d:%02d/%02d)n",
  667. minutes(lba*2352),
  668. seconds(lba*2352),
  669. frames(lba*2352));
  670. sp = set_lin_subcode(sp,
  671. /* ctrl/adr for first track */
  672. st2mode[trackp[1].sectype&ST_MASK], ADR_POS,
  673. 0xA2, /* Point A2 */
  674. MSF_CONV(LBA_MIN(lba)),
  675. MSF_CONV(LBA_SEC(lba)),
  676. MSF_CONV(LBA_FRM(lba)));
  677. status = sp - ((u_char *)buf);
  678. if (lverbose > 1) {
  679. printf("Subcode len: %dn", status);
  680. scsiprbytes("Subcode:", (u_char *)buf, status);
  681. }
  682. status = set_subcode(scgp, (u_char *)buf, status);
  683. sleep(1);
  684. if (status < 0)
  685. return (status);
  686. /*
  687.  * now write the toc
  688.  */
  689. status = teac_freeze(scgp, !onp);
  690. return (status);
  691. }
  692. LOCAL int
  693. teac_open_session(scgp, tracks, trackp, toctype, multi)
  694. SCSI *scgp;
  695. int tracks;
  696. track_t *trackp;
  697. int toctype;
  698. int multi;
  699. {
  700. int i;
  701. for (i = 1; i <= tracks; i++) {
  702. if (trackp[i].tracksize < 0) {
  703. /*
  704.  * XXX How about setting the subcode range to infinity.
  705.  * XXX and correct it in clode track before writing
  706.  * XXX the PMA?
  707.  */
  708. errmsgno(EX_BAD, "Track %d has unknown length.n", i);
  709. return (-1);
  710. }
  711. }
  712. return (teac_calibrate(scgp, toctype, multi));
  713. }
  714. LOCAL int
  715. teac_calibrate(scgp, toctype, multi)
  716. SCSI *scgp;
  717. int toctype;
  718. int multi;
  719. {
  720. int status;
  721. scgp->silent++;
  722. if (read_B0(scgp, TRUE, &lba_addr, NULL) < 0)
  723. lba_addr = -150;
  724. scgp->silent--;
  725. status = clear_subcode(scgp);
  726. if (status < 0)
  727. return (status);
  728. if (lverbose) {
  729. fprintf(stdout, "Judging disk...");
  730. flush();
  731. }
  732. status = opt_power_judge(scgp, 1);
  733. if (status < 0) {
  734. printf("n");
  735. return (status);
  736. }
  737. if (lverbose) {
  738. fprintf(stdout, "done.nCalibrating laser...");
  739. flush();
  740. }
  741. status = opt_power_judge(scgp, 0);
  742. if (lverbose) {
  743. fprintf(stdout, "done.n");
  744. }
  745. scgp->silent++;
  746. if (next_wr_addr_teac(scgp, -1, -1) < 0) {
  747. if (scgp->verbose == 0 && scsi_sense_key(scgp) != SC_ILLEGAL_REQUEST)
  748. scsiprinterr(scgp);
  749. }
  750. scgp->silent--;
  751. return (status);
  752. }
  753. /*--------------------------------------------------------------------------*/
  754. #define SC_SET_LIMITS 0xb3 /* teac 12 byte command */
  755. #define SC_SET_SUBCODE 0xc2 /* teac 10 byte command */
  756. #define SC_READ_PMA 0xc4 /* teac 10 byte command */
  757. #define SC_READ_DISK_INFO 0xc7 /* teac 10 byte command */
  758. #define SC_BUFFER_INQUIRY 0xe0 /* teac 12 byte command */
  759. #define SC_WRITE_PMA 0xe1 /* teac 12 byte command */
  760. #define SC_FREEZE 0xe3 /* teac 12 byte command */
  761. #define SC_OPC_EXECUTE 0xec /* teac 12 byte command */
  762. #define SC_CLEAR_SUBCODE 0xe4 /* teac 12 byte command */
  763. #define SC_NEXT_WR_ADDRESS 0xe6 /* teac 12 byte command */
  764. #define SC_READ_PEAK_BUF_CAP 0xef /* teac 12 byte command */
  765. /* -----------------------------------------------------------------
  766.  * Optimum power calibration for Teac Drives.
  767. ----------------------------------------------------------------- */
  768. LOCAL int
  769. opt_power_judge(scgp, judge)
  770. SCSI *scgp;
  771. int judge;
  772. {
  773. register struct scg_cmd *scmd = scgp->scmd;
  774. fillbytes((caddr_t)scmd, sizeof(*scmd), '');
  775. scmd->addr = (caddr_t)0;
  776. scmd->size = 0;
  777. scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
  778. scmd->cdb_len = SC_G5_CDBLEN;
  779. scmd->sense_len = CCS_SENSE_LEN;
  780. scmd->target = scgp->target;
  781. scmd->timeout = 60;
  782. scmd->cdb.g5_cdb.cmd = SC_OPC_EXECUTE;
  783. scmd->cdb.g5_cdb.lun = scgp->lun;
  784. scmd->cdb.g5_cdb.reladr = judge; /* Judge the Disc */
  785. scgp->cmdname = "opt_power_judge";
  786. return (scsicmd(scgp));
  787. }
  788. /* -----------------------------------------------------------------
  789.  * Clear subcodes for Teac Drives.
  790. ----------------------------------------------------------------- */
  791. LOCAL int
  792. clear_subcode(scgp)
  793. SCSI *scgp;
  794. {
  795. register struct scg_cmd *scmd = scgp->scmd;
  796. fillbytes((caddr_t)scmd, sizeof(*scmd), '');
  797. scmd->addr = (caddr_t)0;
  798. scmd->size = 0;
  799. scmd->flags = SCG_DISRE_ENA;
  800. scmd->cdb_len = SC_G5_CDBLEN;
  801. scmd->sense_len = CCS_SENSE_LEN;
  802. scmd->target = scgp->target;
  803. scmd->cdb.g5_cdb.cmd = SC_CLEAR_SUBCODE;
  804. scmd->cdb.g5_cdb.lun = scgp->lun;
  805. scmd->cdb.g5_cdb.addr[3] = 0x80;
  806. scgp->cmdname = "clear subcode";
  807. return (scsicmd(scgp));
  808. }
  809. /* -----------------------------------------------------------------
  810.  * Set limits for command linking for Teac Drives.
  811. ----------------------------------------------------------------- */
  812. LOCAL int
  813. set_limits(scgp, lba, length)
  814. SCSI *scgp;
  815. long lba;
  816. long length;
  817. {
  818. register struct scg_cmd *scmd = scgp->scmd;
  819. fillbytes((caddr_t)scmd, sizeof(*scmd), '');
  820. scmd->addr = (caddr_t)0;
  821. scmd->size = 0;
  822. scmd->flags = SCG_DISRE_ENA;
  823. scmd->cdb_len = SC_G5_CDBLEN;
  824. scmd->sense_len = CCS_SENSE_LEN;
  825. scmd->target = scgp->target;
  826. scmd->cdb.g5_cdb.cmd = SC_SET_LIMITS;
  827. scmd->cdb.g5_cdb.lun = scgp->lun;
  828. i_to_4_byte(&scmd->cdb.g5_cdb.addr[0], lba);
  829. i_to_4_byte(&scmd->cdb.g5_cdb.count[0], length);
  830. scgp->cmdname = "set limits";
  831. return (scsicmd(scgp));
  832. }
  833. /* -----------------------------------------------------------------
  834.  * Set subcode for Teac Drives.
  835. ----------------------------------------------------------------- */
  836. LOCAL int
  837. set_subcode(scgp, subcode_data, length)
  838. SCSI *scgp;
  839. u_char *subcode_data;
  840. int length;
  841. {
  842. register struct scg_cmd *scmd = scgp->scmd;
  843. fillbytes((caddr_t)scmd, sizeof(*scmd), '');
  844. scmd->addr = (caddr_t)subcode_data;
  845. scmd->size = length;
  846. scmd->flags = SCG_DISRE_ENA;
  847. scmd->cdb_len = SC_G1_CDBLEN;
  848. scmd->sense_len = CCS_SENSE_LEN;
  849. scmd->target = scgp->target;
  850. scmd->cdb.g1_cdb.cmd = SC_SET_SUBCODE;
  851. scmd->cdb.g1_cdb.lun = scgp->lun;
  852. g1_cdblen(&scmd->cdb.g1_cdb, length);
  853. scgp->cmdname = "set subcode";
  854. return (scsicmd(scgp));
  855. }
  856. LOCAL int
  857. read_disk_info_teac(scgp, data, length, type)
  858. SCSI *scgp;
  859. u_char *data;
  860. int length;
  861. int type;
  862. {
  863. register struct scg_cmd *scmd = scgp->scmd;
  864. fillbytes((caddr_t)scmd, sizeof(*scmd), '');
  865. scmd->addr = (caddr_t)data;
  866. scmd->size = length;
  867. scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
  868. scmd->cdb_len = SC_G1_CDBLEN;
  869. scmd->sense_len = CCS_SENSE_LEN;
  870. scmd->target = scgp->target;
  871. scmd->cdb.g1_cdb.cmd = SC_READ_DISK_INFO;
  872. scmd->cdb.g1_cdb.lun = scgp->lun;
  873. scmd->cdb.g1_cdb.reladr = type & 1;
  874. scmd->cdb.g1_cdb.res    = (type & 2) >> 1;
  875. scgp->cmdname = "read disk info teac";
  876. return (scsicmd(scgp));
  877. }
  878. /* -----------------------------------------------------------------
  879.  * Perform the freeze command for Teac Drives.
  880. ----------------------------------------------------------------- */
  881. LOCAL int
  882. teac_freeze(scgp, bp_flag)
  883. SCSI *scgp;
  884. int bp_flag;
  885. {
  886. register struct scg_cmd *scmd = scgp->scmd;
  887. fillbytes((caddr_t)scmd, sizeof(*scmd), '');
  888. scmd->addr = (caddr_t)0;
  889. scmd->size = 0;
  890. scmd->flags = SCG_DISRE_ENA;
  891. scmd->cdb_len = SC_G5_CDBLEN;
  892. scmd->sense_len = CCS_SENSE_LEN;
  893. scmd->target = scgp->target;
  894. scmd->timeout = 8 * 60; /* Needs up to 4 minutes */
  895. scmd->cdb.g5_cdb.cmd = SC_FREEZE;
  896. scmd->cdb.g5_cdb.lun = scgp->lun;
  897. scmd->cdb.g5_cdb.addr[3] = bp_flag ? 0x80 : 0;
  898. scgp->cmdname = "teac_freeze";
  899. return (scsicmd(scgp));
  900. }
  901. LOCAL int
  902. teac_wr_pma(scgp)
  903. SCSI *scgp;
  904. {
  905. register struct scg_cmd *scmd = scgp->scmd;
  906. fillbytes((caddr_t)scmd, sizeof(*scmd), '');
  907. scmd->addr = (caddr_t)0;
  908. scmd->size = 0;
  909. scmd->flags = SCG_DISRE_ENA;
  910. scmd->cdb_len = SC_G5_CDBLEN;
  911. scmd->sense_len = CCS_SENSE_LEN;
  912. scmd->target = scgp->target;
  913. scmd->cdb.g5_cdb.cmd = SC_WRITE_PMA;
  914. scmd->cdb.g5_cdb.lun = scgp->lun;
  915. scgp->cmdname = "teac_write_pma";
  916. return (scsicmd(scgp));
  917. }
  918. /* -----------------------------------------------------------------
  919.  * Read PMA for Teac Drives.
  920. ----------------------------------------------------------------- */
  921. LOCAL int
  922. teac_rd_pma(scgp)
  923. SCSI *scgp;
  924. {
  925. unsigned char xx[256];
  926. register struct scg_cmd *scmd = scgp->scmd;
  927. fillbytes((caddr_t)xx, sizeof(xx), '');
  928. fillbytes((caddr_t)scmd, sizeof(*scmd), '');
  929. scmd->addr = (caddr_t)xx;
  930. scmd->size = sizeof(xx);
  931. scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
  932. scmd->cdb_len = SC_G1_CDBLEN;
  933. scmd->sense_len = CCS_SENSE_LEN;
  934. scmd->target = scgp->target;
  935. scmd->cdb.g1_cdb.cmd = SC_READ_PMA;
  936. scmd->cdb.g1_cdb.lun = scgp->lun;
  937. g1_cdblen(&scmd->cdb.g1_cdb, sizeof(xx));
  938. scgp->cmdname = "teac_read_pma";
  939. /* return (scsicmd(scgp));*/
  940. if (scsicmd(scgp) < 0)
  941. return (-1);
  942. if (scgp->verbose) {
  943. scsiprbytes("PMA Data", xx, sizeof(xx) - scsigetresid(scgp));
  944. }
  945. if (lverbose) {
  946. unsigned i;
  947. Uchar *p;
  948. scsiprbytes("PMA Header: ", xx, 4);
  949. i = xx[2];
  950. p = &xx[4];
  951. for (; i <= xx[3]; i++) {
  952. scsiprbytes("PMA: ", p, 10);
  953. p += 10;
  954. }
  955. }
  956. return (0);
  957. }
  958. /* -----------------------------------------------------------------
  959.  * Next writable address for Teac Drives.
  960. ----------------------------------------------------------------- */
  961. LOCAL int
  962. next_wr_addr_teac(scgp, start_lba, last_lba)
  963. SCSI *scgp;
  964. long start_lba;
  965. long last_lba;
  966. {
  967. unsigned char xx[256];
  968. register struct scg_cmd *scmd = scgp->scmd;
  969. fillbytes((caddr_t)xx, sizeof(xx), '');
  970. fillbytes((caddr_t)scmd, sizeof(*scmd), '');
  971. scmd->addr = (caddr_t)xx;
  972. scmd->size = sizeof(xx);
  973. scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
  974. scmd->cdb_len = SC_G5_CDBLEN;
  975. scmd->sense_len = CCS_SENSE_LEN;
  976. scmd->target = scgp->target;
  977. scmd->cdb.g5_cdb.cmd = SC_NEXT_WR_ADDRESS;
  978. scmd->cdb.g5_cdb.lun = scgp->lun;
  979. i_to_4_byte(&scmd->cdb.g5_cdb.addr[0], start_lba);
  980. i_to_4_byte(&scmd->cdb.g5_cdb.count[0], last_lba);
  981. if (scgp->verbose)
  982. printf("start lba: %ld last lba: %ldn",
  983. start_lba, last_lba);
  984. scgp->cmdname = "next writable address";
  985. /* return (scsicmd(scgp));*/
  986. if (scsicmd(scgp) < 0)
  987. return (-1);
  988. if (scgp->verbose) {
  989. scsiprbytes("WRa Data", xx, sizeof(xx) - scsigetresid(scgp));
  990. printf("NWA: %ldn", a_to_4_byte(xx));
  991. }
  992. return (0);
  993. }
  994. LOCAL int
  995. blank_jvc(scgp, addr, blanktype)
  996. SCSI *scgp;
  997. long addr;
  998. int blanktype;
  999. {
  1000. extern char *blank_types[];
  1001. if (lverbose) {
  1002. printf("Blanking %sn", blank_types[blanktype & 0x07]);
  1003. flush();
  1004. }
  1005. return (scsi_blank(scgp, addr, blanktype));
  1006. }
  1007. LOCAL int
  1008. buf_cap_teac(scgp, sp, fp)
  1009. SCSI *scgp;
  1010. long *sp; /* Size pointer */
  1011. long *fp; /* Free pointer */
  1012. {
  1013. Ulong freespace;
  1014. Ulong bufsize;
  1015. long ret;
  1016. int per;
  1017. ret = read_peak_buffer_cap_teac(scgp);
  1018. if (ret < 0)
  1019. return (-1);
  1020. bufsize = ret;
  1021. freespace = 0;
  1022. if (sp)
  1023. *sp = bufsize;
  1024. if (fp)
  1025. *fp = freespace;
  1026. if (scgp->verbose || (sp == 0 && fp == 0))
  1027. printf("BFree: %ld K BSize: %ld Kn", freespace >> 10, bufsize >> 10);
  1028. if (bufsize == 0)
  1029. return (0);
  1030. per = (100 * (bufsize - freespace)) / bufsize;
  1031. if (per < 0)
  1032. return (0);
  1033. if (per > 100)
  1034. return (100);
  1035. return (per);
  1036. }
  1037. LOCAL long
  1038. read_peak_buffer_cap_teac(scgp)
  1039. SCSI *scgp;
  1040. {
  1041. Uchar xx[4];
  1042. register struct scg_cmd *scmd = scgp->scmd;
  1043. fillbytes((caddr_t)xx, sizeof(xx), '');
  1044. fillbytes((caddr_t)scmd, sizeof(*scmd), '');
  1045. scmd->addr = (caddr_t)xx;
  1046. scmd->size = sizeof(xx);
  1047. scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
  1048. scmd->cdb_len = SC_G5_CDBLEN;
  1049. scmd->sense_len = CCS_SENSE_LEN;
  1050. scmd->target = scgp->target;
  1051. scmd->cdb.g5_cdb.cmd = SC_READ_PEAK_BUF_CAP;
  1052. scmd->cdb.g5_cdb.lun = scgp->lun;
  1053. scgp->cmdname = "read peak buffer capacity";
  1054. #define BDEBUG
  1055. #ifndef BDEBUG
  1056. return (scsicmd(scgp));
  1057. #else
  1058. if (scsicmd(scgp) < 0)
  1059. return (-1);
  1060. /* if (scgp->verbose) {*/
  1061. scsiprbytes("WRa Data", xx, sizeof(xx) - scsigetresid(scgp));
  1062. printf("Buffer cap: %ldn", a_to_u_3_byte(&xx[1]));
  1063. /* }*/
  1064. return (a_to_u_3_byte(&xx[1]));
  1065. /* return (0);*/
  1066. #endif
  1067. }
  1068. #define BI_ONE_BYTE 0xC0
  1069. #define BI_448_BYTE 0x40
  1070. #define BI_APP_CODE 0x10
  1071. LOCAL int
  1072. buffer_inquiry_teac(scgp, fmt)
  1073. SCSI *scgp;
  1074. int fmt;
  1075. {
  1076. Uchar xx[448];
  1077. register struct scg_cmd *scmd = scgp->scmd;
  1078. fillbytes((caddr_t)xx, sizeof(xx), '');
  1079. fillbytes((caddr_t)scmd, sizeof(*scmd), '');
  1080. scmd->addr = (caddr_t)xx;
  1081. scmd->size = sizeof(xx);
  1082. scmd->size = 448;
  1083. scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
  1084. scmd->cdb_len = SC_G5_CDBLEN;
  1085. scmd->sense_len = CCS_SENSE_LEN;
  1086. scmd->target = scgp->target;
  1087. scmd->cdb.g5_cdb.cmd = SC_BUFFER_INQUIRY;
  1088. scmd->cdb.g5_cdb.lun = scgp->lun;
  1089. if (fmt > 0) {
  1090. scmd->cdb.g5_cdb.addr[3] = fmt;
  1091. if (fmt == BI_ONE_BYTE)
  1092. scmd->size = 1;
  1093. } else {
  1094. scmd->cdb.g5_cdb.addr[3] = BI_448_BYTE;
  1095. /* scmd->cdb.g5_cdb.addr[3] = BI_APP_CODE;*/
  1096. }
  1097. scgp->cmdname = "buffer inquiry";
  1098. #define BDEBUG
  1099. #ifndef BDEBUG
  1100. return (scsicmd(scgp));
  1101. #else
  1102. if (scsicmd(scgp) < 0)
  1103. return (-1);
  1104. /* if (scgp->verbose) {*/
  1105. /* scsiprbytes("WRa Data", xx, sizeof(xx) - scsigetresid(scgp));*/
  1106. /* scsiprbytes("WRa Data", xx, 1);*/
  1107. if (fmt > 0) printf("fmt: %X ", fmt);
  1108. scsiprbytes("WRa Data", xx, 9);
  1109. printf("%dn", xx[8] - xx[1]);
  1110. /* printf("Buffer cap: %ldn", a_to_u_3_byte(&xx[1]));*/
  1111. /* }*/
  1112. return (0);
  1113. #endif
  1114. }
  1115. #ifdef XXBUFFER
  1116. LOCAL void
  1117. check_buffer_teac(scgp)
  1118. SCSI *scgp;
  1119. {
  1120. printf("-------n");
  1121. buffer_inquiry_teac(scgp, 0);
  1122. #ifdef SL
  1123. usleep(40000);
  1124. buffer_inquiry_teac(scgp, 0);
  1125. #endif
  1126. read_peak_buffer_cap_teac(scgp);
  1127. }
  1128. #endif
  1129. /*--------------------------------------------------------------------------*/
  1130. #ifdef XXDEBUG
  1131. #include "scsimmc.h"
  1132. LOCAL int g7_teac __PR((SCSI *scgp));
  1133. LOCAL int g6_teac __PR((SCSI *scgp));
  1134. LOCAL int
  1135. g7_teac(scgp)
  1136. SCSI *scgp;
  1137. {
  1138. Uchar xx[2048];
  1139. register struct scg_cmd *scmd = scgp->scmd;
  1140. fillbytes((caddr_t)xx, sizeof(xx), '');
  1141. fillbytes((caddr_t)scmd, sizeof(*scmd), '');
  1142. scmd->addr = (caddr_t)xx;
  1143. scmd->size = sizeof(xx);
  1144. scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
  1145. scmd->cdb_len = SC_G5_CDBLEN;
  1146. scmd->sense_len = CCS_SENSE_LEN;
  1147. scmd->target = scgp->target;
  1148. scmd->cdb.g5_cdb.cmd = 0xDf;
  1149. /* scmd->cdb.g5_cdb.cmd = 0xE5;*/
  1150. scmd->cdb.g5_cdb.lun = scgp->lun;
  1151. /* scmd->cdb.g5_cdb.addr[3] = BI_ONE_BYTE;*/
  1152. /* scmd->size = 1;*/
  1153. /* scmd->cdb.g5_cdb.addr[3] = BI_448_BYTE;*/
  1154. /* scmd->cdb.g5_cdb.addr[3] = BI_APP_CODE;*/
  1155. scgp->cmdname = "g7 teac";
  1156. /* return (scsicmd(scgp));*/
  1157. if (scsicmd(scgp) < 0)
  1158. return (-1);
  1159. /* if (scgp->verbose) {*/
  1160. scsiprbytes("WRa Data", xx, sizeof(xx) - scsigetresid(scgp));
  1161. /* scsiprbytes("WRa Data", xx, 1);*/
  1162. /* scsiprbytes("WRa Data", xx, 9);*/
  1163. /*printf("%dn", xx[8] - xx[1]);*/
  1164. /* printf("Buffer cap: %ldn", a_to_u_3_byte(&xx[1]));*/
  1165. /* }*/
  1166. return (0);
  1167. }
  1168. LOCAL int
  1169. g6_teac(scgp)
  1170. SCSI *scgp;
  1171. {
  1172. Uchar xx[2048];
  1173. register struct scg_cmd *scmd = scgp->scmd;
  1174. fillbytes((caddr_t)xx, sizeof(xx), '');
  1175. fillbytes((caddr_t)scmd, sizeof(*scmd), '');
  1176. scmd->addr = (caddr_t)xx;
  1177. scmd->size = sizeof(xx);
  1178. scmd->flags = SCG_RECV_DATA |SCG_DISRE_ENA;
  1179. scmd->cdb_len = SC_G1_CDBLEN;
  1180. scmd->sense_len = CCS_SENSE_LEN;
  1181. scmd->target = scgp->target;
  1182. scmd->cdb.g1_cdb.cmd = 0xC1;
  1183. scmd->cdb.g1_cdb.cmd = 0xC3;
  1184. scmd->cdb.g1_cdb.cmd = 0xC6;
  1185. scmd->cdb.g1_cdb.cmd = 0xC7; /* Read TOC */
  1186. scmd->cdb.g1_cdb.cmd = 0xCe;
  1187. scmd->cdb.g1_cdb.cmd = 0xCF;
  1188. scmd->cdb.g1_cdb.cmd = 0xC7; /* Read TOC */
  1189. scmd->cdb.g1_cdb.lun = scgp->lun;
  1190. scgp->cmdname = "g6 teac";
  1191. /* return (scsicmd(scgp));*/
  1192. if (scsicmd(scgp) < 0)
  1193. return (-1);
  1194. /* if (scgp->verbose) {*/
  1195. scsiprbytes("WRa Data", xx, sizeof(xx) - scsigetresid(scgp));
  1196. /* scsiprbytes("WRa Data", xx, 1);*/
  1197. /* scsiprbytes("WRa Data", xx, 9);*/
  1198. /*printf("%dn", xx[8] - xx[1]);*/
  1199. /* printf("Buffer cap: %ldn", a_to_u_3_byte(&xx[1]));*/
  1200. /* }*/
  1201. return (0);
  1202. }
  1203. LOCAL void
  1204. xxtest_teac(scgp)
  1205. SCSI *scgp;
  1206. {
  1207. read_peak_buffer_cap_teac(scgp);
  1208. /*#define XDI*/
  1209. #ifdef XDI
  1210. {
  1211. u_char cbuf[512];
  1212. /* read_disk_info_teac(scgp, data, length, type)*/
  1213. /* read_disk_info_teac(scgp, cbuf, 512, 2);*/
  1214. /* read_disk_info_teac(scgp, cbuf, 512, 2);*/
  1215. read_disk_info_teac(scgp, cbuf, 512, 3);
  1216. scsiprbytes("DI Data", cbuf, sizeof(cbuf) - scsigetresid(scgp));
  1217. }
  1218. #endif /* XDI */
  1219. buffer_inquiry_teac(scgp, -1);
  1220. /*#define XBU*/
  1221. #ifdef XBU
  1222. {
  1223. int i;
  1224. for (i = 0; i < 63; i++) {
  1225. scgp->silent++;
  1226. buffer_inquiry_teac(scgp, i<<2);
  1227. scgp->silent--;
  1228. }
  1229. }
  1230. #endif /* XBU */
  1231. /* printf("LLLLn");*/
  1232. /* g7_teac(scgp);*/
  1233. /* g6_teac(scgp);*/
  1234. }
  1235. #endif /* XXDEBUG */