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

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)drv_mmc.c 1.47 00/01/28 Copyright 1997 J. Schilling */
  2. #ifndef lint
  3. static char sccsid[] =
  4. "@(#)drv_mmc.c 1.47 00/01/28 Copyright 1997 J. Schilling";
  5. #endif
  6. /*
  7.  * CDR device implementation for
  8.  * SCSI-3/mmc conforming drives
  9.  * e.g. Yamaha CDR-400, Ricoh MP6200
  10.  *
  11.  * Copyright (c) 1997 J. Schilling
  12.  */
  13. /*
  14.  * This program is free software; you can redistribute it and/or modify
  15.  * it under the terms of the GNU General Public License as published by
  16.  * the Free Software Foundation; either version 2, or (at your option)
  17.  * any later version.
  18.  *
  19.  * This program is distributed in the hope that it will be useful,
  20.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22.  * GNU General Public License for more details.
  23.  *
  24.  * You should have received a copy of the GNU General Public License
  25.  * along with this program; see the file COPYING.  If not, write to
  26.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  27.  */
  28. /*#define DEBUG*/
  29. #define PRINT_ATIP
  30. #include <mconfig.h>
  31. #include <stdio.h>
  32. #include <standard.h>
  33. #include <fctldefs.h>
  34. #include <errno.h>
  35. #include <strdefs.h>
  36. #include <unixstd.h>
  37. #include <timedefs.h>
  38. #include <utypes.h>
  39. #include <btorder.h>
  40. #include <intcvt.h>
  41. #include <scg/scgcmd.h>
  42. #include <scg/scsidefs.h>
  43. #include <scg/scsireg.h>
  44. #include <scg/scsitransp.h>
  45. #include <scsimmc.h>
  46. #include "cdrecord.h"
  47. extern BOOL isgui;
  48. extern int debug;
  49. extern int lverbose;
  50. LOCAL int curspeed = 1;
  51. LOCAL int mmc_load __PR((SCSI *scgp));
  52. LOCAL int mmc_unload __PR((SCSI *scgp));
  53. LOCAL cdr_t *identify_mmc __PR((SCSI *scgp, cdr_t *, struct scsi_inquiry *));
  54. LOCAL int attach_mmc __PR((SCSI *scgp, cdr_t *));
  55. LOCAL int get_diskinfo __PR((SCSI *scgp, struct disk_info *dip));
  56. LOCAL void di_to_dstat __PR((struct disk_info *dip, dstat_t *dsp));
  57. #ifdef PRINT_ATIP
  58. LOCAL int get_pma __PR((SCSI *scgp));
  59. #endif
  60. LOCAL int getdisktype_mmc __PR((SCSI *scgp, cdr_t *dp, dstat_t *dsp));
  61. LOCAL int speed_select_mmc __PR((SCSI *scgp, int *speedp, int dummy));
  62. LOCAL int next_wr_addr_mmc __PR((SCSI *scgp, int track, track_t *trackp, long *ap));
  63. LOCAL int open_track_mmc __PR((SCSI *scgp, cdr_t *dp, int track, track_t *trackp));
  64. LOCAL int close_track_mmc __PR((SCSI *scgp, int track, track_t *trackp));
  65. LOCAL int open_session_mmc __PR((SCSI *scgp, int tracks, track_t *trackp, int toctype, int multi));
  66. LOCAL int waitfix_mmc __PR((SCSI *scgp, int secs));
  67. LOCAL int fixate_mmc __PR((SCSI *scgp, int onp, int dummy, int toctype, int tracks, track_t *trackp));
  68. LOCAL int blank_mmc __PR((SCSI *scgp, long addr, int blanktype));
  69. LOCAL int scsi_sony_write __PR((SCSI *scgp, caddr_t bp, long sectaddr, long size, int blocks, BOOL islast));
  70. LOCAL int
  71. mmc_load(scgp)
  72. SCSI *scgp;
  73. {
  74. return (scsi_load_unload(scgp, 1));
  75. }
  76. LOCAL int
  77. mmc_unload(scgp)
  78. SCSI *scgp;
  79. {
  80. return (scsi_load_unload(scgp, 0));
  81. }
  82. cdr_t cdr_mmc = {
  83. 0,
  84. CDR_TAO|CDR_DAO|CDR_PACKET|CDR_SWABAUDIO,
  85. "mmc_cdr",
  86. "generic SCSI-3/mmc CD-R driver",
  87. 0,
  88. identify_mmc,
  89. attach_mmc,
  90. getdisktype_mmc,
  91. scsi_load,
  92. /* mmc_load,*/
  93. scsi_unload,
  94. read_buff_cap,
  95. (int(*)__PR((SCSI *)))cmd_dummy, /* recovery_needed */
  96. (int(*)__PR((SCSI *, int)))cmd_dummy, /* recover */
  97. speed_select_mmc,
  98. select_secsize,
  99. next_wr_addr_mmc,
  100. (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */
  101. scsi_cdr_write,
  102. send_cue,
  103. open_track_mmc,
  104. close_track_mmc,
  105. open_session_mmc,
  106. cmd_dummy,
  107. read_session_offset,
  108. fixate_mmc,
  109. blank_mmc,
  110. };
  111. cdr_t cdr_mmc_sony = {
  112. 0,
  113. CDR_TAO|CDR_DAO|CDR_PACKET|CDR_SWABAUDIO,
  114. "mmc_cdr_sony",
  115. "generic SCSI-3/mmc CD-R driver (Sony 928 variant)",
  116. 0,
  117. identify_mmc,
  118. attach_mmc,
  119. getdisktype_mmc,
  120. scsi_load,
  121. /* mmc_load,*/
  122. scsi_unload,
  123. read_buff_cap,
  124. (int(*)__PR((SCSI *)))cmd_dummy, /* recovery_needed */
  125. (int(*)__PR((SCSI *, int)))cmd_dummy, /* recover */
  126. speed_select_mmc,
  127. select_secsize,
  128. next_wr_addr_mmc,
  129. (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */
  130. scsi_sony_write,
  131. send_cue,
  132. open_track_mmc,
  133. close_track_mmc,
  134. open_session_mmc,
  135. cmd_dummy,
  136. read_session_offset,
  137. fixate_mmc,
  138. blank_mmc,
  139. };
  140. /*
  141.  * SCSI-3/mmc conformant CD drive
  142.  */
  143. cdr_t cdr_cd = {
  144. 0,
  145. CDR_ISREADER|CDR_SWABAUDIO,
  146. "mmc_cd",
  147. "generic SCSI-3/mmc CD driver",
  148. 0,
  149. identify_mmc,
  150. attach_mmc,
  151. drive_getdisktype,
  152. scsi_load,
  153. scsi_unload,
  154. read_buff_cap,
  155. (int(*)__PR((SCSI *)))cmd_dummy, /* recovery_needed */
  156. (int(*)__PR((SCSI *, int)))cmd_dummy, /* recover */
  157. speed_select_mmc,
  158. select_secsize,
  159. (int(*)__PR((SCSI *scgp, int, track_t *, long *)))cmd_ill, /* next_wr_addr */
  160. (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */
  161. scsi_cdr_write,
  162. no_sendcue,
  163. open_track_mmc,
  164. close_track_mmc,
  165. (int(*)__PR((SCSI *scgp, int, track_t *, int, int)))cmd_dummy,
  166. cmd_dummy,
  167. read_session_offset,
  168. (int(*)__PR((SCSI *scgp, int, int, int, int, track_t *)))cmd_dummy, /* fixation */
  169. blank_dummy,
  170. };
  171. /*
  172.  * Old pre SCSI-3/mmc CD drive
  173.  */
  174. cdr_t cdr_oldcd = {
  175. 0,
  176. CDR_ISREADER,
  177. "scsi2_cd",
  178. "generic SCSI-2 CD driver",
  179. 0,
  180. identify_mmc,
  181. drive_attach,
  182. drive_getdisktype,
  183. scsi_load,
  184. scsi_unload,
  185. buf_dummy,
  186. (int(*)__PR((SCSI *)))cmd_dummy, /* recovery_needed */
  187. (int(*)__PR((SCSI *, int)))cmd_dummy, /* recover */
  188. speed_select_mmc,
  189. select_secsize,
  190. (int(*)__PR((SCSI *scg, int, track_t *, long *)))cmd_ill, /* next_wr_addr */
  191. (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */
  192. scsi_cdr_write,
  193. no_sendcue,
  194. open_track_mmc,
  195. close_track_mmc,
  196. (int(*)__PR((SCSI *scgp, int, track_t *, int, int)))cmd_dummy,
  197. cmd_dummy,
  198. read_session_offset_philips,
  199. (int(*)__PR((SCSI *scgp, int, int, int, int, track_t *)))cmd_dummy, /* fixation */
  200. blank_dummy,
  201. };
  202. LOCAL cdr_t *
  203. identify_mmc(scgp, dp, ip)
  204. SCSI *scgp;
  205. cdr_t *dp;
  206. struct scsi_inquiry *ip;
  207. {
  208. BOOL cdrr  = FALSE; /* Read CD-R */
  209. BOOL cdwr  = FALSE; /* Write CD-R */
  210. BOOL cdrrw  = FALSE; /* Read CD-RW */
  211. BOOL cdwrw  = FALSE; /* Write CD-RW */
  212. Uchar mode[0x100];
  213. struct cd_mode_page_2A *mp;
  214. if (ip->type != INQ_WORM && ip->type != INQ_ROMD)
  215. return ((cdr_t *)0);
  216. allow_atapi(scgp, TRUE);/* Try to switch to 10 byte mode cmds */
  217. scgp->silent++;
  218. mp = mmc_cap(scgp, mode); /* Get MMC capabilities */
  219. scgp->silent--;
  220. if (mp == NULL)
  221. return (&cdr_oldcd); /* Pre SCSI-3/mmc drive   */
  222. mmc_getval(mp, &cdrr, &cdwr, &cdrrw, &cdwrw, NULL);
  223. /*
  224.  * At this point we know that we have a SCSI-3/mmc compliant drive.
  225.  * Unfortunately ATAPI drives violate the SCSI spec in returning
  226.  * a response data format of '1' which from the SCSI spec would
  227.  * tell us not to use the "PF" bit in mode select. As ATAPI drives
  228.  * require the "PF" bit to be set, we 'correct' the inquiry data.
  229.  *
  230.  * XXX xxx_identify() should not have any side_effects ??
  231.  */
  232. if (ip->data_format < 2)
  233. ip->data_format = 2;
  234. if (strncmp(ip->vendor_info, "SONY", 4) == 0 &&
  235.     strncmp(ip->prod_ident, "CD-R   CDU928E", 14) == 0) {
  236. dp = &cdr_mmc_sony;
  237. }
  238. if (!cdwr) /* SCSI-3/mmc CD drive */
  239. dp = &cdr_cd;
  240. return (dp);
  241. }
  242. LOCAL int
  243. attach_mmc(scgp, dp)
  244. SCSI *scgp;
  245. cdr_t *dp;
  246. {
  247. struct cd_mode_page_2A *mp;
  248. allow_atapi(scgp, TRUE);/* Try to switch to 10 byte mode cmds */
  249. scgp->silent++;
  250. mp = mmc_cap(scgp, NULL);/* Get MMC capabilities in allocated mp */
  251. scgp->silent--;
  252. if (mp == NULL)
  253. return (-1); /* Pre SCSI-3/mmc drive   */
  254. dp->cdr_cdcap = mp; /* Store MMC cap pointer */
  255. if (mp->loading_type == LT_TRAY)
  256. dp->cdr_flags |= CDR_TRAYLOAD;
  257. else if (mp->loading_type == LT_CADDY)
  258. dp->cdr_flags |= CDR_CADDYLOAD;
  259. return (0);
  260. }
  261. #ifdef PRINT_ATIP
  262. LOCAL int get_atip __PR((SCSI *scgp, struct atipinfo *atp));
  263. void print_di __PR((struct disk_info *dip));
  264. void print_atip __PR((SCSI *scgp, struct atipinfo *atp));
  265. #endif /* PRINT_ATIP */
  266. LOCAL int
  267. get_diskinfo(scgp, dip)
  268. SCSI *scgp;
  269. struct disk_info *dip;
  270. {
  271. int len;
  272. int ret;
  273. fillbytes((caddr_t)dip, sizeof(*dip), '');
  274. if (read_disk_info(scgp, (caddr_t)dip, 2) < 0)
  275. return (-1);
  276. len = a_to_u_2_byte(dip->data_len);
  277. len += 2;
  278. ret = read_disk_info(scgp, (caddr_t)dip, len);
  279. #ifdef DEBUG
  280. scsiprbytes("Disk info:", (u_char *)dip,
  281. len-scsigetresid(scgp));
  282. #endif
  283. return (ret);
  284. }
  285. LOCAL void
  286. di_to_dstat(dip, dsp)
  287. struct disk_info *dip;
  288. dstat_t *dsp;
  289. {
  290. dsp->ds_diskid = a_to_u_4_byte(dip->disk_id);
  291. if (dip->did_v)
  292. dsp->ds_flags |= DSF_DID_V;
  293. dsp->ds_diskstat = dip->disk_status;
  294. dsp->ds_sessstat = dip->sess_status;
  295. dsp->ds_maxblocks = msf_to_lba(dip->last_lead_out[1],
  296. dip->last_lead_out[2],
  297. dip->last_lead_out[3]);
  298. /*
  299.  * Check for 0xFF:0xFF/0xFF which is an indicator for a complete disk
  300.  */
  301. if (dsp->ds_maxblocks == 716730)
  302. dsp->ds_maxblocks = -1L;
  303. if (dsp->ds_first_leadin == 0) {
  304. dsp->ds_first_leadin = msf_to_lba(dip->last_lead_in[1],
  305. dip->last_lead_in[2],
  306. dip->last_lead_in[3]);
  307. if (dsp->ds_first_leadin > 0)
  308. dsp->ds_first_leadin = 0;
  309. }
  310. if (dsp->ds_last_leadout == 0 && dsp->ds_maxblocks >= 0)
  311. dsp->ds_last_leadout = dsp->ds_maxblocks;
  312. }
  313. #ifdef PRINT_ATIP
  314. LOCAL int
  315. get_atip(scgp, atp)
  316. SCSI *scgp;
  317. struct atipinfo *atp;
  318. {
  319. int len;
  320. int ret;
  321. fillbytes((caddr_t)atp, sizeof(*atp), '');
  322. if (read_toc(scgp, (caddr_t)atp, 0, 2, 0, FMT_ATIP) < 0)
  323. return (-1);
  324. len = a_to_u_2_byte(atp->hd.len);
  325. len += 2;
  326. ret = read_toc(scgp, (caddr_t)atp, 0, len, 0, FMT_ATIP);
  327. #ifdef DEBUG
  328. scsiprbytes("ATIP info:", (u_char *)atp,
  329. len-scsigetresid(scgp));
  330. #endif
  331. /*
  332.  * Yamaha sometimes returns zeroed ATIP info for disks without ATIP
  333.  */
  334. if (atp->desc.lead_in[1] == 0 &&
  335. atp->desc.lead_in[2] == 0 &&
  336. atp->desc.lead_in[3] == 0 &&
  337. atp->desc.lead_out[1] == 0 &&
  338. atp->desc.lead_out[2] == 0 &&
  339. atp->desc.lead_out[3] == 0)
  340. return (-1);
  341. if (atp->desc.lead_in[1] >= 0x90 && debug) {
  342. /*
  343.  * Only makes sense with buggy Ricoh firmware.
  344.  */
  345. errmsgno(EX_BAD, "Converting ATIP from BCDn");
  346. atp->desc.lead_in[1] = from_bcd(atp->desc.lead_in[1]);
  347. atp->desc.lead_in[2] = from_bcd(atp->desc.lead_in[2]);
  348. atp->desc.lead_in[3] = from_bcd(atp->desc.lead_in[3]);
  349. atp->desc.lead_out[1] = from_bcd(atp->desc.lead_out[1]);
  350. atp->desc.lead_out[2] = from_bcd(atp->desc.lead_out[2]);
  351. atp->desc.lead_out[3] = from_bcd(atp->desc.lead_out[3]);
  352. }
  353. return (ret);
  354. }
  355. LOCAL int
  356. /*get_pma(atp)*/
  357. get_pma(scgp)
  358. SCSI *scgp;
  359. /* struct atipinfo *atp;*/
  360. {
  361. int len;
  362. int ret;
  363. char atp[1024];
  364. fillbytes((caddr_t)atp, sizeof(*atp), '');
  365. /* if (read_toc(scgp, (caddr_t)atp, 0, 2, 1, FMT_PMA) < 0)*/
  366. if (read_toc(scgp, (caddr_t)atp, 0, 2, 0, FMT_PMA) < 0)
  367. return (-1);
  368. /* len = a_to_u_2_byte(atp->hd.len);*/
  369. len = a_to_u_2_byte(atp);
  370. len += 2;
  371. /* ret = read_toc(scgp, (caddr_t)atp, 0, len, 1, FMT_PMA);*/
  372. ret = read_toc(scgp, (caddr_t)atp, 0, len, 0, FMT_PMA);
  373. #ifdef DEBUG
  374. scsiprbytes("PMA:", (u_char *)atp,
  375. len-scsigetresid(scgp));
  376. #endif
  377. ret = read_toc(scgp, (caddr_t)atp, 0, len, 1, FMT_PMA);
  378. #ifdef DEBUG
  379. scsiprbytes("PMA:", (u_char *)atp,
  380. len-scsigetresid(scgp));
  381. #endif
  382. return (ret);
  383. }
  384. #endif /* PRINT_ATIP */
  385. LOCAL int
  386. getdisktype_mmc(scgp, dp, dsp)
  387. SCSI *scgp;
  388. cdr_t *dp;
  389. dstat_t *dsp;
  390. {
  391. extern char *buf;
  392. struct disk_info *dip;
  393. u_char mode[0x100];
  394. char ans[2];
  395. msf_t msf;
  396. BOOL did_atip = FALSE;
  397. BOOL did_dummy = FALSE;
  398. msf.msf_min = msf.msf_sec = msf.msf_frame = 0;
  399. #ifdef PRINT_ATIP
  400. /*
  401.  * It seems that there are drives that do not support to
  402.  * read ATIP (e.g. HP 7100)
  403.  * Also if a NON CD-R media is inserted, this will never work.
  404.  * For this reason, make a failure non-fatal.
  405.  */
  406. scgp->silent++;
  407. if (get_atip(scgp, (struct atipinfo *)mode) >= 0) {
  408. msf.msf_min = mode[8];
  409. msf.msf_sec = mode[9];
  410. msf.msf_frame = mode[10];
  411. did_atip = TRUE;
  412. if (lverbose) {
  413. print_atip(scgp, (struct atipinfo *)mode);
  414. pr_manufacturer(&msf,
  415. ((struct atipinfo *)mode)->desc.erasable,
  416. ((struct atipinfo *)mode)->desc.uru);
  417. }
  418. }
  419. scgp->silent--;
  420. #endif
  421. again:
  422. dip = (struct disk_info *)buf;
  423. if (get_diskinfo(scgp, dip) < 0)
  424. return (-1);
  425. /*
  426.  * Check for non writable disk first.
  427.  */
  428. if (dip->disk_status == DS_COMPLETE && dsp->ds_cdrflags & RF_WRITE) {
  429. if (!did_dummy) {
  430. int xspeed = 0xFFFF;
  431. /*
  432.  * Try to clear the dummy bit to reset the virtual
  433.  * drive status. Not all drives support it even though
  434.  * it is mentioned in the MMC standard.
  435.  */
  436. if (lverbose)
  437. printf("Trying to clear drive status.n");
  438. speed_select_mmc(scgp, &xspeed, FALSE);
  439. did_dummy = TRUE;
  440. goto again;
  441. }
  442. errmsgno(EX_BAD, "Drive needs to reload the media to return to proper status.n");
  443. unload_media(scgp, dp, F_EJECT);
  444. if ((dp->cdr_flags & CDR_TRAYLOAD) != 0) {
  445. scgp->silent++;
  446. load_media(scgp, dp, FALSE);
  447. scgp->silent--;
  448. }
  449. scgp->silent++;
  450. if (((dp->cdr_flags & CDR_TRAYLOAD) == 0) ||
  451. !wait_unit_ready(scgp, 5)) {
  452. scgp->silent--;
  453. printf("Re-load disk and hit <CR>");
  454. if (isgui)
  455. printf("n");
  456. flush();
  457. getline(ans, 1);
  458. } else {
  459. scgp->silent--;
  460. }
  461. load_media(scgp, dp, TRUE);
  462. }
  463. if (get_diskinfo(scgp, dip) < 0)
  464. return (-1);
  465. di_to_dstat(dip, dsp);
  466. if (!did_atip && dsp->ds_first_leadin < 0)
  467. lba_to_msf(dsp->ds_first_leadin, &msf);
  468. if (lverbose && !did_atip) {
  469. print_min_atip(dsp->ds_first_leadin, dsp->ds_last_leadout);
  470. if (dsp->ds_first_leadin < 0)
  471.                 pr_manufacturer(&msf,
  472. dip->erasable,
  473. dip->uru);
  474. }
  475. dsp->ds_maxrblocks = disk_rcap(&msf, dsp->ds_maxblocks,
  476. dip->erasable,
  477. dip->uru);
  478. #ifdef PRINT_ATIP
  479. #ifdef DEBUG
  480. if (get_atip(scgp, (struct atipinfo *)mode) < 0)
  481. return (-1);
  482. /*
  483.  * Get pma gibt 膔ger mit CW-7502
  484.  * Wenn Die Disk leer ist, dann stuerzt alles ab.
  485.  * Firmware 4.02 kann nicht get_pma
  486.  */
  487. if (dip->disk_status != DS_EMPTY) {
  488. /* get_pma();*/
  489. }
  490. printf("ATIP lead in:  %ld (%02d:%02d/%02d)n",
  491. msf_to_lba(mode[8], mode[9], mode[10]),
  492. mode[8], mode[9], mode[10]);
  493. printf("ATIP lead out: %ld (%02d:%02d/%02d)n",
  494. msf_to_lba(mode[12], mode[13], mode[14]),
  495. mode[12], mode[13], mode[14]);
  496. print_di(dip);
  497. print_atip(scgp, (struct atipinfo *)mode);
  498. #endif
  499. #endif /* PRINT_ATIP */
  500. return (drive_getdisktype(scgp, dp, dsp));
  501. }
  502. #ifdef PRINT_ATIP
  503. #define DOES(what,flag) printf("  Does %s%sn", flag?"":"not ",what);
  504. #define IS(what,flag) printf("  Is %s%sn", flag?"":"not ",what);
  505. #define VAL(what,val) printf("  %s: %dn", what, val[0]*256 + val[1]);
  506. #define SVAL(what,val) printf("  %s: %sn", what, val);
  507. void
  508. print_di(dip)
  509. struct disk_info *dip;
  510. {
  511. static char *ds_name[] = { "empty", "incomplete/appendable", "complete", "illegal" };
  512. static char *ss_name[] = { "empty", "incomplete/appendable", "illegal", "complete", };
  513. IS("erasable", dip->erasable);
  514. printf("disk status: %sn", ds_name[dip->disk_status]);
  515. printf("session status: %sn", ss_name[dip->sess_status]);
  516. printf("first track: %d number of sessions: %d first track in last sess: %d last track in last sess: %dn",
  517. dip->first_track,
  518. dip->numsess,
  519. dip->first_track_ls,
  520. dip->last_track_ls);
  521. IS("unrestricted", dip->uru);
  522. printf("Disk type: ");
  523. switch (dip->disk_type) {
  524. case SES_DA_ROM: printf("CD-DA or CD-ROM"); break;
  525. case SES_CDI: printf("CDI"); break;
  526. case SES_XA: printf("CD-ROM XA"); break;
  527. case SES_UNDEF: printf("undefined"); break;
  528. default: printf("reserved"); break;
  529. }
  530. printf("n");
  531. if (dip->did_v)
  532. printf("Disk id: 0x%lXn", a_to_u_4_byte(dip->disk_id));
  533. printf("last start of lead in: %ldn",
  534. msf_to_lba(dip->last_lead_in[1],
  535. dip->last_lead_in[2],
  536. dip->last_lead_in[3]));
  537. printf("last start of lead out: %ldn",
  538. msf_to_lba(dip->last_lead_out[1],
  539. dip->last_lead_out[2],
  540. dip->last_lead_out[3]));
  541. if (dip->dbc_v)
  542. printf("Disk bar code: 0x%lX%lXn",
  543. a_to_u_4_byte(dip->disk_barcode),
  544. a_to_u_4_byte(&dip->disk_barcode[4]));
  545. if (dip->num_opc_entries > 0) {
  546. printf("OPC table:n");
  547. }
  548. }
  549. LOCAL char clv_to_speed[8] = {
  550. 0, 2, 4, 6, 8, 0, 0, 0
  551. };
  552. void
  553. print_atip(scgp, atp)
  554. SCSI *scgp;
  555. struct atipinfo *atp;
  556. {
  557. if (scgp->verbose)
  558. scsiprbytes("ATIP info: ", (Uchar *)atp, sizeof (*atp));
  559. printf("ATIP info from disk:n");
  560. printf("  Indicated writing power: %dn", atp->desc.ind_wr_power);
  561. if (atp->desc.erasable || atp->desc.ref_speed)
  562. printf("  Reference speed: %dn", clv_to_speed[atp->desc.ref_speed]);
  563. IS("unrestricted", atp->desc.uru);
  564. /* printf("  Disk application code: %dn", atp->desc.res5_05);*/
  565. IS("erasable", atp->desc.erasable);
  566. if (atp->desc.sub_type)
  567. printf("  Disk sub type: %dn", atp->desc.sub_type);
  568. printf("  ATIP start of lead in:  %ld (%02d:%02d/%02d)n",
  569. msf_to_lba(atp->desc.lead_in[1],
  570. atp->desc.lead_in[2],
  571. atp->desc.lead_in[3]),
  572. atp->desc.lead_in[1],
  573. atp->desc.lead_in[2],
  574. atp->desc.lead_in[3]);
  575. printf("  ATIP start of lead out: %ld (%02d:%02d/%02d)n",
  576. msf_to_lba(atp->desc.lead_out[1],
  577. atp->desc.lead_out[2],
  578. atp->desc.lead_out[3]),
  579. atp->desc.lead_out[1],
  580. atp->desc.lead_out[2],
  581. atp->desc.lead_out[3]);
  582. if (atp->desc.a1_v) {
  583. if (atp->desc.clv_low != 0 || atp->desc.clv_high != 0)
  584. printf("  speed low: %d speed high: %dn",
  585. clv_to_speed[atp->desc.clv_low],
  586. clv_to_speed[atp->desc.clv_high]);
  587. printf("  power mult factor: %d %dn", atp->desc.power_mult, atp->desc.tgt_y_pow);
  588. if (atp->desc.erasable)
  589. printf("  recommended erase/write power: %dn", atp->desc.rerase_pwr_ratio);
  590. }
  591. if (atp->desc.a2_v) {
  592. printf("  A2 values: %02X %02X %02Xn",
  593. atp->desc.a2[0],
  594. atp->desc.a2[1],
  595. atp->desc.a2[2]);
  596. }
  597. if (atp->desc.a3_v) {
  598. printf("  A3 values: %02X %02X %02Xn",
  599. atp->desc.a3[0],
  600. atp->desc.a3[1],
  601. atp->desc.a3[2]);
  602. }
  603. }
  604. #endif /* PRINT_ATIP */
  605. LOCAL int
  606. speed_select_mmc(scgp, speedp, dummy)
  607. SCSI *scgp;
  608. int *speedp;
  609. int dummy;
  610. {
  611. u_char mode[0x100];
  612. int len;
  613. struct cd_mode_page_05 *mp;
  614. int val;
  615. if (speedp)
  616. curspeed = *speedp;
  617. fillbytes((caddr_t)mode, sizeof(mode), '');
  618. if (!get_mode_params(scgp, 0x05, "CD write parameter",
  619. mode, (u_char *)0, (u_char *)0, (u_char *)0, &len))
  620. return (-1);
  621. if (len == 0)
  622. return (-1);
  623. mp = (struct cd_mode_page_05 *)
  624. (mode + sizeof(struct scsi_mode_header) +
  625. ((struct scsi_mode_header *)mode)->blockdesc_len);
  626. #ifdef DEBUG
  627. scsiprbytes("CD write parameter:", (u_char *)mode, len);
  628. #endif
  629. mp->test_write = dummy != 0;
  630. /*
  631.  * Set default values:
  632.  * Write type = 01 (track at once)
  633.  * Track mode = 04 (CD-ROM)
  634.  * Data block type = 08 (CD-ROM)
  635.  * Session format = 00 (CD-ROM)
  636.  */
  637. mp->write_type = WT_TAO;
  638. mp->track_mode = TM_DATA; 
  639. mp->dbtype = DB_ROM_MODE1;
  640. mp->session_format = SES_DA_ROM;/* Matsushita has illegal def. value */
  641. #ifdef DEBUG
  642. scsiprbytes("CD write parameter:", (u_char *)mode, len);
  643. #endif
  644. if (!set_mode_params(scgp, "CD write parameter", mode, len, 0, -1))
  645. return (-1);
  646. if (speedp == 0)
  647. return (0);
  648. /* if (scsi_set_speed(-1, curspeed*176) < 0)*/
  649. /*
  650.  * 44100 * 2 * 2 =  176400 bytes/s
  651.  *
  652.  * The right formula would be:
  653.  * tmp = (((long)curspeed) * 1764) / 10;
  654.  *
  655.  * But the standard is rounding the wrong way.
  656.  * Furtunately rounding down is guaranteed.
  657.  */
  658. if (scsi_set_speed(scgp, -1, curspeed*177) < 0)
  659. return (-1);
  660. if (scsi_get_speed(scgp, 0, &val) >= 0) {
  661. curspeed = val / 176;
  662. *speedp = curspeed;
  663. }
  664. return (0);
  665. }
  666. LOCAL int
  667. next_wr_addr_mmc(scgp, track, trackp, ap)
  668. SCSI *scgp;
  669. int track;
  670. track_t *trackp;
  671. long *ap;
  672. {
  673. struct track_info track_info;
  674. long next_addr;
  675. int result = -1;
  676. /*
  677.  * Reading info for current track may require doing the read_track_info
  678.  * with either the track number (if the track is currently being written)
  679.  * or with 0xFF (if the track hasn't been started yet and is invisible
  680.  */
  681. if (track > 0 && is_packet(trackp)) {
  682. scgp->silent++;
  683. result = read_track_info(scgp, (caddr_t)&track_info, track,
  684. sizeof(track_info));
  685. scgp->silent--;
  686. }
  687. if (result < 0) {
  688. if (read_track_info(scgp, (caddr_t)&track_info, 0xFF,
  689. sizeof(track_info)) < 0)
  690. return (-1);
  691. }
  692. if (scgp->verbose)
  693. scsiprbytes("track info:", (u_char *)&track_info,
  694. sizeof(track_info)-scsigetresid(scgp));
  695. next_addr = a_to_4_byte(track_info.next_writable_addr);
  696. if (ap)
  697. *ap = next_addr;
  698. return (0);
  699. }
  700. int st2mode[] = {
  701. 0, /* 0 */
  702. TM_DATA, /* 1 ST_ROM_MODE1 */
  703. TM_DATA, /* 2 ST_ROM_MODE2 */
  704. 0, /* 3 */
  705. 0, /* 4 ST_AUDIO_NOPRE */
  706. TM_PREEM, /* 5 ST_AUDIO_PRE */
  707. 0, /* 6 */
  708. 0, /* 7 */
  709. };
  710. LOCAL int
  711. open_track_mmc(scgp, dp, track, trackp)
  712. SCSI *scgp;
  713. cdr_t *dp;
  714. int track;
  715. track_t *trackp;
  716. {
  717. u_char mode[0x100];
  718. int len;
  719. struct cd_mode_page_05 *mp;
  720. if (!is_tao(trackp)) {
  721. if (trackp->pregapsize > 0 && (trackp->flags & TI_PREGAP) == 0) {
  722. if (lverbose) {
  723. printf("Writing pregap for track %d at %ldn",
  724. track,
  725. trackp->trackstart-trackp->pregapsize);
  726. }
  727. pad_track(scgp, dp, track, trackp,
  728. trackp->trackstart-trackp->pregapsize,
  729. trackp->pregapsize*trackp->secsize,
  730. FALSE, 0);
  731. }
  732. return (0);
  733. }
  734. fillbytes((caddr_t)mode, sizeof(mode), '');
  735. if (!get_mode_params(scgp, 0x05, "CD write parameter",
  736. mode, (u_char *)0, (u_char *)0, (u_char *)0, &len))
  737. return (-1);
  738. if (len == 0)
  739. return (-1);
  740. mp = (struct cd_mode_page_05 *)
  741. (mode + sizeof(struct scsi_mode_header) +
  742. ((struct scsi_mode_header *)mode)->blockdesc_len);
  743. /* mp->track_mode = ???;*/
  744. mp->track_mode = st2mode[trackp->sectype & ST_MASK];
  745. /* mp->copy = ???;*/
  746. mp->dbtype = trackp->dbtype;
  747. /*i_to_short(mp->audio_pause_len, 300);*/
  748. /*i_to_short(mp->audio_pause_len, 150);*/
  749. /*i_to_short(mp->audio_pause_len, 0);*/
  750. if (is_packet(trackp)) {
  751. mp->write_type = WT_PACKET;
  752. mp->track_mode |= TM_INCREMENTAL;
  753. mp->fp = (trackp->pktsize > 0) ? 1 : 0;
  754. i_to_4_byte(mp->packet_size, trackp->pktsize);
  755. } else {
  756. mp->write_type = WT_TAO;
  757. mp->fp = 0;
  758. i_to_4_byte(mp->packet_size, 0);
  759. }
  760. if (trackp->isrc) {
  761. mp->ISRC[0] = 0x80; /* Set ISRC valid */
  762. strncpy((char *)&mp->ISRC[1], trackp->isrc, 12);
  763. } else {
  764. fillbytes(&mp->ISRC[0], sizeof(mp->ISRC), '');
  765. }
  766.  
  767. #ifdef DEBUG
  768. scsiprbytes("CD write parameter:", (u_char *)mode, len);
  769. #endif
  770. if (!set_mode_params(scgp, "CD write parameter", mode, len, 0, trackp->secsize))
  771. return (-1);
  772. return (0);
  773. }
  774. LOCAL int
  775. close_track_mmc(scgp, track, trackp)
  776. SCSI *scgp;
  777. int track;
  778. track_t *trackp;
  779. {
  780. int ret;
  781. if (!is_tao(trackp))
  782. return (0);
  783. if (scsi_flush_cache(scgp) < 0) {
  784. printf("Trouble flushing the cachen");
  785. return -1;
  786. }
  787. wait_unit_ready(scgp, 300); /* XXX Wait for ATAPI */
  788. if (is_packet(trackp) && !is_noclose(trackp)) {
  789. /* close the incomplete track */
  790. ret = scsi_close_tr_session(scgp, 1, 0xFF);
  791. wait_unit_ready(scgp, 300); /* XXX Wait for ATAPI */
  792. return (ret);
  793. }
  794. return (0);
  795. }
  796. int toc2sess[] = {
  797. SES_DA_ROM, /* CD-DA  */
  798. SES_DA_ROM, /* CD-ROM  */
  799. SES_XA, /* CD-ROM XA mode 1  */
  800. SES_XA, /* CD-ROM XA MODE 2  */
  801. SES_CDI, /* CDI  */
  802. SES_DA_ROM, /* Invalid - use default */
  803. SES_DA_ROM, /* Invalid - use default */
  804. };
  805. LOCAL int
  806. open_session_mmc(scgp, tracks, trackp, toctype, multi)
  807. SCSI *scgp;
  808. int tracks;
  809. track_t *trackp;
  810. int toctype;
  811. int multi;
  812. {
  813. u_char mode[0x100];
  814. int len;
  815. struct cd_mode_page_05 *mp;
  816. fillbytes((caddr_t)mode, sizeof(mode), '');
  817. if (!get_mode_params(scgp, 0x05, "CD write parameter",
  818. mode, (u_char *)0, (u_char *)0, (u_char *)0, &len))
  819. return (-1);
  820. if (len == 0)
  821. return (-1);
  822. mp = (struct cd_mode_page_05 *)
  823. (mode + sizeof(struct scsi_mode_header) +
  824. ((struct scsi_mode_header *)mode)->blockdesc_len);
  825. mp->write_type = WT_TAO; /* fix to allow DAO later */
  826. if (!is_tao(trackp)) {
  827. mp->write_type = WT_SAO;
  828. mp->track_mode = 0;
  829. mp->dbtype = DB_RAW;
  830. }
  831. mp->multi_session = (multi != 0) ? MS_MULTI : MS_NONE;
  832. mp->session_format = toc2sess[toctype & TOC_MASK];
  833. if (trackp->isrc) {
  834. mp->media_cat_number[0] = 0x80; /* Set MCN valid */
  835. strncpy((char *)&mp->media_cat_number[1], trackp->isrc, 13);
  836. } else {
  837. fillbytes(&mp->media_cat_number[0], sizeof(mp->media_cat_number), '');
  838. }
  839. #ifdef DEBUG
  840. scsiprbytes("CD write parameter:", (u_char *)mode, len);
  841. #endif
  842. if (!set_mode_params(scgp, "CD write parameter", mode, len, 0, -1))
  843. return (-1);
  844. return (0);
  845. }
  846. LOCAL int
  847. waitfix_mmc(scgp, secs)
  848. SCSI *scgp;
  849. int secs;
  850. {
  851. char dibuf[16];
  852. int i;
  853. int key;
  854. #define W_SLEEP 2
  855. scgp->silent++;
  856. for (i = 0; i < secs/W_SLEEP; i++) {
  857. if (read_disk_info(scgp, dibuf, sizeof(dibuf)) >= 0) {
  858. scgp->silent--;
  859. return (0);
  860. }
  861. key = scsi_sense_key(scgp);
  862. if (key != SC_UNIT_ATTENTION && key != SC_NOT_READY)
  863. break;
  864. sleep(W_SLEEP);
  865. }
  866. scgp->silent--;
  867. return (-1);
  868. #undef W_SLEEP
  869. }
  870. LOCAL int
  871. fixate_mmc(scgp, onp, dummy, toctype, tracks, trackp)
  872. SCSI *scgp;
  873. int onp;
  874. int dummy;
  875. int toctype;
  876. int tracks;
  877. track_t *trackp;
  878. {
  879. int ret = 0;
  880. int key = 0;
  881. int code = 0;
  882. struct timeval starttime;
  883. struct timeval stoptime;
  884. starttime.tv_sec = 0;
  885. starttime.tv_usec = 0;
  886. stoptime = starttime;
  887. gettimeofday(&starttime, (struct timezone *)0);
  888. if (dummy && lverbose)
  889. printf("WARNING: Some drives don't like fixation in dummy mode.n");
  890. if (is_tao(trackp)) {
  891. scgp->silent++;
  892. ret = scsi_close_tr_session(scgp, 2, 0);
  893. scgp->silent--;
  894. key = scsi_sense_key(scgp);
  895. code = scsi_sense_code(scgp);
  896. } else {
  897. if (scsi_flush_cache(scgp) < 0)
  898. printf("Trouble flushing the cachen");
  899. }
  900. if (ret >= 0) {
  901. wait_unit_ready(scgp, 420/curspeed); /* XXX Wait for ATAPI */
  902. waitfix_mmc(scgp, 420/curspeed); /* XXX Wait for ATAPI */
  903. return (ret);
  904. }
  905. if ((dummy != 0 && (key != SC_ILLEGAL_REQUEST)) ||
  906. /*
  907.  * Try to suppress messages from drives that don't like fixation
  908.  * in -dummy mode.
  909.  */
  910.     ((dummy == 0) &&
  911.      ( ((key != SC_UNIT_ATTENTION) && (key != SC_NOT_READY)) ||
  912. ((code != 0x2E) && (code != 0x04)) ||
  913. (strncmp(scgp->inq->vendor_info, "MITSUMI", 7) != 0)))) {
  914. /*
  915.  * UNIT ATTENTION/2E seems to be a magic for old Mitsumi ATAPI drives
  916.  * NOT READY/ code 4 qual 7 (logical unit not ready, operation in progress)
  917.  * seems to be a magic for newer Mitsumi ATAPI drives
  918.  * when returning early from fixating.
  919.  * Try to supress the error message in this case to make
  920.  * simple minded users less confused.
  921.  */
  922. scsiprinterr(scgp);
  923. scsiprintresult(scgp); /* XXX restore key/code in future */
  924. }
  925. wait_unit_ready(scgp, 420); /* XXX Wait for ATAPI */
  926. waitfix_mmc(scgp, 420/curspeed);/* XXX Wait for ATAPI */
  927. if (!dummy &&
  928. (ret >= 0 || (key == SC_UNIT_ATTENTION && code == 0x2E))) {
  929. /*
  930.  * Some ATAPI drives (e.g. Mitsumi) imply the
  931.  * IMMED bit in the SCSI cdb. As there seems to be no
  932.  * way to properly check for the real end of the
  933.  * fixating process we wait for the expected time.
  934.  */
  935. gettimeofday(&stoptime, (struct timezone *)0);
  936. timevaldiff(&starttime, &stoptime);
  937. if (stoptime.tv_sec < (220 / curspeed)) {
  938. unsigned secs;
  939. if (lverbose) {
  940. printf("Actual fixating time: %ld secondsn",
  941. (long)stoptime.tv_sec);
  942. }
  943. secs = (280 / curspeed) - stoptime.tv_sec;
  944. if (lverbose) {
  945. printf("ATAPI early return: sleeping %d seconds.n",
  946. secs);
  947. }
  948. sleep(secs);
  949. }
  950. }
  951. return (ret);
  952. }
  953. char *blank_types[] = {
  954. "entire disk",
  955. "PMA, TOC, pregap",
  956. "incomplete track",
  957. "reserved track",
  958. "tail of track",
  959. "closing of last session",
  960. "last session",
  961. "reserved blanking type",
  962. };
  963. LOCAL int
  964. blank_mmc(scgp, addr, blanktype)
  965. SCSI *scgp;
  966. long addr;
  967. int blanktype;
  968. {
  969. BOOL cdrr  = FALSE; /* Read CD-R */
  970. BOOL cdwr  = FALSE; /* Write CD-R */
  971. BOOL cdrrw  = FALSE; /* Read CD-RW */
  972. BOOL cdwrw  = FALSE; /* Write CD-RW */
  973. mmc_check(scgp, &cdrr, &cdwr, &cdrrw, &cdwrw, NULL);
  974. if (!cdwrw)
  975. return (blank_dummy(scgp, addr, blanktype));
  976. if (lverbose) {
  977. printf("Blanking %sn", blank_types[blanktype & 0x07]);
  978. flush();
  979. }
  980. return (scsi_blank(scgp, addr, blanktype));
  981. }
  982. LOCAL int
  983. scsi_sony_write(scgp, bp, sectaddr, size, blocks, islast)
  984. SCSI *scgp;
  985. caddr_t bp; /* address of buffer */
  986. long sectaddr; /* disk address (sector) to put */
  987. long size; /* number of bytes to transfer */
  988. int blocks; /* sector count */
  989. BOOL islast; /* last write for track */
  990. {
  991. return (write_xg5(scgp, bp, sectaddr, size, blocks));
  992. }
  993. Uchar db2df[] = {
  994. 0x00, /*  0 2352 bytes of raw data */
  995. 0xFF, /*  1 2368 bytes (raw data + P/Q Subchannel) */
  996. 0xFF, /*  2 2448 bytes (raw data + P-W Subchannel) */
  997. 0xFF, /*  3 2448 bytes (raw data + P-W raw Subchannel)*/
  998. 0xFF, /*  4 -    Reserved */
  999. 0xFF, /*  5 -    Reserved */
  1000. 0xFF, /*  6 -    Reserved */
  1001. 0xFF, /*  7 -    Vendor specific */
  1002. 0x10, /*  8 2048 bytes Mode 1 (ISO/IEC 10149) */
  1003. 0xFF, /*  9 2336 bytes Mode 2 (ISO/IEC 10149) */
  1004. 0xFF, /* 10 2048 bytes Mode 2! (CD-ROM XA form 1) */
  1005. 0xFF, /* 11 2056 bytes Mode 2 (CD-ROM XA form 1) */
  1006. 0xFF, /* 12 2324 bytes Mode 2 (CD-ROM XA form 2) */
  1007. 0xFF, /* 13 2332 bytes Mode 2 (CD-ROM XA 1/2+subhdr) */
  1008. 0xFF, /* 14 -    Reserved */
  1009. 0xFF, /* 15 -    Vendor specific */
  1010. };
  1011. #include <stdxlib.h>
  1012. LOCAL void fillcue __PR((struct mmc_cue *cp, int ca, int tno, int idx, int dataform, int scms, msf_t *mp));
  1013. EXPORT int do_cue __PR((int tracks, track_t *trackp, struct mmc_cue **cuep));
  1014. EXPORT int send_cue __PR((SCSI *scgp, int tracks, track_t *trackp));
  1015. EXPORT int
  1016. do_cue(tracks, trackp, cuep)
  1017. int tracks;
  1018. track_t *trackp;
  1019. struct mmc_cue **cuep;
  1020. {
  1021. int i;
  1022. struct mmc_cue *cue;
  1023. struct mmc_cue *cp;
  1024. int ncue = 0;
  1025. int icue = 0;
  1026. int pgsize;
  1027. msf_t m;
  1028. int ctl;
  1029. int df;
  1030. int scms;
  1031. cue = (struct mmc_cue *)malloc(1);
  1032. for (i = 0; i <= tracks; i++) {
  1033. ctl = (st2mode[trackp[i].sectype & ST_MASK]) << 4;
  1034. if (is_copy(&trackp[i]))
  1035. ctl |= TM_ALLOW_COPY << 4;
  1036. df = db2df[trackp[i].dbtype & 0x0F];
  1037. if (trackp[i].isrc) { /* MCN or ISRC */
  1038. ncue += 2;
  1039. cue = (struct mmc_cue *)realloc(cue, ncue * sizeof(*cue));
  1040. cp = &cue[icue++];
  1041. if (i == 0) {
  1042. cp->cs_ctladr = 0x02;
  1043. movebytes(&trackp[i].isrc[0], &cp->cs_tno, 7);
  1044. cp = &cue[icue++];
  1045. cp->cs_ctladr = 0x02;
  1046. movebytes(&trackp[i].isrc[7], &cp->cs_tno, 7);
  1047. } else {
  1048. cp->cs_ctladr = 0x03;
  1049. cp->cs_tno = i;
  1050. movebytes(&trackp[i].isrc[0], &cp->cs_index, 6);
  1051. cp = &cue[icue++];
  1052. cp->cs_ctladr = 0x03;
  1053. cp->cs_tno = i;
  1054. movebytes(&trackp[i].isrc[6], &cp->cs_index, 6);
  1055. }
  1056. }
  1057. if (i == 0) { /* Lead in */
  1058. if (df < 0x10)
  1059. df |= 1;
  1060. else
  1061. df |= 4;
  1062. lba_to_msf(-150, &m);
  1063. cue = (struct mmc_cue *)realloc(cue, ++ncue * sizeof(*cue));
  1064. cp = &cue[icue++];
  1065. fillcue(cp, ctl|0x01, i, 0, df, 0, &m);
  1066. } else {
  1067. scms = 0;
  1068. if (is_scms(&trackp[i]))
  1069. scms = 0x80;
  1070. pgsize = trackp[i].pregapsize;
  1071. /* if (pgsize == 0)*/
  1072. /* pgsize = 150;*/
  1073. lba_to_msf(trackp[i].trackstart-pgsize, &m);
  1074. cue = (struct mmc_cue *)realloc(cue, ++ncue * sizeof(*cue));
  1075. cp = &cue[icue++];
  1076. fillcue(cp, ctl|0x01, i, 0, df, scms, &m);
  1077. if (trackp[i].nindex == 1) {
  1078. lba_to_msf(trackp[i].trackstart, &m);
  1079. cue = (struct mmc_cue *)realloc(cue, ++ncue * sizeof(*cue));
  1080. cp = &cue[icue++];
  1081. fillcue(cp, ctl|0x01, i, 1, df, scms, &m);
  1082. } else {
  1083. int idx;
  1084. long *idxlist;
  1085. ncue += trackp[i].nindex;
  1086. idxlist = trackp[i].tindex;
  1087. cue = (struct mmc_cue *)realloc(cue, ncue * sizeof(*cue));
  1088. for(idx = 1; idx <=trackp[i].nindex; idx++) {
  1089. lba_to_msf(trackp[i].trackstart + idxlist[idx], &m);
  1090. cp = &cue[icue++];
  1091. fillcue(cp, ctl|0x01, i, idx, df, scms, &m);
  1092. }
  1093. }
  1094. }
  1095. }
  1096. /* Lead out */
  1097. ctl = (st2mode[trackp[tracks+1].sectype & ST_MASK]) << 4;
  1098. df = db2df[trackp[tracks+1].dbtype & 0x0F];
  1099. if (df < 0x10)
  1100. df |= 1;
  1101. else
  1102. df |= 4;
  1103. lba_to_msf(trackp[tracks+1].trackstart, &m);
  1104. cue = (struct mmc_cue *)realloc(cue, ++ncue * sizeof(*cue));
  1105. cp = &cue[icue++];
  1106. fillcue(cp, ctl|0x01, 0xAA, 1, df, 0, &m);
  1107. if (lverbose > 1) for (i = 0; i < ncue; i++) {
  1108. scsiprbytes("", (Uchar *)&cue[i], 8);
  1109. }
  1110. if (cuep)
  1111. *cuep = cue;
  1112. return (ncue);
  1113. }
  1114. LOCAL void
  1115. fillcue(cp, ca, tno, idx, dataform, scms, mp)
  1116. struct mmc_cue *cp; /* The target cue entry */
  1117. int ca; /* Control/adr for this entry */
  1118. int tno; /* Track number for this entry */
  1119. int idx; /* Index for this entry */
  1120. int dataform; /* Data format for this entry */
  1121. int scms; /* Serial copy management */
  1122. msf_t *mp; /* MSF value for this entry */
  1123. {
  1124. cp->cs_ctladr = ca; /* XXX wie lead in */
  1125. cp->cs_tno = tno;
  1126. cp->cs_index = idx;
  1127. cp->cs_dataform = dataform;/* XXX wie lead in */
  1128. cp->cs_scms = scms;
  1129. cp->cs_min = mp->msf_min;
  1130. cp->cs_sec = mp->msf_sec;
  1131. cp->cs_frame = mp->msf_frame;
  1132. }
  1133. EXPORT int
  1134. send_cue(scgp, tracks, trackp)
  1135. SCSI *scgp;
  1136. int tracks;
  1137. track_t *trackp;
  1138. {
  1139. struct mmc_cue *cp;
  1140. int ncue;
  1141. int ret;
  1142. int i;
  1143. ncue = do_cue(tracks, trackp, &cp);
  1144. for (i = 1; i <= tracks; i++) {
  1145. if (trackp[i].tracksize < 0) {
  1146. errmsgno(EX_BAD, "Track %d has unknown length.n", i);
  1147. return (-1);
  1148. }
  1149. }
  1150. ret = send_cue_sheet(scgp, (caddr_t)cp, ncue*8);
  1151. free(cp);
  1152. return (ret);
  1153. }