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

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)wm_packet.c 1.11 99/01/31 Copyright 1995, 1997 J. Schilling */
  2. #ifndef lint
  3. static char sccsid[] =
  4. "@(#)wm_packet.c 1.11 99/01/31 Copyright 1995, 1997 J. Schilling";
  5. #endif
  6. /*
  7.  * CDR write method abtraction layer
  8.  * packet writing intercace routines
  9.  *
  10.  * Copyright (c) 1995, 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. #include <mconfig.h>
  28. #include <stdio.h>
  29. #include <standard.h>
  30. #include <stdxlib.h>
  31. #include <unixstd.h>
  32. /*#include <string.h>*/
  33. #include <sys/types.h>
  34. #include <utypes.h>
  35. #include <scg/scsitransp.h>
  36. #include "cdrecord.h"
  37. extern int debug;
  38. extern int verbose;
  39. extern int lverbose;
  40. extern char *buf; /* The transfer buffer */
  41. EXPORT int write_packet_data __PR((SCSI *scgp, cdr_t *dp, int track, track_t *trackp));
  42. EXPORT int
  43. write_packet_data(scgp, dp, track, trackp)
  44. SCSI *scgp;
  45. cdr_t *dp;
  46. int track;
  47. track_t *trackp;
  48. {
  49. int f;
  50. int isaudio;
  51. long startsec;
  52. long bytes_read = 0;
  53. long bytes = 0;
  54. long savbytes = 0;
  55. int count;
  56. long tracksize;
  57. int secsize;
  58. int secspt;
  59. int bytespt;
  60. long amount;
  61. int pad;
  62. int bswab;
  63. int retried;
  64. long nextblock; 
  65. int bytes_to_read;
  66. BOOL neednl = FALSE;
  67. BOOL islast = FALSE;
  68. char *bp = buf;
  69. f = trackp->f;
  70. isaudio = is_audio(trackp);
  71. tracksize = trackp->tracksize;
  72. startsec = trackp->trackstart;
  73. secsize = trackp->secsize;
  74. secspt = trackp->secspt;
  75. bytespt = secsize * secspt;
  76. pad = !isaudio && is_pad(trackp); /* Pad only data tracks */
  77. bswab = isaudio && is_swab(trackp); /* Swab only audio tracks */
  78. if (debug) {
  79. printf("secsize:%d secspt:%d bytespt:%d audio:%d pad:%dn",
  80. secsize, secspt, bytespt, isaudio, pad);
  81. }
  82. if (lverbose) {
  83. if (tracksize > 0)
  84. printf("rTrack %02d:   0 of %3ld MB written.",
  85.        track, tracksize >> 20);
  86. else
  87. printf("rTrack %02d:   0 MB written.", track);
  88. flush();
  89. neednl = TRUE;
  90. }
  91. do {
  92. bytes_to_read = bytespt;
  93. if (tracksize > 0) {
  94. bytes_to_read = tracksize - bytes_read;
  95. if (bytes_to_read > bytespt)
  96. bytes_to_read = bytespt;
  97. }
  98. count = get_buf(f, &bp, bytes_to_read);
  99. if (count < 0)
  100. comerr("read error on input filen");
  101. if (count == 0)
  102. break;
  103. bytes_read += count;
  104. if (tracksize >= 0 && bytes_read >= tracksize) {
  105. count -= bytes_read - tracksize;
  106. if (trackp->padsize == 0 || (bytes_read/secsize) >= 300)
  107. islast = TRUE;
  108. }
  109. if (bswab)
  110. swabbytes(bp, count);
  111. if (count < bytespt) {
  112. if (debug) {
  113. printf("nNOTICE: reducing block size for last record.n");
  114. neednl = FALSE;
  115. }
  116. if ((amount = count % secsize) != 0) {
  117. amount = secsize - amount;
  118. fillbytes(&bp[count], amount, '');
  119. count += amount;
  120. printf("nWARNING: padding up to secsize.n");
  121. neednl = FALSE;
  122. }
  123. if (is_packet(trackp) && trackp->pktsize > 0) {
  124. if (count < bytespt) {
  125. amount = bytespt - count;
  126. fillbytes(&bp[count], amount, '');
  127. count += amount;
  128. printf("nWARNING: padding remainder of packet.n");
  129. neednl = FALSE;
  130. }
  131. }
  132. bytespt = count;
  133. secspt = count / secsize;
  134. if (trackp->padsize == 0 || (bytes_read/secsize) >= 300)
  135. islast = TRUE;
  136. }
  137. retried = 0;
  138. retry:
  139. /* XXX Fixed-packet writes can be very slow*/
  140. if (is_packet(trackp) && trackp->pktsize > 0)
  141. scsi_settimeout(scgp, 100);
  142. /* XXX */
  143. if (is_packet(trackp) && trackp->pktsize == 0) {
  144. if ((*dp->cdr_next_wr_address)(scgp, track, trackp, &nextblock) == 0) {
  145. /*
  146.  * Some drives (e.g. Ricoh MPS6201S) do not
  147.  * increment the Next Writable Address value to
  148.  * point to the beginning of a new packet if
  149.  * their write buffer has underflowed.
  150.  */
  151. if (retried && nextblock == startsec) {
  152. startsec += 7; 
  153. } else {
  154. startsec = nextblock;
  155. }
  156. }
  157. }
  158. amount = (*dp->cdr_write_trackdata)(scgp, bp, startsec, bytespt, secspt, islast);
  159. if (amount < 0) {
  160. if (is_packet(trackp) && trackp->pktsize == 0 && !retried) {
  161. printf("%swrite track data: error after %ld bytes, retry with new packetn",
  162. neednl?"n":"", bytes);
  163. retried = 1;
  164. neednl = FALSE;
  165. goto retry;
  166. }
  167. printf("%swrite track data: error after %ld bytesn",
  168. neednl?"n":"", bytes);
  169. return (-1);
  170. }
  171. bytes += amount;
  172. startsec += amount / secsize;
  173. if (lverbose && (bytes >= (savbytes + 0x100000))) {
  174. int fper;
  175. printf("rTrack %02d: %3ld", track, bytes >> 20);
  176. if (tracksize > 0)
  177. printf(" of %3ld MB", tracksize >> 20);
  178. else
  179. printf(" MB");
  180. printf(" written");
  181. fper = fifo_percent(TRUE);
  182. if (fper >= 0)
  183. printf(" (fifo %3d%%)", fper);
  184. printf(".");
  185. savbytes = (bytes >> 20) << 20;
  186. flush();
  187. neednl = TRUE;
  188. }
  189. } while (tracksize < 0 || bytes_read < tracksize);
  190. if ((bytes / secsize) < 300) {
  191. amount = roundup(trackp->padsize, secsize);
  192. if (((bytes+amount) / secsize) < 300)
  193. trackp->padsize = 300 * secsize - bytes;
  194. }
  195. if (trackp->padsize) {
  196. if (neednl) {
  197. printf("n");
  198. neednl = FALSE;
  199. }
  200. if ((trackp->padsize >> 20) > 0) {
  201. neednl = TRUE;
  202. } else if (lverbose) {
  203. printf("Track %02d: writing %3ld KB of pad data.n",
  204. track, trackp->padsize >> 10);
  205. neednl = FALSE;
  206. }
  207. pad_track(scgp, dp, track, trackp, startsec, trackp->padsize,
  208. TRUE, &amount);
  209. bytes += amount;
  210. startsec += amount / secsize;
  211. }
  212. printf("%sTrack %02d: Total bytes read/written: %ld/%ld (%ld sectors).n",
  213.        neednl?"n":"", track, bytes_read, bytes, bytes/secsize);
  214. return 0;
  215. }