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

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)modes.c 1.13 99/06/06 Copyright 1988 J. Schilling */
  2. #ifndef lint
  3. static char sccsid[] =
  4. "@(#)modes.c 1.13 99/06/06 Copyright 1988 J. Schilling";
  5. #endif
  6. /*
  7.  * SCSI mode page handling
  8.  *
  9.  * Copyright (c) 1988 J. Schilling
  10.  */
  11. /*
  12.  * This program is free software; you can redistribute it and/or modify
  13.  * it under the terms of the GNU General Public License as published by
  14.  * the Free Software Foundation; either version 2, or (at your option)
  15.  * any later version.
  16.  *
  17.  * This program is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  * GNU General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU General Public License
  23.  * along with this program; see the file COPYING.  If not, write to
  24.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  25.  */
  26. #include <mconfig.h>
  27. #include <sys/types.h>
  28. #include <standard.h>
  29. #include <scg/scgcmd.h>
  30. #include <scg/scsireg.h>
  31. #include <scg/scsitransp.h>
  32. #include "cdrecord.h"
  33. EXPORT int scsi_compliant;
  34. LOCAL BOOL has_mode_page __PR((SCSI *scgp, int page, char *pagename, int *lenp));
  35. EXPORT BOOL get_mode_params __PR((SCSI *scgp, int page, char *pagename,
  36. u_char *modep, u_char *cmodep,
  37. u_char *dmodep, u_char *smodep,
  38. int *lenp));
  39. EXPORT BOOL set_mode_params __PR((SCSI *scgp, char *pagename, u_char *modep,
  40. int len, int save, int secsize));
  41. #define XXX
  42. #ifdef XXX
  43. LOCAL
  44. BOOL has_mode_page(scgp, page, pagename, lenp)
  45. SCSI *scgp;
  46. int page;
  47. char *pagename;
  48. int *lenp;
  49. {
  50. u_char mode[0x100];
  51. int hdlen;
  52. int len = 1; /* Nach SCSI Norm */
  53. int try = 0;
  54. struct scsi_mode_page_header *mp;
  55. again:
  56. fillbytes((caddr_t)mode, sizeof(mode), '');
  57. if (lenp)
  58. *lenp = 0;
  59. (void)test_unit_ready(scgp);
  60. scgp->silent++;
  61. /* Maxoptix bringt Aborted cmd 0x0B mit code 0x4E (overlapping cmds)*/
  62. /*
  63.  * The Matsushita CW-7502 will sometimes deliver a zeroed
  64.  * mode page 2A if "Page n default" is used instead of "current".
  65.  */
  66. if (mode_sense(scgp, mode, len, page, 0) < 0) { /* Page n current */
  67. scgp->silent--;
  68. return (FALSE);
  69. } else {
  70. len = ((struct scsi_mode_header *)mode)->sense_data_len + 1;
  71. }
  72. if (mode_sense(scgp, mode, len, page, 0) < 0) { /* Page n current */
  73. scgp->silent--;
  74. return (FALSE);
  75. }
  76. scgp->silent--;
  77. if (scgp->verbose)
  78. scsiprbytes("Mode Sense Data", mode, len - scsigetresid(scgp));
  79. hdlen = sizeof(struct scsi_mode_header) +
  80. ((struct scsi_mode_header *)mode)->blockdesc_len;
  81. mp = (struct scsi_mode_page_header *)(mode + hdlen);
  82. if (scgp->verbose)
  83. scsiprbytes("Mode Page  Data", (u_char *)mp, mp->p_len+2);
  84. if (mp->p_len == 0) {
  85. if (!scsi_compliant && try == 0) {
  86. len = hdlen;
  87. /*
  88.  * add sizeof page header (page # + len byte)
  89.  * (should normaly result in len == 14)
  90.  * this allowes to work with:
  91.  *  Quantum Q210S (wants at least 13)
  92.  *  MD2x (wants at least 4)
  93.  */
  94. len += 2;
  95. try++;
  96. goto again;
  97. }
  98. /* XXX if (!nowarn) */
  99. errmsgno(EX_BAD,
  100. "Warning: controller returns zero sized %s page.n",
  101. pagename);
  102. }
  103. if (!scsi_compliant &&
  104.     (len < (int)(mp->p_len + hdlen + 2))) {
  105. len = mp->p_len + hdlen + 2;
  106. /* XXX if (!nowarn) */
  107. errmsgno(EX_BAD,
  108. "Warning: controller returns wrong size for %s page.n",
  109. pagename);
  110. }
  111. if (mp->p_code != page) {
  112. /* XXX if (!nowarn) */
  113. errmsgno(EX_BAD,
  114. "Warning: controller returns wrong page %X for %s page (%X).n",
  115. mp->p_code, pagename, page);
  116. return (FALSE);
  117. }
  118. if (lenp)
  119. *lenp = len;
  120. return (mp->p_len > 0);
  121. }
  122. #endif
  123. EXPORT
  124. BOOL get_mode_params(scgp, page, pagename, modep, cmodep, dmodep, smodep, lenp)
  125. SCSI *scgp;
  126. int page;
  127. char *pagename;
  128. u_char *modep;
  129. u_char *cmodep;
  130. u_char *dmodep;
  131. u_char *smodep;
  132. int *lenp;
  133. {
  134. int len;
  135. BOOL ret = TRUE;
  136. #ifdef XXX
  137. if (lenp)
  138. *lenp = 0;
  139. if (!has_mode_page(scgp, page, pagename, &len)) {
  140. if (!scgp->silent) errmsgno(EX_BAD,
  141. "Warning: controller does not support %s page.n",
  142. pagename);
  143. return (FALSE);
  144. }
  145. if (lenp)
  146. *lenp = len;
  147. #else
  148. if (lenp == 0)
  149. len = 0xFF;
  150. #endif
  151. if (modep) {
  152. fillbytes(modep, 0x100, '');
  153. if (mode_sense(scgp, modep, len, page, 0) < 0) {/* Page x current */
  154. errmsgno(EX_BAD, "Cannot get %s data.n", pagename);
  155. ret = FALSE;
  156. } else if (scgp->verbose) {
  157. scsiprbytes("Mode Sense Data", modep, len - scsigetresid(scgp));
  158. }
  159. }
  160. if (cmodep) {
  161. fillbytes(cmodep, 0x100, '');
  162. if (mode_sense(scgp, cmodep, len, page, 1) < 0) {/* Page x change */
  163. errmsgno(EX_BAD, "Cannot get %s mask.n", pagename);
  164. ret = FALSE;
  165. } else if (scgp->verbose) {
  166. scsiprbytes("Mode Sense Data", cmodep, len - scsigetresid(scgp));
  167. }
  168. }
  169. if (dmodep) {
  170. fillbytes(dmodep, 0x100, '');
  171. if (mode_sense(scgp, dmodep, len, page, 2) < 0) {/* Page x default */
  172. errmsgno(EX_BAD, "Cannot get default %s data.n",
  173. pagename);
  174. ret = FALSE;
  175. } else if (scgp->verbose) {
  176. scsiprbytes("Mode Sense Data", dmodep, len - scsigetresid(scgp));
  177. }
  178. }
  179. if (smodep) {
  180. fillbytes(smodep, 0x100, '');
  181. if (mode_sense(scgp, smodep, len, page, 3) < 0) {/* Page x saved */
  182. errmsgno(EX_BAD, "Cannot get saved %s data.n", pagename);
  183. ret = FALSE;
  184. } else if (scgp->verbose) {
  185. scsiprbytes("Mode Sense Data", smodep, len - scsigetresid(scgp));
  186. }
  187. }
  188. return (ret);
  189. }
  190. EXPORT
  191. BOOL set_mode_params(scgp, pagename, modep, len, save, secsize)
  192. SCSI *scgp;
  193. char *pagename;
  194. u_char *modep;
  195. int len;
  196. int save;
  197. int secsize;
  198. {
  199. int i;
  200. ((struct scsi_modesel_header *)modep)->sense_data_len = 0;
  201. ((struct scsi_modesel_header *)modep)->res2 = 0;
  202. i = ((struct scsi_mode_header *)modep)->blockdesc_len;
  203. if (i > 0) {
  204. i_to_3_byte(
  205. ((struct scsi_mode_data *)modep)->blockdesc.nlblock,
  206. 0);
  207. if (secsize >= 0)
  208. i_to_3_byte(((struct scsi_mode_data *)modep)->blockdesc.lblen,
  209. secsize);
  210. }
  211. if (save == 0 || mode_select(scgp, modep, len, save, scgp->inq->data_format >= 2) < 0) {
  212. if (mode_select(scgp, modep, len, 0, scgp->inq->data_format >= 2) < 0) {
  213. errmsgno(EX_BAD,
  214.    "Warning: using default %s data.n", pagename);
  215. scsiprbytes("Mode Select Data", modep, len);
  216. return (FALSE);
  217. }
  218. }
  219. return (TRUE);
  220. }